summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/pgmprot.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/machine/pgmprot.c')
-rw-r--r--src/mame/machine/pgmprot.c891
1 files changed, 891 insertions, 0 deletions
diff --git a/src/mame/machine/pgmprot.c b/src/mame/machine/pgmprot.c
new file mode 100644
index 00000000000..9ecdade6a75
--- /dev/null
+++ b/src/mame/machine/pgmprot.c
@@ -0,0 +1,891 @@
+#include "driver.h"
+
+extern UINT16 *pgm_mainram;
+
+/*** ASIC27a (Puzzle Star) -- ARM but with no external rom? behaves a bit like KOV ***/
+
+
+
+
+/*** (PSTARS) ***/
+static UINT16 PSTARSKEY;
+static UINT16 PSTARSINT[2];
+static UINT32 PSTARS_REGS[16];
+static UINT32 PSTARS_VAL;
+
+static UINT16 pstar_e7,pstar_b1,pstar_ce;
+static UINT16 pstar_ram[3];
+
+static int Pstar_ba[0x1E]={
+ 0x02,0x00,0x00,0x01,0x00,0x03,0x00,0x00, //0
+ 0x02,0x00,0x06,0x00,0x22,0x04,0x00,0x03, //8
+ 0x00,0x00,0x06,0x00,0x20,0x07,0x00,0x03, //10
+ 0x00,0x21,0x01,0x00,0x00,0x63
+};
+
+static int Pstar_b0[0x10]={
+ 0x09,0x0A,0x0B,0x00,0x01,0x02,0x03,0x04,
+ 0x05,0x06,0x07,0x08,0x00,0x00,0x00,0x00
+};
+
+static int Pstar_ae[0x10]={
+ 0x5D,0x86,0x8C ,0x8B,0xE0,0x8B,0x62,0xAF,
+ 0xB6,0xAF,0x10A,0xAF,0x00,0x00,0x00,0x00
+};
+
+static int Pstar_a0[0x10]={
+ 0x02,0x03,0x04,0x05,0x06,0x01,0x0A,0x0B,
+ 0x0C,0x0D,0x0E,0x09,0x00,0x00,0x00,0x00,
+};
+
+static int Pstar_9d[0x10]={
+ 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+static int Pstar_90[0x10]={
+ 0x0C,0x10,0x0E,0x0C,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+};
+static int 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 int 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
+};
+
+
+
+
+READ16_HANDLER (PSTARS_protram_r)
+{
+ if (offset == 4) //region
+ return readinputport(4);
+ else if (offset >= 0x10) //timer
+ {
+ logerror("PSTARS ACCESS COUNTER %6X\n",pstar_ram[offset-0x10]);
+ return pstar_ram[offset-0x10]--;
+ }
+ return 0x0000;
+}
+
+READ16_HANDLER (PSTARS_r16)
+{
+ if(offset==0)
+ {
+ UINT16 d=PSTARS_VAL&0xffff;
+ UINT16 realkey;
+ realkey=PSTARSKEY>>8;
+ realkey|=PSTARSKEY;
+ d^=realkey;
+// logerror("PSTARS A27 R %6X\n",PSTARS_VAL);
+ return d;
+ }
+ else if(offset==1)
+ {
+ UINT16 d=PSTARS_VAL>>16;
+ UINT16 realkey;
+ realkey=PSTARSKEY>>8;
+ realkey|=PSTARSKEY;
+ d^=realkey;
+ return d;
+
+ }
+ return 0xff;
+}
+
+WRITE16_HANDLER (PSTARS_w16)
+{
+ if(offset==0)
+ {
+ PSTARSINT[0]=data;
+ return;
+ }
+
+ if(offset==1)
+ {
+ UINT16 realkey;
+ if((data>>8)==0xff)
+ PSTARSKEY=0xff00;
+ realkey=PSTARSKEY>>8;
+ realkey|=PSTARSKEY;
+ {
+ PSTARSKEY+=0x100;
+ PSTARSKEY&=0xff00;
+ if(PSTARSKEY==0xff00)PSTARSKEY=0x100;
+ }
+ data^=realkey;
+ PSTARSINT[1]=data;
+ PSTARSINT[0]^=realkey;
+
+ switch(PSTARSINT[1]&0xff)
+ {
+ case 0x99:
+ {
+ PSTARSKEY=0x100;
+ PSTARS_VAL=0x880000;
+
+ }
+ break;
+
+ case 0xE0:
+ {
+ PSTARS_VAL=0xa00000+(PSTARSINT[0]<<6);
+ }
+ break;
+ case 0xDC:
+ {
+ PSTARS_VAL=0xa00800+(PSTARSINT[0]<<6);
+ }
+ break;
+ case 0xD0:
+ {
+ PSTARS_VAL=0xa01000+(PSTARSINT[0]<<5);
+ }
+ break;
+
+ case 0xb1:
+ {
+ pstar_b1=PSTARSINT[0];
+ PSTARS_VAL=0x890000;
+ }
+ break;
+ case 0xbf:
+ {
+ PSTARS_VAL=pstar_b1*PSTARSINT[0];
+ }
+ break;
+
+ case 0xc1: //TODO:TIMER 0,1,2,FIX TO 0 should be OK?
+ {
+ PSTARS_VAL=0;
+ }
+ break;
+ case 0xce: //TODO:TIMER 0,1,2
+ {
+ pstar_ce=PSTARSINT[0];
+ PSTARS_VAL=0x890000;
+ }
+ break;
+ case 0xcf: //TODO:TIMER 0,1,2
+ {
+ pstar_ram[pstar_ce]=PSTARSINT[0];
+ PSTARS_VAL=0x890000;
+ }
+ break;
+
+
+ case 0xe7:
+ {
+ pstar_e7=(PSTARSINT[0]>>12)&0xf;
+ PSTARS_REGS[pstar_e7]&=0xffff;
+ PSTARS_REGS[pstar_e7]|=(PSTARSINT[0]&0xff)<<16;
+ PSTARS_VAL=0x890000;
+ }
+ break;
+ case 0xe5:
+ {
+
+ PSTARS_REGS[pstar_e7]&=0xff0000;
+ PSTARS_REGS[pstar_e7]|=PSTARSINT[0];
+ PSTARS_VAL=0x890000;
+ }
+ break;
+ case 0xf8: //@73C
+ {
+ PSTARS_VAL=PSTARS_REGS[PSTARSINT[0]&0xf]&0xffffff;
+ }
+ break;
+
+
+ case 0xba:
+ {
+ PSTARS_VAL=Pstar_ba[PSTARSINT[0]];
+ }
+ break;
+ case 0xb0:
+ {
+ PSTARS_VAL=Pstar_b0[PSTARSINT[0]];
+ }
+ break;
+ case 0xae:
+ {
+ PSTARS_VAL=Pstar_ae[PSTARSINT[0]];
+ }
+ break;
+ case 0xa0:
+ {
+ PSTARS_VAL=Pstar_a0[PSTARSINT[0]];
+ }
+ break;
+ case 0x9d:
+ {
+ PSTARS_VAL=Pstar_9d[PSTARSINT[0]];
+ }
+ break;
+ case 0x90:
+ {
+ PSTARS_VAL=Pstar_90[PSTARSINT[0]];
+ }
+ break;
+ case 0x8c:
+ {
+ PSTARS_VAL=Pstar_8c[PSTARSINT[0]];
+ }
+ break;
+ case 0x80:
+ {
+ PSTARS_VAL=Pstar_80[PSTARSINT[0]];
+ }
+ break;
+ default:
+ PSTARS_VAL=0x890000;
+ logerror("PSTARS PC(%06x) UNKNOWN %4X %4X\n",activecpu_get_pc(),PSTARSINT[1],PSTARSINT[0]);
+
+ }
+
+ }
+}
+
+/*** ASIC 3 (oriental legends protection) ****************************************/
+
+static UINT8 asic3_reg, asic3_latch[3], asic3_x, asic3_y, asic3_z, asic3_h1, asic3_h2;
+static UINT16 asic3_hold;
+
+static UINT32 bt(UINT32 v, int bit)
+{
+ return (v & (1<<bit)) != 0;
+}
+
+static void asic3_compute_hold(void)
+{
+ // The mode is dependant on the region
+ static int modes[4] = { 1, 1, 3, 2 };
+ int mode = modes[readinputport(4) & 3];
+
+ switch(mode) {
+ case 1:
+ asic3_hold =
+ (asic3_hold << 1)
+ ^0x2bad
+ ^bt(asic3_hold, 15)^bt(asic3_hold, 10)^bt(asic3_hold, 8)^bt(asic3_hold, 5)
+ ^bt(asic3_z, asic3_y)
+ ^(bt(asic3_x, 0) << 1)^(bt(asic3_x, 1) << 6)^(bt(asic3_x, 2) << 10)^(bt(asic3_x, 3) << 14);
+ break;
+ case 2:
+ asic3_hold =
+ (asic3_hold << 1)
+ ^0x2bad
+ ^bt(asic3_hold, 15)^bt(asic3_hold, 7)^bt(asic3_hold, 6)^bt(asic3_hold, 5)
+ ^bt(asic3_z, asic3_y)
+ ^(bt(asic3_x, 0) << 4)^(bt(asic3_x, 1) << 6)^(bt(asic3_x, 2) << 10)^(bt(asic3_x, 3) << 12);
+ break;
+ case 3:
+ asic3_hold =
+ (asic3_hold << 1)
+ ^0x2bad
+ ^bt(asic3_hold, 15)^bt(asic3_hold, 10)^bt(asic3_hold, 8)^bt(asic3_hold, 5)
+ ^bt(asic3_z, asic3_y)
+ ^(bt(asic3_x, 0) << 4)^(bt(asic3_x, 1) << 6)^(bt(asic3_x, 2) << 10)^(bt(asic3_x, 3) << 12);
+ break;
+ }
+}
+
+READ16_HANDLER( pgm_asic3_r )
+{
+ UINT8 res = 0;
+ /* region is supplied by the protection device */
+
+ switch(asic3_reg) {
+ case 0x00: res = (asic3_latch[0] & 0xf7) | ((readinputport(4) << 3) & 0x08); break;
+ case 0x01: res = asic3_latch[1]; break;
+ case 0x02: res = (asic3_latch[2] & 0x7f) | ((readinputport(4) << 6) & 0x80); break;
+ case 0x03:
+ res = (bt(asic3_hold, 15) << 0)
+ | (bt(asic3_hold, 12) << 1)
+ | (bt(asic3_hold, 13) << 2)
+ | (bt(asic3_hold, 10) << 3)
+ | (bt(asic3_hold, 7) << 4)
+ | (bt(asic3_hold, 9) << 5)
+ | (bt(asic3_hold, 2) << 6)
+ | (bt(asic3_hold, 5) << 7);
+ break;
+ case 0x20: res = 0x49; break;
+ case 0x21: res = 0x47; break;
+ case 0x22: res = 0x53; break;
+ case 0x24: res = 0x41; break;
+ case 0x25: res = 0x41; break;
+ case 0x26: res = 0x7f; break;
+ case 0x27: res = 0x41; break;
+ case 0x28: res = 0x41; break;
+ case 0x2a: res = 0x3e; break;
+ case 0x2b: res = 0x41; break;
+ case 0x2c: res = 0x49; break;
+ case 0x2d: res = 0xf9; break;
+ case 0x2e: res = 0x0a; break;
+ case 0x30: res = 0x26; break;
+ case 0x31: res = 0x49; break;
+ case 0x32: res = 0x49; break;
+ case 0x33: res = 0x49; break;
+ case 0x34: res = 0x32; break;
+ }
+
+ return res;
+}
+
+WRITE16_HANDLER( pgm_asic3_w )
+{
+ if(ACCESSING_LSB)
+ {
+ if(asic3_reg < 3)
+ asic3_latch[asic3_reg] = data << 1;
+ else if(asic3_reg == 0xa0) {
+ asic3_hold = 0;
+ } else if(asic3_reg == 0x40) {
+ asic3_h2 = asic3_h1;
+ asic3_h1 = data;
+ } else if(asic3_reg == 0x48) {
+ asic3_x = 0;
+ if(!(asic3_h2 & 0x0a))
+ asic3_x |= 8;
+ if(!(asic3_h2 & 0x90))
+ asic3_x |= 4;
+ if(!(asic3_h1 & 0x06))
+ asic3_x |= 2;
+ if(!(asic3_h1 & 0x90))
+ asic3_x |= 1;
+ } else if(asic3_reg >= 0x80 && asic3_reg <= 0x87) {
+ asic3_y = asic3_reg & 7;
+ asic3_z = data;
+ asic3_compute_hold();
+ }
+ }
+}
+
+WRITE16_HANDLER( pgm_asic3_reg_w )
+{
+ if(ACCESSING_LSB)
+ asic3_reg = data & 0xff;
+}
+
+/*** Knights of Valour / Sango / PhotoY2k Protection (from ElSemi) (ASIC28) ***/
+
+static UINT16 ASIC28KEY;
+static UINT16 ASIC28REGS[10];
+static UINT16 ASICPARAMS[256];
+static UINT16 ASIC28RCNT=0;
+static const UINT32 B0TABLE[16]={2,0,1,4,3}; //maps char portraits to tables
+
+// photo2yk bonus stage
+static const UINT32 AETABLE[16]={0x00,0x0a,0x14,
+ 0x01,0x0b,0x15,
+ 0x02,0x0c,0x16};
+
+//Not sure if BATABLE is complete
+static const UINT32 BATABLE[0x40]=
+ {0x00,0x29,0x2c,0x35,0x3a,0x41,0x4a,0x4e, //0x00
+ 0x57,0x5e,0x77,0x79,0x7a,0x7b,0x7c,0x7d, //0x08
+ 0x7e,0x7f,0x80,0x81,0x82,0x85,0x86,0x87, //0x10
+ 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x90, //0x18
+ 0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,
+ 0x9e,0xa3,0xd4,0xa9,0xaf,0xb5,0xbb,0xc1};
+
+static UINT32 E0REGS[16];
+
+
+READ16_HANDLER (sango_protram_r)
+{
+
+
+ // at offset == 4 is region (supplied by device)
+ // 0 = china
+ // 1 = taiwan
+ // 2 = japan
+ // 3 = korea
+ // 4 = hong kong
+ // 5 = world
+
+ if (offset == 4) return readinputport(4);
+
+ // otherwise it doesn't seem to use the ram for anything important, we return 0 to avoid test mode corruption
+ // kovplus reads from offset 000e a lot ... why?
+#ifdef MAME_DEBUG
+ popmessage ("protection ram r %04x",offset);
+#endif
+ return 0x0000;
+}
+
+static UINT32 photoy2k_seqpos;
+static UINT32 photoy2k_trf[3], photoy2k_soff;
+
+#define BITSWAP10(val,B9,B8,B7,B6,B5,B4,B3,B2,B1,B0) \
+ ((BIT(val, B9) << 9) | \
+ (BIT(val, B8) << 8) | \
+ (BIT(val, B7) << 7) | \
+ (BIT(val, B6) << 6) | \
+ (BIT(val, B5) << 5) | \
+ (BIT(val, B4) << 4) | \
+ (BIT(val, B3) << 3) | \
+ (BIT(val, B2) << 2) | \
+ (BIT(val, B1) << 1) | \
+ (BIT(val, B0) << 0))
+
+static UINT32 photoy2k_spritenum(void)
+{
+ UINT32 base = photoy2k_seqpos & 0xffc00;
+ UINT32 low = photoy2k_seqpos & 0x003ff;
+
+ switch((photoy2k_seqpos >> 10) & 0xf) {
+ case 0x0:
+ case 0xa:
+ return base | (BITSWAP10(low, 0,8,3,1,5,9,4,2,6,7) ^ 0x124);
+ case 0x1:
+ case 0xb:
+ return base | (BITSWAP10(low, 5,1,7,4,0,8,3,6,9,2) ^ 0x088);
+ case 0x2:
+ case 0x8:
+ return base | (BITSWAP10(low, 3,5,9,7,6,4,1,8,2,0) ^ 0x011);
+ case 0x3:
+ case 0x9:
+ return base | (BITSWAP10(low, 1,8,3,6,0,4,5,2,9,7) ^ 0x154);
+ case 0x4:
+ case 0xe:
+ return base | (BITSWAP10(low, 2,1,7,4,5,8,3,6,9,0) ^ 0x0a9);
+ case 0x5:
+ case 0xf:
+ return base | (BITSWAP10(low, 9,4,6,8,2,1,7,5,3,0) ^ 0x201);
+ case 0x6:
+ case 0xd:
+ return base | (BITSWAP10(low, 4,6,0,8,9,7,3,5,1,2) ^ 0x008);
+ case 0x7:
+ case 0xc:
+ return base | (BITSWAP10(low, 8,9,3,2,0,1,6,7,5,4) ^ 0x000);
+ }
+ return 0;
+}
+
+READ16_HANDLER (ASIC28_r16)
+//UINT16 ASIC28_r16(UINT32 addr)
+{
+ UINT32 val=(ASIC28REGS[1]<<16)|(ASIC28REGS[0]);
+
+//logerror("Asic28 Read PC = %06x Command = %02x ??\n",activecpu_get_pc(), ASIC28REGS[1]);
+
+ switch(ASIC28REGS[1]&0xff)
+ {
+
+ case 0x20: // PhotoY2k spritenum conversion 4/4
+ if(!ASIC28RCNT)
+ logerror("ASIC28: PhotoY2K spr4 %04x %06x (%06x)\n", val & 0xffff, photoy2k_trf[2], activecpu_get_pc());
+ val = photoy2k_soff >> 16;
+ break;
+
+ case 0x21: // PhotoY2k spritenum conversion 3/4
+ if(!ASIC28RCNT) {
+ extern const UINT32 pgmy2ks[];
+ photoy2k_trf[2] = val & 0xffff;
+ logerror("ASIC28: PhotoY2K spr3 %04x %06x (%06x)\n", val & 0xffff, photoy2k_trf[1], activecpu_get_pc());
+ if(photoy2k_trf[0] < 0x3c00)
+ photoy2k_soff = pgmy2ks[photoy2k_trf[0]];
+ else
+ photoy2k_soff = 0;
+ logerror("ASIC28: spriteval %04x, %06x -> %06x\n", photoy2k_trf[0], (photoy2k_trf[2]<<16)|photoy2k_trf[1], photoy2k_soff);
+ }
+ val = photoy2k_soff & 0xffff;
+ break;
+
+ case 0x22: // PhotoY2k spritenum conversion 2/4
+ if(!ASIC28RCNT) {
+ photoy2k_trf[1] = val & 0xffff;
+ logerror("ASIC28: PhotoY2K spr2 %04x %06x (%06x)\n", val & 0xffff, photoy2k_trf[0], activecpu_get_pc());
+ }
+ val = photoy2k_trf[0] | 0x880000;
+ break;
+
+ case 0x23: // PhotoY2k spritenum conversion 1/4
+ if(!ASIC28RCNT) {
+ photoy2k_trf[0] = val & 0xffff;
+ logerror("ASIC28: PhotoY2K spr1 %04x (%06x)\n", val & 0xffff, activecpu_get_pc());
+ }
+ val = 0x880000;
+ break;
+
+ case 0x30: // PhotoY2k next element
+ if(!ASIC28RCNT)
+ photoy2k_seqpos++;
+ val = photoy2k_spritenum();
+ if(!ASIC28RCNT)
+ logerror("ASIC28: PhotoY2K seq_next %05x -> %06x (%06x)\n", photoy2k_seqpos, val, activecpu_get_pc());
+ break;
+
+ case 0x32: // PhotoY2k start of sequence
+ if(!ASIC28RCNT)
+ photoy2k_seqpos = (val & 0xffff) << 4;
+ val = photoy2k_spritenum();
+ if(!ASIC28RCNT)
+ logerror("ASIC28: PhotoY2K seq_start %05x -> %06x (%06x)\n", photoy2k_seqpos, val, activecpu_get_pc());
+ break;
+
+ case 0x99:
+ val=0x880000;
+ break;
+
+ case 0x9d: // spr palette
+ val=0xa00000+((ASIC28REGS[0]&0x1f)<<6);
+ break;
+
+ case 0xae: //Photo Y2k Bonus stage
+ val=AETABLE[ASIC28REGS[0]&0xf];
+ break;
+
+ case 0xb0:
+ val=B0TABLE[ASIC28REGS[0]&0xf];
+ break;
+
+ case 0xb4:
+ {
+ int v2=ASIC28REGS[0]&0x0f;
+ int v1=(ASIC28REGS[0]&0x0f00)>>8;
+// UINT16 tmp=E0REGS[v2];
+ //E0REGS[v2]=E0REGS[v1];
+ //E0REGS[v1]=tmp;
+ if(ASIC28REGS[0]==0x102)
+ E0REGS[1]=E0REGS[0];
+ else
+ E0REGS[v1]=E0REGS[v2];
+
+ val=0x880000;
+ }
+ break;
+
+ case 0xba:
+ val=BATABLE[ASIC28REGS[0]&0x3f];
+ if(ASIC28REGS[0]>0x2f)
+ {
+// PutMessage("Unmapped BA com, report ElSemi",60);
+ popmessage ("Unmapped BA com %02x, contact ElSemi / MameDev", ASIC28REGS[0]);
+ }
+ break;
+
+ case 0xc0:
+ val=0x880000;
+ break;
+
+ case 0xc3: //TXT tile position Uses C0 to select column
+ {
+ val=0x904000+(ASICPARAMS[0xc0]+ASICPARAMS[0xc3]*64)*4;
+ }
+ break;
+
+ case 0xcb:
+ val=0x880000;
+ break;
+
+ case 0xcc: //BG
+ {
+ int y=ASICPARAMS[0xcc];
+ if(y&0x400) //y is signed (probably x too and it also applies to TXT, but I've never seen it used)
+ y=-(0x400-(y&0x3ff));
+ val=0x900000+(((ASICPARAMS[0xcb]+(y)*64)*4)/*&0x1fff*/);
+ }
+ break;
+
+ case 0xd0: //txt palette
+ val=0xa01000+(ASIC28REGS[0]<<5);
+ break;
+
+ case 0xd6: //???? check it
+ {
+ int v2=ASIC28REGS[0]&0xf;
+// int v1=(ASIC28REGS[0]&0xf0)>>4;
+ E0REGS[0]=E0REGS[v2];
+ //E0REGS[v2]=0;
+ val=0x880000;
+ }
+ break;
+
+ case 0xdc: //bg palette
+ val=0xa00800+(ASIC28REGS[0]<<6);
+ break;
+
+ case 0xe0: //spr palette
+ val=0xa00000+((ASIC28REGS[0]&0x1f)<<6);
+ break;
+
+ case 0xe5:
+ val=0x880000;
+ break;
+
+ case 0xe7:
+ val=0x880000;
+ break;
+
+ case 0xf0:
+ {
+ val=0x00C000;
+ }
+ break;
+
+ case 0xf8:
+ val=E0REGS[ASIC28REGS[0]&0xf]&0xffffff;
+ break;
+
+ case 0xfc: //Adjust damage level to char experience level
+ {
+ val=(ASICPARAMS[0xfc]*ASICPARAMS[0xfe])>>6;
+ break;
+ }
+
+ case 0xfe: //todo
+ val=0x880000;
+ break;
+
+
+ default:
+ {
+ val=0x880000;
+ }
+ }
+
+// if(addr==0x500000)
+ if(offset==0)
+ {
+ UINT16 d=val&0xffff;
+ UINT16 realkey;
+ realkey=ASIC28KEY>>8;
+ realkey|=ASIC28KEY;
+ d^=realkey;
+ return d;
+ }
+// else if(addr==0x500002)
+ else if(offset==1)
+ {
+ UINT16 d=val>>16;
+ UINT16 realkey;
+ realkey=ASIC28KEY>>8;
+ realkey|=ASIC28KEY;
+ d^=realkey;
+ ASIC28RCNT++;
+ if(!(ASIC28RCNT&0xf))
+ {
+ ASIC28KEY+=0x100;
+ ASIC28KEY&=0xFF00;
+ }
+ return d;
+ }
+ return 0xff;
+}
+
+WRITE16_HANDLER (ASIC28_w16)
+//void ASIC28_w16(UINT32 addr,UINT16 data)
+{
+// if(addr==0x500000)
+ if(offset==0)
+ {
+ UINT16 realkey;
+ realkey=ASIC28KEY>>8;
+ realkey|=ASIC28KEY;
+ data^=realkey;
+ ASIC28REGS[0]=data;
+ return;
+ }
+// if(addr==0x500002)
+ if(offset==1)
+ {
+ UINT16 realkey;
+
+ ASIC28KEY=data&0xff00;
+
+ realkey=ASIC28KEY>>8;
+ realkey|=ASIC28KEY;
+ data^=realkey;
+ ASIC28REGS[1]=data;
+// ErrorLogMessage("ASIC28 CMD %X PARAM %X",ASIC28REGS[1],ASIC28REGS[0]);
+ logerror("ASIC28 CMD %04x PARAM %04x\n",ASIC28REGS[1],ASIC28REGS[0]);
+
+ ASICPARAMS[ASIC28REGS[1]&0xff]=ASIC28REGS[0];
+ if(ASIC28REGS[1]==0xE7)
+ {
+ UINT32 E0R=(ASICPARAMS[0xE7]>>12)&0xf;
+ E0REGS[E0R]&=0xffff;
+ E0REGS[E0R]|=ASIC28REGS[0]<<16;
+ }
+ if(ASIC28REGS[1]==0xE5)
+ {
+ UINT32 E0R=(ASICPARAMS[0xE7]>>12)&0xf;
+ E0REGS[E0R]&=0xff0000;
+ E0REGS[E0R]|=ASIC28REGS[0];
+ }
+ ASIC28RCNT=0;
+ }
+}
+
+/* Dragon World 2 */
+
+#define DW2BITSWAP(s,d,bs,bd) d=((d&(~(1<<bd)))|(((s>>bs)&1)<<bd))
+//Use this handler for reading from 0xd80000-0xd80002
+READ16_HANDLER (dw2_d80000_r )
+{
+//addr&=0xff;
+// if(dw2reg<0x20) //NOT SURE!!
+ {
+ //The value at 0x80EECE is computed in the routine at 0x107c18
+ UINT16 d=pgm_mainram[0xEECE/2];
+ UINT16 d2=0;
+ d=(d>>8)|(d<<8);
+ DW2BITSWAP(d,d2,7 ,0);
+ DW2BITSWAP(d,d2,4 ,1);
+ DW2BITSWAP(d,d2,5 ,2);
+ DW2BITSWAP(d,d2,2 ,3);
+ DW2BITSWAP(d,d2,15,4);
+ DW2BITSWAP(d,d2,1 ,5);
+ DW2BITSWAP(d,d2,10,6);
+ DW2BITSWAP(d,d2,13,7);
+ // ... missing bitswaps here (8-15) there is not enough data to know them
+ // the code only checks the lowest 8 bytes
+ return d2;
+ }
+}
+
+/* Dragon World 3
+
+Dragon World 3 has 2 protection chips
+ASIC022 and ASIC025
+one of them also has an external data rom (encrypted?)
+
+code below is ElSemi's preliminary code, it doesn't work properly and isn't used, much of the protection isn't understood */
+
+#if 0
+AddWriteArea(0xda0000,0xdaffff,0,dw3_w8,dw3_w16,dw3_w32);
+AddReadArea (0xda0000,0xdaffff,0,dw3_r8,dw3_r16,dw3_r32);
+
+#define DW3BITSWAP(s,d,bs,bd) d=((d&(~(1<<bd)))|(((s>>bs)&1)<<bd))
+
+UINT16 dw3_Rw[8];
+UINT8 *dw3_R=(UINT8 *) dw3_Rw;
+
+UINT8 dw3_r8(UINT32 addr)
+{
+ if(addr>=0xDA5610 && addr<=0xDA5613)
+ return *((UINT8 *) (dw3_R+((addr-0xDA5610)^1)));
+ return 0;
+}
+
+UINT16 dw3_r16(UINT32 addr)
+{
+ if(addr>=0xDA5610 && addr<=0xDA5613)
+ return *((UINT16 *) (dw3_R+(addr-0xDA5610)));
+ return 0;
+}
+
+UINT32 dw3_r32(UINT32 addr)
+{
+ return 0;
+}
+
+void dw3_w8(UINT32 addr,UINT8 val)
+{
+ if(addr==0xDA5610)
+ dw3_R[1]=val;
+ if(addr==0xDA5611)
+ dw3_R[0]=val;
+ if(addr==0xDA5612)
+ dw3_R[3]=val;
+ if(addr==0xDA5613)
+ dw3_R[2]=val;
+}
+
+void dw3_w16(UINT32 addr,UINT16 val)
+{
+ if(addr>=0xDA5610 && addr<=0xDA5613)
+ {
+ UINT16 *s=((UINT16 *) (dw3_R+(addr-0xDA5610)));
+ *s=val;
+ if(addr==0xDA5610)
+ {
+ if(val==1)
+ {
+ UINT16 v1=dw3_Rw[1];
+ UINT16 v2=0;
+ DW3BITSWAP(v1,v2,0,0);
+ DW3BITSWAP(v1,v2,1,1);
+ DW3BITSWAP(v1,v2,7,2);
+ DW3BITSWAP(v1,v2,6,3);
+ DW3BITSWAP(v1,v2,5,4);
+ DW3BITSWAP(v1,v2,4,5);
+ DW3BITSWAP(v1,v2,3,6);
+ DW3BITSWAP(v1,v2,2,7);
+
+ dw3_Rw[1]=v2;
+ }
+ }
+ }
+
+}
+
+
+void dw3_w32(UINT32 addr,UINT32 val)
+{
+
+}
+#endif
+
+
+