diff --git a/makefile.burn_rules b/makefile.burn_rules index 51e0d6ca5..df4a2e56f 100644 --- a/makefile.burn_rules +++ b/makefile.burn_rules @@ -112,7 +112,7 @@ depobj := $(drvobj) \ \ neo_decrypt.o neo_palette.o neo_run.o neo_sprite.o neo_text.o neo_upd4990a.o neogeo.o \ \ - pgm_crypt.o pgm_draw.o pgm_prot.o pgm_run.o \ + pgm_crypt.o pgm_draw.o pgm_run.o pgm_asic3.o pgm_asic27a_type1.o pgm_asic27a_type2.o pgm_asic27a_type3.o pgm_asic25.o \ \ psikyo_palette.o psikyo_sprite.o psikyo_tile.o psikyosh_render.o \ \ diff --git a/src/burn/drv/pgm/d_pgm.cpp b/src/burn/drv/pgm/d_pgm.cpp index 862454fa0..cd618dbad 100644 --- a/src/burn/drv/pgm/d_pgm.cpp +++ b/src/burn/drv/pgm/d_pgm.cpp @@ -61,14 +61,14 @@ static struct BurnInputInfo pgmInputList[] = { {"Dip A", BIT_DIPSWITCH, PgmInput + 6, "dip" }, {"Dip B", BIT_DIPSWITCH, PgmInput + 7, "dip" }, - {"Dip C", BIT_DIPSWITCH, PgmInput + 8, "dip" }, + {"Dip C", BIT_DIPSWITCH, PgmInput + 8, "dip" }, }; STDINPUTINFO(pgm) static struct BurnDIPInfo pgmDIPList[] = { {0x2D, 0xFF, 0xFF, 0x00, NULL }, - {0x2F, 0xFF, 0x01, 0x01, NULL }, + {0x2F, 0xFF, 0x01, 0x01, NULL }, {0, 0xFE, 0, 2, "Test mode" }, {0x2D, 0x01, 0x01, 0x00, "Off" }, @@ -101,7 +101,7 @@ STDDIPINFO(pgm) static struct BurnDIPInfo jammaDIPList[] = { {0x2D, 0xFF, 0xFF, 0x00, NULL }, - {0x2F, 0xFF, 0x01, 0x00, NULL }, + {0x2F, 0xFF, 0x01, 0x00, NULL }, {0, 0xFE, 0, 2, "Test mode" }, {0x2D, 0x01, 0x01, 0x00, "Off" }, @@ -198,7 +198,7 @@ static struct BurnDIPInfo photoy2kDIPList[] = { {0x2E, 0x01, 0x0F, 0x03, "World" }, {0x2E, 0x01, 0x0F, 0x04, "Korea" }, {0x2E, 0x01, 0x0F, 0x05, "Hong Kong" }, - {0x2E, 0x01, 0x0F, 0x06, "Singapore / Malaysia" }, + {0x2E, 0x01, 0x0F, 0x06, "Singapore / Malaysia" }, }; static struct BurnDIPInfo py2k2DIPList[] = { @@ -211,7 +211,7 @@ static struct BurnDIPInfo py2k2DIPList[] = { {0x2E, 0x01, 0x0F, 0x03, "World" }, {0x2E, 0x01, 0x0F, 0x04, "Korea" }, {0x2E, 0x01, 0x0F, 0x05, "Hong Kong" }, - {0x2E, 0x01, 0x0F, 0x06, "Singapore / Malaysia" }, + {0x2E, 0x01, 0x0F, 0x06, "Singapore / Malaysia" }, }; static struct BurnDIPInfo oldsDIPList[] = { @@ -300,7 +300,7 @@ static struct BurnDIPInfo martmastDIPList[] = { {0x2E, 0x01, 0x07, 0x03, "Korea" }, {0x2E, 0x01, 0x07, 0x04, "Hong Kong" }, {0x2E, 0x01, 0x07, 0x05, "World" }, - {0x2E, 0x01, 0x07, 0x06, "USA" }, + {0x2E, 0x01, 0x07, 0x06, "USA" }, }; static struct BurnDIPInfo martmastc102DIPList[] = { @@ -325,7 +325,7 @@ static struct BurnDIPInfo thegladDIPList[] = { {0x2E, 0x01, 0x07, 0x02, "Japan" }, {0x2E, 0x01, 0x07, 0x03, "Korea" }, {0x2E, 0x01, 0x07, 0x04, "Hong Kong" }, - {0x2E, 0x01, 0x07, 0x05, "Spanish Territories" }, + {0x2E, 0x01, 0x07, 0x05, "Spanish Territories" }, {0x2E, 0x01, 0x07, 0x06, "World" }, }; @@ -338,7 +338,7 @@ static struct BurnDIPInfo theglad100DIPList[] = { {0x2E, 0x01, 0x07, 0x02, "Japan" }, {0x2E, 0x01, 0x07, 0x03, "Korea" }, {0x2E, 0x01, 0x07, 0x04, "Hong Kong" }, - {0x2E, 0x01, 0x07, 0x05, "Spanish Territories" }, + {0x2E, 0x01, 0x07, 0x05, "Spanish Territories" }, {0x2E, 0x01, 0x07, 0x06, "World" }, }; @@ -351,7 +351,7 @@ static struct BurnDIPInfo thegladpcbDIPList[] = { {0x2E, 0x01, 0x07, 0x02, "Japan" }, {0x2E, 0x01, 0x07, 0x03, "Korea" }, {0x2E, 0x01, 0x07, 0x04, "Hong Kong" }, - {0x2E, 0x01, 0x07, 0x05, "Spanish Territories" }, + {0x2E, 0x01, 0x07, 0x05, "Spanish Territories" }, {0x2E, 0x01, 0x07, 0x06, "World" }, }; @@ -423,8 +423,8 @@ static struct BurnDIPInfo svgDIPList[] = { {0x2E, 0x01, 0x07, 0x02, "Japan" }, {0x2E, 0x01, 0x07, 0x03, "Korea" }, {0x2E, 0x01, 0x07, 0x04, "Hong Kong" }, - {0x2E, 0x01, 0x07, 0x05, "Spanish Territories" }, - {0x2E, 0x01, 0x07, 0x06, "World" }, + {0x2E, 0x01, 0x07, 0x05, "Spanish Territories" }, + {0x2E, 0x01, 0x07, 0x06, "World" }, }; static struct BurnDIPInfo svgtwDIPList[] = { @@ -436,9 +436,9 @@ static struct BurnDIPInfo svgtwDIPList[] = { {0x2E, 0x01, 0x07, 0x02, "Japan" }, {0x2E, 0x01, 0x07, 0x03, "Korea" }, {0x2E, 0x01, 0x07, 0x04, "Hong Kong" }, - {0x2E, 0x01, 0x07, 0x05, "Spanish Territories" }, - {0x2E, 0x01, 0x07, 0x06, "World" }, - {0x2E, 0x01, 0x07, 0xff, "Don't Change" }, + {0x2E, 0x01, 0x07, 0x05, "Spanish Territories" }, + {0x2E, 0x01, 0x07, 0x06, "World" }, + {0x2E, 0x01, 0x07, 0xff, "Don't Change" }, }; STDDIPINFOEXT(orlegend, pgm, orlegend ) @@ -447,8 +447,8 @@ STDDIPINFOEXT(orld111t, pgm, orld111t ) STDDIPINFOEXT(orld105k, pgm, orld105k ) STDDIPINFOEXT(orld112c, pgm, orld112c ) STDDIPINFOEXT(kov, pgm, kov ) -STDDIPINFOEXT(kov100, pgm, kov100 ) -STDDIPINFOEXT(kov2, pgm, kov2 ) +STDDIPINFOEXT(kov100, pgm, kov100 ) +STDDIPINFOEXT(kov2, pgm, kov2 ) STDDIPINFOEXT(kovshxas, pgm, kovshxas ) STDDIPINFOEXT(killbld, pgm, killbld ) STDDIPINFOEXT(killbld104, pgm, killbld104 ) @@ -456,10 +456,10 @@ STDDIPINFOEXT(photoy2k, pgm, photoy2k ) STDDIPINFOEXT(py2k2, pgm, py2k2 ) STDDIPINFOEXT(puzzli2, pgm, puzzli2 ) STDDIPINFOEXT(martmast, pgm, martmast ) -STDDIPINFOEXT(martmastc102, pgm, martmastc102 ) +STDDIPINFOEXT(martmastc102, pgm, martmastc102 ) STDDIPINFOEXT(olds, pgm, olds ) STDDIPINFOEXT(olds100, pgm, olds100 ) -STDDIPINFOEXT(olds103t, pgm, olds103t ) +STDDIPINFOEXT(olds103t, pgm, olds103t ) STDDIPINFOEXT(ddp2, pgm, ddp2 ) STDDIPINFOEXT(ddp2hk, pgm, ddp2hk ) STDDIPINFOEXT(ddp2k, pgm, ddp2k ) @@ -469,10 +469,10 @@ STDDIPINFOEXT(ddp2c, pgm, ddp2c ) STDDIPINFOEXT(theglad, pgm, theglad ) STDDIPINFOEXT(theglad100, pgm, theglad100 ) STDDIPINFOEXT(happy6, pgm, happy6 ) -STDDIPINFOEXT(svg, pgm, svg ) +STDDIPINFOEXT(svg, pgm, svg ) STDDIPINFOEXT(svgtw, pgm, svgtw ) -STDDIPINFOEXT(dmnfrntpcb, jamma, dmnfrntpcb ) -STDDIPINFOEXT(thegladpcb, jamma, thegladpcb ) +STDDIPINFOEXT(dmnfrntpcb, jamma, dmnfrntpcb ) +STDDIPINFOEXT(thegladpcb, jamma, thegladpcb ) // ----------------------------------------------------------------------------- // BIOS @@ -993,7 +993,7 @@ static struct BurnRomInfo killbldRomDesc[] = { { "m0300.u1", 0x400000, 0x93159695, 5 | BRF_SND }, // 10 Samples - { "kb_u2.rom", 0x010000, 0xde3eae63, 0 | BRF_PRG | BRF_ESS }, // 11 Protection Data + { "kb_u2.rom", 0x010000, 0xde3eae63, 9 | BRF_PRG | BRF_ESS }, // 11 Protection Data }; STDROMPICKEXT(killbld, killbld, pgm) @@ -1040,7 +1040,7 @@ static struct BurnRomInfo killbld104RomDesc[] = { { "m0300.u1", 0x400000, 0x93159695, 5 | BRF_SND }, // 13 Samples - { "kb_u2_v104.u2", 0x010000, 0xc970f6d5, 0 | BRF_PRG | BRF_ESS }, // 14 Protection Data + { "kb_u2_v104.u2", 0x010000, 0xc970f6d5, 9 | BRF_PRG | BRF_ESS }, // 14 Protection Data }; STDROMPICKEXT(killbld104, killbld104, pgm) @@ -1072,7 +1072,7 @@ static struct BurnRomInfo drgw3RomDesc[] = { { "dw3m0400.u1", 0x400000, 0x031eb9ce, 5 | BRF_SND }, // 6 Samples - { "dw3_v100.u15", 0x010000, 0x03dc4fdf, 0 | BRF_PRG | BRF_ESS }, // 7 Protection data + { "dw3_v100.u15", 0x010000, 0x03dc4fdf, 9 | BRF_PRG | BRF_ESS }, // 7 Protection data }; STDROMPICKEXT(drgw3, drgw3, pgm) @@ -1112,7 +1112,7 @@ static struct BurnRomInfo drgw3105RomDesc[] = { { "dw3m0400.u1", 0x400000, 0x031eb9ce, 5 | BRF_SND }, // 6 Samples - { "dw3_v100.u15", 0x010000, 0x03dc4fdf, 0 | BRF_PRG | BRF_ESS }, // 7 Protection data + { "dw3_v100.u15", 0x010000, 0x03dc4fdf, 9 | BRF_PRG | BRF_ESS }, // 7 Protection data }; STDROMPICKEXT(drgw3105, drgw3105, pgm) @@ -1144,7 +1144,7 @@ static struct BurnRomInfo drgw3100RomDesc[] = { { "dw3m0400.u1", 0x400000, 0x031eb9ce, 5 | BRF_SND }, // 6 Samples - { "dw3_v100.u15", 0x010000, 0x03dc4fdf, 0 | BRF_PRG | BRF_ESS }, // 7 Protection data + { "dw3_v100.u15", 0x010000, 0x03dc4fdf, 9 | BRF_PRG | BRF_ESS }, // 7 Protection data }; STDROMPICKEXT(drgw3100, drgw3100, pgm) @@ -1176,7 +1176,7 @@ static struct BurnRomInfo dwexRomDesc[] = { { "ex_m0400.u1", 0x200000, 0x42d54fd5, 5 | BRF_SND }, // 6 Samples - { "ex_data.u15", 0x010000, 0x03dc4fdf, 0 | BRF_PRG | BRF_ESS }, // 7 Protection data + { "ex_data.u15", 0x010000, 0x03dc4fdf, 9 | BRF_PRG | BRF_ESS }, // 7 Protection data }; STDROMPICKEXT(dwex, dwex, pgm) @@ -1220,9 +1220,7 @@ static struct BurnRomInfo oldsRomDesc[] = { { "m0500.rom", 0x200000, 0x37928cdd, 5 | BRF_SND }, // 18 Samples - { "sp_v101.u6", 0x010000, 0x097046bc, 0 | BRF_PRG | BRF_ESS }, // 19 Protection Rom - -// { "ram_dump", 0x004000, 0x280cfb4e, 0 | BRF_PRG | BRF_ESS }, // 20 ram dump + { "sp_v101.u6", 0x010000, 0x097046bc, 9 | BRF_PRG | BRF_ESS }, // 19 Protection Rom }; STDROMPICKEXT(olds, olds, pgm) @@ -1273,9 +1271,7 @@ static struct BurnRomInfo olds100RomDesc[] = { { "m0500.rom", 0x200000, 0x37928cdd, 5 | BRF_SND }, // 18 Samples - { "kd-u6.512", 0x010000, 0xe7613dda, 0 | BRF_PRG | BRF_ESS }, // 19 Protection Rom - -// { "ram_dump", 0x004000, 0x280cfb4e, 0 | BRF_PRG | BRF_ESS }, // 20 ram dump + { "kd-u6.512", 0x010000, 0xe7613dda, 9 | BRF_PRG | BRF_ESS }, // 19 Protection Rom }; STDROMPICKEXT(olds100, olds100, pgm) @@ -1315,9 +1311,7 @@ static struct BurnRomInfo olds100aRomDesc[] = { { "m0500.rom", 0x200000, 0x37928cdd, 5 | BRF_SND }, // 14 Samples - { "kd-u6.512", 0x010000, 0xe7613dda, 0 | BRF_PRG | BRF_ESS }, // 15 Protection Rom - -// { "ram_dump", 0x004000, 0x280cfb4e, 0 | BRF_PRG | BRF_ESS }, // 16 ram dump + { "kd-u6.512", 0x010000, 0xe7613dda, 9 | BRF_PRG | BRF_ESS }, // 15 Protection Rom }; STDROMPICKEXT(olds100a, olds100a, pgm) @@ -3764,16 +3758,16 @@ struct BurnDriver BurnDrvoldsplus = { // The Killing Blade Plus (V300) static struct BurnRomInfo killbldpRomDesc[] = { - { "v300x.u6", 0x080000, 0xb7fb8ec9, 1 | BRF_PRG | BRF_ESS }, // 0 68K Code + { "v300x.u6", 0x080000, 0xb7fb8ec9, 1 | BRF_PRG | BRF_ESS }, // 0 68K Code - { "t05701w032.bin", 0x400000, 0x567c714f, 2 | BRF_GRA }, // 1 Tile data + { "t05701w032.bin", 0x400000, 0x567c714f, 2 | BRF_GRA }, // 1 Tile data { "a05701w064.bin", 0x800000, 0x8c0c992c, 3 | BRF_GRA }, // 3 Sprite Color Data { "a05702w064.bin", 0x800000, 0x7e5b0f27, 3 | BRF_GRA }, // 4 { "a05703w064.bin", 0x800000, 0xaccbdb44, 3 | BRF_GRA }, // 5 { "b05701w064.bin", 0x800000, 0xa20cdcef, 4 | BRF_GRA }, // 6 Sprite Masks & Color Indexes - { "b05702w016.bin", 0x200000, 0xfe7457df, 4 | BRF_GRA }, // 7 + { "b05702w016.bin", 0x200000, 0xfe7457df, 4 | BRF_GRA }, // 7 { "w05701b032.bin", 0x400000, 0x2d3ae593, 5 | BRF_SND }, // 8 Samples @@ -3802,7 +3796,7 @@ INT32 killbldpInit() struct BurnDriver BurnDrvKillbldp = { "killbldp", NULL, "pgm", NULL, "2005", - "The Killing Blade Plus (V300)\0", "Incomplete Dump", "IGS", "PolyGameMaster", + "The Killing Blade Plus (V300)\0", NULL, "IGS", "PolyGameMaster", L"The Killing Blade Plus \0\u50B2\u5251\u72C2\u5200\u00A0\u52A0\u5F3A\u7248 (V300)\0", NULL, NULL, NULL, BDF_GAME_WORKING, 4, HARDWARE_IGS_PGM | HARDWARE_IGS_USE_ARM_CPU, GBF_VSFIGHT, 0, NULL, killbldpRomInfo, killbldpRomName, NULL, NULL, pgmInputInfo, pgmDIPInfo, @@ -3901,7 +3895,7 @@ static INT32 svgInit() struct BurnDriver BurnDrvSvg = { "svg", NULL, "pgm", NULL, "2005", - "S.V.G. - Spectral vs Generation (V200, China)\0", "Incomplete Dump", "IGS", "PolyGameMaster", + "S.V.G. - Spectral vs Generation (V200, China)\0", NULL, "IGS", "PolyGameMaster", L"S.V.G. - Spectral vs Generation\0\u5723\u9B54\u4E16\u7EAA (V200, China)\0", NULL, NULL, NULL, BDF_GAME_WORKING, 4, HARDWARE_IGS_PGM | HARDWARE_IGS_USE_ARM_CPU, GBF_SCRFIGHT, 0, NULL, svgRomInfo, svgRomName, NULL, NULL, pgmInputInfo, svgDIPInfo, @@ -3961,7 +3955,7 @@ static INT32 svgtwInit() struct BurnDriverD BurnDrvSvgtw = { "svgtw", "svg", "pgm", NULL, "2005", - "S.V.G. - Spectral vs Generation (V100, Taiwan)\0", "Incomplete Dump", "IGS", "PolyGameMaster", + "S.V.G. - Spectral vs Generation (V100, Taiwan)\0", "Incomplete dump", "IGS", "PolyGameMaster", L"S.V.G. - Spectral vs Generation\0\u5723\u9B54\u4E16\u7EAA (V100, Taiwan)\0", NULL, NULL, NULL, BDF_CLONE, 4, HARDWARE_IGS_PGM | HARDWARE_IGS_USE_ARM_CPU, GBF_SCRFIGHT, 0, NULL, svgtwRomInfo, svgtwRomName, NULL, NULL, pgmInputInfo, svgtwDIPInfo, @@ -3971,7 +3965,7 @@ struct BurnDriverD BurnDrvSvgtw = { // ----------------------------------------------------------------------------- -// PCB Versions! +// PCB Versions // DoDonPachi Dai-Ou-Jou (V101, Japan) @@ -4514,7 +4508,7 @@ STD_ROM_FN(thegladpcb) struct BurnDriver BurnDrvThegladpcb = { "thegladpcb", "theglad", NULL, NULL, "2003", - "The Gladiator - Road Of The Sword / Shen Jian (V100, Japan, Single PCB Version)\0", "Incomplete Dump", "IGS", "PolyGameMaster", + "The Gladiator - Road Of The Sword / Shen Jian (V100, Japan, Single PCB Version)\0", NULL, "IGS", "PolyGameMaster", L"The Gladiator - Road Of The Sword\0\u795E\u5251\u98CE\u4E91\0\u795E\u528D\u98A8\u96F2 (V100, Japan, PCB Version)\0", NULL, NULL, NULL, BDF_GAME_WORKING | BDF_CLONE, 4, HARDWARE_IGS_PGM | HARDWARE_IGS_USE_ARM_CPU, GBF_SCRFIGHT, 0, NULL, thegladpcbRomInfo, thegladpcbRomName, NULL, NULL, pgmInputInfo, thegladpcbDIPInfo, @@ -4609,7 +4603,7 @@ static INT32 svgpcbInit() struct BurnDriver BurnDrvSvgpcb = { "svgpcb", "svg", NULL, NULL, "2005", - "S.V.G. - Spectral vs Generation (V100, Japan, Single PCB Version)\0", "Incomplete Dump", "IGS", "PolyGameMaster", + "S.V.G. - Spectral vs Generation (V100, Japan, Single PCB Version)\0", NULL, "IGS", "PolyGameMaster", NULL, NULL, NULL, NULL, BDF_GAME_WORKING | BDF_CLONE, 4, HARDWARE_IGS_PGM | HARDWARE_IGS_USE_ARM_CPU, GBF_SCRFIGHT, 0, NULL, svgpcbRomInfo, svgpcbRomName, NULL, NULL, pgmInputInfo, thegladpcbDIPInfo, @@ -5239,6 +5233,7 @@ struct BurnDriver BurnDrvKovshb = { 448, 224, 4, 3 }; + // Knights of Valour: Luan Shi Quan Huang / Sangoku Senki: Luan Shi Quan Huang (ver. 203CN) static struct BurnRomInfo kovlsqhdRomDesc[] = { @@ -5272,6 +5267,7 @@ struct BurnDriverD BurnDrvkovlsqhd = { 448, 224, 4, 3 }; + // Knights of Valour: Luan Shi Quan Huang / Sangoku Senki: Luan Shi Quan Huang II (ver. 200CN, alt) static struct BurnRomInfo kovlsqh2dRomDesc[] = { diff --git a/src/burn/drv/pgm/pgm.h b/src/burn/drv/pgm/pgm.h index c999aa20e..30dfc22f2 100644 --- a/src/burn/drv/pgm/pgm.h +++ b/src/burn/drv/pgm/pgm.h @@ -21,6 +21,7 @@ extern UINT8 *PGMSPRColROM; extern UINT8 *PGMSPRMaskROM; extern UINT8 *PGMARMROM; extern UINT8 *PGMUSER0; +extern UINT8 *PGMProtROM; extern UINT8 *PGMARMRAM0; extern UINT8 *PGMARMRAM1; extern UINT8 *PGMARMRAM2; diff --git a/src/burn/drv/pgm/pgm_asic25.cpp b/src/burn/drv/pgm/pgm_asic25.cpp new file mode 100644 index 000000000..94e86488d --- /dev/null +++ b/src/burn/drv/pgm/pgm_asic25.cpp @@ -0,0 +1,959 @@ +/* + IGS Asic25 + (Asic12, Asic22, or Asic28) emulation + + Used by: + Oriental Legends Special (Asic25 + Asic28) + The Killing Blade (Asic25 + Asic22) + Dragon World 2 (Asic25 + Asic12) + Dragon World 3 (Asic25 + Asic22) +*/ + +#include "pgm.h" +#include "bitswap.h" + +static const UINT8 source_data[0x22][0xec] = +{ + { 0, }, // Region 0, not used + { // region 1, $14c21a + 0x67, 0x51, 0xf3, 0x19, 0xa0, 0x09, 0xb1, 0x21, 0xb0, 0xee, 0xe3, 0xf6, 0xbe, 0x81, 0x35, 0xe3, + 0xfb, 0xe6, 0xef, 0xdf, 0x61, 0x01, 0xfa, 0x22, 0x5d, 0x43, 0x01, 0xa5, 0x3b, 0x17, 0xd4, 0x74, + 0xf0, 0xf4, 0xf3, 0x43, 0xb5, 0x19, 0x04, 0xd5, 0x84, 0xce, 0x87, 0xfe, 0x35, 0x3e, 0xc4, 0x3c, + 0xc7, 0x85, 0x2a, 0x33, 0x00, 0x86, 0xd0, 0x4d, 0x65, 0x4b, 0xf9, 0xe9, 0xc0, 0xba, 0xaa, 0x77, + 0x9e, 0x66, 0xf6, 0x0f, 0x4f, 0x3a, 0xb6, 0xf1, 0x64, 0x9a, 0xe9, 0x25, 0x1a, 0x5f, 0x22, 0xa3, + 0xa2, 0xbf, 0x4b, 0x77, 0x3f, 0x34, 0xc9, 0x6e, 0xdb, 0x12, 0x5c, 0x33, 0xa5, 0x8b, 0x6c, 0xb1, + 0x74, 0xc8, 0x40, 0x4e, 0x2f, 0xe7, 0x46, 0xae, 0x99, 0xfc, 0xb0, 0x55, 0x54, 0xdf, 0xa7, 0xa1, + 0x0f, 0x5e, 0x49, 0xcf, 0x56, 0x3c, 0x90, 0x2b, 0xac, 0x65, 0x6e, 0xdb, 0x58, 0x3e, 0xc9, 0x00, + 0xae, 0x53, 0x4d, 0x92, 0xfa, 0x40, 0xb2, 0x6b, 0x65, 0x4b, 0x90, 0x8a, 0x0c, 0xe2, 0xa5, 0x9a, + 0xd0, 0x20, 0x29, 0x55, 0xa4, 0x44, 0xac, 0x51, 0x87, 0x54, 0x53, 0x34, 0x24, 0x4b, 0x81, 0x67, + 0x34, 0x4c, 0x5f, 0x31, 0x4e, 0xf2, 0xf1, 0x19, 0x18, 0x1c, 0x34, 0x38, 0xe1, 0x81, 0x17, 0xcf, + 0x24, 0xb9, 0x9a, 0xcb, 0x34, 0x51, 0x50, 0x59, 0x44, 0xb1, 0x0b, 0x50, 0x95, 0x6c, 0x48, 0x7e, + 0x14, 0xa4, 0xc6, 0xd9, 0xd3, 0xa5, 0xd6, 0xd0, 0xc5, 0x97, 0xf0, 0x45, 0xd0, 0x98, 0x51, 0x91, + 0x9f, 0xa3, 0x43, 0x51, 0x05, 0x90, 0xee, 0xca, 0x7e, 0x5f, 0x72, 0x53, 0xb1, 0xd3, 0xaf, 0x36, + 0x08, 0x75, 0xb0, 0x9b, 0xe0, 0x0d, 0x43, 0x88, 0xaa, 0x27, 0x44, 0x11 + }, + { // region 2, $14c126 + 0xf9, 0x19, 0xf3, 0x09, 0xa0, 0x09, 0xb0, 0x21, 0xb0, 0x22, 0xfd, 0x8e, 0xd3, 0xc8, 0x31, 0x67, + 0xc0, 0x10, 0x3c, 0xc2, 0x03, 0xf2, 0x6a, 0x0a, 0x54, 0x49, 0xca, 0xb5, 0x4b, 0xe0, 0x94, 0xe8, + 0x8d, 0xc8, 0x90, 0xee, 0x6b, 0x6f, 0xfa, 0x09, 0x76, 0x84, 0x6f, 0x55, 0xd1, 0x94, 0xca, 0x9c, + 0xe1, 0x22, 0xc6, 0x02, 0xb5, 0x8c, 0xf9, 0x3a, 0x52, 0x10, 0xf0, 0x22, 0xe4, 0x11, 0x15, 0x73, + 0x5e, 0x9e, 0xde, 0xc4, 0x5a, 0xbd, 0xa3, 0x89, 0xe7, 0x9b, 0x95, 0x5d, 0x75, 0xf6, 0xc3, 0x9f, + 0xe4, 0xcf, 0x65, 0x73, 0x90, 0xd0, 0x75, 0x56, 0xfa, 0xcc, 0xe4, 0x3e, 0x9c, 0x41, 0x81, 0x62, + 0xb1, 0xd3, 0x28, 0xbd, 0x6c, 0xed, 0x60, 0x28, 0x27, 0xee, 0xf2, 0xa1, 0xb4, 0x2c, 0x6c, 0xbb, + 0x42, 0xd7, 0x1d, 0x62, 0xc0, 0x33, 0x7d, 0xf9, 0xe4, 0x5c, 0xe2, 0x41, 0xa4, 0x1c, 0x98, 0xa1, + 0x87, 0x95, 0xad, 0x61, 0x56, 0x96, 0x40, 0x08, 0x6b, 0xe2, 0x4b, 0x95, 0x7b, 0x1b, 0xd8, 0x64, + 0xb3, 0xee, 0x9d, 0x79, 0x69, 0xea, 0x5d, 0xcf, 0x01, 0x91, 0xea, 0x3f, 0x70, 0x29, 0xdc, 0xe0, + 0x08, 0x20, 0xbf, 0x46, 0x90, 0xa8, 0xfc, 0x29, 0x14, 0xd1, 0x0d, 0x20, 0x79, 0xd2, 0x2c, 0xe9, + 0x52, 0xa6, 0x8c, 0xbd, 0xa3, 0x3e, 0x88, 0x2d, 0xb8, 0x4e, 0xf2, 0x74, 0x50, 0xcc, 0x12, 0xde, + 0xd3, 0x5a, 0xa4, 0x7b, 0xa2, 0x8d, 0x91, 0x68, 0x12, 0x0c, 0x9c, 0xb9, 0x6d, 0x26, 0x66, 0x60, + 0xc3, 0x6d, 0xd0, 0x11, 0x33, 0x05, 0x1d, 0xa8, 0xb6, 0x51, 0xe6, 0xe0, 0x58, 0x61, 0x74, 0x37, + 0xcc, 0x3a, 0x4d, 0x6a, 0x0a, 0x09, 0x71, 0xe3, 0x7e, 0xa5, 0x3b, 0xe9 + }, + { // region 3, $14E5BE + 0x73, 0x59, 0xf3, 0x09, 0xa0, 0x09, 0xb1, 0x21, 0xb0, 0x55, 0x18, 0x0d, 0xe8, 0x29, 0x2d, 0x04, + 0x85, 0x39, 0x88, 0xbe, 0x8b, 0xcb, 0xd9, 0x0b, 0x32, 0x36, 0x94, 0xac, 0x74, 0xc3, 0x3b, 0x5d, + 0x2a, 0x83, 0x46, 0xb3, 0x3a, 0xac, 0xd8, 0x55, 0x68, 0x21, 0x57, 0xab, 0x6e, 0xd1, 0xd0, 0xfc, + 0xe2, 0xbe, 0x63, 0xd0, 0x6b, 0x79, 0x23, 0x40, 0x58, 0xd4, 0xe7, 0x73, 0x22, 0x67, 0x7f, 0x88, + 0x05, 0xbd, 0xdf, 0x7a, 0x65, 0x41, 0x90, 0x3a, 0x52, 0x83, 0x28, 0xae, 0xe9, 0x8e, 0x65, 0x82, + 0x0e, 0xdf, 0x98, 0x88, 0xe1, 0x86, 0x21, 0x3e, 0x1a, 0x87, 0x6d, 0x62, 0x7a, 0xf6, 0xaf, 0x2c, + 0xd5, 0xc5, 0x10, 0x2d, 0xa9, 0xda, 0x93, 0xa1, 0x9b, 0xc7, 0x35, 0xd4, 0x15, 0x78, 0x18, 0xd5, + 0x75, 0x6a, 0xd7, 0xdb, 0x12, 0x2a, 0x6a, 0xc8, 0x36, 0x53, 0x57, 0xa6, 0xf0, 0x13, 0x67, 0x43, + 0x79, 0xf0, 0x0e, 0x49, 0xb1, 0xec, 0xcd, 0xa4, 0x8a, 0x61, 0x06, 0xb9, 0xea, 0x53, 0xf2, 0x47, + 0x7d, 0xd6, 0xf8, 0x9d, 0x2e, 0xaa, 0x27, 0x35, 0x61, 0xce, 0x9b, 0x63, 0xbc, 0x07, 0x51, 0x5a, + 0xc2, 0x0d, 0x39, 0x42, 0xd2, 0x5e, 0x21, 0x20, 0x10, 0xa0, 0xe5, 0x08, 0xf7, 0x3d, 0x28, 0x04, + 0x99, 0x93, 0x97, 0xaf, 0xf9, 0x12, 0xc0, 0x01, 0x2d, 0xea, 0xf3, 0x98, 0x0b, 0x46, 0xc2, 0x26, + 0x93, 0x10, 0x69, 0x1d, 0x71, 0x8e, 0x33, 0x00, 0x5e, 0x80, 0x2f, 0x47, 0x0a, 0xcc, 0x94, 0x16, + 0xe7, 0x37, 0x45, 0xd0, 0x61, 0x79, 0x32, 0x86, 0x08, 0x2a, 0x5b, 0x55, 0xfe, 0xee, 0x52, 0x38, + 0xaa, 0x18, 0xe9, 0x39, 0x1a, 0x1e, 0xb8, 0x26, 0x6b, 0x3d, 0x4b, 0xa9 + }, + { // region 4, $14d500 + 0x06, 0x01, 0xf3, 0x39, 0xa0, 0x09, 0xa0, 0x21, 0xb0, 0x6f, 0x32, 0x8b, 0xfd, 0x89, 0x29, 0xa0, + 0x4a, 0x62, 0xed, 0xa1, 0x2d, 0xa4, 0x49, 0xf2, 0x10, 0x3c, 0x77, 0xa3, 0x84, 0x8d, 0xfa, 0xd1, + 0xc6, 0x57, 0xe2, 0x78, 0xef, 0xe9, 0xb6, 0xa1, 0x5a, 0xbd, 0x3f, 0x02, 0x0b, 0x28, 0xd6, 0x76, + 0xfc, 0x5b, 0x19, 0x9f, 0x21, 0x66, 0x4c, 0x2d, 0x45, 0x99, 0xde, 0xab, 0x46, 0xbd, 0xe9, 0x84, + 0xc4, 0xdc, 0xc7, 0x30, 0x70, 0xdd, 0x64, 0xea, 0xbc, 0x6b, 0xd3, 0xe6, 0x45, 0x3f, 0x07, 0x7e, + 0x50, 0xef, 0xb2, 0x84, 0x33, 0x3c, 0xcc, 0x3f, 0x39, 0x5b, 0xf5, 0x6d, 0x71, 0xc5, 0xdd, 0xf5, + 0xf9, 0xd0, 0xf7, 0x9c, 0xe6, 0xc7, 0xad, 0x1b, 0x29, 0xb9, 0x90, 0x08, 0x75, 0xc4, 0xc3, 0xef, + 0xa8, 0xfc, 0xab, 0x55, 0x7c, 0x21, 0x57, 0x97, 0x87, 0x4a, 0xcb, 0x0c, 0x56, 0x0a, 0x4f, 0xcb, + 0x52, 0x33, 0x87, 0x31, 0xf3, 0x43, 0x5b, 0x41, 0x90, 0xf8, 0xc0, 0xdd, 0x5a, 0xa4, 0x26, 0x2a, + 0x60, 0xa5, 0x6d, 0xda, 0xf2, 0x6a, 0xf0, 0xb3, 0xda, 0x25, 0x33, 0x87, 0x22, 0xe4, 0xac, 0xd3, + 0x96, 0xe0, 0x99, 0x3e, 0xfb, 0x14, 0x45, 0x17, 0x25, 0x56, 0xbe, 0xef, 0x8f, 0x8e, 0x3d, 0x1e, + 0xc7, 0x99, 0xa2, 0xa1, 0x50, 0xfe, 0xdf, 0xd4, 0xa1, 0x87, 0xf4, 0xd5, 0xde, 0xa6, 0x8c, 0x6d, + 0x6c, 0xde, 0x47, 0xbe, 0x59, 0x8f, 0xd4, 0x97, 0xc3, 0xf4, 0xda, 0xbb, 0xa6, 0x73, 0xa9, 0xcb, + 0xf2, 0x01, 0xb9, 0x90, 0x8f, 0xed, 0x60, 0x64, 0x40, 0x1c, 0xb6, 0xc9, 0xa5, 0x7c, 0x17, 0x52, + 0x6f, 0xdc, 0x6d, 0x08, 0x2a, 0x1a, 0xe6, 0x68, 0x3f, 0xd4, 0x42, 0x69 + }, + { // region 5, $14bfb2 + 0x7f, 0x41, 0xf3, 0x39, 0xa0, 0x09, 0xa1, 0x21, 0xb0, 0xa2, 0x4c, 0x23, 0x13, 0xe9, 0x25, 0x3d, + 0x0f, 0x72, 0x3a, 0x9d, 0xb5, 0x96, 0xd1, 0xda, 0x07, 0x29, 0x41, 0x9a, 0xad, 0x70, 0xba, 0x46, + 0x63, 0x2b, 0x7f, 0x3d, 0xbe, 0x40, 0xad, 0xd4, 0x4c, 0x73, 0x27, 0x58, 0xa7, 0x65, 0xdc, 0xd6, + 0xfd, 0xde, 0xb5, 0x6e, 0xd6, 0x6c, 0x75, 0x1a, 0x32, 0x45, 0xd5, 0xe3, 0x6a, 0x14, 0x6d, 0x80, + 0x84, 0x15, 0xaf, 0xcc, 0x7b, 0x61, 0x51, 0x82, 0x40, 0x53, 0x7f, 0x38, 0xa0, 0xd6, 0x8f, 0x61, + 0x79, 0x19, 0xe5, 0x99, 0x84, 0xd8, 0x78, 0x27, 0x3f, 0x16, 0x97, 0x78, 0x4f, 0x7b, 0x0c, 0xa6, + 0x37, 0xdb, 0xc6, 0x0c, 0x24, 0xb4, 0xc7, 0x94, 0x9d, 0x92, 0xd2, 0x3b, 0xd5, 0x11, 0x6f, 0x0a, + 0xdb, 0x76, 0x66, 0xe7, 0xcd, 0x18, 0x2b, 0x66, 0xd8, 0x41, 0x40, 0x58, 0xa2, 0x01, 0x1e, 0x6d, + 0x44, 0x75, 0xe7, 0x19, 0x4f, 0xb2, 0xe8, 0xc4, 0x96, 0x77, 0x62, 0x02, 0xc9, 0xdc, 0x59, 0xf3, + 0x43, 0x8d, 0xc8, 0xfe, 0x9e, 0x2a, 0xba, 0x32, 0x3b, 0x62, 0xe3, 0x92, 0x6e, 0xc2, 0x08, 0x4d, + 0x51, 0xcd, 0xf9, 0x3a, 0x3e, 0xc9, 0x50, 0x27, 0x21, 0x25, 0x97, 0xd7, 0x0e, 0xf8, 0x39, 0x38, + 0xf5, 0x86, 0x94, 0x93, 0xbf, 0xeb, 0x18, 0xa8, 0xfc, 0x24, 0xf5, 0xf9, 0x99, 0x20, 0x3d, 0xcd, + 0x2c, 0x94, 0x25, 0x79, 0x28, 0x77, 0x8f, 0x2f, 0x10, 0x69, 0x86, 0x30, 0x43, 0x01, 0xd7, 0x9a, + 0x17, 0xe3, 0x47, 0x37, 0xbd, 0x62, 0x75, 0x42, 0x78, 0xf4, 0x2b, 0x57, 0x4c, 0x0a, 0xdb, 0x53, + 0x4d, 0xa1, 0x0a, 0xd6, 0x3a, 0x16, 0x15, 0xaa, 0x2c, 0x6c, 0x39, 0x42 + }, + { // region 6, $14cd82 + 0x12, 0x09, 0xf3, 0x29, 0xa0, 0x09, 0xa0, 0x21, 0xb0, 0xd5, 0x66, 0xa1, 0x28, 0x4a, 0x21, 0xc0, + 0xd3, 0x9b, 0x86, 0x80, 0x57, 0x6f, 0x41, 0xc2, 0xe4, 0x2f, 0x0b, 0x91, 0xbd, 0x3a, 0x7a, 0xba, + 0x00, 0xe5, 0x35, 0x02, 0x74, 0x7d, 0x8b, 0x21, 0x57, 0x10, 0x0f, 0xae, 0x44, 0xbb, 0xe2, 0x37, + 0x18, 0x7b, 0x52, 0x3d, 0x8c, 0x59, 0x9e, 0x20, 0x1f, 0x0a, 0xcc, 0x1c, 0x8e, 0x6a, 0xd7, 0x95, + 0x2b, 0x34, 0xb0, 0x82, 0x6d, 0xfd, 0x25, 0x33, 0xaa, 0x3b, 0x2b, 0x70, 0x15, 0x87, 0x31, 0x5d, + 0xbb, 0x29, 0x19, 0x95, 0xd5, 0x8e, 0x24, 0x28, 0x5e, 0xd0, 0x20, 0x83, 0x46, 0x4a, 0x21, 0x70, + 0x5b, 0xcd, 0xae, 0x7b, 0x61, 0xa1, 0xfa, 0xf4, 0x2b, 0x84, 0x15, 0x6e, 0x36, 0x5d, 0x1b, 0x24, + 0x0f, 0x09, 0x3a, 0x61, 0x38, 0x0f, 0x18, 0x35, 0x11, 0x38, 0xb4, 0xbd, 0xee, 0xf7, 0xec, 0x0f, + 0x1d, 0xb7, 0x48, 0x01, 0xaa, 0x09, 0x8f, 0x61, 0xb5, 0x0f, 0x1d, 0x26, 0x39, 0x2e, 0x8c, 0xd6, + 0x26, 0x5c, 0x3d, 0x23, 0x63, 0xe9, 0x6b, 0x97, 0xb4, 0x9f, 0x7b, 0xb6, 0xba, 0xa0, 0x7c, 0xc6, + 0x25, 0xa1, 0x73, 0x36, 0x67, 0x7f, 0x74, 0x1e, 0x1d, 0xda, 0x70, 0xbf, 0xa5, 0x63, 0x35, 0x39, + 0x24, 0x8c, 0x9f, 0x85, 0x16, 0xd8, 0x50, 0x95, 0x71, 0xc0, 0xf6, 0x1e, 0x6d, 0x80, 0xed, 0x15, + 0xeb, 0x63, 0xe9, 0x1b, 0xf6, 0x78, 0x31, 0xc6, 0x5c, 0xdd, 0x19, 0xbd, 0xdf, 0xa7, 0xec, 0x50, + 0x22, 0xad, 0xbb, 0xf6, 0xeb, 0xd6, 0xa3, 0x20, 0xc9, 0xe6, 0x9f, 0xcb, 0xf2, 0x97, 0xb9, 0x54, + 0x12, 0x66, 0xa6, 0xbe, 0x4a, 0x12, 0x43, 0xec, 0x00, 0xea, 0x49, 0x02 + }, + { // region 7, $14ce76 + 0xa4, 0x49, 0xf3, 0x29, 0xa0, 0x09, 0xa1, 0x21, 0xb0, 0xef, 0x80, 0x20, 0x3d, 0xaa, 0x36, 0x5d, + 0x98, 0xc4, 0xd2, 0x63, 0xdf, 0x61, 0xb0, 0xc3, 0xc2, 0x35, 0xd4, 0x88, 0xe6, 0x1d, 0x3a, 0x2f, + 0x9c, 0xb9, 0xd1, 0xc6, 0x43, 0xba, 0x69, 0x6d, 0x49, 0xac, 0xdd, 0x05, 0xe0, 0xf8, 0xe8, 0x97, + 0x19, 0x18, 0x08, 0x0c, 0x42, 0x46, 0xc7, 0x0d, 0x25, 0xce, 0xc3, 0x54, 0xb2, 0xd9, 0x42, 0x91, + 0xea, 0x53, 0x98, 0x38, 0x78, 0x81, 0x12, 0xca, 0x15, 0x23, 0xbd, 0xc1, 0x70, 0x1f, 0xd2, 0x40, + 0xfd, 0x39, 0x33, 0xaa, 0x27, 0x2b, 0xe8, 0x10, 0x7d, 0xa4, 0xa8, 0x8e, 0x3d, 0x00, 0x4f, 0x3a, + 0x7f, 0xd8, 0x96, 0xea, 0x9e, 0x8e, 0x15, 0x6e, 0x9f, 0x76, 0x57, 0xba, 0x7d, 0xc2, 0xdf, 0x57, + 0x42, 0x82, 0xf4, 0xda, 0x89, 0x06, 0x05, 0x04, 0x62, 0x2f, 0x29, 0x23, 0x54, 0xd5, 0xbb, 0x97, + 0xf5, 0xf9, 0xc1, 0xcf, 0xec, 0x5f, 0x1d, 0xfd, 0xbb, 0xa6, 0xd7, 0x4a, 0xa8, 0x66, 0xbf, 0xb9, + 0x09, 0x44, 0xb1, 0x60, 0x28, 0xa9, 0x35, 0x16, 0x15, 0xf5, 0x13, 0xc1, 0x07, 0x7e, 0xd7, 0x40, + 0xdf, 0x8e, 0xd3, 0x32, 0xa9, 0x35, 0x98, 0x15, 0x32, 0xa9, 0x49, 0xc0, 0x24, 0xb4, 0x4a, 0x53, + 0x6b, 0x79, 0xaa, 0x77, 0x6c, 0xc5, 0x88, 0x69, 0xe5, 0x5d, 0xde, 0x42, 0x28, 0xf9, 0xb7, 0x5c, + 0xab, 0x19, 0xc7, 0xbc, 0xc5, 0x60, 0xeb, 0x5e, 0xa8, 0x52, 0xc4, 0x32, 0x7c, 0x35, 0x02, 0x06, + 0x46, 0x77, 0x30, 0xb6, 0x33, 0x4b, 0xb8, 0xfd, 0x02, 0xd8, 0x14, 0x40, 0x99, 0x25, 0x7e, 0x55, + 0xd6, 0x44, 0x43, 0x8d, 0x73, 0x0e, 0x71, 0x48, 0xd3, 0x82, 0x40, 0xda + }, + { 0, }, // unused region 08 + { 0, }, // unused region 09 + { 0, }, // unused region 0a + { 0, }, // unused region 0b + { 0, }, // unused region 0c + { 0, }, // unused region 0d + { 0, }, // unused region 0e + { 0, }, // unused region 0f + { 0, }, // unused region 10 + { 0, }, // unused region 11 + { 0, }, // unused region 12 + { 0, }, // unused region 13 + { 0, }, // unused region 14 + { 0, }, // unused region 15 + { // region 16, $178772 + 0x5e, 0x09, 0xb3, 0x39, 0x60, 0x71, 0x71, 0x53, 0x11, 0xe5, 0x26, 0x34, 0x4c, 0x8c, 0x90, 0xee, + 0xed, 0xb5, 0x05, 0x95, 0x9e, 0x6b, 0xdd, 0x87, 0x0e, 0x7b, 0xed, 0x33, 0xaf, 0xc2, 0x62, 0x98, + 0xec, 0xc8, 0x2c, 0x2b, 0x57, 0x3d, 0x00, 0xbd, 0x12, 0xac, 0xba, 0x64, 0x81, 0x99, 0x16, 0x29, + 0xb4, 0x63, 0xa8, 0xd9, 0xc9, 0x5f, 0xfe, 0x21, 0xbb, 0xbf, 0x9b, 0xd1, 0x7b, 0x93, 0xc4, 0x82, + 0xef, 0x2b, 0xe8, 0xa6, 0xdc, 0x68, 0x3a, 0xd9, 0xc9, 0x23, 0xc7, 0x7b, 0x98, 0x5b, 0xe1, 0xc7, + 0xa3, 0xd4, 0x51, 0x0a, 0x86, 0x30, 0x20, 0x51, 0x6e, 0x04, 0x1c, 0xd4, 0xfb, 0xf5, 0x22, 0x8f, + 0x16, 0x6f, 0xb9, 0x59, 0x30, 0xcf, 0xab, 0x32, 0x1d, 0x6c, 0x84, 0xab, 0x23, 0x90, 0x94, 0xb1, + 0xe7, 0x4b, 0x6d, 0xc1, 0x84, 0xba, 0x32, 0x68, 0xa3, 0xf2, 0x47, 0x28, 0xe5, 0xcb, 0xbb, 0x47, + 0x14, 0x2c, 0xad, 0x4d, 0xa1, 0xd7, 0x18, 0x53, 0xf7, 0x6f, 0x05, 0x81, 0x8f, 0xbb, 0x29, 0xdc, + 0xbd, 0x17, 0x61, 0x92, 0x9b, 0x1d, 0x4e, 0x7a, 0x83, 0x14, 0x9f, 0x7b, 0x7a, 0x6a, 0xe1, 0x27, + 0x62, 0x52, 0x7e, 0x82, 0x45, 0xda, 0xed, 0xf1, 0x0a, 0x3b, 0x6c, 0x02, 0x5b, 0x6e, 0x45, 0x4e, + 0xf2, 0x65, 0x87, 0x1d, 0x80, 0xed, 0x6a, 0xc3, 0x77, 0xcb, 0xe8, 0x8d, 0x5a, 0xb8, 0xda, 0x89, + 0x88, 0x4b, 0x27, 0xd5, 0x57, 0x29, 0x91, 0x86, 0x12, 0xbb, 0xd3, 0x8c, 0xc7, 0x49, 0x84, 0x9c, + 0x96, 0x59, 0x30, 0x93, 0x92, 0xeb, 0x59, 0x2b, 0x93, 0x5b, 0x5f, 0xf9, 0x67, 0xac, 0x97, 0x8c, + 0x04, 0xda, 0x1b, 0x65, 0xd7, 0xef, 0x44, 0xca, 0xc4, 0x87, 0x18, 0x2b + }, + { // region 17, $178a36 + 0xd7, 0x49, 0xb3, 0x39, 0x60, 0x71, 0x70, 0x53, 0x11, 0x00, 0x27, 0xb2, 0x61, 0xd3, 0x8c, 0x8b, + 0xb2, 0xde, 0x6a, 0x78, 0x40, 0x5d, 0x4d, 0x88, 0xeb, 0x81, 0xd0, 0x2a, 0xbf, 0x8c, 0x22, 0x0d, + 0x89, 0x83, 0xc8, 0xef, 0x0d, 0x7a, 0xf6, 0xf0, 0x1d, 0x49, 0xa2, 0xd3, 0x1e, 0xef, 0x1c, 0xa2, + 0xce, 0x00, 0x5e, 0xa8, 0x7f, 0x4c, 0x41, 0x27, 0xa8, 0x6b, 0x92, 0x0a, 0xb8, 0x03, 0x2f, 0x7e, + 0xaf, 0x4a, 0xd0, 0x5c, 0xce, 0xeb, 0x0e, 0x8a, 0x4d, 0x0b, 0x73, 0xb3, 0xf3, 0x0c, 0x83, 0xaa, + 0xe5, 0xe4, 0x84, 0x06, 0xd7, 0xcc, 0xcb, 0x52, 0x8d, 0xbe, 0xa4, 0xdf, 0xd9, 0xab, 0x50, 0x59, + 0x53, 0x61, 0xa1, 0xc8, 0x6d, 0xbc, 0xde, 0xab, 0xaa, 0x5e, 0xc6, 0xf7, 0x83, 0xdc, 0x40, 0xcb, + 0x1b, 0xdd, 0x28, 0x3b, 0xee, 0xb1, 0x1f, 0x37, 0xdb, 0xe9, 0xbb, 0x74, 0x4b, 0xc2, 0x8a, 0xe8, + 0xec, 0x6e, 0x0e, 0x35, 0xe3, 0x2e, 0xbe, 0xef, 0xfd, 0x07, 0xbf, 0x8c, 0xfe, 0xf3, 0x5c, 0xbf, + 0x87, 0xe5, 0xbc, 0xcf, 0x60, 0xdc, 0x18, 0xf8, 0xfc, 0x51, 0x50, 0x86, 0xc6, 0x48, 0x3d, 0xb9, + 0x1d, 0x26, 0xf7, 0x7e, 0x87, 0x90, 0x12, 0xe8, 0x06, 0x0a, 0x45, 0xe9, 0xd9, 0xd8, 0x41, 0x68, + 0x21, 0x52, 0x92, 0x0f, 0xd6, 0xda, 0xa2, 0x97, 0xeb, 0x68, 0xd0, 0xb1, 0x15, 0x19, 0x8b, 0xd0, + 0x48, 0x1a, 0xeb, 0x90, 0x3f, 0x2a, 0x33, 0x1e, 0x5e, 0x30, 0x66, 0x01, 0x64, 0xef, 0x99, 0x52, + 0xba, 0x23, 0xbd, 0x53, 0xc0, 0x60, 0x87, 0x09, 0xcb, 0x4d, 0xd3, 0x87, 0x0e, 0x3a, 0x5c, 0x8d, + 0xc8, 0xb8, 0xb7, 0x34, 0x01, 0xeb, 0x72, 0x0d, 0xb1, 0x1f, 0x0f, 0xea + }, + { // region 18, $17dac4 + 0x6a, 0x13, 0xb3, 0x09, 0x60, 0x79, 0x61, 0x53, 0x11, 0x33, 0x41, 0x31, 0x76, 0x34, 0x88, 0x0f, + 0x77, 0x08, 0xb6, 0x74, 0xc8, 0x36, 0xbc, 0x70, 0xe2, 0x87, 0x9a, 0x21, 0xe8, 0x56, 0xe1, 0x9a, + 0x26, 0x57, 0x7e, 0x9b, 0xdb, 0xb7, 0xd4, 0x3d, 0x0f, 0xfe, 0x8a, 0x2a, 0xba, 0x2d, 0x22, 0x03, + 0xcf, 0x9c, 0xfa, 0x77, 0x35, 0x39, 0x6a, 0x14, 0xae, 0x30, 0x89, 0x42, 0xdc, 0x59, 0xb2, 0x93, + 0x6f, 0x82, 0xd1, 0x12, 0xd9, 0x88, 0xfa, 0x3b, 0xb7, 0x0c, 0x1f, 0x05, 0x68, 0xa3, 0x0c, 0xa6, + 0x0f, 0xf4, 0x9e, 0x1b, 0x29, 0x82, 0x77, 0x3a, 0xac, 0x92, 0x2d, 0x04, 0xd0, 0x61, 0x65, 0x0a, + 0x77, 0x6c, 0x89, 0x38, 0xaa, 0xa9, 0xf8, 0x0c, 0x1f, 0x37, 0x09, 0x2b, 0xca, 0x29, 0x05, 0xe5, + 0x4e, 0x57, 0xfb, 0xcd, 0x40, 0xa8, 0x0c, 0x06, 0x2d, 0xe0, 0x30, 0xd9, 0x97, 0xb9, 0x59, 0x8a, + 0xde, 0xc9, 0x87, 0x1d, 0x3f, 0x84, 0x4c, 0x73, 0x04, 0x85, 0x61, 0xb0, 0x6e, 0x2c, 0x8f, 0xa2, + 0x6a, 0xcd, 0x31, 0xf3, 0x25, 0x83, 0xe1, 0x5e, 0x5d, 0xa7, 0xe7, 0xaa, 0x13, 0x26, 0xb1, 0x33, + 0xf0, 0x13, 0x58, 0x7a, 0xb0, 0x46, 0x1d, 0xdf, 0x02, 0xbf, 0x1e, 0xd1, 0x71, 0x43, 0x56, 0x82, + 0x4f, 0x58, 0x9d, 0x01, 0x2d, 0xc7, 0xda, 0x6b, 0x47, 0x05, 0xd1, 0xd5, 0xe8, 0x92, 0x3c, 0x18, + 0x21, 0xcf, 0xc9, 0x32, 0x0e, 0x12, 0xed, 0xb5, 0xaa, 0xa4, 0x12, 0x75, 0x01, 0x7d, 0xc7, 0x21, + 0xde, 0xec, 0x32, 0x13, 0xee, 0xd4, 0x9c, 0xe6, 0x04, 0x3f, 0x48, 0xfb, 0xb4, 0xc7, 0x21, 0x8e, + 0x8d, 0x7d, 0x54, 0x03, 0x11, 0xe7, 0xb9, 0x4f, 0x85, 0xb6, 0x1f, 0xaa + }, + { // region 19, $178eee + 0xe3, 0x53, 0xb3, 0x09, 0x60, 0x79, 0x60, 0x53, 0x11, 0x66, 0x5b, 0xc8, 0x8b, 0x94, 0x84, 0xab, + 0x3c, 0x18, 0x03, 0x57, 0x6a, 0x0f, 0x45, 0x58, 0xc0, 0x74, 0x64, 0x18, 0xf8, 0x39, 0xa1, 0x0f, + 0xc2, 0x2b, 0x1b, 0x60, 0xaa, 0x0e, 0xb2, 0x89, 0x01, 0x9b, 0x72, 0x80, 0x57, 0x83, 0x28, 0x63, + 0xe9, 0x39, 0x97, 0x46, 0xea, 0x3f, 0x93, 0x01, 0x9b, 0xf4, 0x80, 0x93, 0x01, 0xaf, 0x1d, 0x8f, + 0x16, 0xa1, 0xb9, 0xc7, 0xe4, 0x0c, 0xe7, 0xd2, 0x3b, 0xf3, 0xca, 0x3d, 0xc3, 0x54, 0xad, 0x89, + 0x51, 0x1e, 0xd1, 0x17, 0x7a, 0x1f, 0x23, 0x22, 0xcb, 0x4d, 0xce, 0x0f, 0xae, 0x30, 0x93, 0xd3, + 0x9b, 0x77, 0x71, 0xa7, 0xe7, 0x96, 0x2c, 0x85, 0xac, 0x29, 0x4b, 0x5e, 0x2b, 0x75, 0xb0, 0x00, + 0x81, 0xe9, 0xb6, 0x47, 0xaa, 0x9f, 0xdf, 0xd4, 0x7e, 0xd7, 0xa4, 0x3f, 0xe3, 0xb0, 0x41, 0x2c, + 0xb7, 0x0c, 0xe7, 0xeb, 0x9a, 0xda, 0xd9, 0x10, 0x23, 0x1d, 0x1c, 0xd4, 0xdd, 0x7d, 0xc2, 0x6c, + 0x4d, 0x9c, 0xa5, 0x18, 0xd0, 0x43, 0xab, 0xdc, 0xbd, 0xe4, 0x7f, 0xb5, 0x5f, 0x04, 0x0d, 0xac, + 0xab, 0xe6, 0xb8, 0x76, 0xf2, 0x15, 0x41, 0xef, 0x17, 0x8e, 0xf6, 0xb9, 0xef, 0x94, 0x52, 0x83, + 0x96, 0x45, 0x8f, 0xf2, 0x9c, 0xb4, 0x13, 0x3f, 0xbb, 0xa1, 0xd2, 0xf9, 0xa3, 0xf2, 0x06, 0x78, + 0xe0, 0x9e, 0xa7, 0xd3, 0xdc, 0x13, 0x8f, 0x4d, 0xf6, 0x19, 0xbd, 0x03, 0x9d, 0x24, 0xdc, 0xd6, + 0xe9, 0xcf, 0xa6, 0xd2, 0x1d, 0x49, 0xca, 0xc4, 0x55, 0x18, 0xbc, 0x70, 0x5b, 0x55, 0xfe, 0x8f, + 0x6b, 0x42, 0xf0, 0xd1, 0x21, 0xe3, 0xe7, 0x91, 0x59, 0x4e, 0x16, 0x83 + }, + { 0, }, // unused region 1a + { 0, }, // unused region 1b + { 0, }, // unused region 1c + { 0, }, // unused region 1d + { 0, }, // unused region 1e + { 0, }, // unused region 1f + { // region 20, $17a322 + 0xb3, 0x10, 0xf3, 0x0b, 0xe0, 0x71, 0x60, 0x53, 0x11, 0x9a, 0x12, 0x70, 0x1f, 0x1e, 0x81, 0xda, + 0x9d, 0x1f, 0x4b, 0xd6, 0x71, 0x48, 0x83, 0xe1, 0x04, 0x6c, 0x1b, 0xf1, 0xcd, 0x09, 0xdf, 0x3e, + 0x0b, 0xaa, 0x95, 0xc1, 0x07, 0xec, 0x0f, 0x54, 0xd0, 0x16, 0xb0, 0xdc, 0x86, 0x7b, 0x52, 0x38, + 0x3c, 0x68, 0x2b, 0xed, 0xe2, 0xeb, 0xb3, 0xc6, 0x48, 0x24, 0x41, 0x36, 0x17, 0x25, 0x1f, 0xa5, + 0x22, 0xc6, 0x5c, 0xa6, 0x19, 0xef, 0x17, 0x5c, 0x56, 0x4b, 0x4a, 0x2b, 0x75, 0xab, 0xe6, 0x22, + 0xd5, 0xc0, 0xd3, 0x46, 0xcc, 0xe4, 0xd4, 0xc4, 0x8c, 0x9a, 0x8a, 0x75, 0x24, 0x73, 0xa4, 0x26, + 0xca, 0x79, 0xaf, 0xb3, 0x94, 0x2a, 0x15, 0xbe, 0x40, 0x7b, 0x4d, 0xf6, 0xb4, 0xa4, 0x7b, 0xcf, + 0xce, 0xa0, 0x1d, 0xcb, 0x2f, 0x60, 0x28, 0x63, 0x85, 0x98, 0xd3, 0xd2, 0x45, 0x3f, 0x02, 0x65, + 0xd7, 0xf4, 0xbc, 0x2a, 0xe7, 0x50, 0xd1, 0x3f, 0x7f, 0xf6, 0x05, 0xb8, 0xe9, 0x39, 0x10, 0x6e, + 0x68, 0xa8, 0x89, 0x60, 0x00, 0x68, 0xfd, 0x20, 0xc4, 0xdc, 0xef, 0x67, 0x75, 0xfb, 0xbe, 0xfe, + 0x2b, 0x16, 0xa6, 0x5a, 0x77, 0x0d, 0x0c, 0xe2, 0x2d, 0xd1, 0xe4, 0x11, 0xc9, 0x4b, 0x81, 0x3a, + 0x0c, 0x24, 0xaa, 0x77, 0x2b, 0x2f, 0x83, 0x23, 0xd1, 0xe9, 0xa7, 0x29, 0x0a, 0xf9, 0x26, 0x9d, + 0x51, 0xc8, 0x6d, 0x71, 0x9d, 0xce, 0x46, 0x72, 0x26, 0x48, 0x3d, 0x64, 0xe5, 0x67, 0xbb, 0x1a, + 0xb4, 0x6d, 0x21, 0x11, 0x79, 0x78, 0xc2, 0xd5, 0x11, 0x6a, 0xd2, 0xea, 0x03, 0x4d, 0x92, 0xaf, + 0x18, 0xd5, 0x07, 0x79, 0xaa, 0xf9, 0x44, 0x93, 0x6f, 0x41, 0x22, 0x0d + }, + { // region 21, $17b3b4 + 0x2d, 0x50, 0xf3, 0x0b, 0xe0, 0x71, 0x61, 0x53, 0x11, 0xb4, 0x2c, 0xee, 0x34, 0x7e, 0x7d, 0x5e, + 0x62, 0x48, 0x97, 0xd2, 0xf9, 0x3a, 0xf2, 0xc9, 0xfa, 0x59, 0xe4, 0xe8, 0xf6, 0xd2, 0x9f, 0xb2, + 0xa7, 0x7e, 0x32, 0x86, 0xbc, 0x43, 0xec, 0xa0, 0xc2, 0xcb, 0x98, 0x33, 0x23, 0xd1, 0x58, 0x98, + 0x56, 0x05, 0xc7, 0xbc, 0x98, 0xd8, 0xdc, 0xb3, 0x35, 0xe8, 0x51, 0x6e, 0x3b, 0x7b, 0x89, 0xba, + 0xe1, 0xe5, 0x44, 0x5c, 0x24, 0x73, 0x04, 0x0d, 0xd9, 0x33, 0xf5, 0x63, 0xe9, 0x5c, 0x88, 0x05, + 0x18, 0xd0, 0x07, 0x5b, 0x1e, 0x81, 0x80, 0xac, 0x92, 0x6e, 0x13, 0x80, 0x1b, 0x29, 0xd2, 0xef, + 0x08, 0x84, 0x97, 0x23, 0xd1, 0x17, 0x2f, 0x38, 0xb4, 0x6d, 0x8f, 0x2a, 0x15, 0xf0, 0x40, 0xe9, + 0x02, 0x33, 0xd7, 0x5e, 0x99, 0x57, 0x15, 0x32, 0xbd, 0x8f, 0x48, 0x38, 0x91, 0x36, 0xe9, 0x07, + 0xc9, 0x37, 0x1d, 0x12, 0x2a, 0xbf, 0x5f, 0xdb, 0x85, 0x75, 0xbf, 0xdc, 0x59, 0x8a, 0x43, 0x51, + 0x4b, 0x77, 0xfd, 0x84, 0xc4, 0x28, 0xc7, 0x85, 0x25, 0x1a, 0x87, 0x8b, 0xc1, 0xd9, 0x1a, 0x78, + 0xe5, 0x03, 0x20, 0x56, 0xa0, 0xc2, 0x17, 0xf2, 0x29, 0xa0, 0xbd, 0xf8, 0x61, 0x9c, 0x7d, 0x54, + 0x3a, 0x11, 0xb5, 0x69, 0x9a, 0x1c, 0xbb, 0xf6, 0x2d, 0x86, 0xa8, 0x4d, 0xdd, 0x5a, 0xd6, 0xe4, + 0x11, 0x7e, 0x4b, 0x13, 0x6c, 0xb6, 0x01, 0x0a, 0x72, 0xbc, 0xe8, 0xf1, 0x82, 0x0e, 0xd0, 0xcf, + 0xbf, 0x50, 0x95, 0xb7, 0xa7, 0xec, 0xd7, 0xb3, 0x49, 0x5c, 0x47, 0x5f, 0xa9, 0xda, 0x70, 0xb0, + 0xdc, 0x9a, 0xa3, 0x48, 0xd3, 0xf5, 0x72, 0xd5, 0x43, 0xd8, 0x19, 0xcc + } +}; + +static UINT16 *sharedprotram; + +static UINT32 kb_regs[0x100]; +static UINT16 kb_prot_hold; +static UINT16 kb_prot_hilo; +static UINT32 kb_ptr; +static UINT8 kb_region; +static UINT8 kb_cmd; +static UINT8 kb_reg; +static UINT8 kb_swap; +static UINT8 kb_cmd3; +static UINT8 olds_bs; +static UINT32 kb_prot_hilo_select; +static UINT32 kb_game_id; + +static void IGS022_do_dma(UINT16 src, UINT16 dst, UINT16 size, UINT16 mode) +{ + UINT16 param = mode >> 8; + + bprintf (0, _T("src: %4.4x, dst: %4.4x, size: %4.4x, mode: %4.4x\n"), src,dst,size,mode); + + mode &= 0x7; // what are the other bits? + + if ((mode == 0) || (mode == 1) || (mode == 2) || (mode == 3) || (mode == 4)) + { + UINT16 *PROTROM = (UINT16*)PGMProtROM; + for (INT32 x = 0; x < size; x++) + { + UINT16 dat2 = BURN_ENDIAN_SWAP_INT16(PROTROM[src + x]); + + UINT8 extraoffset = param&0xff; + UINT8* dectable = PGMProtROM; + UINT8 taboff = ((x*2)+extraoffset) & 0xff; + UINT16 extraxor = ((dectable[taboff+0]) << 8) | (dectable[taboff+1] << 0); + + dat2 = ((dat2 & 0x00ff)<<8) | ((dat2 & 0xff00)>>8); + + if (mode==4) + { + extraxor = 0; + if ((x & 0x003) == 0x000) extraxor |= 0x0049; // 'I' + if ((x & 0x003) == 0x001) extraxor |= 0x0047; // 'G' + if ((x & 0x003) == 0x002) extraxor |= 0x0053; // 'S' + if ((x & 0x003) == 0x003) extraxor |= 0x0020; // ' ' + if ((x & 0x300) == 0x000) extraxor |= 0x4900; // 'I' + if ((x & 0x300) == 0x100) extraxor |= 0x4700; // 'G' + if ((x & 0x300) == 0x200) extraxor |= 0x5300; // 'S' + if ((x & 0x300) == 0x300) extraxor |= 0x2000; // ' ' + + // extraxor = (extraxor << 8) | (extraxor >> 8); // + } + + // mode==0 plain + if (mode==3) dat2 ^= extraxor; + if (mode==2) dat2 += extraxor; + if (mode==1) dat2 -= extraxor; + + if (mode==4) + { + dat2 -= extraxor; + } + + sharedprotram[dst + x] = BURN_ENDIAN_SWAP_INT16(dat2); + } + } + else if (mode == 5) + { + UINT16 *PROTROM = (UINT16*)PGMProtROM; + + for (INT32 x = 0; x < size; x++) + { + UINT16 dat2 = BURN_ENDIAN_SWAP_INT16(PROTROM[src + x]); + + sharedprotram[dst + x] = dat2; + } + } + else if (mode == 6) + { + UINT16 *PROTROM = (UINT16*)PGMProtROM; + for (INT32 x = 0; x < size; x++) + { + UINT16 dat2 = PROTROM[src + x]; + + dat2 = ((dat2 & 0xf000) >> 12)| + ((dat2 & 0x0f00) >> 4)| + ((dat2 & 0x00f0) << 4)| + ((dat2 & 0x000f) << 12); + + sharedprotram[dst + x] = dat2; + } + } +} + +static void IGS022_reset() +{ + INT32 i; + UINT16 *PROTROM = (UINT16*)PGMProtROM; + UINT16 tmp; + + // fill ram with A5 patern + for (i = 0; i < 0x4000/2; i++) + sharedprotram[i] = BURN_ENDIAN_SWAP_INT16(0xa55a); + + // the auto-dma + UINT16 src = BURN_ENDIAN_SWAP_INT16(PROTROM[0x100 / 2]); + UINT32 dst = BURN_ENDIAN_SWAP_INT16(PROTROM[0x102 / 2]); + UINT16 size = BURN_ENDIAN_SWAP_INT16(PROTROM[0x104/ 2]); + UINT16 mode = BURN_ENDIAN_SWAP_INT16(PROTROM[0x106 / 2]); + + src = ((src & 0xff00) >> 8) | ((src & 0x00ff) << 8); + dst = ((dst & 0xff00) >> 8) | ((dst & 0x00ff) << 8); + size = ((size & 0xff00) >> 8) | ((size & 0x00ff) << 8); + mode &= 0xff; + + src >>= 1; + + IGS022_do_dma(src,dst,size,mode); + + // there is also a version ID? (or is it some kind of checksum) that is stored in the data rom, and gets copied.. + // Dragon World 3 checks it + tmp = BURN_ENDIAN_SWAP_INT16(PROTROM[0x114/2]); + tmp = ((tmp & 0xff00) >> 8) | ((tmp & 0x00ff) << 8); + sharedprotram[0x2a2/2] = BURN_ENDIAN_SWAP_INT16(tmp); +} + +static void IGS022_handle_command() +{ + UINT16 cmd = sharedprotram[0x200/2]; + + if (cmd == 0x6d) // Store values to asic ram + { + UINT32 p1 = (sharedprotram[0x298/2] << 16) | sharedprotram[0x29a/2]; + UINT32 p2 = (sharedprotram[0x29c/2] << 16) | sharedprotram[0x29e/2]; + + if ((p2 & 0xffff) == 0x9) // Set value + { + INT32 reg = (p2 >> 16) & 0xffff; + + if (reg & 0x300) { // 300?? killbld expects 0x200, drgw3 expects 0x100? + kb_regs[reg & 0xff] = p1; + } + } + + if ((p2 & 0xffff) == 0x6) // Add value + { + INT32 src1 = (p1 >> 16) & 0xff; + INT32 src2 = (p1 >> 0) & 0xff; + INT32 dst = (p2 >> 16) & 0xff; + + kb_regs[dst] = kb_regs[src2] - kb_regs[src1]; + } + + if ((p2 & 0xffff) == 0x1) // Add Imm? + { + INT32 reg = (p2 >> 16) & 0xff; + INT32 imm = (p1 >> 0) & 0xffff; + + kb_regs[reg] += imm; + } + + if ((p2 & 0xffff) == 0xa) // Get value + { + INT32 reg = (p1 >> 16) & 0xFF; + + sharedprotram[0x29c/2] = (kb_regs[reg] >> 16) & 0xffff; + sharedprotram[0x29e/2] = kb_regs[reg] & 0xffff; + } + + sharedprotram[0x202 / 2] = 0x7c; // this mode complete? + } + + // Is this actually what this is suppose to do? Complete guess. + if (cmd == 0x12) // copy?? + { + sharedprotram[0x28c / 2] = sharedprotram[0x288 / 2]; + sharedprotram[0x28e / 2] = sharedprotram[0x28a / 2]; + + sharedprotram[0x202 / 2] = 0x23; // this mode complete? + } + + // what do these do? write the completion byte for now... + if (cmd == 0x45) sharedprotram[0x202 / 2] = 0x56; + if (cmd == 0x5a) sharedprotram[0x202 / 2] = 0x4b; + if (cmd == 0x2d) sharedprotram[0x202 / 2] = 0x3c; + + if (cmd == 0x4f) // memcpy with encryption / scrambling + { + UINT16 src = sharedprotram[0x290 / 2] >> 1; + UINT32 dst = sharedprotram[0x292 / 2]; + UINT16 size = sharedprotram[0x294 / 2]; + UINT16 mode = sharedprotram[0x296 / 2]; + + IGS022_do_dma(src,dst,size,mode); + + sharedprotram[0x202 / 2] = 0x5e; // this mode complete? + } +} + +static UINT32 olds_prot_addr(UINT16 addr) +{ + switch (addr & 0xff) + { + case 0x0: + case 0x5: + case 0xa: return 0x402a00 + ((addr >> 8) << 2); + case 0x2: + case 0x8: return 0x402e00 + ((addr >> 8) << 2); + case 0x1: return 0x40307e; + case 0x3: return 0x403090; + case 0x4: return 0x40309a; + case 0x6: return 0x4030a4; + case 0x7: return 0x403000; + case 0x9: return 0x40306e; + case 0xb: return 0x403044; + } + + return 0; +} + +static UINT32 olds_read_reg(UINT16 addr) +{ + UINT32 protaddr = (olds_prot_addr(addr) - 0x400000) / 2; + return sharedprotram[protaddr] << 16 | sharedprotram[protaddr + 1]; +} + +static void olds_write_reg( UINT16 addr, UINT32 val ) +{ + sharedprotram[((olds_prot_addr(addr) - 0x400000) / 2) + 0] = val >> 16; + sharedprotram[((olds_prot_addr(addr) - 0x400000) / 2) + 1] = val & 0xffff; +} + +static void IGS028_do_dma(UINT16 src, UINT16 dst, UINT16 size, UINT16 mode) +{ + UINT16 param = mode >> 8; + UINT16 *PROTROM = (UINT16*)(PGMUSER0 + 0x10000); + + mode &= 0x0f; + + switch (mode & 0x7) + { + case 0x00: // -= encryption + case 0x01: // swap nibbles + case 0x02: // ^= encryption + case 0x03: // unused? + case 0x04: // unused? + case 0x05: // swap bytes + case 0x06: // += encryption (correct?) + case 0x07: // unused? + { + UINT8 extraoffset = param & 0xff; + UINT8 *dectable = (UINT8 *)(PGMProtROM + (0x100 / 2)); + + for (INT32 x = 0; x < size; x++) + { + UINT16 dat2 = PROTROM[src + x]; + + int taboff = ((x*2)+extraoffset) & 0xff; // must allow for overflow in instances of odd offsets + unsigned short extraxor = ((dectable[taboff + 0]) << 0) | (dectable[taboff + 1] << 8); + + if (mode==0) dat2 -= extraxor; + else if (mode==1) dat2 = ((dat2 & 0xf0f0) >> 4)|((dat2 & 0x0f0f) << 4); + else if (mode==2) dat2 ^= extraxor; + else if (mode==5) dat2 = ((dat2 &0x00ff) << 8) | ((dat2 &0xff00) >> 8); + else if (mode==6) dat2 += extraxor; + else + { + UINT16 extraxor2 = 0; + if ((x & 0x003) == 0x000) extraxor2 |= 0x0049; // 'I' + if ((x & 0x003) == 0x001) extraxor2 |= 0x0047; // 'G' + if ((x & 0x003) == 0x002) extraxor2 |= 0x0053; // 'S' + if ((x & 0x003) == 0x003) extraxor2 |= 0x0020; // ' ' + if ((x & 0x300) == 0x000) extraxor2 |= 0x4900; // 'I' + if ((x & 0x300) == 0x100) extraxor2 |= 0x4700; // 'G' + if ((x & 0x300) == 0x200) extraxor2 |= 0x5300; // 'S' + if ((x & 0x300) == 0x300) extraxor2 |= 0x2000; // ' ' + + dat2 = 0x4e75; // hack + } + + sharedprotram[dst + x] = dat2; + } + } + break; + } +} + +static void IGS028_handle() +{ + UINT16 cmd = sharedprotram[0x3026 / 2]; + + switch (cmd) + { + case 0x12: + { + UINT16 mode = sharedprotram[0x303e / 2]; // ? + UINT16 src = sharedprotram[0x306a / 2] >> 1; // ? + UINT16 dst = sharedprotram[0x3084 / 2] & 0x1fff; + UINT16 size = sharedprotram[0x30a2 / 2] & 0x1fff; + + IGS028_do_dma(src, dst, size, mode); + } + break; + + case 0x64: // incomplete? + { + UINT16 p1 = sharedprotram[0x3050 / 2]; + UINT16 p2 = sharedprotram[0x3082 / 2]; + UINT16 p3 = sharedprotram[0x3054 / 2]; + UINT16 p4 = sharedprotram[0x3088 / 2]; + + if (p2 == 0x02) + olds_write_reg(p1, olds_read_reg(p1) + 0x10000); + + switch (p4) + { + case 0xd: + olds_write_reg(p1,olds_read_reg(p3)); + break; + case 0x0: + olds_write_reg(p3,(olds_read_reg(p2))^(olds_read_reg(p1))); + break; + case 0xe: + olds_write_reg(p3,olds_read_reg(p3)+0x10000); + break; + case 0x2: + olds_write_reg(p1,(olds_read_reg(p2))+(olds_read_reg(p3))); + break; + case 0x6: + olds_write_reg(p3,(olds_read_reg(p2))&(olds_read_reg(p1))); + break; + case 0x1: + olds_write_reg(p2,olds_read_reg(p1)+0x10000); + break; + case 0x7: + olds_write_reg(p3,olds_read_reg(p1)); + break; + } + } + break; + } +} + +static void killbld_protection_calculate_hold(INT32 y, INT32 z) +{ + UINT16 old = kb_prot_hold; + + kb_prot_hold = ((old << 1) | (old >> 15)); + + kb_prot_hold ^= 0x2bad; + kb_prot_hold ^= BIT(z, y); + kb_prot_hold ^= BIT(old, 7) << 0; + kb_prot_hold ^= BIT(~old, 13) << 4; + kb_prot_hold ^= BIT(old, 3) << 11; + + kb_prot_hold ^= (kb_prot_hilo & ~0x0408) << 1; +} + +static void killbld_protection_calculate_hilo() +{ + kb_prot_hilo_select++; + + if (kb_prot_hilo_select > 0xeb) { + kb_prot_hilo_select = 0; + } + + UINT8 source = source_data[kb_region][kb_prot_hilo_select]; + + if (kb_prot_hilo_select & 1) + { + kb_prot_hilo = (kb_prot_hilo & 0x00ff) | (source << 8); + } + else + { + kb_prot_hilo = (kb_prot_hilo & 0xff00) | (source << 0); + } +} + +static void __fastcall killbld_igs025_prot_write(UINT32 address, UINT16 data) +{ + bprintf (0, _T("PRTW: %5.5x %4.4x\n"), address, data); + + if ((address & 0xf0000f) == 0xd00000) { + kb_cmd = data; + return; + } + + switch (kb_cmd) + { + case 0x00: + kb_reg = data; + break; + + case 0x01: // drgw3 + { + if (data == 0x0002) { // Execute command + IGS022_handle_command(); + } + } + break; + + case 0x02: // killbld + { + if (data == 0x0001) { // Execute command + IGS022_handle_command(); + kb_reg++; + } + } + break; + + case 0x03: + kb_swap = data; + break; + + case 0x04: + // kb_ptr = data; // Suspect. Not good for drgw3 + break; + + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + kb_ptr++; + killbld_protection_calculate_hold(kb_cmd & 0x0f, data & 0xff); + break; + } +} + +static void __fastcall olds_igs025_prot_write(UINT32 address, UINT16 data) +{ + bprintf (0, _T("PRTW: %5.5x %4.4x\n"), address, data); + + if (address == 0xdcb400) { + kb_cmd = data; + return; + } + + switch (kb_cmd) + { + case 0x00: + kb_reg = data; + break; + + case 0x02: + olds_bs = ((data & 0x03) << 6) | ((data & 0x04) << 3) | ((data & 0x08) << 1); + break; + + case 0x03: + { + IGS028_handle(); + kb_cmd3 = ((data >> 4) + 1) & 0x3; + } + break; + + case 0x04: + kb_ptr = data; + break; + + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + kb_ptr++; + killbld_protection_calculate_hold(kb_cmd & 0x0f, data & 0xff); + break; + } +} + +static void __fastcall drgw2_igs025_prot_write(UINT32 address, UINT16 data) +{ + bprintf (0, _T("PRTW: %5.5x %4.4x\n"), address, data); + + if (address == 0xd80000) { + kb_cmd = data; + return; + } + + switch (kb_cmd) + { + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + kb_ptr++; + killbld_protection_calculate_hold(kb_cmd & 0x0f, data & 0xff); + break; + } +} + +static UINT16 __fastcall igs025_prot_read(UINT32 address) +{ + bprintf (0, _T("PRTR: %5.5x\n"), address); + + switch (kb_cmd) + { + case 0x00: + return BITSWAP08((kb_swap + 1) & 0x7f, 0, 1, 2, 3, 4, 5, 6, 7); // drgw3 + + case 0x01: + return kb_reg & 0x7f; + + case 0x02: + return olds_bs | 0x80; + + case 0x03: + return kb_cmd3; + + case 0x05: + { + switch (kb_ptr) + { + case 1: + return 0x3f00 | ((kb_game_id >> 0) & 0xff); + + case 2: + return 0x3f00 | ((kb_game_id >> 8) & 0xff); + + case 3: + return 0x3f00 | ((kb_game_id >> 16) & 0xff); + + case 4: + return 0x3f00 | ((kb_game_id >> 24) & 0xff); + + default: // >= 5 + return 0x3f00 | BITSWAP08(kb_prot_hold, 5, 2, 9, 7, 10, 13, 12, 15); + } + } + + case 0x40: + killbld_protection_calculate_hilo(); + return 0; + } + + return 0; +} + +static void common_reset() +{ + kb_region = PgmInput[7]; + + kb_prot_hold = 0; + kb_prot_hilo = 0; + kb_prot_hilo_select = 0; + kb_cmd = 0; + kb_reg = 0; + kb_ptr = 0; + kb_swap = 0; + olds_bs = 0; + kb_cmd3 = 0; + + memset(kb_regs, 0, 0x100 * sizeof(UINT32)); +} + +static void drgw2_reset() +{ + common_reset(); +} + +static void killbld_reset() +{ + common_reset(); + + kb_game_id = 0x89911400 | kb_region; + + IGS022_reset(); +} + +static void drgw3_reset() +{ + common_reset(); + + kb_game_id = 0x00060000 | kb_region; + + IGS022_reset(); +} + +static INT32 CommonScan(INT32 nAction, INT32 *) +{ + struct BurnArea ba; + + if (nAction & ACB_MEMORY_RAM) { + ba.Data = PGMUSER0; + ba.nLen = 0x0004000; + ba.nAddress = 0x400000; + ba.szName = "ProtRAM"; + BurnAcb(&ba); + + ba.Data = (UINT8*)kb_regs; + ba.nLen = 0x00100 * sizeof(INT32); + ba.nAddress = 0xfffffc00; + ba.szName = "Protection Registers"; + BurnAcb(&ba); + } + + if (nAction & ACB_DRIVER_DATA) { + SCAN_VAR(kb_prot_hold); + SCAN_VAR(kb_prot_hilo); + SCAN_VAR(kb_ptr); + SCAN_VAR(kb_region); + SCAN_VAR(kb_cmd); + SCAN_VAR(kb_reg); + SCAN_VAR(kb_swap); + SCAN_VAR(kb_cmd3); + SCAN_VAR(olds_bs); + SCAN_VAR(kb_prot_hilo_select); + SCAN_VAR(kb_game_id); + } + + return 0; +} + +static void olds_reset() +{ + common_reset(); + + if (strcmp(BurnDrvGetTextA(DRV_NAME), "drgw2") == 0) kb_region = 6; + if (strcmp(BurnDrvGetTextA(DRV_NAME), "dw2v100x") == 0) kb_region = 6; + if (strcmp(BurnDrvGetTextA(DRV_NAME), "drgw2c") == 0) kb_region = 5; + if (strcmp(BurnDrvGetTextA(DRV_NAME), "drgw2j") == 0) kb_region = 1; + + kb_game_id = 0x00900000 | kb_region; + + sharedprotram[0x1000/2] = 0x4749; // 'IGS.28' + sharedprotram[0x1002/2] = 0x2E53; + sharedprotram[0x1004/2] = 0x3832; + + sharedprotram[0x3064/2] = 0xB315; // crc? +} + +void install_protection_asic25_asic22_killbld() +{ + BurnByteswap(PGMProtROM, 0x10000); + + pPgmScanCallback = CommonScan; + pPgmResetCallback = killbld_reset; + + sharedprotram = (UINT16*)PGMUSER0; + + SekOpen(0); + SekMapMemory(PGMUSER0, 0x300000, 0x303fff, SM_RAM); + SekMapHandler(4, 0xd40000, 0xd40003, SM_READ | SM_WRITE); + SekSetReadWordHandler(4, igs025_prot_read); + SekSetWriteWordHandler(4, killbld_igs025_prot_write); + SekClose(); +} + +void install_protection_asic25_asic22_drgw3() +{ + BurnByteswap(PGMProtROM, 0x10000); + + pPgmScanCallback = CommonScan; + pPgmResetCallback = drgw3_reset; + + sharedprotram = (UINT16*)PGMUSER0; + + SekOpen(0); + SekMapMemory(PGMUSER0, 0x300000, 0x303fff, SM_RAM); + SekMapHandler(4, 0xda5610, 0xda5613, SM_READ | SM_WRITE); + SekSetReadWordHandler(4, igs025_prot_read); + SekSetWriteWordHandler(4, killbld_igs025_prot_write); + SekClose(); +} + +void install_protection_asic25_asic12_dw2() +{ + pPgmScanCallback = CommonScan; + pPgmResetCallback = drgw2_reset; + + SekOpen(0); + SekMapHandler(4, 0xd80000, 0xd80003, SM_READ | SM_WRITE); + SekSetReadWordHandler(4, igs025_prot_read); + SekSetWriteWordHandler(4, drgw2_igs025_prot_write); + SekClose(); +} + +void install_protection_asic25_asic28_olds() +{ + pPgmScanCallback = CommonScan; + pPgmResetCallback = olds_reset; + + sharedprotram = (UINT16*)PGMUSER0; + + SekOpen(0); + SekMapMemory(PGMUSER0, 0x400000, 0x403fff, SM_RAM); + SekMapHandler(4, 0xdcb400, 0xdcb403, SM_READ | SM_WRITE); + SekSetReadWordHandler(4, igs025_prot_read); + SekSetWriteWordHandler(4, olds_igs025_prot_write); + SekClose(); +} diff --git a/src/burn/drv/pgm/pgm_asic27a_type1.cpp b/src/burn/drv/pgm/pgm_asic27a_type1.cpp new file mode 100644 index 000000000..43723e5e9 --- /dev/null +++ b/src/burn/drv/pgm/pgm_asic27a_type1.cpp @@ -0,0 +1,1451 @@ +#include "pgm.h" + +/* + IGS Asic27a (type 1) proper emulation + + Used by: + Knights of Valour Superheroes + Photo Y2K + Knights of Valour Super Heroes Plus (Using a small hack) + Various Knights of Valour bootlegs + + Simulations + + Used by: + Oriental Legends Super Plus + ----------------------------------------------------------- + DoDonPachi Dai-Ou-Jou / DoDonPachi Dai-Ou-Jou Black Label + Ketsui Kizuna Jigoku Tachi + Espgaluda + ----------------------------------------------------------- + Knights of Valour + ----------------------------------------------------------- + Puzzli 2 + ----------------------------------------------------------- + Photo Y2K2 - NOT WORKING! + ----------------------------------------------------------- + Puzzle Star - NOT WORKING! +*/ + +static UINT16 kovsh_highlatch_arm_w; +static UINT16 kovsh_lowlatch_arm_w; +static UINT16 kovsh_highlatch_68k_w; +static UINT16 kovsh_lowlatch_68k_w ; +static UINT32 kovsh_counter; + +static inline void pgm_cpu_sync() +{ + INT32 nCycles = SekTotalCycles() - Arm7TotalCycles(); + + if (nCycles > 100) { + Arm7Run(nCycles); + } +} + +static void __fastcall kovsh_asic27a_write_word(UINT32 address, UINT16 data) +{ + switch (address) + { + case 0x500000: + case 0x600000: + kovsh_lowlatch_68k_w = data; + return; + + case 0x500002: + case 0x600002: + kovsh_highlatch_68k_w = data; + return; + } +} + +static UINT16 __fastcall kovsh_asic27a_read_word(UINT32 address) +{ + if ((address & 0xffffc0) == 0x4f0000) { + return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(PGMARMShareRAM + (address & 0x3e)))); + } + + switch (address) + { + case 0x500000: + case 0x600000: + pgm_cpu_sync(); + return kovsh_lowlatch_arm_w; + + case 0x500002: + case 0x600002: + pgm_cpu_sync(); + return kovsh_highlatch_arm_w; + } + + return 0; +} + +static void kovsh_asic27a_arm7_write_word(UINT32 address, UINT16 data) +{ + if ((address & 0xffffff80) == 0x50800000) { // written... but never read? + *((UINT16*)(PGMARMShareRAM + ((address>>1) & 0x3e))) = BURN_ENDIAN_SWAP_INT16(data); + return; + } +} + +static void kovsh_asic27a_arm7_write_long(UINT32 address, UINT32 data) +{ + switch (address) + { + case 0x40000000: + { + kovsh_highlatch_arm_w = data >> 16; + kovsh_lowlatch_arm_w = data; + + kovsh_highlatch_68k_w = 0; + kovsh_lowlatch_68k_w = 0; + } + return; + } +} + +static UINT32 kovsh_asic27a_arm7_read_long(UINT32 address) +{ + switch (address) + { + case 0x40000000: + return (kovsh_highlatch_68k_w << 16) | (kovsh_lowlatch_68k_w); + + case 0x4000000c: + return kovsh_counter++; + } + + return 0; +} + +static void reset_kovsh_asic27a() +{ + kovsh_highlatch_arm_w = 0; + kovsh_lowlatch_arm_w = 0; + kovsh_highlatch_68k_w = 0; + kovsh_lowlatch_68k_w = 0; + kovsh_counter = 1; +} + +static INT32 kovsh_asic27aScan(INT32 nAction, INT32 *) +{ + struct BurnArea ba; + + if (nAction & ACB_MEMORY_RAM) { + ba.Data = PGMARMShareRAM; + ba.nLen = 0x0000040; + ba.nAddress = 0x400000; + ba.szName = "ARM SHARE RAM"; + BurnAcb(&ba); + + ba.Data = PGMARMRAM0; + ba.nLen = 0x0000400; + ba.nAddress = 0; + ba.szName = "ARM RAM 0"; + BurnAcb(&ba); + + ba.Data = PGMARMRAM2; + ba.nLen = 0x0000400; + ba.nAddress = 0; + ba.szName = "ARM RAM 1"; + BurnAcb(&ba); + } + + if (nAction & ACB_DRIVER_DATA) { + Arm7Scan(nAction); + + SCAN_VAR(kovsh_highlatch_arm_w); + SCAN_VAR(kovsh_lowlatch_arm_w); + SCAN_VAR(kovsh_highlatch_68k_w); + SCAN_VAR(kovsh_lowlatch_68k_w); + SCAN_VAR(kovsh_counter); + } + + return 0; +} + +void install_protection_asic27a_kovsh() +{ + nPGMArm7Type = 1; + pPgmScanCallback = kovsh_asic27aScan; + pPgmResetCallback = reset_kovsh_asic27a; + + SekOpen(0); + SekMapMemory(PGMARMShareRAM, 0x4f0000, 0x4f003f, SM_RAM); + + SekMapHandler(4, 0x500000, 0x600005, SM_READ | SM_WRITE); + SekSetReadWordHandler(4, kovsh_asic27a_read_word); + SekSetWriteWordHandler(4, kovsh_asic27a_write_word); + SekClose(); + + Arm7Init(0); + Arm7Open(0); + Arm7MapMemory(PGMARMROM, 0x00000000, 0x00003fff, ARM7_ROM); + Arm7MapMemory(PGMARMRAM0, 0x10000000, 0x100003ff, ARM7_RAM); + Arm7MapMemory(PGMARMRAM2, 0x50000000, 0x500003ff, ARM7_RAM); + Arm7SetWriteWordHandler(kovsh_asic27a_arm7_write_word); + Arm7SetWriteLongHandler(kovsh_asic27a_arm7_write_long); + Arm7SetReadLongHandler(kovsh_asic27a_arm7_read_long); + Arm7Close(); +} + +//------------------------------- +// Knights of Valour Super Heroes Plus Hack + +void __fastcall kovshp_asic27a_write_word(UINT32 address, UINT16 data) +{ + switch (address & 6) + { + case 0: + kovsh_lowlatch_68k_w = data; + return; + + case 2: + { + unsigned char asic_key = data >> 8; + unsigned char asic_cmd = (data & 0xff) ^ asic_key; + + switch (asic_cmd) // Intercept commands and translate them to those used by kovsh + { + case 0x9a: asic_cmd = 0x99; break; // kovassga + case 0xa6: asic_cmd = 0xa9; break; // kovassga + case 0xaa: asic_cmd = 0x56; break; // kovassga + case 0xf8: asic_cmd = 0xf3; break; // kovassga + + case 0x38: asic_cmd = 0xad; break; + case 0x43: asic_cmd = 0xca; break; + case 0x56: asic_cmd = 0xac; break; + case 0x73: asic_cmd = 0x93; break; + case 0x84: asic_cmd = 0xb3; break; + case 0x87: asic_cmd = 0xb1; break; + case 0x89: asic_cmd = 0xb6; break; + case 0x93: asic_cmd = 0x73; break; + case 0xa5: asic_cmd = 0xa9; break; + case 0xac: asic_cmd = 0x56; break; + case 0xad: asic_cmd = 0x38; break; + case 0xb1: asic_cmd = 0x87; break; + case 0xb3: asic_cmd = 0x84; break; + case 0xb4: asic_cmd = 0x90; break; + case 0xb6: asic_cmd = 0x89; break; + case 0xc5: asic_cmd = 0x8c; break; + case 0xca: asic_cmd = 0x43; break; + case 0xcc: asic_cmd = 0xf0; break; + case 0xd0: asic_cmd = 0xe0; break; + case 0xe0: asic_cmd = 0xd0; break; + case 0xe7: asic_cmd = 0x70; break; + case 0xed: asic_cmd = 0xcb; break; + case 0xf0: asic_cmd = 0xcc; break; + case 0xf1: asic_cmd = 0xf5; break; + case 0xf2: asic_cmd = 0xf1; break; + case 0xf4: asic_cmd = 0xf2; break; + case 0xf5: asic_cmd = 0xf4; break; + case 0xfc: asic_cmd = 0xc0; break; + case 0xfe: asic_cmd = 0xc3; break; + } + + kovsh_highlatch_68k_w = asic_cmd ^ (asic_key | (asic_key << 8)); + } + return; + } +} + +void install_protection_asic27a_kovshp() +{ + nPGMArm7Type = 1; + pPgmScanCallback = kovsh_asic27aScan; + + SekOpen(0); + SekMapMemory(PGMARMShareRAM, 0x4f0000, 0x4f003f, SM_RAM); + + SekMapHandler(4, 0x500000, 0x600005, SM_READ | SM_WRITE); + SekSetReadWordHandler(4, kovsh_asic27a_read_word); + SekSetWriteWordHandler(4, kovshp_asic27a_write_word); + SekClose(); + + Arm7Init(0); + Arm7Open(0); + Arm7MapMemory(PGMARMROM, 0x00000000, 0x00003fff, ARM7_ROM); + Arm7MapMemory(PGMARMRAM0, 0x10000000, 0x100003ff, ARM7_RAM); + Arm7MapMemory(PGMARMRAM2, 0x50000000, 0x500003ff, ARM7_RAM); + Arm7SetWriteWordHandler(kovsh_asic27a_arm7_write_word); + Arm7SetWriteLongHandler(kovsh_asic27a_arm7_write_long); + Arm7SetReadLongHandler(kovsh_asic27a_arm7_read_long); + Arm7Close(); +} + + + +//------------------------------------------ +// Common asic27a (type 1) simulation functions + + +static UINT16 asic27a_sim_value; +static UINT16 asic27a_sim_key; +static UINT32 asic27a_sim_response; +static UINT32 asic27a_sim_slots[0x100]; +static UINT16 asic27a_sim_regs[0x100]; +static UINT8 asic27a_sim_internal_slot; + +static void (*asic27a_sim_command)(UINT8); + +void __fastcall asic27a_sim_write(UINT32 offset, UINT16 data) +{ + switch (offset & 0x06) + { + case 0: asic27a_sim_value = data; return; + + case 2: + { + if ((data >> 8) == 0xff) asic27a_sim_key = 0xffff; + + asic27a_sim_value ^= asic27a_sim_key; + + UINT8 command = (data ^ asic27a_sim_key) & 0xff; + + asic27a_sim_regs[command] = asic27a_sim_value; + + // bprintf (0, _T("Command: %2.2x, Data: %2.2x\n"), command, asic27a_sim_value); + + asic27a_sim_command(command); + + asic27a_sim_key = (asic27a_sim_key + 0x0100) & 0xff00; + if (asic27a_sim_key == 0xff00) asic27a_sim_key = 0x0100; + asic27a_sim_key |= asic27a_sim_key >> 8; + } + return; + + case 4: return; + } +} + +static UINT16 __fastcall asic27a_sim_read(UINT32 offset) +{ + switch (offset & 0x02) + { + case 0: return (asic27a_sim_response >> 0) ^ asic27a_sim_key; + case 2: return (asic27a_sim_response >> 16) ^ asic27a_sim_key; + } + + return 0; +} + +static void asic27a_sim_reset() +{ + // The ASIC27a writes this to shared RAM + UINT8 ram_string[16] = { + 'I', 'G', 'S', 'P', 'G', 'M', 0, 0, 0, 0/*REGION*/, 'C', 'H', 'I', 'N', 'A', 0 + }; + + memset (PGMUSER0, 0, 0x400); + + ram_string[9] = PgmInput[7]; // region + + memcpy (PGMUSER0, ram_string, 16); + + BurnByteswap(PGMUSER0, 0x10); + + memset (asic27a_sim_slots, 0, 0x100 * sizeof(INT32)); + memset (asic27a_sim_regs, 0, 0x100 * sizeof(INT16)); + + asic27a_sim_value = 0; + asic27a_sim_key = 0; + asic27a_sim_response = 0; + asic27a_sim_internal_slot = 0; +} + +static INT32 asic27a_sim_scan(INT32 nAction, INT32 *) +{ + struct BurnArea ba; + + if (nAction & ACB_MEMORY_RAM) { + ba.Data = (UINT8*)asic27a_sim_slots; + ba.nLen = 0x0000100 * sizeof(INT32); + ba.nAddress = 0xff00000; + ba.szName = "ASIC27a Slots"; + BurnAcb(&ba); + + ba.Data = (UINT8*)asic27a_sim_regs; + ba.nLen = 0x0000100 * sizeof(INT16); + ba.nAddress = 0xff01000; + ba.szName = "ASIC27a Regs"; + BurnAcb(&ba); + } + + if (nAction & ACB_DRIVER_DATA) { + SCAN_VAR(asic27a_sim_value); + SCAN_VAR(asic27a_sim_key); + SCAN_VAR(asic27a_sim_response); + SCAN_VAR(asic27a_sim_internal_slot); + } + + return 0; +} + + +//--------------------------------- +// Simulation used by DoDonPachi Dai-Ou-Jou, Ketsui Kizuna Jigoku Tachi, and Espgaluda + +static void ddp3_asic27a_sim_command(UINT8 command) +{ + switch (command) + { + case 0x40: // Combine slot values + asic27a_sim_slots[(asic27a_sim_value >> 10) & 0x1f] = (asic27a_sim_slots[(asic27a_sim_value >> 5) & 0x1f] + asic27a_sim_slots[(asic27a_sim_value >> 0) & 0x1f]) & 0xffffff; + asic27a_sim_response = 0x880000; + break; + + case 0x67: // Select slot & write (high) + asic27a_sim_internal_slot = asic27a_sim_value >> 8; + asic27a_sim_slots[asic27a_sim_internal_slot] = (asic27a_sim_value & 0x00ff) << 16; + asic27a_sim_response = 0x880000; + break; + + case 0xe5: // Write slot (low) + asic27a_sim_slots[asic27a_sim_internal_slot] |= asic27a_sim_value; + asic27a_sim_response = 0x880000; + break; + + case 0x8e: // Read slot + asic27a_sim_response = asic27a_sim_slots[asic27a_sim_value & 0xff]; + break; + + case 0x99: // Reset? + asic27a_sim_key = 0; + asic27a_sim_response = 0x880000 | (PgmInput[7] << 8); + break; + + default: + asic27a_sim_response = 0x880000; + break; + } +} + +void install_protection_asic27a_ketsui() +{ + pPgmResetCallback = asic27a_sim_reset; + pPgmScanCallback = asic27a_sim_scan; + asic27a_sim_command = ddp3_asic27a_sim_command; + + SekOpen(0); + SekMapHandler(4, 0x400000, 0x400005, SM_READ | SM_WRITE); + SekSetReadWordHandler(4, asic27a_sim_read); + SekSetWriteWordHandler(4, asic27a_sim_write); + SekClose(); +} + +void install_protection_asic27a_ddp3() +{ + pPgmResetCallback = asic27a_sim_reset; + pPgmScanCallback = asic27a_sim_scan; + asic27a_sim_command = ddp3_asic27a_sim_command; + + SekOpen(0); + SekMapHandler(4, 0x500000, 0x500005, SM_READ | SM_WRITE); + SekSetReadWordHandler(4, asic27a_sim_read); + SekSetWriteWordHandler(4, asic27a_sim_write); + SekClose(); +} + + +//-------------------------- +// Simulation for Oriental Legends Super Plus + +static const UINT8 oldsplus_fc[0x20]={ + 0x00,0x00,0x0a,0x3a,0x4e,0x2e,0x03,0x40,0x33,0x43,0x26,0x2c,0x00,0x00,0x00,0x00, + 0x00,0x00,0x44,0x4d,0x0b,0x27,0x3d,0x0f,0x37,0x2b,0x02,0x2f,0x15,0x45,0x0e,0x30 +}; + +static const UINT16 oldsplus_90[0x7]={ + 0x50,0xa0,0xc8,0xf0,0x190,0x1f4,0x258 +}; + +static const UINT8 oldsplus_5e[0x20]={ + 0x04,0x04,0x04,0x04,0x04,0x03,0x03,0x03,0x02,0x02,0x02,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; + +static const UINT8 oldsplus_b0[0xe0]={ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04, + 0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, + 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18, + 0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c, + 0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13, + 0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f +}; + +static const UINT8 oldsplus_ae[0xe0]={ + 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50, + 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50, + 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50, + 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50, + 0x1E,0x1F,0x20,0x21,0x22,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, + 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, + 0x1F,0x20,0x21,0x22,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, + 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, + 0x20,0x21,0x22,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, + 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, + 0x21,0x22,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, + 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, + 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, + 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23 +}; + +static const UINT16 oldsplus_ba[0x4]={ + 0x3138,0x2328,0x1C20,0x1518 +}; + +static const UINT16 oldsplus_8c[0x20]={ + 0x0032,0x0032,0x0064,0x0096,0x0096,0x00fa,0x012c,0x015e,0x0032,0x0064,0x0096,0x00c8,0x00c8,0x012c,0x015e,0x0190, + 0x0064,0x0096,0x00c8,0x00fa,0x00fa,0x015e,0x0190,0x01c2,0x0096,0x00c8,0x00fa,0x012c,0x012c,0x0190,0x01c2,0x01f4 +}; + +static inline UINT16 oldsplus_9d(UINT16 a) +{ + const UINT8 tab[8] = { 0x3c, 0x46, 0x5a, 0x6e, 0x8c, 0xc8, 0x50, }; + + if ((a % 0x27) <= 0x07) return (a % 0x27) * 0x64; + if ((a % 0x27) >= 0x17) return 0x6bc; + + return 0x2bc + (tab[a / 0x27] * ((a % 0x27) - 7)); +} + +static void oldsplus_asic27a_sim_command(UINT8 command) +{ + switch (command) + { + case 0x88: // Reset? + asic27a_sim_key = 0; + asic27a_sim_response = 0x990000 | (PgmInput[7] << 8); + break; + + case 0xa0: + asic27a_sim_response = ((asic27a_sim_value >= 0x0f) ? 0x0f : asic27a_sim_value) * 0x23; + break; + + case 0xd0: // Text palette offset + asic27a_sim_response = 0xa01000 + (asic27a_sim_value << 5); + break; + + case 0xc0: // Sprite palette offset + asic27a_sim_response = 0xa00000 + (asic27a_sim_value << 6); + break; + + case 0xc3: // Background palette offset + asic27a_sim_response = 0xa00800 + (asic27a_sim_value << 6); + break; + + case 0x33: // Store regs + asic27a_sim_response = 0x990000; + break; + + case 0x35: // Add '36' reg + asic27a_sim_regs[0x36] += asic27a_sim_value; + asic27a_sim_response = 0x990000; + break; + + case 0x36: // Store regs + asic27a_sim_response = 0x990000; + break; + + case 0x37: // Add '33' reg + asic27a_sim_regs[0x33] += asic27a_sim_value; + asic27a_sim_response = 0x990000; + break; + + case 0x34: // Read '36' reg + asic27a_sim_response = asic27a_sim_regs[0x36]; + break; + + case 0x38: // Read '33' reg + asic27a_sim_response = asic27a_sim_regs[0x33]; + break; + + case 0xe7: // Select slot + { + asic27a_sim_response = 0x990000; + + asic27a_sim_internal_slot = (asic27a_sim_value >> 12) & 0x0f; + } + break; + + case 0xe5: // Write slot + { + asic27a_sim_response = 0x990000; + + asic27a_sim_slots[asic27a_sim_internal_slot] = asic27a_sim_value; + + if (asic27a_sim_internal_slot == 0x0b) asic27a_sim_slots[0xc] = 0; // ?? + } + break; + + case 0xf8: // Read slot + asic27a_sim_response = asic27a_sim_slots[asic27a_sim_value]; + break; + + case 0xc5: // Increment slot 'd' + asic27a_sim_slots[0xd]--; + asic27a_sim_response = 0x990000; + break; + + case 0xd6: // Increment slot 'b' + asic27a_sim_slots[0xb]++; + asic27a_sim_response = 0x990000; + break; + + case 0x3a: // Clear slot 'f' + asic27a_sim_slots[0xf] = 0; + asic27a_sim_response = 0x990000; + break; + + case 0xf0: // Background layer 'x' select + asic27a_sim_response = 0x990000; + break; + + case 0xed: // Background layer offset + if (asic27a_sim_value & 0x400) asic27a_sim_value = -(0x400 - (asic27a_sim_value & 0x3ff)); + asic27a_sim_response = 0x900000 + ((asic27a_sim_regs[0xf0] + (asic27a_sim_value * 0x40)) * 4); + break; + + case 0xe0: // Text layer 'x' select + asic27a_sim_response = 0x990000; + break; + + case 0xdc: // Text layer offset + asic27a_sim_response = 0x904000 + ((asic27a_sim_regs[0xe0] + (asic27a_sim_value * 0x40)) * 4); + break; + + case 0xcb: // Some sort of status read? + asic27a_sim_response = 0x00c000; + break; + + case 0x5e: // Read from data table + asic27a_sim_response = oldsplus_5e[asic27a_sim_value]; + break; + + case 0x80: // Read from data table + asic27a_sim_response = (asic27a_sim_value < 4) ? ((asic27a_sim_value + 1) * 0xbb8) : 0xf4240; + break; + + case 0x8c: // Read from data table + asic27a_sim_response = oldsplus_8c[asic27a_sim_value]; + break; + + case 0x90: // Read from data table + asic27a_sim_response = oldsplus_90[asic27a_sim_value]; + break; + + case 0x9d: // Read from data table + asic27a_sim_response = oldsplus_9d(asic27a_sim_value); + break; + + case 0xae: // Read from data table + asic27a_sim_response = oldsplus_ae[asic27a_sim_value]; + break; + + case 0xb0: // Read from data table + asic27a_sim_response = oldsplus_b0[asic27a_sim_value]; + break; + + case 0xba: // Read from data table + asic27a_sim_response = oldsplus_ba[asic27a_sim_value]; + break; + + case 0xfc: // Read from data table + asic27a_sim_response = oldsplus_fc[asic27a_sim_value]; + break; + + default: + asic27a_sim_response = 0x990000; + break; + } +} + +void install_protection_asic27a_oldsplus() +{ + pPgmResetCallback = asic27a_sim_reset; + pPgmScanCallback = asic27a_sim_scan; + asic27a_sim_command = oldsplus_asic27a_sim_command; + + SekOpen(0); + SekMapMemory(PGMUSER0, 0x4f0000, 0x4f003f | 0x3ff, SM_READ); // ram + + SekMapHandler(4, 0x500000, 0x500003, SM_READ | SM_WRITE); + SekSetReadWordHandler(4, asic27a_sim_read); + SekSetWriteWordHandler(4, asic27a_sim_write); + SekClose(); +} + + + +//----------------------------------------------------------------------------------------------------- +// Simulation used by Knights of Valour + + +static const UINT8 B0TABLE[8] = { 2, 0, 1, 4, 3 }; // Maps char portraits to tables + +static const UINT8 BATABLE[0x40] = { + 0x00,0x29,0x2c,0x35,0x3a,0x41,0x4a,0x4e,0x57,0x5e,0x77,0x79,0x7a,0x7b,0x7c,0x7d, + 0x7e,0x7f,0x80,0x81,0x82,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x90, + 0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9e,0xa3,0xd4,0xa9,0xaf,0xb5,0xbb,0xc1 +}; + +static void kov_asic27a_sim_command(UINT8 command) +{ + switch (command) + { + case 0x67: // unknown or status check? + case 0x8e: + case 0xa3: + case 0x33: // kovsgqyz (a3) + case 0x3a: // kovplus + case 0xc5: // kovplus + asic27a_sim_response = 0x880000; + break; + + case 0x99: // Reset + asic27a_sim_key = 0; + asic27a_sim_response = 0x880000 | (PgmInput[7] << 8); + break; + + case 0x9d: // Sprite palette offset + asic27a_sim_response = 0xa00000 + ((asic27a_sim_value & 0x1f) * 0x40); + break; + + case 0xb0: // Read from data table + asic27a_sim_response = B0TABLE[asic27a_sim_value & 0x07]; + break; + + case 0xb4: // Copy slot 'a' to slot 'b' + case 0xb7: // kovsgqyz (b4) + { + asic27a_sim_response = 0x880000; + + if (asic27a_sim_value == 0x0102) asic27a_sim_value = 0x0100; // why? + + asic27a_sim_slots[(asic27a_sim_value >> 8) & 0x0f] = asic27a_sim_slots[(asic27a_sim_value >> 0) & 0x0f]; + } + break; + + case 0xba: // Read from data table + asic27a_sim_response = BATABLE[asic27a_sim_value & 0x3f]; + break; + + case 0xc0: // Text layer 'x' select + asic27a_sim_response = 0x880000; + break; + + case 0xc3: // Text layer offset + asic27a_sim_response = 0x904000 + ((asic27a_sim_regs[0xc0] + (asic27a_sim_value * 0x40)) * 4); + break; + + case 0xcb: // Background layer 'x' select + asic27a_sim_response = 0x880000; + break; + + case 0xcc: // Background layer offset + { + INT32 y = asic27a_sim_value; + if (y & 0x400) y = -(0x400 - (y & 0x3ff)); + asic27a_sim_response = 0x900000 + (((asic27a_sim_regs[0xcb] + y * 64) * 4)); + } + break; + + case 0xd0: // Text palette offset + case 0xcd: // kovsgqyz (d0) + asic27a_sim_response = 0xa01000 + (asic27a_sim_value * 0x20); + break; + + case 0xd6: // Copy slot to slot 0 + asic27a_sim_response = 0x880000; + asic27a_sim_slots[0] = asic27a_sim_slots[asic27a_sim_value & 0x0f]; + break; + + case 0xdc: // Background palette offset + case 0x11: // kovsgqyz (dc) + asic27a_sim_response = 0xa00800 + (asic27a_sim_value * 0x40); + break; + + case 0xe0: // Sprite palette offset + case 0x9e: // kovsgqyz (e0) + asic27a_sim_response = 0xa00000 + ((asic27a_sim_value & 0x1f) * 0x40); + break; + + case 0xe5: // Write slot (low) + { + asic27a_sim_response = 0x880000; + + asic27a_sim_slots[asic27a_sim_internal_slot] = (asic27a_sim_slots[asic27a_sim_internal_slot] & 0x00ff0000) | ((asic27a_sim_value & 0xffff) << 0); + } + break; + + case 0xe7: // Write slot (and slot select) (high) + { + asic27a_sim_response = 0x880000; + asic27a_sim_internal_slot = (asic27a_sim_value >> 12) & 0x0f; + + asic27a_sim_slots[asic27a_sim_internal_slot] = (asic27a_sim_slots[asic27a_sim_internal_slot] & 0x0000ffff) | ((asic27a_sim_value & 0x00ff) << 16); + } + break; + + case 0xf0: // Some sort of status read? + asic27a_sim_response = 0x00c000; + break; + + case 0xf8: // Read slot + case 0xab: // kovsgqyz (f8) + asic27a_sim_response = asic27a_sim_slots[asic27a_sim_value & 0x0f] & 0x00ffffff; + break; + + case 0xfc: // Adjust damage level to char experience level + asic27a_sim_response = (asic27a_sim_value * asic27a_sim_regs[0xfe]) >> 6; + break; + + case 0xfe: // Damage level adjust + asic27a_sim_response = 0x880000; + break; + + default: + asic27a_sim_response = 0x880000; + break; + } +} + +void install_protection_asic27_kov() +{ + pPgmResetCallback = asic27a_sim_reset; + pPgmScanCallback = asic27a_sim_scan; + asic27a_sim_command = kov_asic27a_sim_command; + + SekOpen(0); + SekMapMemory(PGMUSER0, 0x4f0000, 0x4f003f | 0x3ff, SM_READ); + + SekMapHandler(4, 0x500000, 0x500003, SM_READ | SM_WRITE); + SekSetReadWordHandler(4, asic27a_sim_read); + SekSetWriteWordHandler(4, asic27a_sim_write); + SekClose(); +} + + +//-------------------- +// Simulation used by Puzzli 2 + +static int stage; +static int tableoffs; +static int tableoffs2; +static int entries_left; +static int currentcolumn; +static int currentrow; +static int num_entries; +static int full_entry; +static int prev_tablloc; +static int numbercolumns; +static int depth; +static UINT16 m_row_bitmask; +static int hackcount; +static int hackcount2; +static int hack_47_value; +static int hack_31_table_offset; +static int p2_31_retcounter; +static int command_31_write_type; +static UINT16 level_structure[8][10]; + +static const UINT8 puzzli2_level_decode[256] = { + 0x32, 0x3e, 0xb2, 0x37, 0x31, 0x22, 0xd6, 0x0d, 0x35, 0x5c, 0x8d, 0x3c, 0x7a, 0x5f, 0xd7, 0xac, // 0x0 + 0x53, 0xff, 0xeb, 0x44, 0xe8, 0x11, 0x69, 0x77, 0xd9, 0x34, 0x36, 0x45, 0xa6, 0xe9, 0x1c, 0xc6, // 0x1 + 0x3b, 0xbd, 0xad, 0x2e, 0x18, 0xdf, 0xa1, 0xab, 0xdd, 0x52, 0x57, 0xc2, 0xe5, 0x0a, 0x00, 0x6d, // 0x2 + 0x67, 0x64, 0x15, 0x70, 0xb6, 0x39, 0x27, 0x78, 0x82, 0xd2, 0x71, 0xb9, 0x13, 0xf5, 0x93, 0x92, // 0x3 + 0xfa, 0xe7, 0x5e, 0xb0, 0xf6, 0xaf, 0x95, 0x8a, 0x7c, 0x73, 0xf9, 0x63, 0x86, 0xcb, 0x1a, 0x56, // 0x4 + 0xf1, 0x3a, 0xae, 0x61, 0x01, 0x29, 0x97, 0x23, 0x8e, 0x5d, 0x9a, 0x65, 0x74, 0x21, 0x20, 0x40, // 0x5 + 0xd3, 0x05, 0xa2, 0xe1, 0xbc, 0x9e, 0x1e, 0x10, 0x14, 0x0c, 0x88, 0x9c, 0xec, 0x38, 0xb5, 0x9d, // 0x6 + 0x2d, 0xf7, 0x17, 0x0e, 0x84, 0xc7, 0x7d, 0xce, 0x94, 0x16, 0x48, 0xa8, 0x81, 0x6e, 0x7b, 0xd8, // 0x7 + 0xa7, 0x7f, 0x42, 0xe6, 0xa0, 0x2a, 0xef, 0xee, 0x24, 0xba, 0xb8, 0x7e, 0xc9, 0x2b, 0x90, 0xcc, // 0x8 + 0x5b, 0xd1, 0xf3, 0xe2, 0x6f, 0xed, 0x9f, 0xf0, 0x4b, 0x54, 0x8c, 0x08, 0xf8, 0x51, 0x68, 0xc8, // 0x9 + 0x03, 0x0b, 0xbb, 0xc1, 0xe3, 0x4d, 0x04, 0xc5, 0x8f, 0x09, 0x0f, 0xbf, 0x62, 0x49, 0x76, 0x59, // 0xa + 0x1d, 0x80, 0xde, 0x60, 0x07, 0xe0, 0x1b, 0x66, 0xa5, 0xbe, 0xcd, 0x87, 0xdc, 0xc3, 0x6b, 0x4e, // 0xb + 0xd0, 0xfd, 0xd4, 0x3f, 0x98, 0x96, 0x2f, 0x4c, 0xb3, 0xea, 0x2c, 0x75, 0xe4, 0xc0, 0x6c, 0x6a, // 0xc + 0x9b, 0xb7, 0x43, 0x8b, 0x41, 0x47, 0x02, 0xdb, 0x99, 0x3d, 0xa3, 0x79, 0x50, 0x4f, 0xb4, 0x55, // 0xd + 0x5a, 0x25, 0xf4, 0xca, 0x58, 0x30, 0xc4, 0x12, 0xa9, 0x46, 0xda, 0x91, 0xa4, 0xaa, 0xfc, 0x85, // 0xe + 0xfb, 0x89, 0x06, 0xcf, 0xfe, 0x33, 0xd5, 0x28, 0x1f, 0x19, 0x4a, 0xb1, 0x83, 0xf2, 0x72, 0x26, // 0xf +}; + +static int get_position_of_bit(UINT16 value, int bit_wanted) +{ + int count = 0; + for (int i=0;i<16;i++) + { + int bit = (value >> i) & 1; + + if (bit) count++; + + if (count==(bit_wanted+1)) + return i; + } + + return -1; +} + +static int puzzli2_take_leveldata_value(UINT8 datvalue) +{ + if (stage==-1) + { + tableoffs = 0; + tableoffs2 = 0; + entries_left = 0; + currentcolumn = 0; + currentrow = 0; + num_entries = 0; + full_entry = 0; + prev_tablloc = 0; + numbercolumns = 0; + depth = 0; + m_row_bitmask = 0; + + tableoffs = datvalue; + tableoffs2 = 0; + stage = 0; + } + else + { + UINT8 rawvalue = datvalue; + UINT8 tableloc = (tableoffs+tableoffs2)&0xff; + rawvalue ^= puzzli2_level_decode[tableloc]; + + tableoffs2++; + tableoffs2&=0xf; + + if (stage==0) + { + stage = 1; + depth = (rawvalue & 0xf0); + numbercolumns = (rawvalue & 0x0f); + numbercolumns++; + } + else if (stage==1) + { + stage = 2; + entries_left = (rawvalue >> 4); + m_row_bitmask = (rawvalue & 0x0f)<<8; + full_entry = rawvalue; + prev_tablloc = tableloc; + num_entries = entries_left; + } + else if (stage==2) + { + stage = 3; + m_row_bitmask |= rawvalue; + + if (entries_left == 0) + { + stage = 1; + currentcolumn++; + currentrow = 0; + m_row_bitmask = 0; + + if (currentcolumn==numbercolumns) + { + return 1; + } + } + } + else if (stage==3) + { + UINT16 object_value; + + if (rawvalue<=0x10) object_value = 0x0100 + rawvalue; + else if (rawvalue<=0x21) object_value = 0x0120 + (rawvalue - 0x11); + else if (rawvalue<=0x32) object_value = 0x0140 + (rawvalue - 0x22); + else if (rawvalue<=0x43) object_value = 0x0180 + (rawvalue - 0x33); + else if (rawvalue==0xd0) object_value = 0x0200; + else if (rawvalue==0xe0) object_value = 0x8000; + else if (rawvalue==0xe1) object_value = 0x8020; // solid slant top down + else if (rawvalue==0xe2) object_value = 0x8040; // solid slant top up + else if (rawvalue==0xe3) object_value = 0x8060; + else if (rawvalue==0xe4) object_value = 0x8080; // sold slant bottom up + else object_value = 0x0110; + + int realrow = get_position_of_bit(m_row_bitmask, currentrow); + + if (realrow != -1) + level_structure[currentcolumn][realrow] = object_value; + + currentrow++; + + entries_left--; + if (entries_left == 0) + { + stage = 1; + currentcolumn++; + currentrow = 0; + m_row_bitmask = 0; + + if (currentcolumn==numbercolumns) + { + return 1; + } + } + } + } + + return 0; +} + +static void puzzli2_asic27a_sim_command(UINT8 command) +{ + switch (command) + { + case 0x31: + { + if (command_31_write_type==2) + { + if (hackcount2==0) + { + puzzli2_take_leveldata_value(asic27a_sim_value&0xff); + + hack_31_table_offset = asic27a_sim_value & 0xff; + hackcount2++; + asic27a_sim_response = 0x00d20000; + } + else + { + int end = puzzli2_take_leveldata_value(asic27a_sim_value&0xff); + + if (!end) + { + asic27a_sim_response = 0x00d20000; + hackcount2++; + } + else + { + hackcount2=0; + asic27a_sim_response = 0x00630000 | numbercolumns; + } + } + } + else + { + asic27a_sim_response = 0x00d20000 | p2_31_retcounter; + p2_31_retcounter++; + } + } + break; + + case 0x13: + { + UINT16* leveldata = &level_structure[0][0]; + if (hackcount==0) + { + asic27a_sim_response = 0x002d0000 | ((depth>>4)+1); + } + else if (hackcount<((10*numbercolumns)+1)) + { + asic27a_sim_response = 0x002d0000 | leveldata[hackcount-1]; + } + else + { + hackcount=0; + asic27a_sim_response = 0x00740054; + } + + hackcount++; + } + break; + + case 0x38: // Reset + { + asic27a_sim_response = 0x780000 | (PgmInput[7] << 8); + asic27a_sim_key = 0x100; + } + break; + + case 0x47: + hack_47_value = asic27a_sim_value; + asic27a_sim_response = 0x00740047; + break; + + case 0x52: + { + int val = ((hack_47_value & 0x0f00)>>8) * 0x19; + if (asic27a_sim_value!=0x0000) + { + val +=((hack_47_value & 0x000f)>>0) * 0x05; + } + val += asic27a_sim_value & 0x000f; + asic27a_sim_response = 0x00740000 | (val & 0xffff); + } + break; + + case 0x61: + command_31_write_type = 1; + asic27a_sim_response = 0x360000; + p2_31_retcounter = 0xc; + break; + + case 0x41: // ASIC status? + command_31_write_type = 0; + asic27a_sim_response = 0x740061; + break; + + case 0x54: // ?? + { + command_31_write_type = 2; + stage = -1; + hackcount2 = 0; + hackcount = 0; + asic27a_sim_response = 0x360000; + + // clear the return structure + for (int columns=0;columns<8;columns++) + for (int rows=0;rows<10;rows++) + level_structure[columns][rows] = 0x0000; + } + break; + + case 0x63: + { + UINT32 z80table[2][8] = { + { 0x1694a8, 0x16cfae, 0x16ebf2, 0x16faa8, 0x174416, 0x600000, 0x600000, 0x600000 }, // puzzli2 + { 0x19027a, 0x193D80, 0x1959c4, 0x19687a, 0x19b1e8, 0x600000, 0x600000, 0x600000 } // puzzli2s + }; + + if (!strcmp(BurnDrvGetTextA(DRV_NAME),"puzzli2")) + { + asic27a_sim_response = z80table[0][asic27a_sim_value & 7]; + } + else {// puzzli2 super + asic27a_sim_response = z80table[1][asic27a_sim_value & 7]; + } + } + break; + + case 0x67: + { + UINT32 z80table[2][8] = { + { 0x166178, 0x166178, 0x166178, 0x166178, 0x166e72, 0x600000, 0x600000, 0x600000 }, // puzzli2 + { 0x18cf4a, 0x18cf4a, 0x18cf4a, 0x18cf4a, 0x18dc44, 0x600000, 0x600000, 0x600000 } // puzzli2s + }; + + if (!strcmp(BurnDrvGetTextA(DRV_NAME),"puzzli2")) + { + asic27a_sim_response = z80table[0][asic27a_sim_value & 7]; + } + else {// puzzli2 super + asic27a_sim_response = z80table[1][asic27a_sim_value & 7]; + } + } + break; + + default: + asic27a_sim_response = 0x740000; + break; + } +} + +void install_protection_asic27a_puzzli2() +{ + pPgmResetCallback = asic27a_sim_reset; + pPgmScanCallback = asic27a_sim_scan; + asic27a_sim_command = puzzli2_asic27a_sim_command; + + SekOpen(0); + SekMapMemory(PGMUSER0, 0x4f0000, 0x4f003f | 0x3ff, SM_READ); + + SekMapHandler(4, 0x500000, 0x500003, SM_READ | SM_WRITE); + SekSetReadWordHandler(4, asic27a_sim_read); + SekSetWriteWordHandler(4, asic27a_sim_write); + SekClose(); +} + + +//------------------------------------------------------------------------------------------- +// Simulation used by Photo Y2k2 (not working!) + + +static void py2k2_asic27a_sim_command(UINT8 command) +{ + switch (command) + { + case 0x30: // Sprite sequence, advance to next sprite + break; + + case 0x32: // Sprite sequence, decode offset + break; + + // case 0x33: + // case 0x34: + // case 0x35: // table? + // case 0x38: // ? + // break; + + // "CCHANGE.C 285 ( TIME >= VALUE1 ) && TIME <= ALL_LEV_TIME ) + case 0xba: // ?? + asic27a_sim_response = asic27a_sim_value + 1; // gets us in-game + break; + + case 0x99: // Reset? + asic27a_sim_key = 0x100; + asic27a_sim_response = 0x880000 | (PgmInput[7] << 8); + break; + + case 0xc0: + asic27a_sim_response = 0x880000; + break; + + case 0xc3: + asic27a_sim_response = 0x904000 + ((asic27a_sim_regs[0xc0] + (asic27a_sim_value * 0x40)) * 4); + break; + + case 0xd0: + asic27a_sim_response = 0xa01000 + (asic27a_sim_value * 0x20); + break; + + case 0xdc: + asic27a_sim_response = 0xa00800 + (asic27a_sim_value * 0x40); + break; + + case 0xe0: + asic27a_sim_response = 0xa00000 + ((asic27a_sim_value & 0x1f) * 0x40); + break; + + case 0xcb: // Background layer 'x' select (pgm3in1, same as kov) + asic27a_sim_response = 0x880000; + break; + + case 0xcc: // Background layer offset (pgm3in1, same as kov) + { + INT32 y = asic27a_sim_value; + if (y & 0x400) y = -(0x400 - (y & 0x3ff)); + asic27a_sim_response = 0x900000 + ((asic27a_sim_regs[0xcb] + (y * 0x40)) * 4); + } + break; + + default: + asic27a_sim_response = 0x880000; + bprintf (0, _T("Unknown ASIC Command %2.2x Value: %4.4x\n"), command, asic27a_sim_value); + break; + } +} + +void install_protection_asic27a_py2k2() +{ + pPgmResetCallback = asic27a_sim_reset; + pPgmScanCallback = asic27a_sim_scan; + asic27a_sim_command = py2k2_asic27a_sim_command; + + SekOpen(0); + SekMapMemory(PGMUSER0, 0x4f0000, 0x4f003f | 0x3ff, SM_READ); + + SekMapHandler(4, 0x500000, 0x500003, SM_READ | SM_WRITE); + SekSetReadWordHandler(4, asic27a_sim_read); + SekSetWriteWordHandler(4, asic27a_sim_write); + SekClose(); +} + + + +//------------------------------------------------------------------------- +// Simulation used by Puzzle Star + + +static const UINT8 Pstar_ba[0x1e]={ + 0x02,0x00,0x00,0x01,0x00,0x03,0x00,0x00,0x02,0x00,0x06,0x00,0x22,0x04,0x00,0x03, + 0x00,0x00,0x06,0x00,0x20,0x07,0x00,0x03,0x00,0x21,0x01,0x00,0x00,0x63 +}; + +static const UINT8 Pstar_b0[0x10]={ + 0x09,0x0A,0x0B,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x00,0x00,0x00,0x00 +}; + +static const UINT16 Pstar_ae[0x10]={ + 0x5D,0x86,0x8C,0x8B,0xE0,0x8B,0x62,0xAF,0xB6,0xAF,0x10A,0xAF,0x00,0x00,0x00,0x00 +}; + +static const UINT8 Pstar_a0[0x10]={ + 0x02,0x03,0x04,0x05,0x06,0x01,0x0A,0x0B,0x0C,0x0D,0x0E,0x09,0x00,0x00,0x00,0x00 +}; + +static const UINT8 Pstar_9d[0x10]={ + 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; + +static const UINT8 Pstar_90[0x10]={ + 0x0C,0x10,0x0E,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; + +static const UINT8 Pstar_8c[0x23]={ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04, + 0x03,0x03,0x03 +}; + +static const UINT8 Pstar_80[0x1a3]={ + 0x03,0x03,0x04,0x04,0x04,0x04,0x05,0x05,0x05,0x05,0x06,0x06,0x03,0x03,0x04,0x04, + 0x05,0x05,0x05,0x05,0x06,0x06,0x07,0x07,0x03,0x03,0x04,0x04,0x05,0x05,0x05,0x05, + 0x06,0x06,0x07,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07, + 0x06,0x06,0x06,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x08,0x08,0x05,0x05,0x05,0x05, + 0x05,0x05,0x05,0x06,0x06,0x06,0x07,0x07,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08, + 0x09,0x09,0x09,0x09,0x07,0x07,0x07,0x07,0x07,0x08,0x08,0x08,0x08,0x09,0x09,0x09, + 0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,0x08,0x08,0x09,0x09,0x05,0x05,0x06,0x06, + 0x06,0x07,0x07,0x08,0x08,0x08,0x08,0x09,0x07,0x07,0x07,0x07,0x07,0x08,0x08,0x08, + 0x08,0x09,0x09,0x09,0x06,0x06,0x07,0x03,0x07,0x06,0x07,0x07,0x08,0x07,0x05,0x04, + 0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x06,0x06,0x06,0x06,0x03,0x04,0x04,0x04, + 0x04,0x05,0x05,0x06,0x06,0x06,0x06,0x07,0x04,0x04,0x05,0x05,0x06,0x06,0x06,0x06, + 0x06,0x07,0x07,0x08,0x05,0x05,0x06,0x07,0x07,0x08,0x08,0x08,0x08,0x08,0x08,0x08, + 0x05,0x05,0x05,0x07,0x07,0x07,0x07,0x07,0x07,0x08,0x08,0x08,0x08,0x08,0x09,0x09, + 0x09,0x09,0x03,0x04,0x04,0x05,0x05,0x05,0x06,0x06,0x07,0x07,0x07,0x07,0x08,0x08, + 0x08,0x09,0x09,0x09,0x03,0x04,0x05,0x05,0x04,0x03,0x04,0x04,0x04,0x05,0x05,0x04, + 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x03,0x03,0x03,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, + 0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00 +}; + +static UINT16 __fastcall puzlstar_protram_read_word(UINT32 offset) +{ + if ((offset & 0x3e) == 0x08) return PgmInput[7]; // Region + if ((offset & 0x38) == 0x20) return asic27a_sim_slots[((offset & 0x06)/2)+0x10]--; // Timer + + return 0; +} + +static UINT8 __fastcall puzlstar_protram_read_byte(UINT32 offset) +{ + if ((offset & 0x3e) == 0x08) return PgmInput[7]; // Region + + return 0; +} + +static void puzlstar_asic27a_sim_command(UINT8 command) +{ + switch (command) + { + case 0x99: // Reset? + asic27a_sim_key = 0x100; + asic27a_sim_response = 0x880000 | (PgmInput[7] << 8); + break; + + case 0xb1: + asic27a_sim_response = 0x890000; + break; + + case 0xbf: + asic27a_sim_response = asic27a_sim_regs[0xb1] * asic27a_sim_value; + break; + + case 0xc1: // TODO: TIMER 0,1,2,FIX TO 0 should be OK? + asic27a_sim_response = 0; + break; + + case 0xce: // TODO: TIMER 0,1,2 + asic27a_sim_response = 0x890000; + break; + + case 0xcf: // TODO:TIMER 0,1,2 + asic27a_sim_slots[asic27a_sim_regs[0xce] + 0x10] = asic27a_sim_value; + asic27a_sim_response = 0x890000; + break; + + case 0xd0: // Text palette offset + asic27a_sim_response = 0xa01000 + (asic27a_sim_value << 5); + break; + + case 0xdc: // Background palette offset + asic27a_sim_response = 0xa00800 + (asic27a_sim_value << 6); + break; + + case 0xe0: // Sprite palette offset + asic27a_sim_response = 0xa00000 + (asic27a_sim_value << 6); + break; + + case 0xe5: // Write slot (low) + { + asic27a_sim_response = 0x890000; + + asic27a_sim_slots[asic27a_sim_internal_slot] = (asic27a_sim_slots[asic27a_sim_internal_slot] & 0xff0000) | (asic27a_sim_value); + } + break; + + case 0xe7: // Write slot (and slot select) (high) + { + asic27a_sim_response = 0x890000; + + asic27a_sim_internal_slot = (asic27a_sim_value >> 12) & 0xf; + asic27a_sim_slots[asic27a_sim_internal_slot] = (asic27a_sim_slots[asic27a_sim_internal_slot] & 0x00ffff) | ((asic27a_sim_value & 0xff) << 16); + } + break; + + case 0xf8: // Read slot + asic27a_sim_response = asic27a_sim_slots[asic27a_sim_value]; + break; + + case 0x80: // Read from data table + asic27a_sim_response = Pstar_80[asic27a_sim_value]; + break; + + case 0x8c: // Read from data table + asic27a_sim_response = Pstar_8c[asic27a_sim_value]; + break; + + case 0x90: // Read from data table + asic27a_sim_response = Pstar_90[asic27a_sim_value]; + break; + + case 0x9d: // Read from data table + asic27a_sim_response = Pstar_9d[asic27a_sim_value]; + break; + + case 0xa0: // Read from data table + asic27a_sim_response = Pstar_a0[asic27a_sim_value]; + break; + + case 0xae: // Read from data table + asic27a_sim_response = Pstar_ae[asic27a_sim_value]; + break; + + case 0xb0: // Read from data table + asic27a_sim_response = Pstar_b0[asic27a_sim_value]; + break; + + case 0xba: // Read from data table + asic27a_sim_response = Pstar_ba[asic27a_sim_value]; + break; + + default: + asic27a_sim_response = 0x890000; + break; + } +} + +void install_protection_asic27a_puzlstar() +{ + pPgmResetCallback = asic27a_sim_reset; + pPgmScanCallback = asic27a_sim_scan; + + asic27a_sim_command = puzlstar_asic27a_sim_command; + + SekOpen(0); + SekMapHandler(4, 0x500000, 0x500003, SM_READ | SM_WRITE); + SekSetReadWordHandler(4, asic27a_sim_read); + SekSetWriteWordHandler(4, asic27a_sim_write); + + SekMapHandler(5, 0x4f0000, 0x4f03ff, SM_READ); + SekSetReadWordHandler(5, puzlstar_protram_read_word); + SekSetReadByteHandler(5, puzlstar_protram_read_byte); + SekClose(); +} + diff --git a/src/burn/drv/pgm/pgm_asic27a_type2.cpp b/src/burn/drv/pgm/pgm_asic27a_type2.cpp new file mode 100644 index 000000000..a78292033 --- /dev/null +++ b/src/burn/drv/pgm/pgm_asic27a_type2.cpp @@ -0,0 +1,156 @@ +#include "pgm.h" + +/* + IGS Asic27a (type 2) proper emulation + + Used by: + Martial Masters + Bee Storm - DoDonPachi II + Dragon World 2001 + Dragon World Pretty Chance + Knights of Valour 2 + Knights of Valour 2 Plus - Nine Dragons +*/ + +static UINT8 asic27a_to_arm = 0; +static UINT8 asic27a_to_68k = 0; + +static inline void pgm_cpu_sync() +{ + INT32 nCycles = SekTotalCycles() - Arm7TotalCycles(); + + if (nCycles > 100) { + Arm7Run(nCycles); + } +} + +static void __fastcall asic27a_write_byte(UINT32 address, UINT8 data) +{ + if ((address & 0xfffffe) == 0xd10000) { // ddp2 + pgm_cpu_sync(); + asic27a_to_arm = data; + Arm7SetIRQLine(ARM7_FIRQ_LINE, ARM7_IRQSTATUS_ACK); + return; + } +} + +static void __fastcall asic27a_write_word(UINT32 address, UINT16 data) +{ + if ((address & 0xfffffe) == 0xd10000) { + pgm_cpu_sync(); + asic27a_to_arm = data & 0xff; + Arm7SetIRQLine(ARM7_FIRQ_LINE, ARM7_IRQSTATUS_ACK); + return; + } +} + +static UINT8 __fastcall asic27a_read_byte(UINT32 address) +{ + if ((address & 0xfffffc) == 0xd10000) { + pgm_cpu_sync(); + return asic27a_to_68k; + } + + return 0; +} + +static UINT16 __fastcall asic27a_read_word(UINT32 address) +{ + if ((address & 0xfffffc) == 0xd10000) { + pgm_cpu_sync(); + return asic27a_to_68k; + } + + return 0; +} + +static void asic27a_arm7_write_byte(UINT32 address, UINT8 data) +{ + switch (address) + { + case 0x38000000: + asic27a_to_68k = data; + return; + } +} + +static UINT8 asic27a_arm7_read_byte(UINT32 address) +{ + switch (address) + { + case 0x38000000: + Arm7SetIRQLine(ARM7_FIRQ_LINE, ARM7_IRQSTATUS_NONE); + return asic27a_to_arm; + } + + return 0; +} + +static INT32 asic27aScan(INT32 nAction,INT32 *) +{ + struct BurnArea ba; + + if (nAction & ACB_MEMORY_RAM) { + ba.Data = PGMARMShareRAM; + ba.nLen = 0x0010000; + ba.nAddress = 0xd00000; + ba.szName = "ARM SHARE RAM"; + BurnAcb(&ba); + + ba.Data = PGMARMRAM0; + ba.nLen = 0x0000400; + ba.nAddress = 0; + ba.szName = "ARM RAM 0"; + BurnAcb(&ba); + + ba.Data = PGMARMRAM1; + ba.nLen = 0x0010000; + ba.nAddress = 0; + ba.szName = "ARM RAM 1"; + BurnAcb(&ba); + + ba.Data = PGMARMRAM2; + ba.nLen = 0x0000400; + ba.nAddress = 0; + ba.szName = "ARM RAM 2"; + BurnAcb(&ba); + } + + if (nAction & ACB_DRIVER_DATA) { + Arm7Scan(nAction); + + SCAN_VAR(asic27a_to_arm); + SCAN_VAR(asic27a_to_68k); + } + + return 0; +} + +void install_protection_asic27a_martmast() +{ + nPGMArm7Type = 2; + pPgmScanCallback = asic27aScan; + + SekOpen(0); + + SekMapMemory(PGMARMShareRAM, 0xd00000, 0xd0ffff, SM_RAM); + + SekMapHandler(4, 0xd10000, 0xd10003, SM_READ | SM_WRITE); + SekSetReadWordHandler(4, asic27a_read_word); + SekSetReadByteHandler(4, asic27a_read_byte); + SekSetWriteWordHandler(4, asic27a_write_word); + SekSetWriteByteHandler(4, asic27a_write_byte); + SekClose(); + + Arm7Init(0); + Arm7Open(0); + Arm7MapMemory(PGMARMROM, 0x00000000, 0x00003fff, ARM7_ROM); + Arm7MapMemory(PGMUSER0, 0x08000000, 0x08000000+(nPGMExternalARMLen-1), ARM7_ROM); + Arm7MapMemory(PGMARMRAM0, 0x10000000, 0x100003ff, ARM7_RAM); + Arm7MapMemory(PGMARMRAM1, 0x18000000, 0x1800ffff, ARM7_RAM); + Arm7MapMemory(PGMARMShareRAM, 0x48000000, 0x4800ffff, ARM7_RAM); + Arm7MapMemory(PGMARMRAM2, 0x50000000, 0x500003ff, ARM7_RAM); + Arm7SetWriteByteHandler(asic27a_arm7_write_byte); + Arm7SetReadByteHandler(asic27a_arm7_read_byte); + Arm7Close(); +} diff --git a/src/burn/drv/pgm/pgm_asic27a_type3.cpp b/src/burn/drv/pgm/pgm_asic27a_type3.cpp new file mode 100644 index 000000000..84ac86778 --- /dev/null +++ b/src/burn/drv/pgm/pgm_asic27a_type3.cpp @@ -0,0 +1,175 @@ +#include "pgm.h" + +/* + IGS Asic27a (type 3) proper emulation + + Used by: + Demon Front + The Gladiator + The Killing Blade Plus + Spectral VS Generation + Happy 6in1 +*/ + +static UINT8 svg_ram_sel = 0; +static UINT8 *svg_ram[2]; +static UINT8 asic27a_68k_to_arm = 0; +static UINT8 asic27a_arm_to_68k = 0; + +static inline void pgm_cpu_sync() +{ + INT32 nCycles = SekTotalCycles() - Arm7TotalCycles(); + + if (nCycles > 100) { + Arm7Run(nCycles); + } +} + +static void svg_set_ram_bank(INT32 data) +{ + svg_ram_sel = data & 1; + Arm7MapMemory(svg_ram[svg_ram_sel], 0x38000000, 0x3800ffff, ARM7_RAM); + SekMapMemory(svg_ram[svg_ram_sel^1], 0x500000, 0x50ffff, SM_RAM); +} + +static void __fastcall svg_write_byte(UINT32 address, UINT8 data) +{ + pgm_cpu_sync(); + + switch (address) + { + case 0x5c0000: + Arm7SetIRQLine(ARM7_FIRQ_LINE, ARM7_IRQSTATUS_AUTO); + return; + } +} + +static void __fastcall svg_write_word(UINT32 address, UINT16 data) +{ + pgm_cpu_sync(); + + switch (address) + { + case 0x5c0300: + asic27a_68k_to_arm = data; // byte + return; + } +} + +static UINT16 __fastcall svg_read_word(UINT32 address) +{ + switch (address) + { + case 0x5c0300: + pgm_cpu_sync(); + return asic27a_arm_to_68k; + } + + return 0; +} + +static void svg_arm7_write_byte(UINT32 address, UINT8 data) +{ + switch (address) + { + case 0x40000018: + svg_set_ram_bank(data); + return; + + case 0x48000000: + asic27a_arm_to_68k = data; + return; + } +} + +static UINT8 svg_arm7_read_byte(UINT32 address) +{ + switch (address) + { + case 0x48000000: + return asic27a_68k_to_arm; + } + + return 0; +} + +static INT32 svg_asic27aScan(INT32 nAction,INT32 *) +{ + struct BurnArea ba; + + if (nAction & ACB_MEMORY_RAM) { + ba.Data = PGMARMShareRAM; + ba.nLen = 0x0020000; + ba.nAddress = 0x400000; + ba.szName = "ARM SHARE RAM #0 (address 500000)"; + BurnAcb(&ba); + + ba.Data = PGMARMShareRAM2; + ba.nLen = 0x0020000; + ba.nAddress = 0x500000; + ba.szName = "ARM SHARE RAM #1"; + BurnAcb(&ba); + + ba.Data = PGMARMRAM0; + ba.nLen = 0x0000400; + ba.nAddress = 0; + ba.szName = "ARM RAM 0"; + BurnAcb(&ba); + + ba.Data = PGMARMRAM1; + ba.nLen = 0x0040000; + ba.nAddress = 0; + ba.szName = "ARM RAM 1"; + BurnAcb(&ba); + + ba.Data = PGMARMRAM2; + ba.nLen = 0x0000400; + ba.nAddress = 0; + ba.szName = "ARM RAM 2"; + BurnAcb(&ba); + } + + if (nAction & ACB_DRIVER_DATA) { + Arm7Scan(nAction); + SCAN_VAR(asic27a_68k_to_arm); + SCAN_VAR(asic27a_arm_to_68k); + + SCAN_VAR(svg_ram_sel); + } + + if (nAction & ACB_WRITE) { + svg_set_ram_bank(svg_ram_sel); + } + + return 0; +} + +void install_protection_asic27a_svg() +{ + nPGMArm7Type = 3; + + pPgmScanCallback = svg_asic27aScan; + + svg_ram_sel = 0; + svg_ram[0] = PGMARMShareRAM; + svg_ram[1] = PGMARMShareRAM2; + + SekOpen(0); + SekMapHandler(5, 0x500000, 0x5fffff, SM_RAM); + SekSetReadWordHandler(5, svg_read_word); + SekSetWriteWordHandler(5, svg_write_word); + SekSetWriteByteHandler(5, svg_write_byte); + SekClose(); + + Arm7Init(0); + Arm7Open(0); + Arm7MapMemory(PGMARMROM, 0x00000000, 0x00003fff, ARM7_ROM); + Arm7MapMemory(PGMUSER0, 0x08000000, 0x08000000 | (nPGMExternalARMLen-1), ARM7_ROM); + Arm7MapMemory(PGMARMRAM0, 0x10000000, 0x100003ff, ARM7_RAM); + Arm7MapMemory(PGMARMRAM1, 0x18000000, 0x1803ffff, ARM7_RAM); + Arm7MapMemory(svg_ram[1], 0x38000000, 0x3800ffff, ARM7_RAM); + Arm7MapMemory(PGMARMRAM2, 0x50000000, 0x500003ff, ARM7_RAM); + Arm7SetWriteByteHandler(svg_arm7_write_byte); + Arm7SetReadByteHandler(svg_arm7_read_byte); + Arm7Close(); +} diff --git a/src/burn/drv/pgm/pgm_asic3.cpp b/src/burn/drv/pgm/pgm_asic3.cpp new file mode 100644 index 000000000..7778e12a5 --- /dev/null +++ b/src/burn/drv/pgm/pgm_asic3.cpp @@ -0,0 +1,172 @@ +#include "pgm.h" +#include "bitswap.h" + +/* + IGS Asic3 emulation + + Used by: + Oriental Legends +*/ + +static UINT8 asic3_latch[3]; +static UINT8 asic3_x; +static UINT8 asic3_reg; +static UINT16 asic3_hold; +static UINT16 asic3_hilo; + +static void asic3_compute_hold(INT32 y, INT32 z) +{ + UINT16 old = asic3_hold; + + asic3_hold = ((old << 1) | (old >> 15)); + asic3_hold ^= 0x2bad; + asic3_hold ^= BIT(z, y); + asic3_hold ^= BIT(asic3_x, 2) << 10; + asic3_hold ^= BIT(old, 5); + + static INT32 modes[8] = { 1, 1, 3, 2, 4, 4, 4, 4 }; + + switch (modes[PgmInput[7] & 7]) // The mode is dependent on the region + { + case 1: + asic3_hold ^= BIT(old, 10) ^ BIT(old, 8) ^ (BIT(asic3_x, 0) << 1) ^ (BIT(asic3_x, 1) << 6) ^ (BIT(asic3_x, 3) << 14); + break; + + case 2: + asic3_hold ^= BIT(old, 7) ^ BIT(old, 6) ^ (BIT(asic3_x, 0) << 4) ^ (BIT(asic3_x, 1) << 6) ^ (BIT(asic3_x, 3) << 12); + break; + + case 3: + asic3_hold ^= BIT(old, 10) ^ BIT(old, 8) ^ (BIT(asic3_x, 0) << 4) ^ (BIT(asic3_x, 1) << 6) ^ (BIT(asic3_x, 3) << 12); + break; + + case 4: + asic3_hold ^= BIT(old, 7) ^ BIT(old, 6) ^ (BIT(asic3_x, 0) << 3) ^ (BIT(asic3_x, 1) << 8) ^ (BIT(asic3_x, 3) << 14); + break; + } +} + +static UINT16 __fastcall asic3_read_word(UINT32 ) +{ + switch (asic3_reg) + { + case 0x00: + return (asic3_latch[0] & 0xf7) | ((PgmInput[7] << 3) & 0x08); + + case 0x01: + return (asic3_latch[1]); + + case 0x02: + return (asic3_latch[2] & 0x7f) | ((PgmInput[7] << 6) & 0x80); + + case 0x03: + return BITSWAP08(asic3_hold, 5,2,9,7,10,13,12,15); + + case 0x20: return 0x49; + case 0x21: return 0x47; + case 0x22: return 0x53; + + case 0x24: return 0x41; + case 0x25: return 0x41; + case 0x26: return 0x7f; + case 0x27: return 0x41; + case 0x28: return 0x41; + + case 0x2a: return 0x3e; + case 0x2b: return 0x41; + case 0x2c: return 0x49; + case 0x2d: return 0xf9; + case 0x2e: return 0x0a; + + case 0x30: return 0x26; + case 0x31: return 0x49; + case 0x32: return 0x49; + case 0x33: return 0x49; + case 0x34: return 0x32; + } + + return 0; +} + +static void __fastcall asic3_write_word(UINT32 address, UINT16 data) +{ + if (address == 0xc04000) { + asic3_reg = data; + return; + } + + switch (asic3_reg) + { + case 0x00: + case 0x01: + case 0x02: + asic3_latch[asic3_reg] = data << 1; + break; + + case 0x40: + asic3_hilo = (asic3_hilo << 8) | data; + break; + + case 0x48: + { + asic3_x = 0; + if ((asic3_hilo & 0x0090) == 0) asic3_x |= 0x01; + if ((asic3_hilo & 0x0006) == 0) asic3_x |= 0x02; + if ((asic3_hilo & 0x9000) == 0) asic3_x |= 0x04; + if ((asic3_hilo & 0x0a00) == 0) asic3_x |= 0x08; + } + break; + + case 0x80: + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + asic3_compute_hold(asic3_reg & 0x07, data); + break; + + case 0xa0: + asic3_hold = 0; + break; + } +} + +static void reset_asic3() +{ + memset (asic3_latch, 0, 3 * sizeof(UINT8)); + + asic3_hold = 0; + asic3_reg = 0; + asic3_x = 0; + asic3_hilo = 0; +} + +static INT32 asic3Scan(INT32 nAction, INT32 *) +{ + if (nAction & ACB_DRIVER_DATA) { + SCAN_VAR(asic3_reg); + SCAN_VAR(asic3_latch[0]); + SCAN_VAR(asic3_latch[1]); + SCAN_VAR(asic3_latch[2]); + SCAN_VAR(asic3_x); + SCAN_VAR(asic3_hilo); + SCAN_VAR(asic3_hold); + } + + return 0; +} + +void install_protection_asic3_orlegend() +{ + pPgmScanCallback = asic3Scan; + pPgmResetCallback = reset_asic3; + + SekOpen(0); + SekMapHandler(4, 0xc04000, 0xc0400f, SM_READ | SM_WRITE); + SekSetReadWordHandler(4, asic3_read_word); + SekSetWriteWordHandler(4, asic3_write_word); + SekClose(); +} diff --git a/src/burn/drv/pgm/pgm_prot.cpp b/src/burn/drv/pgm/pgm_prot.cpp deleted file mode 100644 index 1abf36f51..000000000 --- a/src/burn/drv/pgm/pgm_prot.cpp +++ /dev/null @@ -1,3416 +0,0 @@ - -#include "pgm.h" -#include "bitswap.h" - -static UINT16 *sharedprotram; // shared by several simulations - -//------------------------------------------------------------------------------------------------------------------- -// Proper emulation -//------------------------------------------------------------------------------------------------------------------- - -//----------------------------------- -// kov2, kov2p, Martmast, ddp2, dw2001, dwpc - -static UINT8 asic27a_to_arm = 0; -static UINT8 asic27a_to_68k = 0; - -static inline void pgm_cpu_sync() -{ - INT32 nCycles = SekTotalCycles() - Arm7TotalCycles(); - - if (nCycles > 0) { - Arm7Run(nCycles); - } -} - -static void __fastcall asic27a_write_byte(UINT32 address, UINT8 data) -{ - if ((address & 0xfffffe) == 0xd10000) { // ddp2 - pgm_cpu_sync(); - asic27a_to_arm = data; - Arm7SetIRQLine(ARM7_FIRQ_LINE, ARM7_IRQSTATUS_ACK); - return; - } -} - -static void __fastcall asic27a_write_word(UINT32 address, UINT16 data) -{ - if ((address & 0xfffffe) == 0xd10000) { - pgm_cpu_sync(); - asic27a_to_arm = data & 0xff; - Arm7SetIRQLine(ARM7_FIRQ_LINE, ARM7_IRQSTATUS_ACK); - return; - } -} - -static UINT8 __fastcall asic27a_read_byte(UINT32 address) -{ - if ((address & 0xfffffc) == 0xd10000) { - pgm_cpu_sync(); - return asic27a_to_68k; - } - - return 0; -} - -static UINT16 __fastcall asic27a_read_word(UINT32 address) -{ - if ((address & 0xfffffc) == 0xd10000) { - pgm_cpu_sync(); - return asic27a_to_68k; - } - - return 0; -} - -static void asic27a_arm7_write_byte(UINT32 address, UINT8 data) -{ - switch (address) - { - case 0x38000000: - asic27a_to_68k = data; - return; - } -} - -static UINT8 asic27a_arm7_read_byte(UINT32 address) -{ - switch (address) - { - case 0x38000000: - Arm7SetIRQLine(ARM7_FIRQ_LINE, ARM7_IRQSTATUS_NONE); - return asic27a_to_arm; - } - - return 0; -} - -static INT32 asic27aScan(INT32 nAction,INT32 *) -{ - struct BurnArea ba; - - if (nAction & ACB_MEMORY_RAM) { - ba.Data = PGMARMShareRAM; - ba.nLen = 0x0010000; - ba.nAddress = 0xd00000; - ba.szName = "ARM SHARE RAM"; - BurnAcb(&ba); - - ba.Data = PGMARMRAM0; - ba.nLen = 0x0000400; - ba.nAddress = 0; - ba.szName = "ARM RAM 0"; - BurnAcb(&ba); - - ba.Data = PGMARMRAM1; - ba.nLen = 0x0010000; - ba.nAddress = 0; - ba.szName = "ARM RAM 1"; - BurnAcb(&ba); - - ba.Data = PGMARMRAM2; - ba.nLen = 0x0000400; - ba.nAddress = 0; - ba.szName = "ARM RAM 2"; - BurnAcb(&ba); - } - - if (nAction & ACB_DRIVER_DATA) { - Arm7Scan(nAction); - - SCAN_VAR(asic27a_to_arm); - SCAN_VAR(asic27a_to_68k); - } - - return 0; -} - -void install_protection_asic27a_martmast() -{ - nPGMArm7Type = 2; - pPgmScanCallback = asic27aScan; - - SekOpen(0); - - SekMapMemory(PGMARMShareRAM, 0xd00000, 0xd0ffff, SM_RAM); - - SekMapHandler(4, 0xd10000, 0xd10003, SM_READ | SM_WRITE); - SekSetReadWordHandler(4, asic27a_read_word); - SekSetReadByteHandler(4, asic27a_read_byte); - SekSetWriteWordHandler(4, asic27a_write_word); - SekSetWriteByteHandler(4, asic27a_write_byte); - SekClose(); - - Arm7Init(0); - Arm7Open(0); - Arm7MapMemory(PGMARMROM, 0x00000000, 0x00003fff, ARM7_ROM); - Arm7MapMemory(PGMUSER0, 0x08000000, 0x08000000+(nPGMExternalARMLen-1), ARM7_ROM); - Arm7MapMemory(PGMARMRAM0, 0x10000000, 0x100003ff, ARM7_RAM); - Arm7MapMemory(PGMARMRAM1, 0x18000000, 0x1800ffff, ARM7_RAM); - Arm7MapMemory(PGMARMShareRAM, 0x48000000, 0x4800ffff, ARM7_RAM); - Arm7MapMemory(PGMARMRAM2, 0x50000000, 0x500003ff, ARM7_RAM); - Arm7SetWriteByteHandler(asic27a_arm7_write_byte); - Arm7SetReadByteHandler(asic27a_arm7_read_byte); - Arm7Close(); -} - - -//--------------------------------------------------------------- -// kovsh / photoy2k / photoy2k2 (XingXing) - -static UINT16 kovsh_highlatch_arm_w; -static UINT16 kovsh_lowlatch_arm_w; -static UINT16 kovsh_highlatch_68k_w; -static UINT16 kovsh_lowlatch_68k_w ; -static UINT32 kovsh_counter; - -static void __fastcall kovsh_asic27a_write_word(UINT32 address, UINT16 data) -{ - switch (address) - { - case 0x500000: - case 0x600000: - kovsh_lowlatch_68k_w = data; - return; - - case 0x500002: - case 0x600002: - kovsh_highlatch_68k_w = data; - return; - } -} - -static UINT16 __fastcall kovsh_asic27a_read_word(UINT32 address) -{ - if ((address & 0xffffc0) == 0x4f0000) { - return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(PGMARMShareRAM + (address & 0x3e)))); - } - - switch (address) - { - case 0x500000: - case 0x600000: - pgm_cpu_sync(); - return kovsh_lowlatch_arm_w; - - case 0x500002: - case 0x600002: - pgm_cpu_sync(); - return kovsh_highlatch_arm_w; - } - - return 0; -} - -static void kovsh_asic27a_arm7_write_word(UINT32 address, UINT16 data) -{ - // written... but never read? - if ((address & 0xffffff80) == 0x50800000) { - *((UINT16*)(PGMARMShareRAM + ((address>>1) & 0x3e))) = BURN_ENDIAN_SWAP_INT16(data); - return; - } -} - -static void kovsh_asic27a_arm7_write_long(UINT32 address, UINT32 data) -{ - switch (address) - { - case 0x40000000: - { - kovsh_highlatch_arm_w = data >> 16; - kovsh_lowlatch_arm_w = data; - - kovsh_highlatch_68k_w = 0; - kovsh_lowlatch_68k_w = 0; - } - return; - } -} - -static UINT32 kovsh_asic27a_arm7_read_long(UINT32 address) -{ - switch (address) - { - case 0x40000000: - return (kovsh_highlatch_68k_w << 16) | (kovsh_lowlatch_68k_w); - - case 0x4000000c: - return kovsh_counter++; - } - - return 0; -} - -static void reset_kovsh_asic27a() -{ - kovsh_highlatch_arm_w = 0; - kovsh_lowlatch_arm_w = 0; - kovsh_highlatch_68k_w = 0; - kovsh_lowlatch_68k_w = 0; - kovsh_counter = 1; -} - -static INT32 kovsh_asic27aScan(INT32 nAction, INT32 *) -{ - struct BurnArea ba; - - if (nAction & ACB_MEMORY_RAM) { - ba.Data = PGMARMShareRAM; - ba.nLen = 0x0000040; - ba.nAddress = 0x400000; - ba.szName = "ARM SHARE RAM"; - BurnAcb(&ba); - - ba.Data = PGMARMRAM0; - ba.nLen = 0x0000400; - ba.nAddress = 0; - ba.szName = "ARM RAM 0"; - BurnAcb(&ba); - - ba.Data = PGMARMRAM2; - ba.nLen = 0x0000400; - ba.nAddress = 0; - ba.szName = "ARM RAM 1"; - BurnAcb(&ba); - } - - if (nAction & ACB_DRIVER_DATA) { - Arm7Scan(nAction); - - SCAN_VAR(kovsh_highlatch_arm_w); - SCAN_VAR(kovsh_lowlatch_arm_w); - SCAN_VAR(kovsh_highlatch_68k_w); - SCAN_VAR(kovsh_lowlatch_68k_w); - SCAN_VAR(kovsh_counter); - } - - return 0; -} - -void install_protection_asic27a_kovsh() -{ - nPGMArm7Type = 1; - pPgmScanCallback = kovsh_asic27aScan; - pPgmResetCallback = reset_kovsh_asic27a; - - SekOpen(0); - SekMapMemory(PGMARMShareRAM, 0x4f0000, 0x4f003f, SM_RAM); - - SekMapHandler(4, 0x500000, 0x600005, SM_READ | SM_WRITE); - SekSetReadWordHandler(4, kovsh_asic27a_read_word); - SekSetWriteWordHandler(4, kovsh_asic27a_write_word); - SekClose(); - - Arm7Init(0); - Arm7Open(0); - Arm7MapMemory(PGMARMROM, 0x00000000, 0x00003fff, ARM7_ROM); - Arm7MapMemory(PGMARMRAM0, 0x10000000, 0x100003ff, ARM7_RAM); - Arm7MapMemory(PGMARMRAM2, 0x50000000, 0x500003ff, ARM7_RAM); - Arm7SetWriteWordHandler(kovsh_asic27a_arm7_write_word); - Arm7SetWriteLongHandler(kovsh_asic27a_arm7_write_long); - Arm7SetReadLongHandler(kovsh_asic27a_arm7_read_long); - Arm7Close(); -} - -//------------------------------- -// Kovshp hack - -void __fastcall kovshp_asic27a_write_word(UINT32 address, UINT16 data) -{ - switch (address & 6) - { - case 0: - kovsh_lowlatch_68k_w = data; - return; - - case 2: - { - unsigned char asic_key = data >> 8; - unsigned char asic_cmd = (data & 0xff) ^ asic_key; - - switch (asic_cmd) // Intercept commands and translate them to those used by kovsh - { - case 0x9a: asic_cmd = 0x99; break; // kovassga - case 0xa6: asic_cmd = 0xa9; break; // kovassga - case 0xaa: asic_cmd = 0x56; break; // kovassga - case 0xf8: asic_cmd = 0xf3; break; // kovassga - - case 0x38: asic_cmd = 0xad; break; - case 0x43: asic_cmd = 0xca; break; - case 0x56: asic_cmd = 0xac; break; - case 0x73: asic_cmd = 0x93; break; - case 0x84: asic_cmd = 0xb3; break; - case 0x87: asic_cmd = 0xb1; break; - case 0x89: asic_cmd = 0xb6; break; - case 0x93: asic_cmd = 0x73; break; - case 0xa5: asic_cmd = 0xa9; break; - case 0xac: asic_cmd = 0x56; break; - case 0xad: asic_cmd = 0x38; break; - case 0xb1: asic_cmd = 0x87; break; - case 0xb3: asic_cmd = 0x84; break; - case 0xb4: asic_cmd = 0x90; break; - case 0xb6: asic_cmd = 0x89; break; - case 0xc5: asic_cmd = 0x8c; break; - case 0xca: asic_cmd = 0x43; break; - case 0xcc: asic_cmd = 0xf0; break; - case 0xd0: asic_cmd = 0xe0; break; - case 0xe0: asic_cmd = 0xd0; break; - case 0xe7: asic_cmd = 0x70; break; - case 0xed: asic_cmd = 0xcb; break; - case 0xf0: asic_cmd = 0xcc; break; - case 0xf1: asic_cmd = 0xf5; break; - case 0xf2: asic_cmd = 0xf1; break; - case 0xf4: asic_cmd = 0xf2; break; - case 0xf5: asic_cmd = 0xf4; break; - case 0xfc: asic_cmd = 0xc0; break; - case 0xfe: asic_cmd = 0xc3; break; - } - - kovsh_highlatch_68k_w = asic_cmd ^ (asic_key | (asic_key << 8)); - } - return; - } -} - -void install_protection_asic27a_kovshp() -{ - nPGMArm7Type = 1; - pPgmScanCallback = kovsh_asic27aScan; - - SekOpen(0); - SekMapMemory(PGMARMShareRAM, 0x4f0000, 0x4f003f, SM_RAM); - - SekMapHandler(4, 0x500000, 0x600005, SM_READ | SM_WRITE); - SekSetReadWordHandler(4, kovsh_asic27a_read_word); - SekSetWriteWordHandler(4, kovshp_asic27a_write_word); - SekClose(); - - Arm7Init(0); - Arm7Open(0); - Arm7MapMemory(PGMARMROM, 0x00000000, 0x00003fff, ARM7_ROM); - Arm7MapMemory(PGMARMRAM0, 0x10000000, 0x100003ff, ARM7_RAM); - Arm7MapMemory(PGMARMRAM2, 0x50000000, 0x500003ff, ARM7_RAM); - Arm7SetWriteWordHandler(kovsh_asic27a_arm7_write_word); - Arm7SetWriteLongHandler(kovsh_asic27a_arm7_write_long); - Arm7SetReadLongHandler(kovsh_asic27a_arm7_read_long); - Arm7Close(); -} - -//------------------------------------------------------------------------------------------- -// svg / dmnfrnt / theglad / killbld / Happy6 - -static UINT8 svg_ram_sel = 0; -static UINT8 *svg_ram[2]; - -static void svg_set_ram_bank(INT32 data) -{ - svg_ram_sel = data & 1; - Arm7MapMemory(svg_ram[svg_ram_sel], 0x38000000, 0x3800ffff, ARM7_RAM); - SekMapMemory(svg_ram[svg_ram_sel^1], 0x500000, 0x50ffff, SM_FETCH); -} - -static void __fastcall svg_write_byte(UINT32 address, UINT8 data) -{ - pgm_cpu_sync(); - - if ((address & 0xfff0000) == 0x0500000) { - svg_ram[svg_ram_sel^1][(address & 0xffff)^1] = data; - return; - } - - switch (address) - { - case 0x5c0000: - case 0x5c0001: - Arm7SetIRQLine(ARM7_FIRQ_LINE, ARM7_IRQSTATUS_AUTO); - return; - } -} - -static void __fastcall svg_write_word(UINT32 address, UINT16 data) -{ - pgm_cpu_sync(); - - if ((address & 0xfff0000) == 0x0500000) { - *((UINT16*)(svg_ram[svg_ram_sel^1] + (address & 0xfffe))) = BURN_ENDIAN_SWAP_INT16(data); - - return; - } - - switch (address) - { - case 0x5c0000: - Arm7SetIRQLine(ARM7_FIRQ_LINE, ARM7_IRQSTATUS_AUTO); - return; - - case 0x5c0300: - asic27a_to_arm = data; - return; - } -} - -static UINT8 __fastcall svg_read_byte(UINT32 address) -{ - if ((address & 0xfff0000) == 0x0500000) { - pgm_cpu_sync(); - - INT32 d = svg_ram[svg_ram_sel^1][(address & 0xffff)^1]; - return d; - } - - switch (address) - { - case 0x5c0000: - case 0x5c0001: - return 0; - } - - return 0; -} - -static UINT16 __fastcall svg_read_word(UINT32 address) -{ - if ((address & 0xfff0000) == 0x0500000) { - pgm_cpu_sync(); - - return BURN_ENDIAN_SWAP_INT16(*((UINT16*)(svg_ram[svg_ram_sel^1] + (address & 0xfffe)))); - } - - switch (address) - { - case 0x5c0000: - case 0x5c0001: - return 0; - - case 0x5c0300: - pgm_cpu_sync(); - return asic27a_to_68k; - } - - return 0; -} - -static void svg_arm7_write_byte(UINT32 address, UINT8 data) -{ - switch (address) - { - case 0x40000018: - svg_set_ram_bank(data); - return; - - case 0x48000000: - asic27a_to_68k = data; - return; - } -} - -static void svg_arm7_write_word(UINT32 /*address*/, UINT16 /*data*/) -{ - -} - -static void svg_arm7_write_long(UINT32 address, UINT32 data) -{ - switch (address) - { - case 0x40000018: - svg_set_ram_bank(data); - return; - - case 0x48000000: - asic27a_to_68k = data; - return; - } -} - -static UINT8 svg_arm7_read_byte(UINT32 address) -{ - switch (address) - { - case 0x48000000: - case 0x48000001: - case 0x48000002: - case 0x48000003: - return asic27a_to_arm; - } - - return 0; -} - -static UINT16 svg_arm7_read_word(UINT32 address) -{ - switch (address) - { - case 0x48000000: - case 0x48000002: - return asic27a_to_arm; - } - - return 0; -} - -static UINT32 svg_arm7_read_long(UINT32 address) -{ - switch (address) - { - case 0x48000000: - return asic27a_to_arm; - } - - return 0; -} - -static INT32 svg_asic27aScan(INT32 nAction,INT32 *) -{ - struct BurnArea ba; - - if (nAction & ACB_MEMORY_RAM) { - ba.Data = PGMARMShareRAM; - ba.nLen = 0x0020000; - ba.nAddress = 0x400000; - ba.szName = "ARM SHARE RAM #0 (address 500000)"; - BurnAcb(&ba); - - ba.Data = PGMARMShareRAM2; - ba.nLen = 0x0020000; - ba.nAddress = 0x500000; - ba.szName = "ARM SHARE RAM #1"; - BurnAcb(&ba); - - ba.Data = PGMARMRAM0; - ba.nLen = 0x0000400; - ba.nAddress = 0; - ba.szName = "ARM RAM 0"; - BurnAcb(&ba); - - ba.Data = PGMARMRAM1; - ba.nLen = 0x0040000; - ba.nAddress = 0; - ba.szName = "ARM RAM 1"; - BurnAcb(&ba); - - ba.Data = PGMARMRAM2; - ba.nLen = 0x0000400; - ba.nAddress = 0; - ba.szName = "ARM RAM 2"; - BurnAcb(&ba); - } - - if (nAction & ACB_DRIVER_DATA) { - Arm7Scan(nAction); - SCAN_VAR(asic27a_to_arm); - SCAN_VAR(asic27a_to_68k); - - SCAN_VAR(svg_ram_sel); - svg_set_ram_bank(svg_ram_sel); - } - - return 0; -} - -void install_protection_asic27a_svg() -{ - nPGMArm7Type = 3; - - pPgmScanCallback = svg_asic27aScan; - - svg_ram_sel = 0; - svg_ram[0] = PGMARMShareRAM; - svg_ram[1] = PGMARMShareRAM2; - - SekOpen(0); - SekMapHandler(5, 0x500000, 0x5fffff, SM_RAM); - SekSetReadWordHandler(5, svg_read_word); - SekSetReadByteHandler(5, svg_read_byte); - SekSetWriteWordHandler(5, svg_write_word); - SekSetWriteByteHandler(5, svg_write_byte); - SekClose(); - - Arm7Init(0); - Arm7Open(0); - Arm7MapMemory(PGMARMROM, 0x00000000, 0x00003fff, ARM7_ROM); - Arm7MapMemory(PGMUSER0, 0x08000000, 0x08000000 | (nPGMExternalARMLen-1), ARM7_ROM); - Arm7MapMemory(PGMARMRAM0, 0x10000000, 0x100003ff, ARM7_RAM); - Arm7MapMemory(PGMARMRAM1, 0x18000000, 0x1803ffff, ARM7_RAM); - Arm7MapMemory(svg_ram[1], 0x38000000, 0x3800ffff, ARM7_RAM); - Arm7MapMemory(PGMARMRAM2, 0x50000000, 0x500003ff, ARM7_RAM); - Arm7SetWriteByteHandler(svg_arm7_write_byte); - Arm7SetWriteWordHandler(svg_arm7_write_word); - Arm7SetWriteLongHandler(svg_arm7_write_long); - Arm7SetReadByteHandler(svg_arm7_read_byte); - Arm7SetReadWordHandler(svg_arm7_read_word); - Arm7SetReadLongHandler(svg_arm7_read_long); - Arm7Close(); -} - - -//------------------------------------------------------------------------------------------------------------------- -// Simulations -//------------------------------------------------------------------------------------------------------------------- - - -//--------------------- -// Oriental Legends - -static UINT8 asic3_latch[3]; -static UINT8 asic3_x; -static UINT8 asic3_y; -static UINT8 asic3_z; -static UINT8 asic3_h1; -static UINT8 asic3_h2; -static UINT8 asic3_reg; -static UINT16 asic3_hold; - -static UINT32 bt(UINT32 v, INT32 bit) -{ - return (v & (1<= 0x80 && asic3_reg <= 0x87) { - asic3_y = asic3_reg & 7; - asic3_z = data; - asic3_compute_hold(); - } - } -} - -static void pgm_asic3_reg_w(UINT16 data) -{ - asic3_reg = data & 0xff; -} - -static void __fastcall asic3_write_word(UINT32 address, UINT16 data) -{ - if (address == 0xc04000) { - pgm_asic3_reg_w(data); - return; - } - - if (address == 0xc0400e) { - pgm_asic3_w(data); - return; - } -} - -static UINT16 __fastcall asic3_read_word(UINT32 address) -{ - if (address == 0xc0400e) { - return pgm_asic3_r(); - } - - return 0; -} - -static void reset_asic3() -{ - memset (asic3_latch, 0, 3 * sizeof(UINT8)); - - asic3_hold = 0; - asic3_reg = 0; - asic3_x = 0; - asic3_y = 0; - asic3_z = 0; - asic3_h1 = 0; - asic3_h2 = 0; -} - -static INT32 asic3Scan(INT32 nAction, INT32 *) -{ - if (nAction & ACB_DRIVER_DATA) { - SCAN_VAR(asic3_reg); - SCAN_VAR(asic3_latch[0]); - SCAN_VAR(asic3_latch[1]); - SCAN_VAR(asic3_latch[2]); - SCAN_VAR(asic3_x); - SCAN_VAR(asic3_y); - SCAN_VAR(asic3_z); - SCAN_VAR(asic3_h1); - SCAN_VAR(asic3_h2); - SCAN_VAR(asic3_hold); - } - - return 0; -} - -void install_protection_asic3_orlegend() -{ - pPgmScanCallback = asic3Scan; - pPgmResetCallback = reset_asic3; - - SekOpen(0); - SekMapHandler(4, 0xc04000, 0xc0400f, SM_READ | SM_WRITE); - - SekSetReadWordHandler(4, asic3_read_word); - SekSetWriteWordHandler(4, asic3_write_word); - SekClose(); -} - - -//-------------------- -// killblade - -static const UINT8 (*m_kb_source_data)[0xec]; -static INT32 m_kb_source_data_offset; -static UINT32 m_kb_game_id; -static UINT16 m_kb_prot_hold; -static UINT16 m_kb_prot_hilo; -static UINT16 m_kb_prot_hilo_select; -static int m_kb_cmd; -static int m_kb_reg; -static int m_kb_ptr; -static UINT8 m_kb_swap; -static UINT32 m_kb_regs[0x10]; - -// these were all xored by a table at $178B2A -static const UINT8 killbld_source_data[0x0c][0xec] = // offsets to these tables stored at $155ed0 -{ - { // region 16, $178772 - 0x5e, 0x09, 0xb3, 0x39, 0x60, 0x71, 0x71, 0x53, 0x11, 0xe5, 0x26, 0x34, 0x4c, 0x8c, 0x90, 0xee, - 0xed, 0xb5, 0x05, 0x95, 0x9e, 0x6b, 0xdd, 0x87, 0x0e, 0x7b, 0xed, 0x33, 0xaf, 0xc2, 0x62, 0x98, - 0xec, 0xc8, 0x2c, 0x2b, 0x57, 0x3d, 0x00, 0xbd, 0x12, 0xac, 0xba, 0x64, 0x81, 0x99, 0x16, 0x29, - 0xb4, 0x63, 0xa8, 0xd9, 0xc9, 0x5f, 0xfe, 0x21, 0xbb, 0xbf, 0x9b, 0xd1, 0x7b, 0x93, 0xc4, 0x82, - 0xef, 0x2b, 0xe8, 0xa6, 0xdc, 0x68, 0x3a, 0xd9, 0xc9, 0x23, 0xc7, 0x7b, 0x98, 0x5b, 0xe1, 0xc7, - 0xa3, 0xd4, 0x51, 0x0a, 0x86, 0x30, 0x20, 0x51, 0x6e, 0x04, 0x1c, 0xd4, 0xfb, 0xf5, 0x22, 0x8f, - 0x16, 0x6f, 0xb9, 0x59, 0x30, 0xcf, 0xab, 0x32, 0x1d, 0x6c, 0x84, 0xab, 0x23, 0x90, 0x94, 0xb1, - 0xe7, 0x4b, 0x6d, 0xc1, 0x84, 0xba, 0x32, 0x68, 0xa3, 0xf2, 0x47, 0x28, 0xe5, 0xcb, 0xbb, 0x47, - 0x14, 0x2c, 0xad, 0x4d, 0xa1, 0xd7, 0x18, 0x53, 0xf7, 0x6f, 0x05, 0x81, 0x8f, 0xbb, 0x29, 0xdc, - 0xbd, 0x17, 0x61, 0x92, 0x9b, 0x1d, 0x4e, 0x7a, 0x83, 0x14, 0x9f, 0x7b, 0x7a, 0x6a, 0xe1, 0x27, - 0x62, 0x52, 0x7e, 0x82, 0x45, 0xda, 0xed, 0xf1, 0x0a, 0x3b, 0x6c, 0x02, 0x5b, 0x6e, 0x45, 0x4e, - 0xf2, 0x65, 0x87, 0x1d, 0x80, 0xed, 0x6a, 0xc3, 0x77, 0xcb, 0xe8, 0x8d, 0x5a, 0xb8, 0xda, 0x89, - 0x88, 0x4b, 0x27, 0xd5, 0x57, 0x29, 0x91, 0x86, 0x12, 0xbb, 0xd3, 0x8c, 0xc7, 0x49, 0x84, 0x9c, - 0x96, 0x59, 0x30, 0x93, 0x92, 0xeb, 0x59, 0x2b, 0x93, 0x5b, 0x5f, 0xf9, 0x67, 0xac, 0x97, 0x8c, - 0x04, 0xda, 0x1b, 0x65, 0xd7, 0xef, 0x44, 0xca, 0xc4, 0x87, 0x18, 0x2b - }, - { // region 17, $178a36 - 0xd7, 0x49, 0xb3, 0x39, 0x60, 0x71, 0x70, 0x53, 0x11, 0x00, 0x27, 0xb2, 0x61, 0xd3, 0x8c, 0x8b, - 0xb2, 0xde, 0x6a, 0x78, 0x40, 0x5d, 0x4d, 0x88, 0xeb, 0x81, 0xd0, 0x2a, 0xbf, 0x8c, 0x22, 0x0d, - 0x89, 0x83, 0xc8, 0xef, 0x0d, 0x7a, 0xf6, 0xf0, 0x1d, 0x49, 0xa2, 0xd3, 0x1e, 0xef, 0x1c, 0xa2, - 0xce, 0x00, 0x5e, 0xa8, 0x7f, 0x4c, 0x41, 0x27, 0xa8, 0x6b, 0x92, 0x0a, 0xb8, 0x03, 0x2f, 0x7e, - 0xaf, 0x4a, 0xd0, 0x5c, 0xce, 0xeb, 0x0e, 0x8a, 0x4d, 0x0b, 0x73, 0xb3, 0xf3, 0x0c, 0x83, 0xaa, - 0xe5, 0xe4, 0x84, 0x06, 0xd7, 0xcc, 0xcb, 0x52, 0x8d, 0xbe, 0xa4, 0xdf, 0xd9, 0xab, 0x50, 0x59, - 0x53, 0x61, 0xa1, 0xc8, 0x6d, 0xbc, 0xde, 0xab, 0xaa, 0x5e, 0xc6, 0xf7, 0x83, 0xdc, 0x40, 0xcb, - 0x1b, 0xdd, 0x28, 0x3b, 0xee, 0xb1, 0x1f, 0x37, 0xdb, 0xe9, 0xbb, 0x74, 0x4b, 0xc2, 0x8a, 0xe8, - 0xec, 0x6e, 0x0e, 0x35, 0xe3, 0x2e, 0xbe, 0xef, 0xfd, 0x07, 0xbf, 0x8c, 0xfe, 0xf3, 0x5c, 0xbf, - 0x87, 0xe5, 0xbc, 0xcf, 0x60, 0xdc, 0x18, 0xf8, 0xfc, 0x51, 0x50, 0x86, 0xc6, 0x48, 0x3d, 0xb9, - 0x1d, 0x26, 0xf7, 0x7e, 0x87, 0x90, 0x12, 0xe8, 0x06, 0x0a, 0x45, 0xe9, 0xd9, 0xd8, 0x41, 0x68, - 0x21, 0x52, 0x92, 0x0f, 0xd6, 0xda, 0xa2, 0x97, 0xeb, 0x68, 0xd0, 0xb1, 0x15, 0x19, 0x8b, 0xd0, - 0x48, 0x1a, 0xeb, 0x90, 0x3f, 0x2a, 0x33, 0x1e, 0x5e, 0x30, 0x66, 0x01, 0x64, 0xef, 0x99, 0x52, - 0xba, 0x23, 0xbd, 0x53, 0xc0, 0x60, 0x87, 0x09, 0xcb, 0x4d, 0xd3, 0x87, 0x0e, 0x3a, 0x5c, 0x8d, - 0xc8, 0xb8, 0xb7, 0x34, 0x01, 0xeb, 0x72, 0x0d, 0xb1, 0x1f, 0x0f, 0xea - }, - { // region 18, $17dac4 - 0x6a, 0x13, 0xb3, 0x09, 0x60, 0x79, 0x61, 0x53, 0x11, 0x33, 0x41, 0x31, 0x76, 0x34, 0x88, 0x0f, - 0x77, 0x08, 0xb6, 0x74, 0xc8, 0x36, 0xbc, 0x70, 0xe2, 0x87, 0x9a, 0x21, 0xe8, 0x56, 0xe1, 0x9a, - 0x26, 0x57, 0x7e, 0x9b, 0xdb, 0xb7, 0xd4, 0x3d, 0x0f, 0xfe, 0x8a, 0x2a, 0xba, 0x2d, 0x22, 0x03, - 0xcf, 0x9c, 0xfa, 0x77, 0x35, 0x39, 0x6a, 0x14, 0xae, 0x30, 0x89, 0x42, 0xdc, 0x59, 0xb2, 0x93, - 0x6f, 0x82, 0xd1, 0x12, 0xd9, 0x88, 0xfa, 0x3b, 0xb7, 0x0c, 0x1f, 0x05, 0x68, 0xa3, 0x0c, 0xa6, - 0x0f, 0xf4, 0x9e, 0x1b, 0x29, 0x82, 0x77, 0x3a, 0xac, 0x92, 0x2d, 0x04, 0xd0, 0x61, 0x65, 0x0a, - 0x77, 0x6c, 0x89, 0x38, 0xaa, 0xa9, 0xf8, 0x0c, 0x1f, 0x37, 0x09, 0x2b, 0xca, 0x29, 0x05, 0xe5, - 0x4e, 0x57, 0xfb, 0xcd, 0x40, 0xa8, 0x0c, 0x06, 0x2d, 0xe0, 0x30, 0xd9, 0x97, 0xb9, 0x59, 0x8a, - 0xde, 0xc9, 0x87, 0x1d, 0x3f, 0x84, 0x4c, 0x73, 0x04, 0x85, 0x61, 0xb0, 0x6e, 0x2c, 0x8f, 0xa2, - 0x6a, 0xcd, 0x31, 0xf3, 0x25, 0x83, 0xe1, 0x5e, 0x5d, 0xa7, 0xe7, 0xaa, 0x13, 0x26, 0xb1, 0x33, - 0xf0, 0x13, 0x58, 0x7a, 0xb0, 0x46, 0x1d, 0xdf, 0x02, 0xbf, 0x1e, 0xd1, 0x71, 0x43, 0x56, 0x82, - 0x4f, 0x58, 0x9d, 0x01, 0x2d, 0xc7, 0xda, 0x6b, 0x47, 0x05, 0xd1, 0xd5, 0xe8, 0x92, 0x3c, 0x18, - 0x21, 0xcf, 0xc9, 0x32, 0x0e, 0x12, 0xed, 0xb5, 0xaa, 0xa4, 0x12, 0x75, 0x01, 0x7d, 0xc7, 0x21, - 0xde, 0xec, 0x32, 0x13, 0xee, 0xd4, 0x9c, 0xe6, 0x04, 0x3f, 0x48, 0xfb, 0xb4, 0xc7, 0x21, 0x8e, - 0x8d, 0x7d, 0x54, 0x03, 0x11, 0xe7, 0xb9, 0x4f, 0x85, 0xb6, 0x1f, 0xaa - }, - { // region 19, $178eee - 0xe3, 0x53, 0xb3, 0x09, 0x60, 0x79, 0x60, 0x53, 0x11, 0x66, 0x5b, 0xc8, 0x8b, 0x94, 0x84, 0xab, - 0x3c, 0x18, 0x03, 0x57, 0x6a, 0x0f, 0x45, 0x58, 0xc0, 0x74, 0x64, 0x18, 0xf8, 0x39, 0xa1, 0x0f, - 0xc2, 0x2b, 0x1b, 0x60, 0xaa, 0x0e, 0xb2, 0x89, 0x01, 0x9b, 0x72, 0x80, 0x57, 0x83, 0x28, 0x63, - 0xe9, 0x39, 0x97, 0x46, 0xea, 0x3f, 0x93, 0x01, 0x9b, 0xf4, 0x80, 0x93, 0x01, 0xaf, 0x1d, 0x8f, - 0x16, 0xa1, 0xb9, 0xc7, 0xe4, 0x0c, 0xe7, 0xd2, 0x3b, 0xf3, 0xca, 0x3d, 0xc3, 0x54, 0xad, 0x89, - 0x51, 0x1e, 0xd1, 0x17, 0x7a, 0x1f, 0x23, 0x22, 0xcb, 0x4d, 0xce, 0x0f, 0xae, 0x30, 0x93, 0xd3, - 0x9b, 0x77, 0x71, 0xa7, 0xe7, 0x96, 0x2c, 0x85, 0xac, 0x29, 0x4b, 0x5e, 0x2b, 0x75, 0xb0, 0x00, - 0x81, 0xe9, 0xb6, 0x47, 0xaa, 0x9f, 0xdf, 0xd4, 0x7e, 0xd7, 0xa4, 0x3f, 0xe3, 0xb0, 0x41, 0x2c, - 0xb7, 0x0c, 0xe7, 0xeb, 0x9a, 0xda, 0xd9, 0x10, 0x23, 0x1d, 0x1c, 0xd4, 0xdd, 0x7d, 0xc2, 0x6c, - 0x4d, 0x9c, 0xa5, 0x18, 0xd0, 0x43, 0xab, 0xdc, 0xbd, 0xe4, 0x7f, 0xb5, 0x5f, 0x04, 0x0d, 0xac, - 0xab, 0xe6, 0xb8, 0x76, 0xf2, 0x15, 0x41, 0xef, 0x17, 0x8e, 0xf6, 0xb9, 0xef, 0x94, 0x52, 0x83, - 0x96, 0x45, 0x8f, 0xf2, 0x9c, 0xb4, 0x13, 0x3f, 0xbb, 0xa1, 0xd2, 0xf9, 0xa3, 0xf2, 0x06, 0x78, - 0xe0, 0x9e, 0xa7, 0xd3, 0xdc, 0x13, 0x8f, 0x4d, 0xf6, 0x19, 0xbd, 0x03, 0x9d, 0x24, 0xdc, 0xd6, - 0xe9, 0xcf, 0xa6, 0xd2, 0x1d, 0x49, 0xca, 0xc4, 0x55, 0x18, 0xbc, 0x70, 0x5b, 0x55, 0xfe, 0x8f, - 0x6b, 0x42, 0xf0, 0xd1, 0x21, 0xe3, 0xe7, 0x91, 0x59, 0x4e, 0x16, 0x83 - }, - { 0, }, // unused region 1a - { 0, }, // unused region 1b - { 0, }, // unused region 1c - { 0, }, // unused region 1d - { 0, }, // unused region 1e - { 0, }, // unused region 1f - { // region 20, $17a322 - 0xb3, 0x10, 0xf3, 0x0b, 0xe0, 0x71, 0x60, 0x53, 0x11, 0x9a, 0x12, 0x70, 0x1f, 0x1e, 0x81, 0xda, - 0x9d, 0x1f, 0x4b, 0xd6, 0x71, 0x48, 0x83, 0xe1, 0x04, 0x6c, 0x1b, 0xf1, 0xcd, 0x09, 0xdf, 0x3e, - 0x0b, 0xaa, 0x95, 0xc1, 0x07, 0xec, 0x0f, 0x54, 0xd0, 0x16, 0xb0, 0xdc, 0x86, 0x7b, 0x52, 0x38, - 0x3c, 0x68, 0x2b, 0xed, 0xe2, 0xeb, 0xb3, 0xc6, 0x48, 0x24, 0x41, 0x36, 0x17, 0x25, 0x1f, 0xa5, - 0x22, 0xc6, 0x5c, 0xa6, 0x19, 0xef, 0x17, 0x5c, 0x56, 0x4b, 0x4a, 0x2b, 0x75, 0xab, 0xe6, 0x22, - 0xd5, 0xc0, 0xd3, 0x46, 0xcc, 0xe4, 0xd4, 0xc4, 0x8c, 0x9a, 0x8a, 0x75, 0x24, 0x73, 0xa4, 0x26, - 0xca, 0x79, 0xaf, 0xb3, 0x94, 0x2a, 0x15, 0xbe, 0x40, 0x7b, 0x4d, 0xf6, 0xb4, 0xa4, 0x7b, 0xcf, - 0xce, 0xa0, 0x1d, 0xcb, 0x2f, 0x60, 0x28, 0x63, 0x85, 0x98, 0xd3, 0xd2, 0x45, 0x3f, 0x02, 0x65, - 0xd7, 0xf4, 0xbc, 0x2a, 0xe7, 0x50, 0xd1, 0x3f, 0x7f, 0xf6, 0x05, 0xb8, 0xe9, 0x39, 0x10, 0x6e, - 0x68, 0xa8, 0x89, 0x60, 0x00, 0x68, 0xfd, 0x20, 0xc4, 0xdc, 0xef, 0x67, 0x75, 0xfb, 0xbe, 0xfe, - 0x2b, 0x16, 0xa6, 0x5a, 0x77, 0x0d, 0x0c, 0xe2, 0x2d, 0xd1, 0xe4, 0x11, 0xc9, 0x4b, 0x81, 0x3a, - 0x0c, 0x24, 0xaa, 0x77, 0x2b, 0x2f, 0x83, 0x23, 0xd1, 0xe9, 0xa7, 0x29, 0x0a, 0xf9, 0x26, 0x9d, - 0x51, 0xc8, 0x6d, 0x71, 0x9d, 0xce, 0x46, 0x72, 0x26, 0x48, 0x3d, 0x64, 0xe5, 0x67, 0xbb, 0x1a, - 0xb4, 0x6d, 0x21, 0x11, 0x79, 0x78, 0xc2, 0xd5, 0x11, 0x6a, 0xd2, 0xea, 0x03, 0x4d, 0x92, 0xaf, - 0x18, 0xd5, 0x07, 0x79, 0xaa, 0xf9, 0x44, 0x93, 0x6f, 0x41, 0x22, 0x0d - }, - { // region 21, $17b3b4 - 0x2d, 0x50, 0xf3, 0x0b, 0xe0, 0x71, 0x61, 0x53, 0x11, 0xb4, 0x2c, 0xee, 0x34, 0x7e, 0x7d, 0x5e, - 0x62, 0x48, 0x97, 0xd2, 0xf9, 0x3a, 0xf2, 0xc9, 0xfa, 0x59, 0xe4, 0xe8, 0xf6, 0xd2, 0x9f, 0xb2, - 0xa7, 0x7e, 0x32, 0x86, 0xbc, 0x43, 0xec, 0xa0, 0xc2, 0xcb, 0x98, 0x33, 0x23, 0xd1, 0x58, 0x98, - 0x56, 0x05, 0xc7, 0xbc, 0x98, 0xd8, 0xdc, 0xb3, 0x35, 0xe8, 0x51, 0x6e, 0x3b, 0x7b, 0x89, 0xba, - 0xe1, 0xe5, 0x44, 0x5c, 0x24, 0x73, 0x04, 0x0d, 0xd9, 0x33, 0xf5, 0x63, 0xe9, 0x5c, 0x88, 0x05, - 0x18, 0xd0, 0x07, 0x5b, 0x1e, 0x81, 0x80, 0xac, 0x92, 0x6e, 0x13, 0x80, 0x1b, 0x29, 0xd2, 0xef, - 0x08, 0x84, 0x97, 0x23, 0xd1, 0x17, 0x2f, 0x38, 0xb4, 0x6d, 0x8f, 0x2a, 0x15, 0xf0, 0x40, 0xe9, - 0x02, 0x33, 0xd7, 0x5e, 0x99, 0x57, 0x15, 0x32, 0xbd, 0x8f, 0x48, 0x38, 0x91, 0x36, 0xe9, 0x07, - 0xc9, 0x37, 0x1d, 0x12, 0x2a, 0xbf, 0x5f, 0xdb, 0x85, 0x75, 0xbf, 0xdc, 0x59, 0x8a, 0x43, 0x51, - 0x4b, 0x77, 0xfd, 0x84, 0xc4, 0x28, 0xc7, 0x85, 0x25, 0x1a, 0x87, 0x8b, 0xc1, 0xd9, 0x1a, 0x78, - 0xe5, 0x03, 0x20, 0x56, 0xa0, 0xc2, 0x17, 0xf2, 0x29, 0xa0, 0xbd, 0xf8, 0x61, 0x9c, 0x7d, 0x54, - 0x3a, 0x11, 0xb5, 0x69, 0x9a, 0x1c, 0xbb, 0xf6, 0x2d, 0x86, 0xa8, 0x4d, 0xdd, 0x5a, 0xd6, 0xe4, - 0x11, 0x7e, 0x4b, 0x13, 0x6c, 0xb6, 0x01, 0x0a, 0x72, 0xbc, 0xe8, 0xf1, 0x82, 0x0e, 0xd0, 0xcf, - 0xbf, 0x50, 0x95, 0xb7, 0xa7, 0xec, 0xd7, 0xb3, 0x49, 0x5c, 0x47, 0x5f, 0xa9, 0xda, 0x70, 0xb0, - 0xdc, 0x9a, 0xa3, 0x48, 0xd3, 0xf5, 0x72, 0xd5, 0x43, 0xd8, 0x19, 0xcc - } -}; - -// all tables xored with data from $149c4c -static const UINT8 dw3_source_data[0x07][0xec] = -{ - { // region 1, $14c21a - 0x67, 0x51, 0xf3, 0x19, 0xa0, 0x09, 0xb1, 0x21, 0xb0, 0xee, 0xe3, 0xf6, 0xbe, 0x81, 0x35, 0xe3, - 0xfb, 0xe6, 0xef, 0xdf, 0x61, 0x01, 0xfa, 0x22, 0x5d, 0x43, 0x01, 0xa5, 0x3b, 0x17, 0xd4, 0x74, - 0xf0, 0xf4, 0xf3, 0x43, 0xb5, 0x19, 0x04, 0xd5, 0x84, 0xce, 0x87, 0xfe, 0x35, 0x3e, 0xc4, 0x3c, - 0xc7, 0x85, 0x2a, 0x33, 0x00, 0x86, 0xd0, 0x4d, 0x65, 0x4b, 0xf9, 0xe9, 0xc0, 0xba, 0xaa, 0x77, - 0x9e, 0x66, 0xf6, 0x0f, 0x4f, 0x3a, 0xb6, 0xf1, 0x64, 0x9a, 0xe9, 0x25, 0x1a, 0x5f, 0x22, 0xa3, - 0xa2, 0xbf, 0x4b, 0x77, 0x3f, 0x34, 0xc9, 0x6e, 0xdb, 0x12, 0x5c, 0x33, 0xa5, 0x8b, 0x6c, 0xb1, - 0x74, 0xc8, 0x40, 0x4e, 0x2f, 0xe7, 0x46, 0xae, 0x99, 0xfc, 0xb0, 0x55, 0x54, 0xdf, 0xa7, 0xa1, - 0x0f, 0x5e, 0x49, 0xcf, 0x56, 0x3c, 0x90, 0x2b, 0xac, 0x65, 0x6e, 0xdb, 0x58, 0x3e, 0xc9, 0x00, - 0xae, 0x53, 0x4d, 0x92, 0xfa, 0x40, 0xb2, 0x6b, 0x65, 0x4b, 0x90, 0x8a, 0x0c, 0xe2, 0xa5, 0x9a, - 0xd0, 0x20, 0x29, 0x55, 0xa4, 0x44, 0xac, 0x51, 0x87, 0x54, 0x53, 0x34, 0x24, 0x4b, 0x81, 0x67, - 0x34, 0x4c, 0x5f, 0x31, 0x4e, 0xf2, 0xf1, 0x19, 0x18, 0x1c, 0x34, 0x38, 0xe1, 0x81, 0x17, 0xcf, - 0x24, 0xb9, 0x9a, 0xcb, 0x34, 0x51, 0x50, 0x59, 0x44, 0xb1, 0x0b, 0x50, 0x95, 0x6c, 0x48, 0x7e, - 0x14, 0xa4, 0xc6, 0xd9, 0xd3, 0xa5, 0xd6, 0xd0, 0xc5, 0x97, 0xf0, 0x45, 0xd0, 0x98, 0x51, 0x91, - 0x9f, 0xa3, 0x43, 0x51, 0x05, 0x90, 0xee, 0xca, 0x7e, 0x5f, 0x72, 0x53, 0xb1, 0xd3, 0xaf, 0x36, - 0x08, 0x75, 0xb0, 0x9b, 0xe0, 0x0d, 0x43, 0x88, 0xaa, 0x27, 0x44, 0x11 - }, - { // region 2, $14c126 - 0xf9, 0x19, 0xf3, 0x09, 0xa0, 0x09, 0xb0, 0x21, 0xb0, 0x22, 0xfd, 0x8e, 0xd3, 0xc8, 0x31, 0x67, - 0xc0, 0x10, 0x3c, 0xc2, 0x03, 0xf2, 0x6a, 0x0a, 0x54, 0x49, 0xca, 0xb5, 0x4b, 0xe0, 0x94, 0xe8, - 0x8d, 0xc8, 0x90, 0xee, 0x6b, 0x6f, 0xfa, 0x09, 0x76, 0x84, 0x6f, 0x55, 0xd1, 0x94, 0xca, 0x9c, - 0xe1, 0x22, 0xc6, 0x02, 0xb5, 0x8c, 0xf9, 0x3a, 0x52, 0x10, 0xf0, 0x22, 0xe4, 0x11, 0x15, 0x73, - 0x5e, 0x9e, 0xde, 0xc4, 0x5a, 0xbd, 0xa3, 0x89, 0xe7, 0x9b, 0x95, 0x5d, 0x75, 0xf6, 0xc3, 0x9f, - 0xe4, 0xcf, 0x65, 0x73, 0x90, 0xd0, 0x75, 0x56, 0xfa, 0xcc, 0xe4, 0x3e, 0x9c, 0x41, 0x81, 0x62, - 0xb1, 0xd3, 0x28, 0xbd, 0x6c, 0xed, 0x60, 0x28, 0x27, 0xee, 0xf2, 0xa1, 0xb4, 0x2c, 0x6c, 0xbb, - 0x42, 0xd7, 0x1d, 0x62, 0xc0, 0x33, 0x7d, 0xf9, 0xe4, 0x5c, 0xe2, 0x41, 0xa4, 0x1c, 0x98, 0xa1, - 0x87, 0x95, 0xad, 0x61, 0x56, 0x96, 0x40, 0x08, 0x6b, 0xe2, 0x4b, 0x95, 0x7b, 0x1b, 0xd8, 0x64, - 0xb3, 0xee, 0x9d, 0x79, 0x69, 0xea, 0x5d, 0xcf, 0x01, 0x91, 0xea, 0x3f, 0x70, 0x29, 0xdc, 0xe0, - 0x08, 0x20, 0xbf, 0x46, 0x90, 0xa8, 0xfc, 0x29, 0x14, 0xd1, 0x0d, 0x20, 0x79, 0xd2, 0x2c, 0xe9, - 0x52, 0xa6, 0x8c, 0xbd, 0xa3, 0x3e, 0x88, 0x2d, 0xb8, 0x4e, 0xf2, 0x74, 0x50, 0xcc, 0x12, 0xde, - 0xd3, 0x5a, 0xa4, 0x7b, 0xa2, 0x8d, 0x91, 0x68, 0x12, 0x0c, 0x9c, 0xb9, 0x6d, 0x26, 0x66, 0x60, - 0xc3, 0x6d, 0xd0, 0x11, 0x33, 0x05, 0x1d, 0xa8, 0xb6, 0x51, 0xe6, 0xe0, 0x58, 0x61, 0x74, 0x37, - 0xcc, 0x3a, 0x4d, 0x6a, 0x0a, 0x09, 0x71, 0xe3, 0x7e, 0xa5, 0x3b, 0xe9 - }, - { // region 3, $14E5BE - 0x73, 0x59, 0xf3, 0x09, 0xa0, 0x09, 0xb1, 0x21, 0xb0, 0x55, 0x18, 0x0d, 0xe8, 0x29, 0x2d, 0x04, - 0x85, 0x39, 0x88, 0xbe, 0x8b, 0xcb, 0xd9, 0x0b, 0x32, 0x36, 0x94, 0xac, 0x74, 0xc3, 0x3b, 0x5d, - 0x2a, 0x83, 0x46, 0xb3, 0x3a, 0xac, 0xd8, 0x55, 0x68, 0x21, 0x57, 0xab, 0x6e, 0xd1, 0xd0, 0xfc, - 0xe2, 0xbe, 0x63, 0xd0, 0x6b, 0x79, 0x23, 0x40, 0x58, 0xd4, 0xe7, 0x73, 0x22, 0x67, 0x7f, 0x88, - 0x05, 0xbd, 0xdf, 0x7a, 0x65, 0x41, 0x90, 0x3a, 0x52, 0x83, 0x28, 0xae, 0xe9, 0x8e, 0x65, 0x82, - 0x0e, 0xdf, 0x98, 0x88, 0xe1, 0x86, 0x21, 0x3e, 0x1a, 0x87, 0x6d, 0x62, 0x7a, 0xf6, 0xaf, 0x2c, - 0xd5, 0xc5, 0x10, 0x2d, 0xa9, 0xda, 0x93, 0xa1, 0x9b, 0xc7, 0x35, 0xd4, 0x15, 0x78, 0x18, 0xd5, - 0x75, 0x6a, 0xd7, 0xdb, 0x12, 0x2a, 0x6a, 0xc8, 0x36, 0x53, 0x57, 0xa6, 0xf0, 0x13, 0x67, 0x43, - 0x79, 0xf0, 0x0e, 0x49, 0xb1, 0xec, 0xcd, 0xa4, 0x8a, 0x61, 0x06, 0xb9, 0xea, 0x53, 0xf2, 0x47, - 0x7d, 0xd6, 0xf8, 0x9d, 0x2e, 0xaa, 0x27, 0x35, 0x61, 0xce, 0x9b, 0x63, 0xbc, 0x07, 0x51, 0x5a, - 0xc2, 0x0d, 0x39, 0x42, 0xd2, 0x5e, 0x21, 0x20, 0x10, 0xa0, 0xe5, 0x08, 0xf7, 0x3d, 0x28, 0x04, - 0x99, 0x93, 0x97, 0xaf, 0xf9, 0x12, 0xc0, 0x01, 0x2d, 0xea, 0xf3, 0x98, 0x0b, 0x46, 0xc2, 0x26, - 0x93, 0x10, 0x69, 0x1d, 0x71, 0x8e, 0x33, 0x00, 0x5e, 0x80, 0x2f, 0x47, 0x0a, 0xcc, 0x94, 0x16, - 0xe7, 0x37, 0x45, 0xd0, 0x61, 0x79, 0x32, 0x86, 0x08, 0x2a, 0x5b, 0x55, 0xfe, 0xee, 0x52, 0x38, - 0xaa, 0x18, 0xe9, 0x39, 0x1a, 0x1e, 0xb8, 0x26, 0x6b, 0x3d, 0x4b, 0xa9 - }, - { // region 4, $14d500 - 0x06, 0x01, 0xf3, 0x39, 0xa0, 0x09, 0xa0, 0x21, 0xb0, 0x6f, 0x32, 0x8b, 0xfd, 0x89, 0x29, 0xa0, - 0x4a, 0x62, 0xed, 0xa1, 0x2d, 0xa4, 0x49, 0xf2, 0x10, 0x3c, 0x77, 0xa3, 0x84, 0x8d, 0xfa, 0xd1, - 0xc6, 0x57, 0xe2, 0x78, 0xef, 0xe9, 0xb6, 0xa1, 0x5a, 0xbd, 0x3f, 0x02, 0x0b, 0x28, 0xd6, 0x76, - 0xfc, 0x5b, 0x19, 0x9f, 0x21, 0x66, 0x4c, 0x2d, 0x45, 0x99, 0xde, 0xab, 0x46, 0xbd, 0xe9, 0x84, - 0xc4, 0xdc, 0xc7, 0x30, 0x70, 0xdd, 0x64, 0xea, 0xbc, 0x6b, 0xd3, 0xe6, 0x45, 0x3f, 0x07, 0x7e, - 0x50, 0xef, 0xb2, 0x84, 0x33, 0x3c, 0xcc, 0x3f, 0x39, 0x5b, 0xf5, 0x6d, 0x71, 0xc5, 0xdd, 0xf5, - 0xf9, 0xd0, 0xf7, 0x9c, 0xe6, 0xc7, 0xad, 0x1b, 0x29, 0xb9, 0x90, 0x08, 0x75, 0xc4, 0xc3, 0xef, - 0xa8, 0xfc, 0xab, 0x55, 0x7c, 0x21, 0x57, 0x97, 0x87, 0x4a, 0xcb, 0x0c, 0x56, 0x0a, 0x4f, 0xcb, - 0x52, 0x33, 0x87, 0x31, 0xf3, 0x43, 0x5b, 0x41, 0x90, 0xf8, 0xc0, 0xdd, 0x5a, 0xa4, 0x26, 0x2a, - 0x60, 0xa5, 0x6d, 0xda, 0xf2, 0x6a, 0xf0, 0xb3, 0xda, 0x25, 0x33, 0x87, 0x22, 0xe4, 0xac, 0xd3, - 0x96, 0xe0, 0x99, 0x3e, 0xfb, 0x14, 0x45, 0x17, 0x25, 0x56, 0xbe, 0xef, 0x8f, 0x8e, 0x3d, 0x1e, - 0xc7, 0x99, 0xa2, 0xa1, 0x50, 0xfe, 0xdf, 0xd4, 0xa1, 0x87, 0xf4, 0xd5, 0xde, 0xa6, 0x8c, 0x6d, - 0x6c, 0xde, 0x47, 0xbe, 0x59, 0x8f, 0xd4, 0x97, 0xc3, 0xf4, 0xda, 0xbb, 0xa6, 0x73, 0xa9, 0xcb, - 0xf2, 0x01, 0xb9, 0x90, 0x8f, 0xed, 0x60, 0x64, 0x40, 0x1c, 0xb6, 0xc9, 0xa5, 0x7c, 0x17, 0x52, - 0x6f, 0xdc, 0x6d, 0x08, 0x2a, 0x1a, 0xe6, 0x68, 0x3f, 0xd4, 0x42, 0x69 - }, - { // region 5, $14bfb2 - 0x7f, 0x41, 0xf3, 0x39, 0xa0, 0x09, 0xa1, 0x21, 0xb0, 0xa2, 0x4c, 0x23, 0x13, 0xe9, 0x25, 0x3d, - 0x0f, 0x72, 0x3a, 0x9d, 0xb5, 0x96, 0xd1, 0xda, 0x07, 0x29, 0x41, 0x9a, 0xad, 0x70, 0xba, 0x46, - 0x63, 0x2b, 0x7f, 0x3d, 0xbe, 0x40, 0xad, 0xd4, 0x4c, 0x73, 0x27, 0x58, 0xa7, 0x65, 0xdc, 0xd6, - 0xfd, 0xde, 0xb5, 0x6e, 0xd6, 0x6c, 0x75, 0x1a, 0x32, 0x45, 0xd5, 0xe3, 0x6a, 0x14, 0x6d, 0x80, - 0x84, 0x15, 0xaf, 0xcc, 0x7b, 0x61, 0x51, 0x82, 0x40, 0x53, 0x7f, 0x38, 0xa0, 0xd6, 0x8f, 0x61, - 0x79, 0x19, 0xe5, 0x99, 0x84, 0xd8, 0x78, 0x27, 0x3f, 0x16, 0x97, 0x78, 0x4f, 0x7b, 0x0c, 0xa6, - 0x37, 0xdb, 0xc6, 0x0c, 0x24, 0xb4, 0xc7, 0x94, 0x9d, 0x92, 0xd2, 0x3b, 0xd5, 0x11, 0x6f, 0x0a, - 0xdb, 0x76, 0x66, 0xe7, 0xcd, 0x18, 0x2b, 0x66, 0xd8, 0x41, 0x40, 0x58, 0xa2, 0x01, 0x1e, 0x6d, - 0x44, 0x75, 0xe7, 0x19, 0x4f, 0xb2, 0xe8, 0xc4, 0x96, 0x77, 0x62, 0x02, 0xc9, 0xdc, 0x59, 0xf3, - 0x43, 0x8d, 0xc8, 0xfe, 0x9e, 0x2a, 0xba, 0x32, 0x3b, 0x62, 0xe3, 0x92, 0x6e, 0xc2, 0x08, 0x4d, - 0x51, 0xcd, 0xf9, 0x3a, 0x3e, 0xc9, 0x50, 0x27, 0x21, 0x25, 0x97, 0xd7, 0x0e, 0xf8, 0x39, 0x38, - 0xf5, 0x86, 0x94, 0x93, 0xbf, 0xeb, 0x18, 0xa8, 0xfc, 0x24, 0xf5, 0xf9, 0x99, 0x20, 0x3d, 0xcd, - 0x2c, 0x94, 0x25, 0x79, 0x28, 0x77, 0x8f, 0x2f, 0x10, 0x69, 0x86, 0x30, 0x43, 0x01, 0xd7, 0x9a, - 0x17, 0xe3, 0x47, 0x37, 0xbd, 0x62, 0x75, 0x42, 0x78, 0xf4, 0x2b, 0x57, 0x4c, 0x0a, 0xdb, 0x53, - 0x4d, 0xa1, 0x0a, 0xd6, 0x3a, 0x16, 0x15, 0xaa, 0x2c, 0x6c, 0x39, 0x42 - }, - { // region 6, $14cd82 - 0x12, 0x09, 0xf3, 0x29, 0xa0, 0x09, 0xa0, 0x21, 0xb0, 0xd5, 0x66, 0xa1, 0x28, 0x4a, 0x21, 0xc0, - 0xd3, 0x9b, 0x86, 0x80, 0x57, 0x6f, 0x41, 0xc2, 0xe4, 0x2f, 0x0b, 0x91, 0xbd, 0x3a, 0x7a, 0xba, - 0x00, 0xe5, 0x35, 0x02, 0x74, 0x7d, 0x8b, 0x21, 0x57, 0x10, 0x0f, 0xae, 0x44, 0xbb, 0xe2, 0x37, - 0x18, 0x7b, 0x52, 0x3d, 0x8c, 0x59, 0x9e, 0x20, 0x1f, 0x0a, 0xcc, 0x1c, 0x8e, 0x6a, 0xd7, 0x95, - 0x2b, 0x34, 0xb0, 0x82, 0x6d, 0xfd, 0x25, 0x33, 0xaa, 0x3b, 0x2b, 0x70, 0x15, 0x87, 0x31, 0x5d, - 0xbb, 0x29, 0x19, 0x95, 0xd5, 0x8e, 0x24, 0x28, 0x5e, 0xd0, 0x20, 0x83, 0x46, 0x4a, 0x21, 0x70, - 0x5b, 0xcd, 0xae, 0x7b, 0x61, 0xa1, 0xfa, 0xf4, 0x2b, 0x84, 0x15, 0x6e, 0x36, 0x5d, 0x1b, 0x24, - 0x0f, 0x09, 0x3a, 0x61, 0x38, 0x0f, 0x18, 0x35, 0x11, 0x38, 0xb4, 0xbd, 0xee, 0xf7, 0xec, 0x0f, - 0x1d, 0xb7, 0x48, 0x01, 0xaa, 0x09, 0x8f, 0x61, 0xb5, 0x0f, 0x1d, 0x26, 0x39, 0x2e, 0x8c, 0xd6, - 0x26, 0x5c, 0x3d, 0x23, 0x63, 0xe9, 0x6b, 0x97, 0xb4, 0x9f, 0x7b, 0xb6, 0xba, 0xa0, 0x7c, 0xc6, - 0x25, 0xa1, 0x73, 0x36, 0x67, 0x7f, 0x74, 0x1e, 0x1d, 0xda, 0x70, 0xbf, 0xa5, 0x63, 0x35, 0x39, - 0x24, 0x8c, 0x9f, 0x85, 0x16, 0xd8, 0x50, 0x95, 0x71, 0xc0, 0xf6, 0x1e, 0x6d, 0x80, 0xed, 0x15, - 0xeb, 0x63, 0xe9, 0x1b, 0xf6, 0x78, 0x31, 0xc6, 0x5c, 0xdd, 0x19, 0xbd, 0xdf, 0xa7, 0xec, 0x50, - 0x22, 0xad, 0xbb, 0xf6, 0xeb, 0xd6, 0xa3, 0x20, 0xc9, 0xe6, 0x9f, 0xcb, 0xf2, 0x97, 0xb9, 0x54, - 0x12, 0x66, 0xa6, 0xbe, 0x4a, 0x12, 0x43, 0xec, 0x00, 0xea, 0x49, 0x02 - }, - { // region 7, $14ce76 - 0xa4, 0x49, 0xf3, 0x29, 0xa0, 0x09, 0xa1, 0x21, 0xb0, 0xef, 0x80, 0x20, 0x3d, 0xaa, 0x36, 0x5d, - 0x98, 0xc4, 0xd2, 0x63, 0xdf, 0x61, 0xb0, 0xc3, 0xc2, 0x35, 0xd4, 0x88, 0xe6, 0x1d, 0x3a, 0x2f, - 0x9c, 0xb9, 0xd1, 0xc6, 0x43, 0xba, 0x69, 0x6d, 0x49, 0xac, 0xdd, 0x05, 0xe0, 0xf8, 0xe8, 0x97, - 0x19, 0x18, 0x08, 0x0c, 0x42, 0x46, 0xc7, 0x0d, 0x25, 0xce, 0xc3, 0x54, 0xb2, 0xd9, 0x42, 0x91, - 0xea, 0x53, 0x98, 0x38, 0x78, 0x81, 0x12, 0xca, 0x15, 0x23, 0xbd, 0xc1, 0x70, 0x1f, 0xd2, 0x40, - 0xfd, 0x39, 0x33, 0xaa, 0x27, 0x2b, 0xe8, 0x10, 0x7d, 0xa4, 0xa8, 0x8e, 0x3d, 0x00, 0x4f, 0x3a, - 0x7f, 0xd8, 0x96, 0xea, 0x9e, 0x8e, 0x15, 0x6e, 0x9f, 0x76, 0x57, 0xba, 0x7d, 0xc2, 0xdf, 0x57, - 0x42, 0x82, 0xf4, 0xda, 0x89, 0x06, 0x05, 0x04, 0x62, 0x2f, 0x29, 0x23, 0x54, 0xd5, 0xbb, 0x97, - 0xf5, 0xf9, 0xc1, 0xcf, 0xec, 0x5f, 0x1d, 0xfd, 0xbb, 0xa6, 0xd7, 0x4a, 0xa8, 0x66, 0xbf, 0xb9, - 0x09, 0x44, 0xb1, 0x60, 0x28, 0xa9, 0x35, 0x16, 0x15, 0xf5, 0x13, 0xc1, 0x07, 0x7e, 0xd7, 0x40, - 0xdf, 0x8e, 0xd3, 0x32, 0xa9, 0x35, 0x98, 0x15, 0x32, 0xa9, 0x49, 0xc0, 0x24, 0xb4, 0x4a, 0x53, - 0x6b, 0x79, 0xaa, 0x77, 0x6c, 0xc5, 0x88, 0x69, 0xe5, 0x5d, 0xde, 0x42, 0x28, 0xf9, 0xb7, 0x5c, - 0xab, 0x19, 0xc7, 0xbc, 0xc5, 0x60, 0xeb, 0x5e, 0xa8, 0x52, 0xc4, 0x32, 0x7c, 0x35, 0x02, 0x06, - 0x46, 0x77, 0x30, 0xb6, 0x33, 0x4b, 0xb8, 0xfd, 0x02, 0xd8, 0x14, 0x40, 0x99, 0x25, 0x7e, 0x55, - 0xd6, 0x44, 0x43, 0x8d, 0x73, 0x0e, 0x71, 0x48, 0xd3, 0x82, 0x40, 0xda - } -}; - -static void IGS022_do_dma(UINT16 src, UINT16 dst, UINT16 size, UINT16 mode) -{ - UINT16 param; - - param = mode >> 8; - mode &=0xf; // what are the other bits? - - if ((mode == 0) || (mode == 1) || (mode == 2) || (mode == 3)) - { - int x; - UINT16 *PROTROM = (UINT16*)(PGMUSER0 + 0x10000); - - for (x = 0; x < size; x++) - { - UINT16 dat2 = BURN_ENDIAN_SWAP_INT16(PROTROM[src + x]); - - UINT8 extraoffset = param&0xff; - UINT8* dectable = (UINT8*)PROTROM; // the basic decryption table is at the start of the mcu data rom! at least in killbld - UINT8 taboff = ((x*2)+extraoffset) & 0xff; // must allow for overflow in instances of odd offsets - UINT16 extraxor = ((dectable[taboff+0]) << 8) | (dectable[taboff+1] << 0); - - dat2 = ((dat2 & 0x00ff)<<8) | ((dat2 & 0xff00)>>8); - - // mode==0 plain - if (mode==3) dat2 ^= extraxor; - if (mode==2) dat2 += extraxor; - if (mode==1) dat2 -= extraxor; - - sharedprotram[dst + x] = BURN_ENDIAN_SWAP_INT16(dat2); - } - - /* Killing Blade: hack, patches out some additional security checks... we need to emulate them instead! */ - // different region IGS025 devices supply different sequences - we currently only have the china sequence for Killing Blade - //if ((mode==3) && (param==0x54) && (src*2==0x2120) && (dst*2==0x2600)) sharedprotram[0x2600 / 2] = 0x4e75; - - } - if (mode == 4) - { - // not used by killing blade - /* looks almost like a fixed value xor, but isn't */ - } - else if (mode == 5) - { - /* mode 5 seems to be a straight copy */ - int x; - UINT16 *PROTROM = (UINT16*)(PGMUSER0 + 0x10000); - for (x = 0; x < size; x++) - { - UINT16 dat = PROTROM[src + x]; - - sharedprotram[dst + x] = dat; - } - } - else if (mode == 6) - { - /* mode 6 seems to swap bytes and nibbles */ - int x; - UINT16 *PROTROM = (UINT16*)(PGMUSER0 + 0x10000); - for (x = 0; x < size; x++) - { - UINT16 dat = BURN_ENDIAN_SWAP_INT16(PROTROM[src + x]); - - dat = ((dat & 0xf000) >> 12)| - ((dat & 0x0f00) >> 4)| - ((dat & 0x00f0) << 4)| - ((dat & 0x000f) << 12); - - sharedprotram[dst + x] = BURN_ENDIAN_SWAP_INT16(dat); - } - } - else if (mode == 7) - { - // not used by killing blade - /* weird mode, the params get left in memory? - maybe it's a NOP? */ - } - else - { - // not used by killing blade - /* invalid? */ - - } -} - -// the internal MCU boot code automatically does this DMA -// and puts the version # of the data rom in ram -static void IGS022_reset() -{ - int i; - UINT16 *PROTROM = (UINT16*)(PGMUSER0 + 0x10000); - UINT16 tmp; - - // fill ram with A5 patern - for (i = 0; i < 0x4000/2; i++) - sharedprotram[i] = BURN_ENDIAN_SWAP_INT16(0xa55a); - - // the auto-dma - UINT16 src = BURN_ENDIAN_SWAP_INT16(PROTROM[0x100 / 2]); - UINT32 dst = BURN_ENDIAN_SWAP_INT16(PROTROM[0x102 / 2]); - UINT16 size = BURN_ENDIAN_SWAP_INT16(PROTROM[0x104/ 2]); - UINT16 mode = BURN_ENDIAN_SWAP_INT16(PROTROM[0x106 / 2]); - - src = ((src & 0xff00) >> 8) | ((src & 0x00ff) << 8); - dst = ((dst & 0xff00) >> 8) | ((dst & 0x00ff) << 8); - size = ((size & 0xff00) >> 8) | ((size & 0x00ff) << 8); - mode &= 0xff; - - src >>= 1; - - IGS022_do_dma(src,dst,size,mode); - - // there is also a version ID? (or is it some kind of checksum) that is stored in the data rom, and gets copied.. - // Dragon World 3 checks it - tmp = BURN_ENDIAN_SWAP_INT16(PROTROM[0x114/2]); - tmp = ((tmp & 0xff00) >> 8) | ((tmp & 0x00ff) << 8); - sharedprotram[0x2a2/2] = BURN_ENDIAN_SWAP_INT16(tmp); -} - -void IGS022_handle_command() -{ - UINT16 cmd = BURN_ENDIAN_SWAP_INT16(sharedprotram[0x200/2]); - - if (cmd == 0x6d) // Store values to asic ram - { - UINT32 p1 = (BURN_ENDIAN_SWAP_INT16(sharedprotram[0x298/2]) << 16) | BURN_ENDIAN_SWAP_INT16(sharedprotram[0x29a/2]); - UINT32 p2 = (BURN_ENDIAN_SWAP_INT16(sharedprotram[0x29c/2]) << 16) | BURN_ENDIAN_SWAP_INT16(sharedprotram[0x29e/2]); - - if ((p2 & 0xffff) == 0x9) // Set value - { - int reg = (p2 >> 16) & 0xffff; - - if (reg & 0x200) - m_kb_regs[reg & 0xff] = p1; - } - - if ((p2 & 0xffff) == 0x6) // Add value - { - int src1 = (p1 >> 16) & 0xff; - int src2 = (p1 >> 0) & 0xff; - int dst = (p2 >> 16) & 0xff; - - m_kb_regs[dst] = m_kb_regs[src2] - m_kb_regs[src1]; - } - - if ((p2 & 0xffff) == 0x1) // Add Imm? - { - int reg = (p2 >> 16) & 0xff; - int imm = (p1 >> 0) & 0xffff; - - m_kb_regs[reg] += imm; - } - - if ((p2 & 0xffff) == 0xa) // Get value - { - int reg = (p1 >> 16) & 0xFF; - - sharedprotram[0x29c/2] = (m_kb_regs[reg] >> 16) & 0xffff; - sharedprotram[0x29e/2] = m_kb_regs[reg] & 0xffff; - } - } - - if(cmd == 0x4f) //memcpy with encryption / scrambling - { - UINT16 src = BURN_ENDIAN_SWAP_INT16(sharedprotram[0x290 / 2]) >> 1; // ? - UINT32 dst = BURN_ENDIAN_SWAP_INT16(sharedprotram[0x292 / 2]); - UINT16 size = BURN_ENDIAN_SWAP_INT16(sharedprotram[0x294 / 2]); - UINT16 mode = BURN_ENDIAN_SWAP_INT16(sharedprotram[0x296 / 2]); - - IGS022_do_dma(src,dst,size,mode); - } -} - -void killbld_protection_calculate_hold(int y, int z) -{ - unsigned short old = m_kb_prot_hold; - - m_kb_prot_hold = ((old << 1) | (old >> 15)); - - m_kb_prot_hold ^= 0x2bad; - m_kb_prot_hold ^= BIT(z, y); - m_kb_prot_hold ^= BIT( old, 7) << 0; - m_kb_prot_hold ^= BIT(~old, 13) << 4; - m_kb_prot_hold ^= BIT( old, 3) << 11; - - m_kb_prot_hold ^= (m_kb_prot_hilo & ~0x0408) << 1; -} - -void killbld_protection_calculate_hilo() -{ - UINT8 source; - - m_kb_prot_hilo_select++; - - if (m_kb_prot_hilo_select > 0xeb) { - m_kb_prot_hilo_select = 0; - } - - source = m_kb_source_data[(PgmInput[7] - m_kb_source_data_offset)][m_kb_prot_hilo_select]; - - if (m_kb_prot_hilo_select & 1) - { - m_kb_prot_hilo = (m_kb_prot_hilo & 0x00ff) | (source << 8); - } - else - { - m_kb_prot_hilo = (m_kb_prot_hilo & 0xff00) | (source << 0); - } -} - -static void __fastcall killbld_igs025_prot_w(UINT32 offset, UINT16 data) -{ - offset &= 0xf; - - if (offset == 0) - { - m_kb_cmd = data; - } - else - { - switch (m_kb_cmd) - { - case 0x00: - m_kb_reg = data; - break; - - //case 0x01: // ?? - //break; - - case 0x02: - { - if (data == 0x0001) { // Execute cmd - IGS022_handle_command(); - m_kb_reg++; - } - } - break; - - case 0x03: - m_kb_swap = data; - break; - - case 0x04: - m_kb_ptr = data; - break; - - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - m_kb_ptr++; - killbld_protection_calculate_hold(m_kb_cmd & 0x0f, data & 0xff); - break; - } - } -} - -static UINT16 __fastcall killbld_igs025_prot_r(UINT32 offset) -{ - offset &= 2; - - if (offset) - { - switch (m_kb_cmd) - { - case 0x00: - return BITSWAP08((m_kb_swap+1)&0xff, 0,1,2,3,4,5,6,7); // dw3 - - case 0x01: - return m_kb_reg & 0x7f; - - case 0x05: - { - switch (m_kb_ptr) - { - case 1: - return 0x3f00 | PgmInput[7]; - - case 2: - return 0x3f00 | ((m_kb_game_id >> 8) & 0xff); - - case 3: - return 0x3f00 | ((m_kb_game_id >> 16) & 0xff); - - case 4: - return 0x3f00 | ((m_kb_game_id >> 24) & 0xff); - - case 5: - default: // >= 5 - return 0x3f00 | BITSWAP08(m_kb_prot_hold, 5,2,9,7,10,13,12,15); - } - - return 0; - } - - case 0x40: - killbld_protection_calculate_hilo(); - return 0; // is this used? - } - } - - return 0; -} - -static void killbld_reset() -{ - /* fill the protection ram with a5 + auto dma */ - IGS022_reset(); - - // Reset IGS025 stuff - m_kb_prot_hold = 0; - m_kb_prot_hilo = 0; - m_kb_prot_hilo_select = 0; - m_kb_cmd = 0; - m_kb_reg = 0; - m_kb_ptr = 0; - m_kb_swap = 0; - - memset(m_kb_regs, 0, 0x10 * sizeof(UINT32)); -} - -static INT32 killbldScan(INT32 nAction, INT32 *) -{ - struct BurnArea ba; - - if (nAction & ACB_MEMORY_RAM) { - ba.Data = PGMUSER0 + 0x000000; - ba.nLen = 0x0004000; - ba.nAddress = 0x300000; - ba.szName = "ProtRAM"; - BurnAcb(&ba); - - ba.Data = (UINT8*)m_kb_regs; - ba.nLen = 0x00100 * sizeof(INT32); - ba.nAddress = 0xfffffc00; - ba.szName = "Protection Registers"; - BurnAcb(&ba); - } - - if (nAction & ACB_DRIVER_DATA) { - SCAN_VAR(m_kb_prot_hold); - SCAN_VAR(m_kb_prot_hilo); - SCAN_VAR(m_kb_prot_hilo_select); - SCAN_VAR(m_kb_cmd); - SCAN_VAR(m_kb_reg); - SCAN_VAR(m_kb_ptr); - SCAN_VAR(m_kb_swap); - } - - return 0; -} - - -void install_protection_asic25_asic22_killbld() -{ - if (strcmp(BurnDrvGetTextA(DRV_NAME), "killbld") == 0) { - BurnLoadRom(PGMUSER0 + 0x10000, 11, 1); - } else { - BurnLoadRom(PGMUSER0 + 0x10000, 14, 1); // killbld104 - } - - BurnByteswap(PGMUSER0 + 0x10000, 0x10000); - - pPgmScanCallback = killbldScan; - pPgmResetCallback = killbld_reset; - - sharedprotram = (UINT16*)PGMUSER0; - - m_kb_source_data = killbld_source_data; - m_kb_source_data_offset = 0x16; - m_kb_game_id = 0x89911400; - - SekOpen(0); - SekMapMemory(PGMUSER0, 0x300000, 0x303fff, SM_RAM); - SekMapHandler(4, 0xd40000, 0xd40003, SM_READ | SM_WRITE); - SekSetReadWordHandler(4, killbld_igs025_prot_r); - SekSetWriteWordHandler(4, killbld_igs025_prot_w); - SekClose(); -} - - -static void drgw3_reset() -{ - /* fill the protection ram with a5 + auto dma */ - IGS022_reset(); - - /* game won't boot unless various values are in protection RAM - - these should almost certainly end up there as the result of executing the protection - commands are startup, but which, and how? */ - - sharedprotram[0x200/2] = 0x006d; - sharedprotram[0x202/2] = 0x007c; // it cares about this, operation status flag? - - sharedprotram[0x20c/2] = 0x0000; - sharedprotram[0x20e/2] = 0x0007; - sharedprotram[0x210/2] = 0x0000; - sharedprotram[0x212/2] = 0x0004; - sharedprotram[0x214/2] = 0x0000; - sharedprotram[0x216/2] = 0x0007; - sharedprotram[0x218/2] = 0x0000; - sharedprotram[0x21a/2] = 0x0004; - - sharedprotram[0x288/2] = 0x0000; - sharedprotram[0x28a/2] = 0x00c2; - sharedprotram[0x28c/2] = 0x0000; - sharedprotram[0x28e/2] = 0x00c2; - sharedprotram[0x290/2] = 0x0500; - sharedprotram[0x292/2] = 0x1000; - sharedprotram[0x294/2] = 0x00c3; - sharedprotram[0x296/2] = 0x7104; - sharedprotram[0x298/2] = 0x0000; - sharedprotram[0x29a/2] = 0x0003; - sharedprotram[0x29c/2] = 0x0108; - sharedprotram[0x29e/2] = 0x0009; - - sharedprotram[0x2a2/2] = 0x84f6; // it cares about this, it's the version number of the data rom, copied automatically! - - sharedprotram[0x2ac/2] = 0x006d; - sharedprotram[0x2ae/2] = 0x0000; - - sharedprotram[0x2b0/2] = 0xaf56; - - // Reset IGS025 stuff - m_kb_prot_hold = 0; - m_kb_prot_hilo = 0; - m_kb_prot_hilo_select = 0; - m_kb_cmd = 0; - m_kb_reg = 0; - m_kb_ptr = 0; - m_kb_swap = 0; - memset(m_kb_regs, 0, 0x10 * sizeof(UINT32)); - -} - -void install_protection_asic25_asic22_drgw3() -{ - BurnLoadRom(PGMUSER0 + 0x10000, 7, 1); - BurnByteswap(PGMUSER0 + 0x10000, 0x10000); - - pPgmScanCallback = killbldScan; - pPgmResetCallback = drgw3_reset; - - sharedprotram = (UINT16*)PGMUSER0; - - m_kb_source_data = dw3_source_data; - m_kb_source_data_offset = 1; - m_kb_game_id = 0x00060000; - - SekOpen(0); - SekMapMemory(PGMUSER0, 0x300000, 0x303fff, SM_RAM); - SekMapHandler(4, 0xd40000, 0xd40003, SM_READ | SM_WRITE); - SekSetReadWordHandler(4, killbld_igs025_prot_r); - SekSetWriteWordHandler(4, killbld_igs025_prot_w); - SekClose(); -} - - - -//------------------------------------------ -// Common asic27a simulation functions - - -static UINT16 asic27a_sim_value; -static UINT16 asic27a_sim_key; -static UINT32 asic27a_sim_response; -static UINT32 asic27a_sim_slots[0x100]; -static UINT16 asic27a_sim_regs[0x100]; -static UINT8 asic27a_sim_internal_slot; - -static void (*asic27a_sim_command)(UINT8); - -void __fastcall asic27a_sim_write(UINT32 offset, UINT16 data) -{ - switch (offset & 0x06) - { - case 0: asic27a_sim_value = data; return; - - case 2: - { - if ((data >> 8) == 0xff) asic27a_sim_key = 0xffff; - - asic27a_sim_value ^= asic27a_sim_key; - - UINT8 command = (data ^ asic27a_sim_key) & 0xff; - - asic27a_sim_regs[command] = asic27a_sim_value; - - // bprintf (0, _T("Command: %2.2x, Data: %2.2x\n"), command, asic27a_sim_value); - - asic27a_sim_command(command); - - asic27a_sim_key = (asic27a_sim_key + 0x0100) & 0xff00; - if (asic27a_sim_key == 0xff00) asic27a_sim_key = 0x0100; - asic27a_sim_key |= asic27a_sim_key >> 8; - } - return; - - case 4: return; - } -} - -static UINT16 __fastcall asic27a_sim_read(UINT32 offset) -{ - switch (offset & 0x02) - { - case 0: return (asic27a_sim_response >> 0) ^ asic27a_sim_key; - case 2: return (asic27a_sim_response >> 16) ^ asic27a_sim_key; - } - - return 0; -} - -static void asic27a_sim_reset() -{ - // The ASIC27a writes this to shared RAM - UINT8 ram_string[16] = { - 'I', 'G', 'S', 'P', 'G', 'M', 0, 0, 0, 0/*REGION*/, 'C', 'H', 'I', 'N', 'A', 0 - }; - - memset (PGMUSER0, 0, 0x400); - - ram_string[9] = PgmInput[7]; // region - - memcpy (PGMUSER0, ram_string, 16); - - BurnByteswap(PGMUSER0, 0x10); - - memset (asic27a_sim_slots, 0, 0x100 * sizeof(INT32)); - memset (asic27a_sim_regs, 0, 0x100 * sizeof(INT16)); - - asic27a_sim_value = 0; - asic27a_sim_key = 0; - asic27a_sim_response = 0; - asic27a_sim_internal_slot = 0; -} - -static INT32 asic27a_sim_scan(INT32 nAction, INT32 *) -{ - struct BurnArea ba; - - if (nAction & ACB_MEMORY_RAM) { - ba.Data = (UINT8*)asic27a_sim_slots; - ba.nLen = 0x0000100 * sizeof(INT32); - ba.nAddress = 0xff00000; - ba.szName = "ASIC27a Slots"; - BurnAcb(&ba); - - ba.Data = (UINT8*)asic27a_sim_regs; - ba.nLen = 0x0000100 * sizeof(INT16); - ba.nAddress = 0xff01000; - ba.szName = "ASIC27a Regs"; - BurnAcb(&ba); - } - - if (nAction & ACB_DRIVER_DATA) { - SCAN_VAR(asic27a_sim_value); - SCAN_VAR(asic27a_sim_key); - SCAN_VAR(asic27a_sim_response); - SCAN_VAR(asic27a_sim_internal_slot); - } - - return 0; -} - - -//--------------------------------- -// ketsui / espgaluda / ddp3 - -static void ddp3_asic27a_sim_command(UINT8 command) -{ - switch (command) - { - case 0x40: // Combine slot values - asic27a_sim_slots[(asic27a_sim_value >> 10) & 0x1f] = (asic27a_sim_slots[(asic27a_sim_value >> 5) & 0x1f] + asic27a_sim_slots[(asic27a_sim_value >> 0) & 0x1f]) & 0xffffff; - asic27a_sim_response = 0x880000; - break; - - case 0x67: // Select slot & write (high) - asic27a_sim_internal_slot = asic27a_sim_value >> 8; - asic27a_sim_slots[asic27a_sim_internal_slot] = (asic27a_sim_value & 0x00ff) << 16; - asic27a_sim_response = 0x880000; - break; - - case 0xe5: // Write slot (low) - asic27a_sim_slots[asic27a_sim_internal_slot] |= asic27a_sim_value; - asic27a_sim_response = 0x880000; - break; - - case 0x8e: // Read slot - asic27a_sim_response = asic27a_sim_slots[asic27a_sim_value & 0xff]; - break; - - case 0x99: // Reset? - asic27a_sim_key = 0; - asic27a_sim_response = 0x880000 | (PgmInput[7] << 8); - break; - - default: - asic27a_sim_response = 0x880000; - break; - } -} - -void install_protection_asic27a_ketsui() -{ - pPgmResetCallback = asic27a_sim_reset; - pPgmScanCallback = asic27a_sim_scan; - asic27a_sim_command = ddp3_asic27a_sim_command; - - SekOpen(0); - SekMapHandler(4, 0x400000, 0x400005, SM_READ | SM_WRITE); - SekSetReadWordHandler(4, asic27a_sim_read); - SekSetWriteWordHandler(4, asic27a_sim_write); - SekClose(); -} - -void install_protection_asic27a_ddp3() -{ - pPgmResetCallback = asic27a_sim_reset; - pPgmScanCallback = asic27a_sim_scan; - asic27a_sim_command = ddp3_asic27a_sim_command; - - SekOpen(0); - SekMapHandler(4, 0x500000, 0x500005, SM_READ | SM_WRITE); - SekSetReadWordHandler(4, asic27a_sim_read); - SekSetWriteWordHandler(4, asic27a_sim_write); - SekClose(); -} - - -//-------------------------- -// oldsplus - -static const UINT8 oldsplus_fc[0x20]={ - 0x00,0x00,0x0a,0x3a,0x4e,0x2e,0x03,0x40,0x33,0x43,0x26,0x2c,0x00,0x00,0x00,0x00, - 0x00,0x00,0x44,0x4d,0x0b,0x27,0x3d,0x0f,0x37,0x2b,0x02,0x2f,0x15,0x45,0x0e,0x30 -}; - -static const UINT16 oldsplus_90[0x7]={ - 0x50,0xa0,0xc8,0xf0,0x190,0x1f4,0x258 -}; - -static const UINT8 oldsplus_5e[0x20]={ - 0x04,0x04,0x04,0x04,0x04,0x03,0x03,0x03,0x02,0x02,0x02,0x01,0x01,0x01,0x01,0x01, - 0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -}; - -static const UINT8 oldsplus_b0[0xe0]={ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04, - 0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, - 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18, - 0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c, - 0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c, - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, - 0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13, - 0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f -}; - -static const UINT8 oldsplus_ae[0xe0]={ - 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50, - 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50, - 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50, - 0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50, - 0x1E,0x1F,0x20,0x21,0x22,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, - 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, - 0x1F,0x20,0x21,0x22,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, - 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, - 0x20,0x21,0x22,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, - 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, - 0x21,0x22,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, - 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, - 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23, - 0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23 -}; - -static const UINT16 oldsplus_ba[0x4]={ - 0x3138,0x2328,0x1C20,0x1518 -}; - -static const UINT16 oldsplus_8c[0x20]={ - 0x0032,0x0032,0x0064,0x0096,0x0096,0x00fa,0x012c,0x015e,0x0032,0x0064,0x0096,0x00c8,0x00c8,0x012c,0x015e,0x0190, - 0x0064,0x0096,0x00c8,0x00fa,0x00fa,0x015e,0x0190,0x01c2,0x0096,0x00c8,0x00fa,0x012c,0x012c,0x0190,0x01c2,0x01f4 -}; - -static inline UINT16 oldsplus_9d(UINT16 a) -{ - const UINT8 tab[8] = { 0x3c, 0x46, 0x5a, 0x6e, 0x8c, 0xc8, 0x50, }; - - if ((a % 0x27) <= 0x07) return (a % 0x27) * 0x64; - if ((a % 0x27) >= 0x17) return 0x6bc; - - return 0x2bc + (tab[a / 0x27] * ((a % 0x27) - 7)); -} - -static void oldsplus_asic27a_sim_command(UINT8 command) -{ - switch (command) - { - case 0x88: // Reset? - asic27a_sim_key = 0; - asic27a_sim_response = 0x990000 | (PgmInput[7] << 8); - break; - - case 0xa0: - asic27a_sim_response = ((asic27a_sim_value >= 0x0f) ? 0x0f : asic27a_sim_value) * 0x23; - break; - - case 0xd0: // Text palette offset - asic27a_sim_response = 0xa01000 + (asic27a_sim_value << 5); - break; - - case 0xc0: // Sprite palette offset - asic27a_sim_response = 0xa00000 + (asic27a_sim_value << 6); - break; - - case 0xc3: // Background palette offset - asic27a_sim_response = 0xa00800 + (asic27a_sim_value << 6); - break; - - case 0x33: // Store regs - asic27a_sim_response = 0x990000; - break; - - case 0x35: // Add '36' reg - asic27a_sim_regs[0x36] += asic27a_sim_value; - asic27a_sim_response = 0x990000; - break; - - case 0x36: // Store regs - asic27a_sim_response = 0x990000; - break; - - case 0x37: // Add '33' reg - asic27a_sim_regs[0x33] += asic27a_sim_value; - asic27a_sim_response = 0x990000; - break; - - case 0x34: // Read '36' reg - asic27a_sim_response = asic27a_sim_regs[0x36]; - break; - - case 0x38: // Read '33' reg - asic27a_sim_response = asic27a_sim_regs[0x33]; - break; - - case 0xe7: // Select slot - { - asic27a_sim_response = 0x990000; - - asic27a_sim_internal_slot = (asic27a_sim_value >> 12) & 0x0f; - } - break; - - case 0xe5: // Write slot - { - asic27a_sim_response = 0x990000; - - asic27a_sim_slots[asic27a_sim_internal_slot] = asic27a_sim_value; - - if (asic27a_sim_internal_slot == 0x0b) asic27a_sim_slots[0xc] = 0; // ?? - } - break; - - case 0xf8: // Read slot - asic27a_sim_response = asic27a_sim_slots[asic27a_sim_value]; - break; - - case 0xc5: // Increment slot 'd' - asic27a_sim_slots[0xd]--; - asic27a_sim_response = 0x990000; - break; - - case 0xd6: // Increment slot 'b' - asic27a_sim_slots[0xb]++; - asic27a_sim_response = 0x990000; - break; - - case 0x3a: // Clear slot 'f' - asic27a_sim_slots[0xf] = 0; - asic27a_sim_response = 0x990000; - break; - - case 0xf0: // Background layer 'x' select - asic27a_sim_response = 0x990000; - break; - - case 0xed: // Background layer offset - if (asic27a_sim_value & 0x400) asic27a_sim_value = -(0x400 - (asic27a_sim_value & 0x3ff)); - asic27a_sim_response = 0x900000 + ((asic27a_sim_regs[0xf0] + (asic27a_sim_value * 0x40)) * 4); - break; - - case 0xe0: // Text layer 'x' select - asic27a_sim_response = 0x990000; - break; - - case 0xdc: // Text layer offset - asic27a_sim_response = 0x904000 + ((asic27a_sim_regs[0xe0] + (asic27a_sim_value * 0x40)) * 4); - break; - - case 0xcb: // Some sort of status read? - asic27a_sim_response = 0x00c000; - break; - - case 0x5e: // Read from data table - asic27a_sim_response = oldsplus_5e[asic27a_sim_value]; - break; - - case 0x80: // Read from data table - asic27a_sim_response = (asic27a_sim_value < 4) ? ((asic27a_sim_value + 1) * 0xbb8) : 0xf4240; - break; - - case 0x8c: // Read from data table - asic27a_sim_response = oldsplus_8c[asic27a_sim_value]; - break; - - case 0x90: // Read from data table - asic27a_sim_response = oldsplus_90[asic27a_sim_value]; - break; - - case 0x9d: // Read from data table - asic27a_sim_response = oldsplus_9d(asic27a_sim_value); - break; - - case 0xae: // Read from data table - asic27a_sim_response = oldsplus_ae[asic27a_sim_value]; - break; - - case 0xb0: // Read from data table - asic27a_sim_response = oldsplus_b0[asic27a_sim_value]; - break; - - case 0xba: // Read from data table - asic27a_sim_response = oldsplus_ba[asic27a_sim_value]; - break; - - case 0xfc: // Read from data table - asic27a_sim_response = oldsplus_fc[asic27a_sim_value]; - break; - - default: - asic27a_sim_response = 0x990000; - break; - } -} - -void install_protection_asic27a_oldsplus() -{ - pPgmResetCallback = asic27a_sim_reset; - pPgmScanCallback = asic27a_sim_scan; - asic27a_sim_command = oldsplus_asic27a_sim_command; - - SekOpen(0); - SekMapMemory(PGMUSER0, 0x4f0000, 0x4f003f | 0x3ff, SM_READ); // ram - - SekMapHandler(4, 0x500000, 0x500003, SM_READ | SM_WRITE); - SekSetReadWordHandler(4, asic27a_sim_read); - SekSetWriteWordHandler(4, asic27a_sim_write); - SekClose(); -} - - -//------------------------------------- -// Knights of Valour - - - - -//----------------------------------------------------------------------------------------------------- -// ASIC28 - Knights of Valour - - -static const UINT8 B0TABLE[8] = { 2, 0, 1, 4, 3 }; // Maps char portraits to tables - -static const UINT8 BATABLE[0x40] = { - 0x00,0x29,0x2c,0x35,0x3a,0x41,0x4a,0x4e,0x57,0x5e,0x77,0x79,0x7a,0x7b,0x7c,0x7d, - 0x7e,0x7f,0x80,0x81,0x82,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x90, - 0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9e,0xa3,0xd4,0xa9,0xaf,0xb5,0xbb,0xc1 -}; - -static void kov_asic27a_sim_command(UINT8 command) -{ - switch (command) - { - case 0x67: // unknown or status check? - case 0x8e: - case 0xa3: - case 0x33: // kovsgqyz (a3) - case 0x3a: // kovplus - case 0xc5: // kovplus - asic27a_sim_response = 0x880000; - break; - - case 0x99: // Reset - asic27a_sim_key = 0; - asic27a_sim_response = 0x880000 | (PgmInput[7] << 8); - break; - - case 0x9d: // Sprite palette offset - asic27a_sim_response = 0xa00000 + ((asic27a_sim_value & 0x1f) * 0x40); - break; - - case 0xb0: // Read from data table - asic27a_sim_response = B0TABLE[asic27a_sim_value & 0x07]; - break; - - case 0xb4: // Copy slot 'a' to slot 'b' - case 0xb7: // kovsgqyz (b4) - { - asic27a_sim_response = 0x880000; - - if (asic27a_sim_value == 0x0102) asic27a_sim_value = 0x0100; // why? - - asic27a_sim_slots[(asic27a_sim_value >> 8) & 0x0f] = asic27a_sim_slots[(asic27a_sim_value >> 0) & 0x0f]; - } - break; - - case 0xba: // Read from data table - asic27a_sim_response = BATABLE[asic27a_sim_value & 0x3f]; - break; - - case 0xc0: // Text layer 'x' select - asic27a_sim_response = 0x880000; - break; - - case 0xc3: // Text layer offset - asic27a_sim_response = 0x904000 + ((asic27a_sim_regs[0xc0] + (asic27a_sim_value * 0x40)) * 4); - break; - - case 0xcb: // Background layer 'x' select - asic27a_sim_response = 0x880000; - break; - - case 0xcc: // Background layer offset - { - INT32 y = asic27a_sim_value; - if (y & 0x400) y = -(0x400 - (y & 0x3ff)); - asic27a_sim_response = 0x900000 + (((asic27a_sim_regs[0xcb] + y * 64) * 4)); - } - break; - - case 0xd0: // Text palette offset - case 0xcd: // kovsgqyz (d0) - asic27a_sim_response = 0xa01000 + (asic27a_sim_value * 0x20); - break; - - case 0xd6: // Copy slot to slot 0 - asic27a_sim_response = 0x880000; - asic27a_sim_slots[0] = asic27a_sim_slots[asic27a_sim_value & 0x0f]; - break; - - case 0xdc: // Background palette offset - case 0x11: // kovsgqyz (dc) - asic27a_sim_response = 0xa00800 + (asic27a_sim_value * 0x40); - break; - - case 0xe0: // Sprite palette offset - case 0x9e: // kovsgqyz (e0) - asic27a_sim_response = 0xa00000 + ((asic27a_sim_value & 0x1f) * 0x40); - break; - - case 0xe5: // Write slot (low) - { - asic27a_sim_response = 0x880000; - - asic27a_sim_slots[asic27a_sim_internal_slot] = (asic27a_sim_slots[asic27a_sim_internal_slot] & 0x00ff0000) | ((asic27a_sim_value & 0xffff) << 0); - } - break; - - case 0xe7: // Write slot (and slot select) (high) - { - asic27a_sim_response = 0x880000; - asic27a_sim_internal_slot = (asic27a_sim_value >> 12) & 0x0f; - - asic27a_sim_slots[asic27a_sim_internal_slot] = (asic27a_sim_slots[asic27a_sim_internal_slot] & 0x0000ffff) | ((asic27a_sim_value & 0x00ff) << 16); - } - break; - - case 0xf0: // Some sort of status read? - asic27a_sim_response = 0x00c000; - break; - - case 0xf8: // Read slot - case 0xab: // kovsgqyz (f8) - asic27a_sim_response = asic27a_sim_slots[asic27a_sim_value & 0x0f] & 0x00ffffff; - break; - - case 0xfc: // Adjust damage level to char experience level - asic27a_sim_response = (asic27a_sim_value * asic27a_sim_regs[0xfe]) >> 6; - break; - - case 0xfe: // Damage level adjust - asic27a_sim_response = 0x880000; - break; - - default: - asic27a_sim_response = 0x880000; - break; - } -} - -void install_protection_asic27_kov() -{ - pPgmResetCallback = asic27a_sim_reset; - pPgmScanCallback = asic27a_sim_scan; - asic27a_sim_command = kov_asic27a_sim_command; - - SekOpen(0); - SekMapMemory(PGMUSER0, 0x4f0000, 0x4f003f | 0x3ff, SM_READ); - - SekMapHandler(4, 0x500000, 0x500003, SM_READ | SM_WRITE); - SekSetReadWordHandler(4, asic27a_sim_read); - SekSetWriteWordHandler(4, asic27a_sim_write); - SekClose(); -} - -//------------------------------------------------------------------------- -// puzlstar - -static const UINT8 Pstar_ba[0x1e]={ - 0x02,0x00,0x00,0x01,0x00,0x03,0x00,0x00,0x02,0x00,0x06,0x00,0x22,0x04,0x00,0x03, - 0x00,0x00,0x06,0x00,0x20,0x07,0x00,0x03,0x00,0x21,0x01,0x00,0x00,0x63 -}; - -static const UINT8 Pstar_b0[0x10]={ - 0x09,0x0A,0x0B,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x00,0x00,0x00,0x00 -}; - -static const UINT16 Pstar_ae[0x10]={ - 0x5D,0x86,0x8C,0x8B,0xE0,0x8B,0x62,0xAF,0xB6,0xAF,0x10A,0xAF,0x00,0x00,0x00,0x00 -}; - -static const UINT8 Pstar_a0[0x10]={ - 0x02,0x03,0x04,0x05,0x06,0x01,0x0A,0x0B,0x0C,0x0D,0x0E,0x09,0x00,0x00,0x00,0x00 -}; - -static const UINT8 Pstar_9d[0x10]={ - 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -}; - -static const UINT8 Pstar_90[0x10]={ - 0x0C,0x10,0x0E,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -}; - -static const UINT8 Pstar_8c[0x23]={ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01, - 0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04, - 0x03,0x03,0x03 -}; - -static const UINT8 Pstar_80[0x1a3]={ - 0x03,0x03,0x04,0x04,0x04,0x04,0x05,0x05,0x05,0x05,0x06,0x06,0x03,0x03,0x04,0x04, - 0x05,0x05,0x05,0x05,0x06,0x06,0x07,0x07,0x03,0x03,0x04,0x04,0x05,0x05,0x05,0x05, - 0x06,0x06,0x07,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07, - 0x06,0x06,0x06,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x08,0x08,0x05,0x05,0x05,0x05, - 0x05,0x05,0x05,0x06,0x06,0x06,0x07,0x07,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08, - 0x09,0x09,0x09,0x09,0x07,0x07,0x07,0x07,0x07,0x08,0x08,0x08,0x08,0x09,0x09,0x09, - 0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,0x08,0x08,0x09,0x09,0x05,0x05,0x06,0x06, - 0x06,0x07,0x07,0x08,0x08,0x08,0x08,0x09,0x07,0x07,0x07,0x07,0x07,0x08,0x08,0x08, - 0x08,0x09,0x09,0x09,0x06,0x06,0x07,0x03,0x07,0x06,0x07,0x07,0x08,0x07,0x05,0x04, - 0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x06,0x06,0x06,0x06,0x03,0x04,0x04,0x04, - 0x04,0x05,0x05,0x06,0x06,0x06,0x06,0x07,0x04,0x04,0x05,0x05,0x06,0x06,0x06,0x06, - 0x06,0x07,0x07,0x08,0x05,0x05,0x06,0x07,0x07,0x08,0x08,0x08,0x08,0x08,0x08,0x08, - 0x05,0x05,0x05,0x07,0x07,0x07,0x07,0x07,0x07,0x08,0x08,0x08,0x08,0x08,0x09,0x09, - 0x09,0x09,0x03,0x04,0x04,0x05,0x05,0x05,0x06,0x06,0x07,0x07,0x07,0x07,0x08,0x08, - 0x08,0x09,0x09,0x09,0x03,0x04,0x05,0x05,0x04,0x03,0x04,0x04,0x04,0x05,0x05,0x04, - 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x04,0x04,0x04,0x04,0x04, - 0x04,0x04,0x04,0x04,0x04,0x03,0x03,0x03,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, - 0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00 -}; - -static UINT16 __fastcall puzlstar_protram_read_word(UINT32 offset) -{ - if ((offset & 0x3e) == 0x08) return PgmInput[7]; // Region - if ((offset & 0x38) == 0x20) return asic27a_sim_slots[((offset & 0x06)/2)+0x10]--; // Timer - - return 0; -} - -static UINT8 __fastcall puzlstar_protram_read_byte(UINT32 offset) -{ - if ((offset & 0x3e) == 0x08) return PgmInput[7]; // Region - - return 0; -} - -static void puzlstar_asic27a_sim_command(UINT8 command) -{ - switch (command) - { - case 0x99: // Reset? - asic27a_sim_key = 0x100; - asic27a_sim_response = 0x880000 | (PgmInput[7] << 8); - break; - - case 0xb1: - asic27a_sim_response = 0x890000; - break; - - case 0xbf: - asic27a_sim_response = asic27a_sim_regs[0xb1] * asic27a_sim_value; - break; - - case 0xc1: // TODO: TIMER 0,1,2,FIX TO 0 should be OK? - asic27a_sim_response = 0; - break; - - case 0xce: // TODO: TIMER 0,1,2 - asic27a_sim_response = 0x890000; - break; - - case 0xcf: // TODO:TIMER 0,1,2 - asic27a_sim_slots[asic27a_sim_regs[0xce] + 0x10] = asic27a_sim_value; - asic27a_sim_response = 0x890000; - break; - - case 0xd0: // Text palette offset - asic27a_sim_response = 0xa01000 + (asic27a_sim_value << 5); - break; - - case 0xdc: // Background palette offset - asic27a_sim_response = 0xa00800 + (asic27a_sim_value << 6); - break; - - case 0xe0: // Sprite palette offset - asic27a_sim_response = 0xa00000 + (asic27a_sim_value << 6); - break; - - case 0xe5: // Write slot (low) - { - asic27a_sim_response = 0x890000; - - asic27a_sim_slots[asic27a_sim_internal_slot] = (asic27a_sim_slots[asic27a_sim_internal_slot] & 0xff0000) | (asic27a_sim_value); - } - break; - - case 0xe7: // Write slot (and slot select) (high) - { - asic27a_sim_response = 0x890000; - - asic27a_sim_internal_slot = (asic27a_sim_value >> 12) & 0xf; - asic27a_sim_slots[asic27a_sim_internal_slot] = (asic27a_sim_slots[asic27a_sim_internal_slot] & 0x00ffff) | ((asic27a_sim_value & 0xff) << 16); - } - break; - - case 0xf8: // Read slot - asic27a_sim_response = asic27a_sim_slots[asic27a_sim_value]; - break; - - case 0x80: // Read from data table - asic27a_sim_response = Pstar_80[asic27a_sim_value]; - break; - - case 0x8c: // Read from data table - asic27a_sim_response = Pstar_8c[asic27a_sim_value]; - break; - - case 0x90: // Read from data table - asic27a_sim_response = Pstar_90[asic27a_sim_value]; - break; - - case 0x9d: // Read from data table - asic27a_sim_response = Pstar_9d[asic27a_sim_value]; - break; - - case 0xa0: // Read from data table - asic27a_sim_response = Pstar_a0[asic27a_sim_value]; - break; - - case 0xae: // Read from data table - asic27a_sim_response = Pstar_ae[asic27a_sim_value]; - break; - - case 0xb0: // Read from data table - asic27a_sim_response = Pstar_b0[asic27a_sim_value]; - break; - - case 0xba: // Read from data table - asic27a_sim_response = Pstar_ba[asic27a_sim_value]; - break; - - default: - asic27a_sim_response = 0x890000; - break; - } -} - -void install_protection_asic27a_puzlstar() -{ - pPgmResetCallback = asic27a_sim_reset; - pPgmScanCallback = asic27a_sim_scan; - - asic27a_sim_command = puzlstar_asic27a_sim_command; - - SekOpen(0); - SekMapHandler(4, 0x500000, 0x500003, SM_READ | SM_WRITE); - SekSetReadWordHandler(4, asic27a_sim_read); - SekSetWriteWordHandler(4, asic27a_sim_write); - - SekMapHandler(5, 0x4f0000, 0x4f03ff, SM_READ); - SekSetReadWordHandler(5, puzlstar_protram_read_word); - SekSetReadByteHandler(5, puzlstar_protram_read_byte); - SekClose(); -} - - -//-------------------- -// puzzli2 - -static int stage; -static int tableoffs; -static int tableoffs2; -static int entries_left; -static int currentcolumn; -static int currentrow; -static int num_entries; -static int full_entry; -static int prev_tablloc; -static int numbercolumns; -static int depth; -static UINT16 m_row_bitmask; -static int hackcount; -static int hackcount2; -static int hack_47_value; -static int hack_31_table_offset; -static int p2_31_retcounter; -static int command_31_write_type; -static UINT16 level_structure[8][10]; - -static const UINT8 puzzli2_level_decode[256] = { - 0x32, 0x3e, 0xb2, 0x37, 0x31, 0x22, 0xd6, 0x0d, 0x35, 0x5c, 0x8d, 0x3c, 0x7a, 0x5f, 0xd7, 0xac, // 0x0 - 0x53, 0xff, 0xeb, 0x44, 0xe8, 0x11, 0x69, 0x77, 0xd9, 0x34, 0x36, 0x45, 0xa6, 0xe9, 0x1c, 0xc6, // 0x1 - 0x3b, 0xbd, 0xad, 0x2e, 0x18, 0xdf, 0xa1, 0xab, 0xdd, 0x52, 0x57, 0xc2, 0xe5, 0x0a, 0x00, 0x6d, // 0x2 - 0x67, 0x64, 0x15, 0x70, 0xb6, 0x39, 0x27, 0x78, 0x82, 0xd2, 0x71, 0xb9, 0x13, 0xf5, 0x93, 0x92, // 0x3 - 0xfa, 0xe7, 0x5e, 0xb0, 0xf6, 0xaf, 0x95, 0x8a, 0x7c, 0x73, 0xf9, 0x63, 0x86, 0xcb, 0x1a, 0x56, // 0x4 - 0xf1, 0x3a, 0xae, 0x61, 0x01, 0x29, 0x97, 0x23, 0x8e, 0x5d, 0x9a, 0x65, 0x74, 0x21, 0x20, 0x40, // 0x5 - 0xd3, 0x05, 0xa2, 0xe1, 0xbc, 0x9e, 0x1e, 0x10, 0x14, 0x0c, 0x88, 0x9c, 0xec, 0x38, 0xb5, 0x9d, // 0x6 - 0x2d, 0xf7, 0x17, 0x0e, 0x84, 0xc7, 0x7d, 0xce, 0x94, 0x16, 0x48, 0xa8, 0x81, 0x6e, 0x7b, 0xd8, // 0x7 - 0xa7, 0x7f, 0x42, 0xe6, 0xa0, 0x2a, 0xef, 0xee, 0x24, 0xba, 0xb8, 0x7e, 0xc9, 0x2b, 0x90, 0xcc, // 0x8 - 0x5b, 0xd1, 0xf3, 0xe2, 0x6f, 0xed, 0x9f, 0xf0, 0x4b, 0x54, 0x8c, 0x08, 0xf8, 0x51, 0x68, 0xc8, // 0x9 - 0x03, 0x0b, 0xbb, 0xc1, 0xe3, 0x4d, 0x04, 0xc5, 0x8f, 0x09, 0x0f, 0xbf, 0x62, 0x49, 0x76, 0x59, // 0xa - 0x1d, 0x80, 0xde, 0x60, 0x07, 0xe0, 0x1b, 0x66, 0xa5, 0xbe, 0xcd, 0x87, 0xdc, 0xc3, 0x6b, 0x4e, // 0xb - 0xd0, 0xfd, 0xd4, 0x3f, 0x98, 0x96, 0x2f, 0x4c, 0xb3, 0xea, 0x2c, 0x75, 0xe4, 0xc0, 0x6c, 0x6a, // 0xc - 0x9b, 0xb7, 0x43, 0x8b, 0x41, 0x47, 0x02, 0xdb, 0x99, 0x3d, 0xa3, 0x79, 0x50, 0x4f, 0xb4, 0x55, // 0xd - 0x5a, 0x25, 0xf4, 0xca, 0x58, 0x30, 0xc4, 0x12, 0xa9, 0x46, 0xda, 0x91, 0xa4, 0xaa, 0xfc, 0x85, // 0xe - 0xfb, 0x89, 0x06, 0xcf, 0xfe, 0x33, 0xd5, 0x28, 0x1f, 0x19, 0x4a, 0xb1, 0x83, 0xf2, 0x72, 0x26, // 0xf -}; - -static int get_position_of_bit(UINT16 value, int bit_wanted) -{ - int count = 0; - for (int i=0;i<16;i++) - { - int bit = (value >> i) & 1; - - if (bit) count++; - - if (count==(bit_wanted+1)) - return i; - } - - return -1; -} - -static int puzzli2_take_leveldata_value(UINT8 datvalue) -{ - if (stage==-1) - { - tableoffs = 0; - tableoffs2 = 0; - entries_left = 0; - currentcolumn = 0; - currentrow = 0; - num_entries = 0; - full_entry = 0; - prev_tablloc = 0; - numbercolumns = 0; - depth = 0; - m_row_bitmask = 0; - - tableoffs = datvalue; - tableoffs2 = 0; - stage = 0; - } - else - { - UINT8 rawvalue = datvalue; - UINT8 tableloc = (tableoffs+tableoffs2)&0xff; - rawvalue ^= puzzli2_level_decode[tableloc]; - - tableoffs2++; - tableoffs2&=0xf; - - if (stage==0) - { - stage = 1; - depth = (rawvalue & 0xf0); - numbercolumns = (rawvalue & 0x0f); - numbercolumns++; - } - else if (stage==1) - { - stage = 2; - entries_left = (rawvalue >> 4); - m_row_bitmask = (rawvalue & 0x0f)<<8; - full_entry = rawvalue; - prev_tablloc = tableloc; - num_entries = entries_left; - } - else if (stage==2) - { - stage = 3; - m_row_bitmask |= rawvalue; - - if (entries_left == 0) - { - stage = 1; - currentcolumn++; - currentrow = 0; - m_row_bitmask = 0; - - if (currentcolumn==numbercolumns) - { - return 1; - } - } - // else - // { - // int num = (1 << ((num > 8) ? 8 : num)) - 1; - // } - } - else if (stage==3) - { - UINT16 object_value; - - if (rawvalue<=0x10) object_value = 0x0100 + rawvalue; - else if (rawvalue<=0x21) object_value = 0x0120 + (rawvalue - 0x11); - else if (rawvalue<=0x32) object_value = 0x0140 + (rawvalue - 0x22); - else if (rawvalue<=0x43) object_value = 0x0180 + (rawvalue - 0x33); - else if (rawvalue==0xd0) object_value = 0x0200; - else if (rawvalue==0xe0) object_value = 0x8000; - else if (rawvalue==0xe1) object_value = 0x8020; // solid slant top down - else if (rawvalue==0xe2) object_value = 0x8040; // solid slant top up - else if (rawvalue==0xe3) object_value = 0x8060; - else if (rawvalue==0xe4) object_value = 0x8080; // sold slant bottom up - else object_value = 0x0110; - - int realrow = get_position_of_bit(m_row_bitmask, currentrow); - - if (realrow != -1) - level_structure[currentcolumn][realrow] = object_value; - - currentrow++; - - entries_left--; - if (entries_left == 0) - { - stage = 1; - currentcolumn++; - currentrow = 0; - m_row_bitmask = 0; - - if (currentcolumn==numbercolumns) - { - return 1; - } - } - } - } - - return 0; -} - -static void puzzli2_asic27a_sim_command(UINT8 command) -{ - switch (command) - { - case 0x31: - { - if (command_31_write_type==2) - { - if (hackcount2==0) - { - puzzli2_take_leveldata_value(asic27a_sim_value&0xff); - - hack_31_table_offset = asic27a_sim_value & 0xff; - hackcount2++; - asic27a_sim_response = 0x00d20000; - } - else - { - int end = puzzli2_take_leveldata_value(asic27a_sim_value&0xff); - - if (!end) - { - asic27a_sim_response = 0x00d20000; - hackcount2++; - } - else - { - hackcount2=0; - asic27a_sim_response = 0x00630000 | numbercolumns; - } - } - } - else - { - asic27a_sim_response = 0x00d20000 | p2_31_retcounter; - p2_31_retcounter++; - } - } - break; - - case 0x13: - { - UINT16* leveldata = &level_structure[0][0]; - if (hackcount==0) - { - asic27a_sim_response = 0x002d0000 | ((depth>>4)+1); - } - else if (hackcount<((10*numbercolumns)+1)) - { - asic27a_sim_response = 0x002d0000 | leveldata[hackcount-1]; - } - else - { - hackcount=0; - asic27a_sim_response = 0x00740054; - } - - hackcount++; - } - break; - - case 0x38: // Reset - { - asic27a_sim_response = 0x780000 | (PgmInput[7] << 8); - asic27a_sim_key = 0x100; - } - break; - - case 0x47: - hack_47_value = asic27a_sim_value; - asic27a_sim_response = 0x00740047; - break; - - case 0x52: - { - int val = ((hack_47_value & 0x0f00)>>8) * 0x19; - if (asic27a_sim_value!=0x0000) - { - val +=((hack_47_value & 0x000f)>>0) * 0x05; - } - val += asic27a_sim_value & 0x000f; - asic27a_sim_response = 0x00740000 | (val & 0xffff); - } - break; - - case 0x61: - command_31_write_type = 1; - asic27a_sim_response = 0x360000; - p2_31_retcounter = 0xc; - break; - - case 0x41: // ASIC status? - command_31_write_type = 0; - asic27a_sim_response = 0x740061; - break; - - case 0x54: // ?? - { - command_31_write_type = 2; - stage = -1; - hackcount2 = 0; - hackcount = 0; - asic27a_sim_response = 0x360000; - - // clear the return structure - for (int columns=0;columns<8;columns++) - for (int rows=0;rows<10;rows++) - level_structure[columns][rows] = 0x0000; - } - break; - - case 0x63: - { - UINT32 z80table[2][8] = { - { 0x1694a8, 0x16cfae, 0x16ebf2, 0x16faa8, 0x174416, 0x600000, 0x600000, 0x600000 }, // puzzli2 - { 0x19027a, 0x193D80, 0x1959c4, 0x19687a, 0x19b1e8, 0x600000, 0x600000, 0x600000 } // puzzli2s - }; - - if (!strcmp(BurnDrvGetTextA(DRV_NAME),"puzzli2")) - { - asic27a_sim_response = z80table[0][asic27a_sim_value & 7]; - } - else {// puzzli2 super - asic27a_sim_response = z80table[1][asic27a_sim_value & 7]; - } - } - break; - - case 0x67: - { - UINT32 z80table[2][8] = { - { 0x166178, 0x166178, 0x166178, 0x166178, 0x166e72, 0x600000, 0x600000, 0x600000 }, // puzzli2 - { 0x18cf4a, 0x18cf4a, 0x18cf4a, 0x18cf4a, 0x18dc44, 0x600000, 0x600000, 0x600000 } // puzzli2s - }; - - if (!strcmp(BurnDrvGetTextA(DRV_NAME),"puzzli2")) - { - asic27a_sim_response = z80table[0][asic27a_sim_value & 7]; - } - else {// puzzli2 super - asic27a_sim_response = z80table[1][asic27a_sim_value & 7]; - } - } - break; - - default: - asic27a_sim_response = 0x740000; - break; - } -} - -void install_protection_asic27a_puzzli2() -{ - pPgmResetCallback = asic27a_sim_reset; - pPgmScanCallback = asic27a_sim_scan; - asic27a_sim_command = puzzli2_asic27a_sim_command; - - SekOpen(0); - SekMapMemory(PGMUSER0, 0x4f0000, 0x4f003f | 0x3ff, SM_READ); - - SekMapHandler(4, 0x500000, 0x500003, SM_READ | SM_WRITE); - SekSetReadWordHandler(4, asic27a_sim_read); - SekSetWriteWordHandler(4, asic27a_sim_write); - SekClose(); -} - - -//------------------------------------------------------------------------------------------- -// py2k2 - -static void py2k2_asic27a_sim_command(UINT8 command) -{ - switch (command) - { - case 0x30: // Sprite sequence, advance to next sprite - break; - - case 0x32: // Sprite sequence, decode offset - break; - - // case 0x33: - // case 0x34: - // case 0x35: // table? - // case 0x38: // ? - // break; - - // "CCHANGE.C 285 ( TIME >= VALUE1 ) && TIME <= ALL_LEV_TIME ) - case 0xba: // ?? - asic27a_sim_response = asic27a_sim_value + 1; // gets us in-game - break; - - case 0x99: // Reset? - asic27a_sim_key = 0x100; - asic27a_sim_response = 0x880000 | (PgmInput[7] << 8); - break; - - case 0xc0: - asic27a_sim_response = 0x880000; - break; - - case 0xc3: - asic27a_sim_response = 0x904000 + ((asic27a_sim_regs[0xc0] + (asic27a_sim_value * 0x40)) * 4); - break; - - case 0xd0: - asic27a_sim_response = 0xa01000 + (asic27a_sim_value * 0x20); - break; - - case 0xdc: - asic27a_sim_response = 0xa00800 + (asic27a_sim_value * 0x40); - break; - - case 0xe0: - asic27a_sim_response = 0xa00000 + ((asic27a_sim_value & 0x1f) * 0x40); - break; - - case 0xcb: // Background layer 'x' select (pgm3in1, same as kov) - asic27a_sim_response = 0x880000; - break; - - case 0xcc: // Background layer offset (pgm3in1, same as kov) - { - INT32 y = asic27a_sim_value; - if (y & 0x400) y = -(0x400 - (y & 0x3ff)); - asic27a_sim_response = 0x900000 + ((asic27a_sim_regs[0xcb] + (y * 0x40)) * 4); - } - break; - - default: - asic27a_sim_response = 0x880000; - bprintf (0, _T("Unknown ASIC Command %2.2x Value: %4.4x\n"), command, asic27a_sim_value); - break; - } -} - -void install_protection_asic27a_py2k2() -{ - pPgmResetCallback = asic27a_sim_reset; - pPgmScanCallback = asic27a_sim_scan; - asic27a_sim_command = py2k2_asic27a_sim_command; - - SekOpen(0); - SekMapMemory(PGMUSER0, 0x4f0000, 0x4f003f | 0x3ff, SM_READ); - - SekMapHandler(4, 0x500000, 0x500003, SM_READ | SM_WRITE); - SekSetReadWordHandler(4, asic27a_sim_read); - SekSetWriteWordHandler(4, asic27a_sim_write); - SekClose(); -} - - -//-------------------------- -// drgw2 - -static const UINT8 drgw2_source_data[0x08][0xec] = -{ - { 0, }, // Region 0, not used - { // Region 1, $13A886 - 0x67, 0x51, 0xF3, 0x19, 0xA0, 0x11, 0xB1, 0x11, 0xB0, 0xEE, 0xE3, 0xF6, 0xBE, 0x81, 0x35, 0xE3, - 0xFB, 0xE6, 0xEF, 0xDF, 0x61, 0x01, 0xFA, 0x22, 0x5D, 0x43, 0x01, 0xA5, 0x3B, 0x17, 0xD4, 0x74, - 0xF0, 0xF4, 0xF3, 0x43, 0xB5, 0x19, 0x04, 0xD5, 0x84, 0xCE, 0x87, 0xFE, 0x35, 0x3E, 0xC4, 0x3C, - 0xC7, 0x85, 0x2A, 0x33, 0x00, 0x86, 0xD0, 0x4D, 0x65, 0x4B, 0xF9, 0xE9, 0xC0, 0xBA, 0xAA, 0x77, - 0x9E, 0x66, 0xF6, 0x0F, 0x4F, 0x3A, 0xB6, 0xF1, 0x64, 0x9A, 0xE9, 0x25, 0x1A, 0x5F, 0x22, 0xA3, - 0xA2, 0xBF, 0x4B, 0x77, 0x3F, 0x34, 0xC9, 0x6E, 0xDB, 0x12, 0x5C, 0x33, 0xA5, 0x8B, 0x6C, 0xB1, - 0x74, 0xC8, 0x40, 0x4E, 0x2F, 0xE7, 0x46, 0xAE, 0x99, 0xFC, 0xB0, 0x55, 0x54, 0xDF, 0xA7, 0xA1, - 0x0F, 0x5E, 0x49, 0xCF, 0x56, 0x3C, 0x90, 0x2B, 0xAC, 0x65, 0x6E, 0xDB, 0x58, 0x3E, 0xC9, 0x00, - 0xAE, 0x53, 0x4D, 0x92, 0xFA, 0x40, 0xB2, 0x6B, 0x65, 0x4B, 0x90, 0x8A, 0x0C, 0xE2, 0xA5, 0x9A, - 0xD0, 0x20, 0x29, 0x55, 0xA4, 0x44, 0xAC, 0x51, 0x87, 0x54, 0x53, 0x34, 0x24, 0x4B, 0x81, 0x67, - 0x34, 0x4C, 0x5F, 0x31, 0x4E, 0xF2, 0xF1, 0x19, 0x18, 0x1C, 0x34, 0x38, 0xE1, 0x81, 0x17, 0xCF, - 0x24, 0xB9, 0x9A, 0xCB, 0x34, 0x51, 0x50, 0x59, 0x44, 0xB1, 0x0B, 0x50, 0x95, 0x6C, 0x48, 0x7E, - 0x14, 0xA4, 0xC6, 0xD9, 0xD3, 0xA5, 0xD6, 0xD0, 0xC5, 0x97, 0xF0, 0x45, 0xD0, 0x98, 0x51, 0x91, - 0x9F, 0xA3, 0x43, 0x51, 0x05, 0x90, 0xEE, 0xCA, 0x7E, 0x5F, 0x72, 0x53, 0xB1, 0xD3, 0xAF, 0x36, - 0x08, 0x75, 0xB0, 0x9B, 0xE0, 0x0D, 0x43, 0x88, 0xAA, 0x27, 0x44, 0x11 - }, - { 0, }, // Region 2, not used - { 0, }, // Region 3, not used - { 0, }, // Region 4, not used - { // Region 5, $13ab42 (drgw2c) - 0x7F, 0x41, 0xF3, 0x39, 0xA0, 0x11, 0xA1, 0x11, 0xB0, 0xA2, 0x4C, 0x23, 0x13, 0xE9, 0x25, 0x3D, - 0x0F, 0x72, 0x3A, 0x9D, 0xB5, 0x96, 0xD1, 0xDA, 0x07, 0x29, 0x41, 0x9A, 0xAD, 0x70, 0xBA, 0x46, - 0x63, 0x2B, 0x7F, 0x3D, 0xBE, 0x40, 0xAD, 0xD4, 0x4C, 0x73, 0x27, 0x58, 0xA7, 0x65, 0xDC, 0xD6, - 0xFD, 0xDE, 0xB5, 0x6E, 0xD6, 0x6C, 0x75, 0x1A, 0x32, 0x45, 0xD5, 0xE3, 0x6A, 0x14, 0x6D, 0x80, - 0x84, 0x15, 0xAF, 0xCC, 0x7B, 0x61, 0x51, 0x82, 0x40, 0x53, 0x7F, 0x38, 0xA0, 0xD6, 0x8F, 0x61, - 0x79, 0x19, 0xE5, 0x99, 0x84, 0xD8, 0x78, 0x27, 0x3F, 0x16, 0x97, 0x78, 0x4F, 0x7B, 0x0C, 0xA6, - 0x37, 0xDB, 0xC6, 0x0C, 0x24, 0xB4, 0xC7, 0x94, 0x9D, 0x92, 0xD2, 0x3B, 0xD5, 0x11, 0x6F, 0x0A, - 0xDB, 0x76, 0x66, 0xE7, 0xCD, 0x18, 0x2B, 0x66, 0xD8, 0x41, 0x40, 0x58, 0xA2, 0x01, 0x1E, 0x6D, - 0x44, 0x75, 0xE7, 0x19, 0x4F, 0xB2, 0xE8, 0xC4, 0x96, 0x77, 0x62, 0x02, 0xC9, 0xDC, 0x59, 0xF3, - 0x43, 0x8D, 0xC8, 0xFE, 0x9E, 0x2A, 0xBA, 0x32, 0x3B, 0x62, 0xE3, 0x92, 0x6E, 0xC2, 0x08, 0x4D, - 0x51, 0xCD, 0xF9, 0x3A, 0x3E, 0xC9, 0x50, 0x27, 0x21, 0x25, 0x97, 0xD7, 0x0E, 0xF8, 0x39, 0x38, - 0xF5, 0x86, 0x94, 0x93, 0xBF, 0xEB, 0x18, 0xA8, 0xFC, 0x24, 0xF5, 0xF9, 0x99, 0x20, 0x3D, 0xCD, - 0x2C, 0x94, 0x25, 0x79, 0x28, 0x77, 0x8F, 0x2F, 0x10, 0x69, 0x86, 0x30, 0x43, 0x01, 0xD7, 0x9A, - 0x17, 0xE3, 0x47, 0x37, 0xBD, 0x62, 0x75, 0x42, 0x78, 0xF4, 0x2B, 0x57, 0x4C, 0x0A, 0xDB, 0x53, - 0x4D, 0xA1, 0x0A, 0xD6, 0x3A, 0x16, 0x15, 0xAA, 0x2C, 0x6C, 0x39, 0x42 - }, - { // Region 6, $13ab42 (drgw2), $13ab2e (dw2v100x) - 0x12, 0x09, 0xF3, 0x29, 0xA0, 0x11, 0xA0, 0x11, 0xB0, 0xD5, 0x66, 0xA1, 0x28, 0x4A, 0x21, 0xC0, - 0xD3, 0x9B, 0x86, 0x80, 0x57, 0x6F, 0x41, 0xC2, 0xE4, 0x2F, 0x0B, 0x91, 0xBD, 0x3A, 0x7A, 0xBA, - 0x00, 0xE5, 0x35, 0x02, 0x74, 0x7D, 0x8B, 0x21, 0x57, 0x10, 0x0F, 0xAE, 0x44, 0xBB, 0xE2, 0x37, - 0x18, 0x7B, 0x52, 0x3D, 0x8C, 0x59, 0x9E, 0x20, 0x1F, 0x0A, 0xCC, 0x1C, 0x8E, 0x6A, 0xD7, 0x95, - 0x2B, 0x34, 0xB0, 0x82, 0x6D, 0xFD, 0x25, 0x33, 0xAA, 0x3B, 0x2B, 0x70, 0x15, 0x87, 0x31, 0x5D, - 0xBB, 0x29, 0x19, 0x95, 0xD5, 0x8E, 0x24, 0x28, 0x5E, 0xD0, 0x20, 0x83, 0x46, 0x4A, 0x21, 0x70, - 0x5B, 0xCD, 0xAE, 0x7B, 0x61, 0xA1, 0xFA, 0xF4, 0x2B, 0x84, 0x15, 0x6E, 0x36, 0x5D, 0x1B, 0x24, - 0x0F, 0x09, 0x3A, 0x61, 0x38, 0x0F, 0x18, 0x35, 0x11, 0x38, 0xB4, 0xBD, 0xEE, 0xF7, 0xEC, 0x0F, - 0x1D, 0xB7, 0x48, 0x01, 0xAA, 0x09, 0x8F, 0x61, 0xB5, 0x0F, 0x1D, 0x26, 0x39, 0x2E, 0x8C, 0xD6, - 0x26, 0x5C, 0x3D, 0x23, 0x63, 0xE9, 0x6B, 0x97, 0xB4, 0x9F, 0x7B, 0xB6, 0xBA, 0xA0, 0x7C, 0xC6, - 0x25, 0xA1, 0x73, 0x36, 0x67, 0x7F, 0x74, 0x1E, 0x1D, 0xDA, 0x70, 0xBF, 0xA5, 0x63, 0x35, 0x39, - 0x24, 0x8C, 0x9F, 0x85, 0x16, 0xD8, 0x50, 0x95, 0x71, 0xC0, 0xF6, 0x1E, 0x6D, 0x80, 0xED, 0x15, - 0xEB, 0x63, 0xE9, 0x1B, 0xF6, 0x78, 0x31, 0xC6, 0x5C, 0xDD, 0x19, 0xBD, 0xDF, 0xA7, 0xEC, 0x50, - 0x22, 0xAD, 0xBB, 0xF6, 0xEB, 0xD6, 0xA3, 0x20, 0xC9, 0xE6, 0x9F, 0xCB, 0xF2, 0x97, 0xB9, 0x54, - 0x12, 0x66, 0xA6, 0xBE, 0x4A, 0x12, 0x43, 0xEC, 0x00, 0xEA, 0x49, 0x02 - }, - { 0, } // Region 7, not used -}; - -static UINT16 m_drgw2_prot_hold; -static UINT16 m_drgw2_prot_hilo; -static UINT16 m_drgw2_prot_hilo_select; -static UINT16 m_drgw2_ptr; -static UINT16 m_drgw2_cmd; -static UINT32 m_drgw2_protection_region; - -static void drgw2_protection_calculate_hold(int y, int z) -{ - unsigned short old = m_drgw2_prot_hold; - - m_drgw2_prot_hold = ((old << 1) | (old >> 15)); - - m_drgw2_prot_hold ^= 0x2bad; - m_drgw2_prot_hold ^= BIT(z, y); - m_drgw2_prot_hold ^= BIT( old, 7) << 0; - m_drgw2_prot_hold ^= BIT(~old, 13) << 4; - m_drgw2_prot_hold ^= BIT( old, 3) << 11; - - m_drgw2_prot_hold ^= (m_drgw2_prot_hilo & ~0x0408) << 1; -} - -static void drgw2_protection_calculate_hilo() -{ - UINT8 source; - - m_drgw2_prot_hilo_select++; - if (m_drgw2_prot_hilo_select > 0xeb) { - m_drgw2_prot_hilo_select = 0; - } - - source = drgw2_source_data[m_drgw2_protection_region][m_drgw2_prot_hilo_select]; - - if (m_drgw2_prot_hilo_select & 1) - { - m_drgw2_prot_hilo = (m_drgw2_prot_hilo & 0x00ff) | (source << 8); - } - else - { - m_drgw2_prot_hilo = (m_drgw2_prot_hilo & 0xff00) | (source << 0); - } -} - -static UINT16 __fastcall drgw2_d80000_protection_r(UINT32 ) -{ - switch (m_drgw2_cmd) - { - case 0x05: - { - switch (m_drgw2_ptr) - { - case 1: return 0x3f00 | ((m_drgw2_protection_region >> 0) & 0xff); - - case 2: - return 0x3f00 | ((m_drgw2_protection_region >> 8) & 0xff); - - case 3: - return 0x3f00 | ((m_drgw2_protection_region >> 16) & 0xff); - - case 4: - return 0x3f00 | ((m_drgw2_protection_region >> 24) & 0xff); - - case 5: - default: - return 0x3f00 | BITSWAP08(m_drgw2_prot_hold, 5,2,9,7,10,13,12,15); - } - - return 0x3f00; - } - - case 0x40: - drgw2_protection_calculate_hilo(); - return 0; - } - - return 0; -} - -static void __fastcall drgw2_d80000_protection_w(UINT32 offset, UINT16 data) -{ - offset &= 2; - - if (offset == 0) - { - m_drgw2_cmd = data; - return; - } - - switch (m_drgw2_cmd) - { - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - m_drgw2_ptr++; - drgw2_protection_calculate_hold(m_drgw2_cmd & 0x0f, data & 0xff); - break; - } -} - -static INT32 dw2Scan(INT32 nAction, INT32 *) -{ - if (nAction & ACB_DRIVER_DATA) { - SCAN_VAR(m_drgw2_prot_hold); - SCAN_VAR(m_drgw2_prot_hilo); - SCAN_VAR(m_drgw2_prot_hilo_select); - SCAN_VAR(m_drgw2_ptr); - SCAN_VAR(m_drgw2_cmd); - } - - return 0; -} - -static void reset_asic25_asic12_dw2() -{ - m_drgw2_prot_hold = 0; - m_drgw2_prot_hilo = 0; - m_drgw2_prot_hilo_select = 0; - m_drgw2_ptr = 0; - m_drgw2_cmd = 0; -} - -void install_protection_asic25_asic12_dw2() -{ - if (strcmp(BurnDrvGetTextA(DRV_NAME), "drgw2") == 0) m_drgw2_protection_region = 6; - if (strcmp(BurnDrvGetTextA(DRV_NAME), "dw2v100x") == 0) m_drgw2_protection_region = 6; - if (strcmp(BurnDrvGetTextA(DRV_NAME), "drgw2c") == 0) m_drgw2_protection_region = 5; - if (strcmp(BurnDrvGetTextA(DRV_NAME), "drgw2j") == 0) m_drgw2_protection_region = 1; - - pPgmScanCallback = dw2Scan; - pPgmResetCallback = reset_asic25_asic12_dw2; - - SekOpen(0); - SekMapHandler(4, 0xd80000, 0xd80003, SM_READ | SM_WRITE); - SekSetReadWordHandler(4, drgw2_d80000_protection_r); - SekSetWriteWordHandler(4, drgw2_d80000_protection_w); - SekClose(); -} - - -//------------------------- -// olds - -static int m_olds_cmd; -static int m_olds_reg; -static int m_olds_ptr; -static UINT16 m_olds_bs; -static UINT16 m_olds_cmd3; -static UINT16 m_olds_prot_hold; -static UINT16 m_olds_prot_hilo; -static UINT16 m_olds_prot_hilo_select; - -static const UINT8 olds_source_data[7][0xec] = // table addresses $2951CA -{ - { // region 1, $1A669A - 0x67, 0x51, 0xf3, 0x19, 0xa0, 0x11, 0xe1, 0x11, 0x10, 0xee, 0xe3, 0xf6, 0xbe, 0x81, 0x35, 0xe3, - 0xfb, 0xe6, 0xef, 0xdf, 0x61, 0x01, 0xfa, 0x22, 0x5d, 0x43, 0x01, 0xa5, 0x3b, 0x17, 0xd4, 0x74, - 0xf0, 0xf4, 0xf3, 0x43, 0xb5, 0x19, 0x04, 0xd5, 0x84, 0xce, 0x87, 0xfe, 0x35, 0x3e, 0xc4, 0x3c, - 0xc7, 0x85, 0x2a, 0x33, 0x00, 0x86, 0xd0, 0x4d, 0x65, 0x4b, 0xf9, 0xe9, 0xc0, 0xba, 0xaa, 0x77, - 0x9e, 0x66, 0xf6, 0x0f, 0x4f, 0x3a, 0xb6, 0xf1, 0x64, 0x9a, 0xe9, 0x25, 0x1a, 0x5f, 0x22, 0xa3, - 0xa2, 0xbf, 0x4b, 0x77, 0x3f, 0x34, 0xc9, 0x6e, 0xdb, 0x12, 0x5c, 0x33, 0xa5, 0x8b, 0x6c, 0xb1, - 0x74, 0xc8, 0x40, 0x4e, 0x2f, 0xe7, 0x46, 0xae, 0x99, 0xfc, 0xb0, 0x55, 0x54, 0xdf, 0xa7, 0xa1, - 0x0f, 0x5e, 0x49, 0xcf, 0x56, 0x3c, 0x90, 0x2b, 0xac, 0x65, 0x6e, 0xdb, 0x58, 0x3e, 0xc9, 0x00, - 0xae, 0x53, 0x4d, 0x92, 0xfa, 0x40, 0xb2, 0x6b, 0x65, 0x4b, 0x90, 0x8a, 0x0c, 0xe2, 0xa5, 0x9a, - 0xd0, 0x20, 0x29, 0x55, 0xa4, 0x44, 0xac, 0x51, 0x87, 0x54, 0x53, 0x34, 0x24, 0x4b, 0x81, 0x67, - 0x34, 0x4c, 0x5f, 0x31, 0x4e, 0xf2, 0xf1, 0x19, 0x18, 0x1c, 0x34, 0x38, 0xe1, 0x81, 0x17, 0xcf, - 0x24, 0xb9, 0x9a, 0xcb, 0x34, 0x51, 0x50, 0x59, 0x44, 0xb1, 0x0b, 0x50, 0x95, 0x6c, 0x48, 0x7e, - 0x14, 0xa4, 0xc6, 0xd9, 0xd3, 0xa5, 0xd6, 0xd0, 0xc5, 0x97, 0xf0, 0x45, 0xd0, 0x98, 0x51, 0x91, - 0x9f, 0xa3, 0x43, 0x51, 0x05, 0x90, 0xee, 0xca, 0x7e, 0x5f, 0x72, 0x53, 0xb1, 0xd3, 0xaf, 0x36, - 0x08, 0x75, 0xb0, 0x9b, 0xe0, 0x0d, 0x43, 0x88, 0xaa, 0x27, 0x44, 0x11 - }, - { // region 2, $19A5F8 - 0xf9, 0x19, 0xf3, 0x09, 0xa0, 0x11, 0xe0, 0x11, 0x10, 0x22, 0xfd, 0x8e, 0xd3, 0xc8, 0x31, 0x67, - 0xc0, 0x10, 0x3c, 0xc2, 0x03, 0xf2, 0x6a, 0x0a, 0x54, 0x49, 0xca, 0xb5, 0x4b, 0xe0, 0x94, 0xe8, - 0x8d, 0xc8, 0x90, 0xee, 0x6b, 0x6f, 0xfa, 0x09, 0x76, 0x84, 0x6f, 0x55, 0xd1, 0x94, 0xca, 0x9c, - 0xe1, 0x22, 0xc6, 0x02, 0xb5, 0x8c, 0xf9, 0x3a, 0x52, 0x10, 0xf0, 0x22, 0xe4, 0x11, 0x15, 0x73, - 0x5e, 0x9e, 0xde, 0xc4, 0x5a, 0xbd, 0xa3, 0x89, 0xe7, 0x9b, 0x95, 0x5d, 0x75, 0xf6, 0xc3, 0x9f, - 0xe4, 0xcf, 0x65, 0x73, 0x90, 0xd0, 0x75, 0x56, 0xfa, 0xcc, 0xe4, 0x3e, 0x9c, 0x41, 0x81, 0x62, - 0xb1, 0xd3, 0x28, 0xbd, 0x6c, 0xed, 0x60, 0x28, 0x27, 0xee, 0xf2, 0xa1, 0xb4, 0x2c, 0x6c, 0xbb, - 0x42, 0xd7, 0x1d, 0x62, 0xc0, 0x33, 0x7d, 0xf9, 0xe4, 0x5c, 0xe2, 0x41, 0xa4, 0x1c, 0x98, 0xa1, - 0x87, 0x95, 0xad, 0x61, 0x56, 0x96, 0x40, 0x08, 0x6b, 0xe2, 0x4b, 0x95, 0x7b, 0x1b, 0xd8, 0x64, - 0xb3, 0xee, 0x9d, 0x79, 0x69, 0xea, 0x5d, 0xcf, 0x01, 0x91, 0xea, 0x3f, 0x70, 0x29, 0xdc, 0xe0, - 0x08, 0x20, 0xbf, 0x46, 0x90, 0xa8, 0xfc, 0x29, 0x14, 0xd1, 0x0d, 0x20, 0x79, 0xd2, 0x2c, 0xe9, - 0x52, 0xa6, 0x8c, 0xbd, 0xa3, 0x3e, 0x88, 0x2d, 0xb8, 0x4e, 0xf2, 0x74, 0x50, 0xcc, 0x12, 0xde, - 0xd3, 0x5a, 0xa4, 0x7b, 0xa2, 0x8d, 0x91, 0x68, 0x12, 0x0c, 0x9c, 0xb9, 0x6d, 0x26, 0x66, 0x60, - 0xc3, 0x6d, 0xd0, 0x11, 0x33, 0x05, 0x1d, 0xa8, 0xb6, 0x51, 0xe6, 0xe0, 0x58, 0x61, 0x74, 0x37, - 0xcc, 0x3a, 0x4d, 0x6a, 0x0a, 0x09, 0x71, 0xe3, 0x7e, 0xa5, 0x3b, 0xe9 - }, - { // region 3, $1F9508 - 0x73, 0x59, 0xf3, 0x09, 0xa0, 0x11, 0xe1, 0x11, 0x10, 0x55, 0x18, 0x0d, 0xe8, 0x29, 0x2d, 0x04, - 0x85, 0x39, 0x88, 0xbe, 0x8b, 0xcb, 0xd9, 0x0b, 0x32, 0x36, 0x94, 0xac, 0x74, 0xc3, 0x3b, 0x5d, - 0x2a, 0x83, 0x46, 0xb3, 0x3a, 0xac, 0xd8, 0x55, 0x68, 0x21, 0x57, 0xab, 0x6e, 0xd1, 0xd0, 0xfc, - 0xe2, 0xbe, 0x63, 0xd0, 0x6b, 0x79, 0x23, 0x40, 0x58, 0xd4, 0xe7, 0x73, 0x22, 0x67, 0x7f, 0x88, - 0x05, 0xbd, 0xdf, 0x7a, 0x65, 0x41, 0x90, 0x3a, 0x52, 0x83, 0x28, 0xae, 0xe9, 0x8e, 0x65, 0x82, - 0x0e, 0xdf, 0x98, 0x88, 0xe1, 0x86, 0x21, 0x3e, 0x1a, 0x87, 0x6d, 0x62, 0x7a, 0xf6, 0xaf, 0x2c, - 0xd5, 0xc5, 0x10, 0x2d, 0xa9, 0xda, 0x93, 0xa1, 0x9b, 0xc7, 0x35, 0xd4, 0x15, 0x78, 0x18, 0xd5, - 0x75, 0x6a, 0xd7, 0xdb, 0x12, 0x2a, 0x6a, 0xc8, 0x36, 0x53, 0x57, 0xa6, 0xf0, 0x13, 0x67, 0x43, - 0x79, 0xf0, 0x0e, 0x49, 0xb1, 0xec, 0xcd, 0xa4, 0x8a, 0x61, 0x06, 0xb9, 0xea, 0x53, 0xf2, 0x47, - 0x7d, 0xd6, 0xf8, 0x9d, 0x2e, 0xaa, 0x27, 0x35, 0x61, 0xce, 0x9b, 0x63, 0xbc, 0x07, 0x51, 0x5a, - 0xc2, 0x0d, 0x39, 0x42, 0xd2, 0x5e, 0x21, 0x20, 0x10, 0xa0, 0xe5, 0x08, 0xf7, 0x3d, 0x28, 0x04, - 0x99, 0x93, 0x97, 0xaf, 0xf9, 0x12, 0xc0, 0x01, 0x2d, 0xea, 0xf3, 0x98, 0x0b, 0x46, 0xc2, 0x26, - 0x93, 0x10, 0x69, 0x1d, 0x71, 0x8e, 0x33, 0x00, 0x5e, 0x80, 0x2f, 0x47, 0x0a, 0xcc, 0x94, 0x16, - 0xe7, 0x37, 0x45, 0xd0, 0x61, 0x79, 0x32, 0x86, 0x08, 0x2a, 0x5b, 0x55, 0xfe, 0xee, 0x52, 0x38, - 0xaa, 0x18, 0xe9, 0x39, 0x1a, 0x1e, 0xb8, 0x26, 0x6b, 0x3d, 0x4b, 0xa9 - }, - { // region 4, $1CA7B8 - 0x06, 0x01, 0xf3, 0x39, 0xa0, 0x11, 0xf0, 0x11, 0x10, 0x6f, 0x32, 0x8b, 0xfd, 0x89, 0x29, 0xa0, - 0x4a, 0x62, 0xed, 0xa1, 0x2d, 0xa4, 0x49, 0xf2, 0x10, 0x3c, 0x77, 0xa3, 0x84, 0x8d, 0xfa, 0xd1, - 0xc6, 0x57, 0xe2, 0x78, 0xef, 0xe9, 0xb6, 0xa1, 0x5a, 0xbd, 0x3f, 0x02, 0x0b, 0x28, 0xd6, 0x76, - 0xfc, 0x5b, 0x19, 0x9f, 0x21, 0x66, 0x4c, 0x2d, 0x45, 0x99, 0xde, 0xab, 0x46, 0xbd, 0xe9, 0x84, - 0xc4, 0xdc, 0xc7, 0x30, 0x70, 0xdd, 0x64, 0xea, 0xbc, 0x6b, 0xd3, 0xe6, 0x45, 0x3f, 0x07, 0x7e, - 0x50, 0xef, 0xb2, 0x84, 0x33, 0x3c, 0xcc, 0x3f, 0x39, 0x5b, 0xf5, 0x6d, 0x71, 0xc5, 0xdd, 0xf5, - 0xf9, 0xd0, 0xf7, 0x9c, 0xe6, 0xc7, 0xad, 0x1b, 0x29, 0xb9, 0x90, 0x08, 0x75, 0xc4, 0xc3, 0xef, - 0xa8, 0xfc, 0xab, 0x55, 0x7c, 0x21, 0x57, 0x97, 0x87, 0x4a, 0xcb, 0x0c, 0x56, 0x0a, 0x4f, 0xcb, - 0x52, 0x33, 0x87, 0x31, 0xf3, 0x43, 0x5b, 0x41, 0x90, 0xf8, 0xc0, 0xdd, 0x5a, 0xa4, 0x26, 0x2a, - 0x60, 0xa5, 0x6d, 0xda, 0xf2, 0x6a, 0xf0, 0xb3, 0xda, 0x25, 0x33, 0x87, 0x22, 0xe4, 0xac, 0xd3, - 0x96, 0xe0, 0x99, 0x3e, 0xfb, 0x14, 0x45, 0x17, 0x25, 0x56, 0xbe, 0xef, 0x8f, 0x8e, 0x3d, 0x1e, - 0xc7, 0x99, 0xa2, 0xa1, 0x50, 0xfe, 0xdf, 0xd4, 0xa1, 0x87, 0xf4, 0xd5, 0xde, 0xa6, 0x8c, 0x6d, - 0x6c, 0xde, 0x47, 0xbe, 0x59, 0x8f, 0xd4, 0x97, 0xc3, 0xf4, 0xda, 0xbb, 0xa6, 0x73, 0xa9, 0xcb, - 0xf2, 0x01, 0xb9, 0x90, 0x8f, 0xed, 0x60, 0x64, 0x40, 0x1c, 0xb6, 0xc9, 0xa5, 0x7c, 0x17, 0x52, - 0x6f, 0xdc, 0x6d, 0x08, 0x2a, 0x1a, 0xe6, 0x68, 0x3f, 0xd4, 0x42, 0x69 - }, - { // region 5, $1A19FA - 0x7f, 0x41, 0xf3, 0x39, 0xa0, 0x11, 0xf1, 0x11, 0x10, 0xa2, 0x4c, 0x23, 0x13, 0xe9, 0x25, 0x3d, - 0x0f, 0x72, 0x3a, 0x9d, 0xb5, 0x96, 0xd1, 0xda, 0x07, 0x29, 0x41, 0x9a, 0xad, 0x70, 0xba, 0x46, - 0x63, 0x2b, 0x7f, 0x3d, 0xbe, 0x40, 0xad, 0xd4, 0x4c, 0x73, 0x27, 0x58, 0xa7, 0x65, 0xdc, 0xd6, - 0xfd, 0xde, 0xb5, 0x6e, 0xd6, 0x6c, 0x75, 0x1a, 0x32, 0x45, 0xd5, 0xe3, 0x6a, 0x14, 0x6d, 0x80, - 0x84, 0x15, 0xaf, 0xcc, 0x7b, 0x61, 0x51, 0x82, 0x40, 0x53, 0x7f, 0x38, 0xa0, 0xd6, 0x8f, 0x61, - 0x79, 0x19, 0xe5, 0x99, 0x84, 0xd8, 0x78, 0x27, 0x3f, 0x16, 0x97, 0x78, 0x4f, 0x7b, 0x0c, 0xa6, - 0x37, 0xdb, 0xc6, 0x0c, 0x24, 0xb4, 0xc7, 0x94, 0x9d, 0x92, 0xd2, 0x3b, 0xd5, 0x11, 0x6f, 0x0a, - 0xdb, 0x76, 0x66, 0xe7, 0xcd, 0x18, 0x2b, 0x66, 0xd8, 0x41, 0x40, 0x58, 0xa2, 0x01, 0x1e, 0x6d, - 0x44, 0x75, 0xe7, 0x19, 0x4f, 0xb2, 0xe8, 0xc4, 0x96, 0x77, 0x62, 0x02, 0xc9, 0xdc, 0x59, 0xf3, - 0x43, 0x8d, 0xc8, 0xfe, 0x9e, 0x2a, 0xba, 0x32, 0x3b, 0x62, 0xe3, 0x92, 0x6e, 0xc2, 0x08, 0x4d, - 0x51, 0xcd, 0xf9, 0x3a, 0x3e, 0xc9, 0x50, 0x27, 0x21, 0x25, 0x97, 0xd7, 0x0e, 0xf8, 0x39, 0x38, - 0xf5, 0x86, 0x94, 0x93, 0xbf, 0xeb, 0x18, 0xa8, 0xfc, 0x24, 0xf5, 0xf9, 0x99, 0x20, 0x3d, 0xcd, - 0x2c, 0x94, 0x25, 0x79, 0x28, 0x77, 0x8f, 0x2f, 0x10, 0x69, 0x86, 0x30, 0x43, 0x01, 0xd7, 0x9a, - 0x17, 0xe3, 0x47, 0x37, 0xbd, 0x62, 0x75, 0x42, 0x78, 0xf4, 0x2b, 0x57, 0x4c, 0x0a, 0xdb, 0x53, - 0x4d, 0xa1, 0x0a, 0xd6, 0x3a, 0x16, 0x15, 0xaa, 0x2c, 0x6c, 0x39, 0x42 - }, - { // region 6, $2937EA - 0x12, 0x09, 0xf3, 0x29, 0xa0, 0x11, 0xf0, 0x11, 0x10, 0xd5, 0x66, 0xa1, 0x28, 0x4a, 0x21, 0xc0, - 0xd3, 0x9b, 0x86, 0x80, 0x57, 0x6f, 0x41, 0xc2, 0xe4, 0x2f, 0x0b, 0x91, 0xbd, 0x3a, 0x7a, 0xba, - 0x00, 0xe5, 0x35, 0x02, 0x74, 0x7d, 0x8b, 0x21, 0x57, 0x10, 0x0f, 0xae, 0x44, 0xbb, 0xe2, 0x37, - 0x18, 0x7b, 0x52, 0x3d, 0x8c, 0x59, 0x9e, 0x20, 0x1f, 0x0a, 0xcc, 0x1c, 0x8e, 0x6a, 0xd7, 0x95, - 0x2b, 0x34, 0xb0, 0x82, 0x6d, 0xfd, 0x25, 0x33, 0xaa, 0x3b, 0x2b, 0x70, 0x15, 0x87, 0x31, 0x5d, - 0xbb, 0x29, 0x19, 0x95, 0xd5, 0x8e, 0x24, 0x28, 0x5e, 0xd0, 0x20, 0x83, 0x46, 0x4a, 0x21, 0x70, - 0x5b, 0xcd, 0xae, 0x7b, 0x61, 0xa1, 0xfa, 0xf4, 0x2b, 0x84, 0x15, 0x6e, 0x36, 0x5d, 0x1b, 0x24, - 0x0f, 0x09, 0x3a, 0x61, 0x38, 0x0f, 0x18, 0x35, 0x11, 0x38, 0xb4, 0xbd, 0xee, 0xf7, 0xec, 0x0f, - 0x1d, 0xb7, 0x48, 0x01, 0xaa, 0x09, 0x8f, 0x61, 0xb5, 0x0f, 0x1d, 0x26, 0x39, 0x2e, 0x8c, 0xd6, - 0x26, 0x5c, 0x3d, 0x23, 0x63, 0xe9, 0x6b, 0x97, 0xb4, 0x9f, 0x7b, 0xb6, 0xba, 0xa0, 0x7c, 0xc6, - 0x25, 0xa1, 0x73, 0x36, 0x67, 0x7f, 0x74, 0x1e, 0x1d, 0xda, 0x70, 0xbf, 0xa5, 0x63, 0x35, 0x39, - 0x24, 0x8c, 0x9f, 0x85, 0x16, 0xd8, 0x50, 0x95, 0x71, 0xc0, 0xf6, 0x1e, 0x6d, 0x80, 0xed, 0x15, - 0xeb, 0x63, 0xe9, 0x1b, 0xf6, 0x78, 0x31, 0xc6, 0x5c, 0xdd, 0x19, 0xbd, 0xdf, 0xa7, 0xec, 0x50, - 0x22, 0xad, 0xbb, 0xf6, 0xeb, 0xd6, 0xa3, 0x20, 0xc9, 0xe6, 0x9f, 0xcb, 0xf2, 0x97, 0xb9, 0x54, - 0x12, 0x66, 0xa6, 0xbe, 0x4a, 0x12, 0x43, 0xec, 0x00, 0xea, 0x49, 0x02 - }, - { // region 7, $255E8C - 0xa4, 0x49, 0xf3, 0x29, 0xa0, 0x11, 0xf1, 0x11, 0x10, 0xef, 0x80, 0x20, 0x3d, 0xaa, 0x36, 0x5d, - 0x98, 0xc4, 0xd2, 0x63, 0xdf, 0x61, 0xb0, 0xc3, 0xc2, 0x35, 0xd4, 0x88, 0xe6, 0x1d, 0x3a, 0x2f, - 0x9c, 0xb9, 0xd1, 0xc6, 0x43, 0xba, 0x69, 0x6d, 0x49, 0xac, 0xdd, 0x05, 0xe0, 0xf8, 0xe8, 0x97, - 0x19, 0x18, 0x08, 0x0c, 0x42, 0x46, 0xc7, 0x0d, 0x25, 0xce, 0xc3, 0x54, 0xb2, 0xd9, 0x42, 0x91, - 0xea, 0x53, 0x98, 0x38, 0x78, 0x81, 0x12, 0xca, 0x15, 0x23, 0xbd, 0xc1, 0x70, 0x1f, 0xd2, 0x40, - 0xfd, 0x39, 0x33, 0xaa, 0x27, 0x2b, 0xe8, 0x10, 0x7d, 0xa4, 0xa8, 0x8e, 0x3d, 0x00, 0x4f, 0x3a, - 0x7f, 0xd8, 0x96, 0xea, 0x9e, 0x8e, 0x15, 0x6e, 0x9f, 0x76, 0x57, 0xba, 0x7d, 0xc2, 0xdf, 0x57, - 0x42, 0x82, 0xf4, 0xda, 0x89, 0x06, 0x05, 0x04, 0x62, 0x2f, 0x29, 0x23, 0x54, 0xd5, 0xbb, 0x97, - 0xf5, 0xf9, 0xc1, 0xcf, 0xec, 0x5f, 0x1d, 0xfd, 0xbb, 0xa6, 0xd7, 0x4a, 0xa8, 0x66, 0xbf, 0xb9, - 0x09, 0x44, 0xb1, 0x60, 0x28, 0xa9, 0x35, 0x16, 0x15, 0xf5, 0x13, 0xc1, 0x07, 0x7e, 0xd7, 0x40, - 0xdf, 0x8e, 0xd3, 0x32, 0xa9, 0x35, 0x98, 0x15, 0x32, 0xa9, 0x49, 0xc0, 0x24, 0xb4, 0x4a, 0x53, - 0x6b, 0x79, 0xaa, 0x77, 0x6c, 0xc5, 0x88, 0x69, 0xe5, 0x5d, 0xde, 0x42, 0x28, 0xf9, 0xb7, 0x5c, - 0xab, 0x19, 0xc7, 0xbc, 0xc5, 0x60, 0xeb, 0x5e, 0xa8, 0x52, 0xc4, 0x32, 0x7c, 0x35, 0x02, 0x06, - 0x46, 0x77, 0x30, 0xb6, 0x33, 0x4b, 0xb8, 0xfd, 0x02, 0xd8, 0x14, 0x40, 0x99, 0x25, 0x7e, 0x55, - 0xd6, 0x44, 0x43, 0x8d, 0x73, 0x0e, 0x71, 0x48, 0xd3, 0x82, 0x40, 0xda - } -}; - -static UINT32 olds_prot_addr(UINT16 addr) -{ - switch (addr & 0xff) - { - case 0x0: - case 0x5: - case 0xa: return 0x402a00 + ((addr >> 8) << 2); - case 0x2: - case 0x8: return 0x402e00 + ((addr >> 8) << 2); - case 0x1: return 0x40307e; - case 0x3: return 0x403090; - case 0x4: return 0x40309a; - case 0x6: return 0x4030a4; - case 0x7: return 0x403000; - case 0x9: return 0x40306e; - } - - return 0; -} - -static UINT32 olds_read_reg(UINT16 addr) -{ - UINT32 protaddr = (olds_prot_addr(addr) - 0x400000) / 2; - return sharedprotram[protaddr] << 16 | sharedprotram[protaddr + 1]; -} - -static void olds_write_reg( UINT16 addr, UINT32 val ) -{ - sharedprotram[(olds_prot_addr(addr) - 0x400000) / 2] = val >> 16; - sharedprotram[(olds_prot_addr(addr) - 0x400000) / 2 + 1] = val & 0xffff; -} - -static void IGS028_do_dma(UINT16 src, UINT16 dst, UINT16 size, UINT16 mode) -{ - UINT16 param = mode >> 8; - UINT16 *PROTROM = (UINT16*)(PGMUSER0 + 0x10000); - - mode &= 0x0f; - - switch (mode) - { - case 0x00: // This mode copies code later on in the game! Encrypted somehow? - // src:2fc8, dst: 045a, size: 025e, mode: 0000 - // jumps from 12beb4 in unprotected set - // jumps from 1313e0 in protected set - case 0x01: // swap bytes and nibbles - case 0x02: // ^= encryption - case 0x05: // copy - case 0x06: // += encryption (correct?) - { - UINT8 extraoffset = param & 0xff; - UINT8 *dectable = (UINT8 *)(PROTROM + (0x100 / 2)); - - for (INT32 x = 0; x < size; x++) - { - UINT16 dat2 = PROTROM[src + x]; - - int taboff = ((x*2)+extraoffset) & 0xff; // must allow for overflow in instances of odd offsets - unsigned short extraxor = ((dectable[taboff + 0]) << 0) | (dectable[taboff + 1] << 8); - - if (mode==0) dat2 = 0x4e75; // hack - if (mode==1) dat2 = ((dat2 & 0xf000) >> 12) | ((dat2 & 0x0f00) >> 4) | ((dat2 & 0x00f0) << 4) | ((dat2 & 0x000f) << 12); - if (mode==2) dat2 ^= extraxor; - //if (mode==5) dat2 = dat2; - if (mode==6) dat2 += extraxor; - - if (mode==2 || mode==6) dat2 = (dat2<<8)|(dat2>>8); - - sharedprotram[dst + x] = (dat2 << 8) | (dat2 >> 8); - } - } - } -} - -static void olds_protection_calculate_hold(int y, int z) // calculated in routine $12dbc2 in olds -{ - unsigned short old = m_olds_prot_hold; - - m_olds_prot_hold = ((old << 1) | (old >> 15)); - - m_olds_prot_hold ^= 0x2bad; - m_olds_prot_hold ^= BIT(z, y); - m_olds_prot_hold ^= BIT( old, 7) << 0; - m_olds_prot_hold ^= BIT(~old, 13) << 4; - m_olds_prot_hold ^= BIT( old, 3) << 11; - - m_olds_prot_hold ^= (m_olds_prot_hilo & ~0x0408) << 1; // $81790c -} - -static void olds_protection_calculate_hilo() // calculated in routine $12dbc2 in olds -{ - UINT8 source; - - m_olds_prot_hilo_select++; - if (m_olds_prot_hilo_select > 0xeb) { - m_olds_prot_hilo_select = 0; - } - - source = olds_source_data[PgmInput[7] - 1][m_olds_prot_hilo_select]; - - if (m_olds_prot_hilo_select & 1) // $8178fa - { - m_olds_prot_hilo = (m_olds_prot_hilo & 0x00ff) | (source << 8); // $8178d8 - } - else - { - m_olds_prot_hilo = (m_olds_prot_hilo & 0xff00) | (source << 0); // $8178d8 - } -} - -static void __fastcall olds_protection_w(UINT32 offset, UINT16 data) -{ - offset &= 2; - - if (offset == 0) - { - m_olds_cmd = data; - } - else - { - switch (m_olds_cmd) - { - case 0x00: - m_olds_reg = data; - break; - - case 0x02: - m_olds_bs = ((data & 0x03) << 6) | ((data & 0x04) << 3) | ((data & 0x08) << 1); - break; - - case 0x03: - { - UINT16 cmd = sharedprotram[0x3026 / 2]; - - switch (cmd) - { - case 0x12: - { - UINT16 mode = sharedprotram[0x303e / 2]; // ? - UINT16 src = sharedprotram[0x306a / 2] >> 1; // ? - UINT16 dst = sharedprotram[0x3084 / 2] & 0x1fff; - UINT16 size = sharedprotram[0x30a2 / 2] & 0x1fff; - - IGS028_do_dma(src, dst, size, mode); - } - break; - - case 0x64: // incomplete... - { - UINT16 p1 = sharedprotram[0x3050 / 2]; - UINT16 p2 = sharedprotram[0x3082 / 2]; - UINT16 p3 = sharedprotram[0x3054 / 2]; - UINT16 p4 = sharedprotram[0x3088 / 2]; - - if (p2 == 0x02) - olds_write_reg(p1, olds_read_reg(p1) + 0x10000); - - switch (p4) - { - case 0xd: - olds_write_reg(p1,olds_read_reg(p3)); - break; - case 0x0: - olds_write_reg(p3,(olds_read_reg(p2))^(olds_read_reg(p1))); - break; - case 0xe: - olds_write_reg(p3,olds_read_reg(p3)+0x10000); - break; - case 0x2: - olds_write_reg(p1,(olds_read_reg(p2))+(olds_read_reg(p3))); - break; - case 0x6: - olds_write_reg(p3,(olds_read_reg(p2))&(olds_read_reg(p1))); - break; - case 0x1: - olds_write_reg(p2,olds_read_reg(p1)+0x10000); - break; - case 0x7: - olds_write_reg(p3,olds_read_reg(p1)); - break; - default: - break; - } - } - } - - m_olds_cmd3 = ((data >> 4) + 1) & 0x3; - } - break; - - case 0x04: - m_olds_ptr = data; - break; - - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - m_olds_ptr++; - olds_protection_calculate_hold(m_olds_cmd & 0x0f, data & 0xff); - break; - } - } -} - -static UINT16 __fastcall olds_protection_r(UINT32 offset) -{ - offset &= 2; - - if (offset) - { - switch (m_olds_cmd) - { - case 0x01: - return m_olds_reg & 0x7f; - - case 0x02: - return m_olds_bs | 0x80; - - case 0x03: - return m_olds_cmd3; - - case 0x05: - { - switch (m_olds_ptr) - { - case 1: return 0x3f00 | PgmInput[7]; - - case 2: - return 0x3f00 | 0x00; - - case 3: - return 0x3f00 | 0x90; - - case 4: - return 0x3f00 | 0x00; - - case 5: - default: // >= 5 - return 0x3f00 | BITSWAP08(m_olds_prot_hold, 5,2,9,7,10,13,12,15); // $817906 - } - } - - case 0x40: - olds_protection_calculate_hilo(); - return 0; // unused? - } - } - - return 0; -} - -static void reset_olds() -{ -// written by protection device -// there seems to be an auto-dma that writes from $401000-402573? - sharedprotram[0x1000/2] = 0x4749; // 'IGS.28' - sharedprotram[0x1002/2] = 0x2E53; - sharedprotram[0x1004/2] = 0x3832; - sharedprotram[0x3064/2] = 0xB315; // crc or status check? - -// Should these be written by command 64?? -// sharedprotram[0x2a00/2] = 0x0000; // ? -// sharedprotram[0x2a02/2] = 0x0000; // ? - sharedprotram[0x2a04/2] = 0x0002; // ? -// sharedprotram[0x2a06/2] = 0x0000; // ? -// sharedprotram[0x2ac0/2] = 0x0000; // ? - sharedprotram[0x2ac2/2] = 0x0001; // ? -// sharedprotram[0x2e00/2] = 0x0000; // ? -// sharedprotram[0x2e02/2] = 0x0000; // ? -// sharedprotram[0x2e04/2] = 0x0000; // ? - sharedprotram[0x2e06/2] = 0x0009; // seconds on char. select timer -// sharedprotram[0x2e08/2] = 0x0000; // ? - sharedprotram[0x2e0a/2] = 0x0006; // ? - - m_olds_prot_hold = 0; - m_olds_prot_hilo = 0; - m_olds_prot_hilo_select = 0; - m_olds_cmd = 0; - m_olds_reg = 0; - m_olds_ptr = 0; - m_olds_bs = 0; - m_olds_cmd3 = 0; -} - -static INT32 oldsScan(INT32 nAction, INT32 *) -{ - struct BurnArea ba; - - if (nAction & ACB_MEMORY_RAM) { - ba.Data = PGMUSER0 + 0x000000; - ba.nLen = 0x0004000; - ba.nAddress = 0x400000; - ba.szName = "ProtRAM"; - BurnAcb(&ba); - } - - if (nAction & ACB_DRIVER_DATA) { - SCAN_VAR(m_olds_prot_hold); - SCAN_VAR(m_olds_prot_hilo); - SCAN_VAR(m_olds_prot_hilo_select); - SCAN_VAR(m_olds_cmd); - SCAN_VAR(m_olds_reg); - SCAN_VAR(m_olds_ptr); - SCAN_VAR(m_olds_bs); - SCAN_VAR(m_olds_cmd3); - } - - return 0; -} - -void install_protection_asic25_asic28_olds() -{ - pPgmScanCallback = oldsScan; - pPgmResetCallback = reset_olds; - - sharedprotram = (UINT16*)PGMUSER0; - - // no protection rom and different offset for olds100a - if (strcmp(BurnDrvGetTextA(DRV_NAME), "olds100a") == 0) { - BurnLoadRom(PGMUSER0 + 0x10000, 15, 1); - } else { - BurnLoadRom(PGMUSER0 + 0x10000, 19, 1); - } - - SekOpen(0); - - SekMapMemory(PGMUSER0, 0x400000, 0x403fff, SM_RAM); - - SekMapHandler(4, 0xdcb400, 0xdcb403, SM_READ | SM_WRITE); - SekSetReadWordHandler(4, olds_protection_r); - SekSetWriteWordHandler(4, olds_protection_w); - - SekClose(); -} diff --git a/src/burn/drv/pgm/pgm_run.cpp b/src/burn/drv/pgm/pgm_run.cpp index 9b2a7ddbf..dfee7e26c 100644 --- a/src/burn/drv/pgm/pgm_run.cpp +++ b/src/burn/drv/pgm/pgm_run.cpp @@ -35,7 +35,7 @@ static UINT8 *Mem = NULL, *MemEnd = NULL; static UINT8 *RamStart, *RamEnd; UINT8 *PGM68KBIOS, *PGM68KROM, *PGMTileROM, *PGMTileROMExp, *PGMSPRColROM, *PGMSPRMaskROM, *PGMARMROM; -UINT8 *PGMARMRAM0, *PGMUSER0, *PGMARMRAM1, *PGMARMRAM2, *PGMARMShareRAM, *PGMARMShareRAM2; +UINT8 *PGMARMRAM0, *PGMUSER0, *PGMARMRAM1, *PGMARMRAM2, *PGMARMShareRAM, *PGMARMShareRAM2, *PGMProtROM; UINT8 nPgmPalRecalc = 0; static UINT8 nPgmZ80Work = 0; @@ -71,6 +71,8 @@ static INT32 pgmMemIndex() PGMUSER0 = Next; Next += nPGMExternalARMLen; + PGMProtROM = PGMUSER0 + 0x10000; // Olds, Killbld, drgw3 + if (BurnDrvGetHardwareCode() & HARDWARE_IGS_USE_ARM_CPU) { PGMARMROM = Next; Next += 0x0004000; } @@ -220,6 +222,13 @@ static INT32 pgmGetRoms(bool bLoad) } continue; } + + if ((ri.nType & BRF_PRG) && (ri.nType & 0x0f) == 9) + { + if (bLoad) { + BurnLoadRom(PGMProtROM, i, 1); + } + } } if (!bLoad) {