summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/namcos1.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/machine/namcos1.c')
-rw-r--r--src/mame/machine/namcos1.c1430
1 files changed, 1430 insertions, 0 deletions
diff --git a/src/mame/machine/namcos1.c b/src/mame/machine/namcos1.c
new file mode 100644
index 00000000000..ef4349ab30a
--- /dev/null
+++ b/src/mame/machine/namcos1.c
@@ -0,0 +1,1430 @@
+#include "driver.h"
+#include "sound/ym2151.h"
+#include "sound/namco.h"
+
+#define NAMCOS1_MAX_BANK 0x400
+
+/* from video */
+READ8_HANDLER( namcos1_videoram_r );
+WRITE8_HANDLER( namcos1_videoram_w );
+WRITE8_HANDLER( namcos1_paletteram_w );
+READ8_HANDLER( namcos1_spriteram_r );
+WRITE8_HANDLER( namcos1_spriteram_w );
+extern void namcos1_set_scroll_offsets( const int *bgx, const int *bgy, int negative, int optimize );
+extern void namcos1_set_sprite_offsets( int x, int y );
+
+UINT8 *namcos1_paletteram;
+
+static UINT8 *namcos1_triram;
+static UINT8 *s1ram;
+
+
+/*******************************************************************************
+* *
+* BANK area handling *
+* *
+*******************************************************************************/
+
+/* Bank handler definitions */
+typedef struct
+{
+ read8_handler bank_handler_r;
+ write8_handler bank_handler_w;
+ int bank_offset;
+ UINT8 *bank_pointer;
+} bankhandler;
+
+/* hardware elements of 1Mbytes physical memory space */
+static bankhandler namcos1_bank_element[NAMCOS1_MAX_BANK];
+static bankhandler namcos1_active_bank[16];
+
+static READ8_HANDLER( bank1_r ) { return (*namcos1_active_bank[0].bank_handler_r )(offset + namcos1_active_bank[0].bank_offset); }
+static READ8_HANDLER( bank2_r ) { return (*namcos1_active_bank[1].bank_handler_r )(offset + namcos1_active_bank[1].bank_offset); }
+static READ8_HANDLER( bank3_r ) { return (*namcos1_active_bank[2].bank_handler_r )(offset + namcos1_active_bank[2].bank_offset); }
+static READ8_HANDLER( bank4_r ) { return (*namcos1_active_bank[3].bank_handler_r )(offset + namcos1_active_bank[3].bank_offset); }
+static READ8_HANDLER( bank5_r ) { return (*namcos1_active_bank[4].bank_handler_r )(offset + namcos1_active_bank[4].bank_offset); }
+static READ8_HANDLER( bank6_r ) { return (*namcos1_active_bank[5].bank_handler_r )(offset + namcos1_active_bank[5].bank_offset); }
+static READ8_HANDLER( bank7_r ) { return (*namcos1_active_bank[6].bank_handler_r )(offset + namcos1_active_bank[6].bank_offset); }
+static READ8_HANDLER( bank8_r ) { return (*namcos1_active_bank[7].bank_handler_r )(offset + namcos1_active_bank[7].bank_offset); }
+static READ8_HANDLER( bank9_r ) { return (*namcos1_active_bank[8].bank_handler_r )(offset + namcos1_active_bank[8].bank_offset); }
+static READ8_HANDLER( bank10_r ) { return (*namcos1_active_bank[9].bank_handler_r )(offset + namcos1_active_bank[9].bank_offset); }
+static READ8_HANDLER( bank11_r ) { return (*namcos1_active_bank[10].bank_handler_r)(offset + namcos1_active_bank[10].bank_offset); }
+static READ8_HANDLER( bank12_r ) { return (*namcos1_active_bank[11].bank_handler_r)(offset + namcos1_active_bank[11].bank_offset); }
+static READ8_HANDLER( bank13_r ) { return (*namcos1_active_bank[12].bank_handler_r)(offset + namcos1_active_bank[12].bank_offset); }
+static READ8_HANDLER( bank14_r ) { return (*namcos1_active_bank[13].bank_handler_r)(offset + namcos1_active_bank[13].bank_offset); }
+static READ8_HANDLER( bank15_r ) { return (*namcos1_active_bank[14].bank_handler_r)(offset + namcos1_active_bank[14].bank_offset); }
+static READ8_HANDLER( bank16_r ) { return (*namcos1_active_bank[15].bank_handler_r)(offset + namcos1_active_bank[15].bank_offset); }
+
+static WRITE8_HANDLER( bank1_w ) { (*namcos1_active_bank[0].bank_handler_w )(offset + namcos1_active_bank[0].bank_offset, data); }
+static WRITE8_HANDLER( bank2_w ) { (*namcos1_active_bank[1].bank_handler_w )(offset + namcos1_active_bank[1].bank_offset, data); }
+static WRITE8_HANDLER( bank3_w ) { (*namcos1_active_bank[2].bank_handler_w )(offset + namcos1_active_bank[2].bank_offset, data); }
+static WRITE8_HANDLER( bank4_w ) { (*namcos1_active_bank[3].bank_handler_w )(offset + namcos1_active_bank[3].bank_offset, data); }
+static WRITE8_HANDLER( bank5_w ) { (*namcos1_active_bank[4].bank_handler_w )(offset + namcos1_active_bank[4].bank_offset, data); }
+static WRITE8_HANDLER( bank6_w ) { (*namcos1_active_bank[5].bank_handler_w )(offset + namcos1_active_bank[5].bank_offset, data); }
+static WRITE8_HANDLER( bank7_w ) { (*namcos1_active_bank[6].bank_handler_w )(offset + namcos1_active_bank[6].bank_offset, data); }
+static WRITE8_HANDLER( bank8_w ) { (*namcos1_active_bank[7].bank_handler_w )(offset + namcos1_active_bank[7].bank_offset, data); }
+static WRITE8_HANDLER( bank9_w ) { (*namcos1_active_bank[8].bank_handler_w )(offset + namcos1_active_bank[8].bank_offset, data); }
+static WRITE8_HANDLER( bank10_w ) { (*namcos1_active_bank[9].bank_handler_w )(offset + namcos1_active_bank[9].bank_offset, data); }
+static WRITE8_HANDLER( bank11_w ) { (*namcos1_active_bank[10].bank_handler_w)(offset + namcos1_active_bank[10].bank_offset, data); }
+static WRITE8_HANDLER( bank12_w ) { (*namcos1_active_bank[11].bank_handler_w)(offset + namcos1_active_bank[11].bank_offset, data); }
+static WRITE8_HANDLER( bank13_w ) { (*namcos1_active_bank[12].bank_handler_w)(offset + namcos1_active_bank[12].bank_offset, data); }
+static WRITE8_HANDLER( bank14_w ) { (*namcos1_active_bank[13].bank_handler_w)(offset + namcos1_active_bank[13].bank_offset, data); }
+static WRITE8_HANDLER( bank15_w ) { (*namcos1_active_bank[14].bank_handler_w)(offset + namcos1_active_bank[14].bank_offset, data); }
+static WRITE8_HANDLER( bank16_w ) { (*namcos1_active_bank[15].bank_handler_w)(offset + namcos1_active_bank[15].bank_offset, data); }
+
+static const read8_handler ram_bank_handler_r[16] =
+{
+ MRA8_BANK1 ,MRA8_BANK2 ,MRA8_BANK3 ,MRA8_BANK4 ,
+ MRA8_BANK5 ,MRA8_BANK6 ,MRA8_BANK7 ,MRA8_BANK8 ,
+ MRA8_BANK9 ,MRA8_BANK10,MRA8_BANK11,MRA8_BANK12,
+ MRA8_BANK13,MRA8_BANK14,MRA8_BANK15,MRA8_BANK16
+};
+
+static const write8_handler ram_bank_handler_w[16] =
+{
+ MWA8_BANK1 ,MWA8_BANK2 ,MWA8_BANK3 ,MWA8_BANK4 ,
+ MWA8_BANK5 ,MWA8_BANK6 ,MWA8_BANK7 ,MWA8_BANK8 ,
+ MWA8_BANK9 ,MWA8_BANK10,MWA8_BANK11,MWA8_BANK12,
+ MWA8_BANK13,MWA8_BANK14,MWA8_BANK15,MWA8_BANK16
+};
+
+static const read8_handler io_bank_handler_r[16] =
+{
+ bank1_r, bank2_r, bank3_r, bank4_r,
+ bank5_r, bank6_r, bank7_r, bank8_r,
+ bank9_r, bank10_r, bank11_r, bank12_r,
+ bank13_r, bank14_r, bank15_r, bank16_r
+};
+
+static const write8_handler io_bank_handler_w[16] =
+{
+ bank1_w, bank2_w, bank3_w, bank4_w,
+ bank5_w, bank6_w, bank7_w, bank8_w,
+ bank9_w, bank10_w, bank11_w, bank12_w,
+ bank13_w, bank14_w, bank15_w, bank16_w
+};
+
+
+
+static WRITE8_HANDLER( namcos1_3dcs_w )
+{
+ if (offset & 1) popmessage("LEFT");
+ else popmessage("RIGHT");
+}
+
+
+
+static int key_id,key_reg,key_rng,key_swap4_arg,key_swap4,key_bottom4,key_top4;
+static UINT8 key[8];
+
+
+static READ8_HANDLER( no_key_r )
+{
+ popmessage("CPU #%d PC %08x: keychip read %04x\n",cpu_getactivecpu(),activecpu_get_pc(),offset);
+ return 0;
+}
+
+static WRITE8_HANDLER( no_key_w )
+{
+ popmessage("CPU #%d PC %08x: keychip write %04x=%02x\n",cpu_getactivecpu(),activecpu_get_pc(),offset,data);
+}
+
+
+/*****************************************************************************
+
+ Key custom type 1 (CUS136, CUS143, CUS144)
+
+ 16/8 bit division + key no.
+
+*****************************************************************************/
+
+/*
+the startup checks are the same in the three games using this kind of chip,
+apart from the [operating mode?] values written.
+
+dspirit: (CUS136)
+CPU #0 PC da06: keychip write 0000=01 [maybe to initialize chip?]
+CPU #0 PC da09: keychip read 0003 [return key no.]
+CPU #0 PC da14: keychip write 0003=f2 [operating mode?]
+CPU #0 PC da1d: keychip write 0000=xx [ \ operands]
+CPU #0 PC da22: keychip write 0001=xx [ " " ]
+CPU #0 PC da22: keychip write 0002=xx [ " " ]
+CPU #0 PC da25: keychip read 0001 [ division result (verified to be correct)]
+CPU #0 PC da25: keychip read 0002 [ " " (verified to be correct)]
+CPU #0 PC da28: keychip read 0000 [ / " " (verified to be correct)]
+CPU #0 PC daf6: keychip write 0003=c2 [operating mode?]
+CPU #0 PC dafa: keychip write 0002=00-ff [???????]
+CPU #0 PC db00: keychip read 0003 [???? - stored in 0001]
+CPU #0 PC db07: keychip write 0001=82-ff [ \ ???????]
+CPU #0 PC db07: keychip write 0002=8d [ / ???????]
+CPU #0 PC db0d: keychip read 0003 [???? - stored in 0002]
+CPU #0 PC db14: keychip read 0001 [ \ ???????]
+CPU #0 PC db14: keychip read 0002 [ ???????]
+CPU #0 PC db17: keychip write 0001=xx [ ???????]
+CPU #0 PC db17: keychip write 0002=xx [ / ???????]
+CPU #0 PC db1d: keychip read 0001 [???? - stored in 0003]
+CPU #0 PC db1d: keychip read 0002 [???? - stored in 0004]
+CPU #0 PC db24: keychip write 0003=f2 [operating mode?]
+---- end of common checks
+CPU #0 PC 8191: keychip write 0003=01 [????]
+CPU #0 PC 8196: keychip write 0000=40 [ \ operands]
+CPU #0 PC 819c: keychip write 0002=00 [ " " ]
+CPU #0 PC 819f: keychip write 0001=04 [ " " ]
+CPU #0 PC 81a2: keychip read 0001 [ division result (verified to be correct)]
+CPU #0 PC 81a2: keychip read 0002 [ / " " (verified to be correct)]
+if division result is wrong, reads again key no. from 03, and doesn't crash if it's correct
+
+wldcourt: (CUS143)
+CPU #0 PC db0a: keychip write 0000=01 [maybe to initialize chip?]
+CPU #0 PC db0d: keychip read 0003 [return key no.]
+CPU #0 PC db18: keychip write 0003=d9 [operating mode?]
+CPU #0 PC db21: keychip write 0000=xx [ \ operands]
+CPU #0 PC db26: keychip write 0001=xx [ " " ]
+CPU #0 PC db26: keychip write 0002=xx [ " " ]
+CPU #0 PC db29: keychip read 0001 [ division result (verified to be correct)]
+CPU #0 PC db29: keychip read 0002 [ " " (verified to be correct)]
+CPU #0 PC db2c: keychip read 0000 [ / " " (verified to be correct)]
+CPU #0 PC dbfa: keychip write 0003=db [operating mode?]
+CPU #0 PC dbfe: keychip write 0002=00-ff [???????]
+CPU #0 PC dc04: keychip read 0003 [???? - stored in 0001]
+CPU #0 PC dc0b: keychip write 0001=82-ff [ \ ???????]
+CPU #0 PC dc0b: keychip write 0002=8d [ / ???????]
+CPU #0 PC dc11: keychip read 0003 [???? - stored in 0002]
+CPU #0 PC dc18: keychip read 0001 [ \ ???????]
+CPU #0 PC dc18: keychip read 0002 [ ???????]
+CPU #0 PC dc1b: keychip write 0001=xx [ ???????]
+CPU #0 PC dc1b: keychip write 0002=xx [ / ???????]
+CPU #0 PC dc21: keychip read 0001 [???? - stored in 0003]
+CPU #0 PC dc21: keychip read 0002 [???? - stored in 0004]
+CPU #0 PC dc28: keychip write 0003=d9 [operating mode?]
+---- end of common checks
+CPU #0 PC e31c: keychip read 0003 [return key no.]
+
+blazer: (CUS144)
+CPU #0 PC da0b: keychip write 0000=01 [maybe to initialize chip?]
+CPU #0 PC da0e: keychip read 0003 [return key no.]
+CPU #0 PC da19: keychip write 0003=b7 [operating mode?]
+CPU #0 PC da22: keychip write 0000=12 [ \ operands]
+CPU #0 PC da27: keychip write 0001=0a [ " " ]
+CPU #0 PC da27: keychip write 0002=95 [ " " ]
+CPU #0 PC da2a: keychip read 0001 [ division result (verified to be correct)]
+CPU #0 PC da2a: keychip read 0002 [ " " (verified to be correct)]
+CPU #0 PC da2d: keychip read 0000 [ / " " (verified to be correct)]
+CPU #0 PC dafb: keychip write 0003=b6 [operating mode?]
+CPU #0 PC daff: keychip write 0002=00-ff [???????]
+CPU #0 PC db05: keychip read 0003 [???? - stored in 0001]
+CPU #0 PC db0c: keychip write 0001=82-ff [ \ ???????]
+CPU #0 PC db0c: keychip write 0002=8d [ / ???????]
+CPU #0 PC db12: keychip read 0003 [???? - stored in 0002]
+CPU #0 PC db19: keychip read 0001 [ \ ???????]
+CPU #0 PC db19: keychip read 0002 [ ???????]
+CPU #0 PC db1c: keychip write 0001=xx [ ???????]
+CPU #0 PC db1c: keychip write 0002=xx [ / ???????]
+CPU #0 PC db22: keychip read 0001 [???? - stored in 0003]
+CPU #0 PC db22: keychip read 0002 [???? - stored in 0004]
+CPU #0 PC db29: keychip write 0003=b7 [operating mode?]
+---- end of common checks
+
+puzlclub:
+CPU #0 PC e017: keychip write 0003=35 [they probably used RAM instead of a key chip for this prototype]
+CPU #0 PC e3d4: keychip read 0003 [AND #$37 = key no.]
+*/
+static READ8_HANDLER( key_type1_r )
+{
+// logerror("CPU #%d PC %04x: keychip read %04x\n",cpu_getactivecpu(),activecpu_get_pc(),offset);
+
+ if (offset < 3)
+ {
+ int d = key[0];
+ int n = (key[1] << 8) | key[2];
+ int q,r;
+
+ if (d)
+ {
+ q = n / d;
+ r = n % d;
+ }
+ else
+ {
+ q = 0xffff;
+ r = 0x00;
+ }
+
+ if (offset == 0) return r;
+ if (offset == 1) return q >> 8;
+ if (offset == 2) return q & 0xff;
+ }
+ else if (offset == 3)
+ return key_id;
+
+ return 0;
+}
+
+static WRITE8_HANDLER( key_type1_w )
+{
+// logerror("CPU #%d PC %04x: keychip write %04x=%02x\n",cpu_getactivecpu(),activecpu_get_pc(),offset,data);
+
+ if (offset < 4)
+ key[offset] = data;
+}
+
+
+/*****************************************************************************
+
+ Key custom type 2 (CUS151 - CUS155)
+
+ 16/16 bit division + key no.
+
+*****************************************************************************/
+
+/*
+pacmania: (CUS151)
+CPU #0 PC dac2: keychip write 0004=4b [operating mode?]
+CPU #0 PC dac5: keychip read 0004 [AND #$37 = key no.]
+CPU #0 PC dad9: keychip write 0000=xx
+CPU #0 PC dad9: keychip write 0001=xx
+CPU #0 PC dae0: keychip write 0002=xx
+CPU #0 PC dae0: keychip write 0003=xx
+CPU #0 PC dae4: keychip read 0000
+CPU #0 PC dae4: keychip read 0001
+CPU #0 PC daed: keychip read 0002
+CPU #0 PC daed: keychip read 0003
+CPU #1 PC f188: keychip write 0004=4b [operating mode?]
+CPU #1 PC f2d0: keychip write 0000=01
+CPU #1 PC f2d0: keychip write 0001=aa
+CPU #1 PC f30d: keychip write 0002=xx
+CPU #1 PC f30d: keychip write 0003=xx
+CPU #1 PC f310: keychip read 0003
+CPU #1 PC f55d: keychip write 0000=00
+CPU #1 PC f55d: keychip write 0001=10
+CPU #1 PC f562: keychip write 0004=4b [operating mode?]
+CPU #1 PC f5d3: keychip write 0002=xx
+CPU #1 PC f5d3: keychip write 0003=xx
+CPU #1 PC f5d6: keychip read 0003
+CPU #1 PC f5ef: keychip read 0001
+CPU #1 PC cbc6: keychip write 0000=00
+CPU #1 PC cbc6: keychip write 0001=02
+CPU #1 PC cbdd: keychip write 0002=xx
+CPU #1 PC cbdd: keychip write 0003=xx
+CPU #1 PC cbe8: keychip read 0002
+CPU #1 PC cbe8: keychip read 0003
+
+mmaze: (CUS152)
+CPU #0 PC 60f3: keychip write 0004=5b
+CPU #0 PC 60fe: keychip write 0000=00
+CPU #0 PC 60fe: keychip write 0001=01
+CPU #0 PC 6101: keychip write 0002=00
+CPU #0 PC 6101: keychip write 0003=01
+CPU #0 PC 6104: keychip read 0004
+CPU #0 PC 61ae: keychip write 0000=00
+CPU #0 PC 61ae: keychip write 0001=33
+CPU #0 PC 61b1: keychip write 0002=02
+CPU #0 PC 61b1: keychip write 0003=00
+CPU #0 PC 61b4: keychip read 0002
+CPU #0 PC 61b4: keychip read 0003
+CPU #0 PC 68fa: keychip write 0000=01
+CPU #0 PC 68fa: keychip write 0001=00
+CPU #0 PC 68fd: keychip write 0002=00
+CPU #0 PC 68fd: keychip write 0003=00
+CPU #0 PC 6900: keychip read 0002
+CPU #0 PC 6900: keychip read 0003
+CPU #0 PC bf6c: keychip write 0000=00
+CPU #0 PC bf6c: keychip write 0001=20
+CPU #0 PC bf6f: keychip write 0002=00
+CPU #0 PC bf6f: keychip write 0003=00
+CPU #0 PC bf72: keychip read 0002
+CPU #0 PC bf72: keychip read 0003
+CPU #0 PC 9576: keychip write 0000=00
+CPU #0 PC 9576: keychip write 0001=14
+CPU #0 PC 9579: keychip write 0002=00
+CPU #0 PC 9579: keychip write 0003=00
+CPU #0 PC 957c: keychip read 0002
+CPU #0 PC 957c: keychip read 0003
+CPU #0 PC 6538: keychip write 0000=00
+CPU #0 PC 6538: keychip write 0001=15
+CPU #0 PC 653b: keychip write 0002=00
+CPU #0 PC 653b: keychip write 0003=01
+CPU #0 PC 653e: keychip read 0002
+CPU #0 PC 653e: keychip read 0003
+
+galaga88: (CUS153)
+CPU #0 PC db02: keychip write 0004=2d [operating mode?]
+CPU #0 PC db05: keychip read 0004 [AND #$7F = key no.]
+CPU #0 PC db17: keychip write 0000=xx
+CPU #0 PC db17: keychip write 0001=xx
+CPU #0 PC db1e: keychip write 0002=xx
+CPU #0 PC db1e: keychip write 0003=xx
+CPU #0 PC db22: keychip read 0000
+CPU #0 PC db22: keychip read 0001
+CPU #0 PC db2b: keychip read 0002
+CPU #0 PC db2b: keychip read 0003
+CPU #0 PC e136: keychip write 0004=0c
+
+ws: (CUS154)
+CPU #0 PC e052: keychip write 0004=d3 [operating mode?]
+CPU #0 PC e82a: keychip read 0004 [AND #$3F = key no.]
+
+bakutotu: (CUS155)
+CPU #0 PC db38: keychip write 0004=03 [operating mode?]
+CPU #0 PC db3b: keychip read 0004 [AND #$37 = key no.]
+CPU #0 PC db4f: keychip write 0000=xx
+CPU #0 PC db4f: keychip write 0001=xx
+CPU #0 PC db56: keychip write 0002=xx
+CPU #0 PC db56: keychip write 0003=xx
+CPU #0 PC db5a: keychip read 0000
+CPU #0 PC db5a: keychip read 0001
+CPU #0 PC db63: keychip read 0002
+CPU #0 PC db63: keychip read 0003
+CPU #0 PC db70: keychip write 0004=0b
+CPU #0 PC db77: keychip write 0000=ff
+CPU #0 PC db77: keychip write 0001=ff
+CPU #0 PC db7e: keychip write 0002=ff
+CPU #0 PC db7e: keychip write 0003=ff
+CPU #0 PC db82: keychip read 0000
+CPU #0 PC db82: keychip read 0001
+CPU #0 PC db8b: keychip read 0002
+CPU #0 PC db8b: keychip read 0003
+CPU #0 PC db95: keychip write 0004=03
+CPU #0 PC e552: keychip read 0004 [AND #$3F = key no.]
+CPU #0 PC e560: keychip write 0000=00
+CPU #0 PC e560: keychip write 0001=73
+CPU #0 PC e566: keychip write 0002=a4
+CPU #0 PC e566: keychip write 0003=83
+CPU #0 PC e569: keychip read 0002
+CPU #0 PC e569: keychip read 0003
+CPU #0 PC e574: keychip read 0000
+CPU #0 PC e574: keychip read 0001
+
+*/
+
+static READ8_HANDLER( key_type2_r )
+{
+// logerror("CPU #%d PC %04x: keychip read %04x\n",cpu_getactivecpu(),activecpu_get_pc(),offset);
+
+ if (offset < 4)
+ {
+ int d = (key[0] << 8) | key[1];
+ int n = (key[2] << 8) | key[3];
+ int q,r;
+
+ if (d)
+ {
+ q = n / d;
+ r = n % d;
+ }
+ else
+ {
+ q = 0xffff;
+ r = 0x00;
+ }
+
+ if (offset == 0) return r >> 8;
+ if (offset == 1) return r & 0xff;
+ if (offset == 2) return q >> 8;
+ if (offset == 3) return q & 0xff;
+ }
+ else if (offset == 4)
+ return key_id;
+
+ return 0;
+}
+
+static WRITE8_HANDLER( key_type2_w )
+{
+// logerror("CPU #%d PC %04x: keychip write %04x=%02x\n",cpu_getactivecpu(),activecpu_get_pc(),offset,data);
+
+ if (offset < 5)
+ key[offset] = data;
+}
+
+
+/*****************************************************************************
+
+ Key custom type 3 (CUS181 - CUS185, CUS308 - CUS311)
+
+ Nibble swapper + rng + key no.
+
+*****************************************************************************/
+
+/*
+splatter: (CUS181)
+CPU #0 PC cd66: keychip write 003f=01 [maybe to initialize chip?]
+CPU #0 PC cd78: keychip read 004f [rng]
+CPU #0 PC cd91: keychip read 003f [key no.]
+CPU #0 PC f90c: keychip read 0036 [key no.]
+CPU #0 PC f91f: keychip read 0036 [key no.]
+
+rompers: (CUS182)
+CPU #0 PC b891: keychip read 0070 [key no.]
+
+blastoff: (CUS183)
+CPU #0 PC db4f: keychip read 0000 [key no.]
+CPU #0 PC db55: keychip read 0070 [rng?]
+CPU #0 PC db57: keychip write 0030=xx [ARG for 58]
+CPU #0 PC db60: keychip write 0858=xx [debug leftover?]
+CPU #0 PC db67: keychip read 0858 [debug leftover?]
+CPU #0 PC db69: keychip read 0058 [ARG >> 4) | (ARG << 4]
+CPU #0 PC e01a: keychip read 0000 [key no.]
+CPU #0 PC e021: keychip read 0070 [rng?]
+CPU #0 PC e024: keychip write 0030=xx [arg for 58]
+CPU #0 PC e037: keychip read 0058 [ARG >> 4) | (ARG << 4]
+CPU #0 PC 6989: keychip read 0000 [ignored]
+CPU #0 PC 6989: keychip read 0001 [ignored]
+
+ws89: (CUS184)
+CPU #0 PC e050: keychip read 0020 [key no.]
+CPU #0 PC e835: keychip read 0020 [key no.]
+
+tankfrce: (CUS185)
+CPU #0 PC c441: keychip read 0057 [key no.]
+CPU #0 PC c444: keychip write 0017=b9 [ARG for 2b]
+CPU #0 PC c447: keychip read 002b [0xb0 | (ARG & 0x0f)]
+CPU #0 PC f700: keychip read 0050 [key no.]
+
+dangseed: (CUS308)
+CPU #0 PC c628: keychip read 0067 [key no.]
+CPU #0 PC c62b: keychip write 0057=34 [ARG for 03]
+CPU #0 PC c62e: keychip read 0003 [0x30 | (ARG & 0x0f)]
+CPU #1 PC feb8: keychip write 0050=xx [ARG for 41 and 01]
+CPU #1 PC febb: keychip read 0041 [0x10 | (ARG >> 4)] used for stars display
+CPU #1 PC fec0: keychip read 0001 [0x10 | (ARG & 0x0f)] used for stars display
+CPU #1 PC f74d: keychip write 0050=xx [ARG for 40 and 00]
+CPU #1 PC f750: keychip read 0040 [0x00 | (ARG >> 4)] used for score display
+CPU #1 PC f755: keychip read 0000 [0x00 | (ARG & 0x0f)] used for score display
+CPU #1 PC c310: keychip write 0050=xx [ARG for 00]
+CPU #1 PC c31e: keychip read 0000 [0x00 | (ARG & 0x0f)] used for credits display
+
+pistoldm: (CUS309)
+CPU #0 PC c84a: keychip read 0017 [key no.]
+CPU #0 PC c84d: keychip write 0007=35 [ARG for 43]
+CPU #0 PC c850: keychip read 0043 [0x30 | (ARG & 0x0f)]
+CPU #0 PC cdef: keychip read 0020 [rng] used for several random events
+
+ws90: (CUS310)
+CPU #0 PC c82f: keychip read 0047 [key no.]
+CPU #0 PC c832: keychip write 007f=36 [ARG for 33]
+CPU #0 PC c835: keychip read 0033 [0x30 | (ARG & 0x0f)]
+CPU #0 PC e828: keychip read 0040 [key no.]
+
+soukobdx: (CUS311)
+CPU #0 PC ca90: keychip read 0027 [key no.]
+CPU #0 PC ca93: keychip write 0007=37 [ARG for 43]
+CPU #0 PC ca96: keychip read 0043 [0x30 | (ARG & 0x0f)]
+CPU #0 PC e45a: keychip read 0030 [discarded]
+*/
+
+static READ8_HANDLER( key_type3_r )
+{
+ int op;
+
+// logerror("CPU #%d PC %04x: keychip read %04x\n",cpu_getactivecpu(),activecpu_get_pc(),offset);
+
+ /* I need to handle blastoff's read from 0858. The game previously writes to 0858,
+ using it as temporary storage, so maybe it expects to act as RAM, however
+ it happens to work correctly also using the standard handling for 0058.
+ The schematics don't show A11 being used, so I go for this handling.
+ */
+ op = (offset & 0x70) >> 4;
+
+ if (op == key_reg) return key_id;
+ if (op == key_rng) return mame_rand(Machine);
+ if (op == key_swap4) return (key[key_swap4_arg] << 4) | (key[key_swap4_arg] >> 4);
+ if (op == key_bottom4) return (offset << 4) | (key[key_swap4_arg] & 0x0f);
+ if (op == key_top4) return (offset << 4) | (key[key_swap4_arg] >> 4);
+
+ popmessage("CPU #%d PC %08x: keychip read %04x",cpu_getactivecpu(),activecpu_get_pc(),offset);
+
+ return 0;
+}
+
+static WRITE8_HANDLER( key_type3_w )
+{
+// logerror("CPU #%d PC %04x: keychip write %04x=%02x\n",cpu_getactivecpu(),activecpu_get_pc(),offset,data);
+
+ key[(offset & 0x70) >> 4] = data;
+}
+
+
+
+/*******************************************************************************
+* *
+* Sound banking emulation (CUS121) *
+* *
+*******************************************************************************/
+
+WRITE8_HANDLER( namcos1_sound_bankswitch_w )
+{
+ UINT8 *rom = memory_region(REGION_CPU3) + 0xc000;
+
+ int bank = (data & 0x70) >> 4;
+ memory_set_bankptr(17,rom + 0x4000 * bank);
+}
+
+
+
+/*******************************************************************************
+* *
+* Banking emulation (CUS117) *
+* *
+*******************************************************************************/
+
+static int mcu_patch_data;
+static int namcos1_reset = 0;
+
+WRITE8_HANDLER( namcos1_cpu_control_w )
+{
+// logerror("reset control pc=%04x %02x\n",activecpu_get_pc(),data);
+ if ((data & 1) ^ namcos1_reset)
+ {
+ mcu_patch_data = 0;
+ namcos1_reset = data & 1;
+ }
+
+ cpunum_set_input_line(1, INPUT_LINE_RESET, (data & 1) ? CLEAR_LINE : ASSERT_LINE);
+ cpunum_set_input_line(2, INPUT_LINE_RESET, (data & 1) ? CLEAR_LINE : ASSERT_LINE);
+ cpunum_set_input_line(3, INPUT_LINE_RESET, (data & 1) ? CLEAR_LINE : ASSERT_LINE);
+}
+
+
+
+WRITE8_HANDLER( namcos1_watchdog_w )
+{
+ static int wdog;
+
+ wdog |= 1 << (cpu_getactivecpu());
+ if (wdog == 7 || !namcos1_reset)
+ {
+ wdog = 0;
+ watchdog_reset_w(0,0);
+ }
+}
+
+
+
+static READ8_HANDLER( soundram_r )
+{
+ if (offset < 0x1000)
+ {
+ offset &= 0x3ff;
+
+ /* CUS 30 */
+ return namcos1_cus30_r(offset);
+ }
+ else
+ {
+ offset &= 0x7ff;
+
+ /* shared ram */
+ return namcos1_triram[offset];
+ }
+}
+
+static WRITE8_HANDLER( soundram_w )
+{
+ if (offset < 0x1000)
+ {
+ offset &= 0x3ff;
+
+ /* CUS 30 */
+ namcos1_cus30_w(offset,data);
+ }
+ else
+ {
+ offset &= 0x7ff;
+
+ /* shared ram */
+ namcos1_triram[offset] = data;
+ return;
+ }
+}
+
+/* ROM handlers */
+
+static WRITE8_HANDLER( rom_w )
+{
+ logerror("CPU #%d PC %04x: warning - write %02x to rom address %04x\n",cpu_getactivecpu(),activecpu_get_pc(),data,offset);
+}
+
+/* error handlers */
+static READ8_HANDLER( unknown_r )
+{
+ logerror("CPU #%d PC %04x: warning - read from unknown chip\n",cpu_getactivecpu(),activecpu_get_pc() );
+// popmessage("CPU #%d PC %04x: read from unknown chip",cpu_getactivecpu(),activecpu_get_pc() );
+ return 0;
+}
+
+static WRITE8_HANDLER( unknown_w )
+{
+ logerror("CPU #%d PC %04x: warning - wrote to unknown chip\n",cpu_getactivecpu(),activecpu_get_pc() );
+// popmessage("CPU #%d PC %04x: wrote to unknown chip",cpu_getactivecpu(),activecpu_get_pc() );
+}
+
+/* Main bankswitching routine */
+static void set_bank(int banknum, bankhandler *handler)
+{
+ int bankstart = (banknum & 7) * 0x2000;
+ int cpunum = (banknum >> 3) & 1;
+
+ /* for BANK handlers , memory direct and OP-code base */
+ if (handler->bank_pointer)
+ memory_set_bankptr(banknum + 1, handler->bank_pointer);
+
+ /* read handlers */
+ if (!handler->bank_handler_r)
+ {
+ if (namcos1_active_bank[banknum].bank_handler_r)
+ memory_install_read8_handler(cpunum, ADDRESS_SPACE_PROGRAM, bankstart, bankstart + 0x1fff, 0, 0, ram_bank_handler_r[banknum]);
+ }
+ else
+ {
+ if (!namcos1_active_bank[banknum].bank_handler_r)
+ memory_install_read8_handler(cpunum, ADDRESS_SPACE_PROGRAM, bankstart, bankstart + 0x1fff, 0, 0, io_bank_handler_r[banknum]);
+ }
+
+ /* write handlers (except for the 0xe000-0xffff range) */
+ if (bankstart != 0xe000)
+ {
+ if (!handler->bank_handler_w)
+ {
+ if (namcos1_active_bank[banknum].bank_handler_w)
+ memory_install_write8_handler(cpunum, ADDRESS_SPACE_PROGRAM, bankstart, bankstart + 0x1fff, 0, 0, ram_bank_handler_w[banknum]);
+ }
+ else
+ {
+ if (!namcos1_active_bank[banknum].bank_handler_r)
+ memory_install_write8_handler(cpunum, ADDRESS_SPACE_PROGRAM, bankstart, bankstart + 0x1fff, 0, 0, io_bank_handler_w[banknum]);
+ }
+ }
+
+ /* Remember this bank handler */
+ namcos1_active_bank[banknum] = *handler;
+}
+
+static void namcos1_bankswitch(int cpu, offs_t offset, UINT8 data)
+{
+ static int chip[16];
+ int bank = (cpu*8) + (( offset >> 9) & 0x07);
+
+ if (offset & 1)
+ {
+ chip[bank] &= 0x0300;
+ chip[bank] |= (data & 0xff);
+ }
+ else
+ {
+ chip[bank] &= 0x00ff;
+ chip[bank] |= (data & 0x03) << 8;
+ }
+
+ set_bank(bank, &namcos1_bank_element[chip[bank]]);
+
+ /* unmapped bank warning */
+ if( namcos1_active_bank[bank].bank_handler_r == unknown_r)
+ {
+ logerror("CPU #%d PC %04x:warning unknown chip selected bank %x=$%04x\n", cpu , activecpu_get_pc(), bank , chip[bank] );
+// if (chip) popmessage("CPU #%d PC %04x:unknown chip selected bank %x=$%04x", cpu , activecpu_get_pc(), bank , chip[bank] );
+ }
+
+ /* renew pc base */
+// change_pc(activecpu_get_pc());
+}
+
+WRITE8_HANDLER( namcos1_bankswitch_w )
+{
+// logerror("cpu %d: namcos1_bankswitch_w offset %04x data %02x\n",cpu_getactivecpu(),offset,data);
+
+ namcos1_bankswitch(cpu_getactivecpu(), offset, data);
+}
+
+/* Sub cpu set start bank port */
+WRITE8_HANDLER( namcos1_subcpu_bank_w )
+{
+// logerror("namcos1_subcpu_bank_w offset %04x data %02x\n",offset,data);
+
+ /* Prepare code for CPU 1 */
+ namcos1_bankswitch( 1, 0x0e00, 0x03 );
+ namcos1_bankswitch( 1, 0x0e01, data );
+}
+
+/*******************************************************************************
+* *
+* Initialization *
+* *
+*******************************************************************************/
+
+static void namcos1_install_bank(int start,int end,read8_handler hr,write8_handler hw,
+ int offset,UINT8 *pointer)
+{
+ int i;
+ for(i=start;i<=end;i++)
+ {
+ namcos1_bank_element[i].bank_handler_r = hr;
+ namcos1_bank_element[i].bank_handler_w = hw;
+ namcos1_bank_element[i].bank_offset = offset;
+ namcos1_bank_element[i].bank_pointer = pointer;
+ offset += 0x2000;
+ if(pointer) pointer += 0x2000;
+ }
+}
+
+
+
+static void namcos1_build_banks(read8_handler key_r,write8_handler key_w)
+{
+ int i;
+
+ /**** kludge alert ****/
+ UINT8 *dummyrom = auto_malloc(0x2000);
+
+ /* when the games want to reset because the test switch has been flipped (or
+ because the protection checks failed!) they just set the top bits of bank #7
+ to 0, effectively crashing and waiting for the watchdog to kick in.
+ To avoid crashes in MAME, I prepare a dummy ROM containing just BRA -2 so
+ the program doesn't start executing code in unmapped areas.
+ Conveniently, the opcode for BRA -2 is 20 FE, and FE 20 FE is LDU $20FE,
+ so misaligned entry points get immediatly corrected. */
+ for (i = 0;i < 0x2000;i+=2)
+ {
+ dummyrom[i] = 0x20;
+ dummyrom[i+1] = 0xfe;
+ }
+ /* also provide a valid IRQ vector */
+ dummyrom[0x1ff8] = 0xff;
+ dummyrom[0x1ff9] = 0x00;
+
+ /* clear all banks to unknown area */
+ for(i = 0;i < NAMCOS1_MAX_BANK;i++)
+ namcos1_install_bank(i,i,0,unknown_w,0,dummyrom);
+ /**** end of kludge alert ****/
+
+
+ /* 3D glasses */
+ namcos1_install_bank(0x160,0x160,0,namcos1_3dcs_w,0,0);
+ /* RAM 6 banks - palette */
+ namcos1_install_bank(0x170,0x173,0,namcos1_paletteram_w,0,namcos1_paletteram);
+ /* RAM 5 banks - videoram */
+ namcos1_install_bank(0x178,0x17b,namcos1_videoram_r,namcos1_videoram_w,0,0);
+ /* key chip bank */
+ namcos1_install_bank(0x17c,0x17c,key_r,key_w,0,0);
+ /* RAM 7 banks - display control, playfields, sprites */
+ namcos1_install_bank(0x17e,0x17e,namcos1_spriteram_r,namcos1_spriteram_w,0,0);
+ /* RAM 1 shared ram, PSG device */
+ namcos1_install_bank(0x17f,0x17f,soundram_r,soundram_w,0,0);
+ /* RAM 3 banks */
+ namcos1_install_bank(0x180,0x183,0,0,0,s1ram);
+
+ /* PRG0-PRG7 */
+ {
+ UINT8 *rom = memory_region(REGION_USER1);
+
+ namcos1_install_bank(0x200,0x3ff,0,rom_w,0,rom);
+
+ /* bit 16 of the address is inverted for PRG7 (and bits 17,18 just not connected) */
+ for (i = 0x380000;i < 0x400000;i++)
+ {
+ if ((i & 0x010000) == 0)
+ {
+ UINT8 t = rom[i];
+ rom[i] = rom[i + 0x010000];
+ rom[i + 0x010000] = t;
+ }
+ }
+ }
+}
+
+MACHINE_RESET( namcos1 )
+{
+ static bankhandler unknown_handler = { unknown_r, unknown_w, 0, NULL };
+ int bank;
+
+ /* Point all of our bankhandlers to the error handlers */
+ for (bank = 0; bank < 2*8 ; bank++)
+ set_bank(bank, &unknown_handler);
+
+ /* Default MMU setup for Cpu 0 */
+ namcos1_bankswitch(0, 0x0000, 0x01 ); /* bank0 = 0x180(RAM) - evidence: wldcourt */
+ namcos1_bankswitch(0, 0x0001, 0x80 );
+ namcos1_bankswitch(0, 0x0200, 0x01 ); /* bank1 = 0x180(RAM) - evidence: berabohm */
+ namcos1_bankswitch(0, 0x0201, 0x80 );
+
+ namcos1_bankswitch(0, 0x0e00, 0x03 ); /* bank7 = 0x3ff(PRG7) */
+ namcos1_bankswitch(0, 0x0e01, 0xff );
+
+ /* Default MMU setup for Cpu 1 */
+ namcos1_bankswitch(1, 0x0000, 0x01 ); /* bank0 = 0x180(RAM) - evidence: wldcourt */
+ namcos1_bankswitch(1, 0x0001, 0x80 );
+
+ namcos1_bankswitch(1, 0x0e00, 0x03); /* bank7 = 0x3ff(PRG7) */
+ namcos1_bankswitch(1, 0x0e01, 0xff);
+
+ /* stop all CPUs */
+ cpunum_set_input_line(1, INPUT_LINE_RESET, ASSERT_LINE);
+ cpunum_set_input_line(2, INPUT_LINE_RESET, ASSERT_LINE);
+ cpunum_set_input_line(3, INPUT_LINE_RESET, ASSERT_LINE);
+
+ /* mcu patch data clear */
+ mcu_patch_data = 0;
+ namcos1_reset = 0;
+}
+
+
+
+/*******************************************************************************
+* *
+* 63701 MCU emulation (CUS64) *
+* *
+*******************************************************************************/
+
+/*******************************************************************************
+* *
+* MCU banking emulation and patch *
+* *
+*******************************************************************************/
+
+/* mcu banked rom area select */
+WRITE8_HANDLER( namcos1_mcu_bankswitch_w )
+{
+ int addr;
+
+ /* bit 2-7 : chip select line of ROM chip */
+ switch (data & 0xfc)
+ {
+ case 0xf8: addr = 0x10000; data ^= 2; break; /* bit 2 : ROM 0 (bit 1 is inverted in that case) */
+ case 0xf4: addr = 0x30000; break; /* bit 3 : ROM 1 */
+ case 0xec: addr = 0x50000; break; /* bit 4 : ROM 2 */
+ case 0xdc: addr = 0x70000; break; /* bit 5 : ROM 3 */
+ case 0xbc: addr = 0x90000; break; /* bit 6 : ROM 4 */
+ case 0x7c: addr = 0xb0000; break; /* bit 7 : ROM 5 */
+ default: addr = 0x10000; break; /* illegal */
+ }
+
+ /* bit 0-1 : address line A15-A16 */
+ addr += (data & 3) * 0x8000;
+
+ memory_set_bankptr(20, memory_region(REGION_CPU4) + addr);
+}
+
+
+
+/* This point is very obscure, but i havent found any better way yet. */
+/* Works with all games so far. */
+
+/* patch points of memory address */
+/* CPU0/1 bank[17f][1000] */
+/* CPU2 [7000] */
+/* CPU3 [c000] */
+
+/* This memory point should be set $A6 by anywhere, but */
+/* I found set $A6 only initialize in MCU */
+/* This patch kill write this data by MCU case $A6 to xx(clear) */
+
+WRITE8_HANDLER( namcos1_mcu_patch_w )
+{
+ //logerror("mcu C000 write pc=%04x data=%02x\n",activecpu_get_pc(),data);
+ if (mcu_patch_data == 0xa6) return;
+ mcu_patch_data = data;
+ namcos1_triram[0] = data;
+}
+
+
+
+/*******************************************************************************
+* *
+* driver specific initialize routine *
+* *
+*******************************************************************************/
+struct namcos1_specific
+{
+ /* keychip */
+ read8_handler key_r;
+ write8_handler key_w;
+ int key_id;
+ int key_reg1;
+ int key_reg2;
+ int key_reg3;
+ int key_reg4;
+ int key_reg5;
+ int key_reg6;
+};
+
+static void namcos1_driver_init(const struct namcos1_specific *specific )
+{
+ const struct namcos1_specific no_key =
+ {
+ no_key_r,no_key_w
+ };
+
+ if (!specific) specific = &no_key;
+
+ /* keychip id */
+ key_id = specific->key_id;
+ /* for key type 3 */
+ key_reg = specific->key_reg1;
+ key_rng = specific->key_reg2;
+ key_swap4_arg = specific->key_reg3;
+ key_swap4 = specific->key_reg4;
+ key_bottom4 = specific->key_reg5;
+ key_top4 = specific->key_reg6;
+
+ /* S1 RAM pointer set */
+ s1ram = auto_malloc(0x8000);
+ namcos1_triram = auto_malloc(0x800);
+ namcos1_paletteram = auto_malloc(0x8000);
+
+ /* Register volatile user memory for save state */
+ state_save_register_global_pointer(s1ram, 0x8000);
+ state_save_register_global_pointer(namcos1_triram, 0x800);
+ state_save_register_global_pointer(namcos1_paletteram, 0x8000);
+
+ /* Point mcu & sound shared RAM to destination */
+ memory_set_bankptr( 18, namcos1_triram );
+ memory_set_bankptr( 19, namcos1_triram );
+
+ /* build bank elements */
+ namcos1_build_banks(specific->key_r,specific->key_w);
+}
+
+
+/*******************************************************************************
+* Shadowland / Youkai Douchuuki specific *
+*******************************************************************************/
+DRIVER_INIT( shadowld )
+{
+ namcos1_driver_init(NULL);
+}
+
+/*******************************************************************************
+* Dragon Spirit specific (CUS136) *
+*******************************************************************************/
+DRIVER_INIT( dspirit )
+{
+ const struct namcos1_specific dspirit_specific=
+ {
+ key_type1_r,key_type1_w, 0x36
+ };
+ namcos1_driver_init(&dspirit_specific);
+}
+
+/*******************************************************************************
+* World Court specific (CUS143) *
+*******************************************************************************/
+DRIVER_INIT( wldcourt )
+{
+ const struct namcos1_specific worldcourt_specific=
+ {
+ key_type1_r,key_type1_w, 0x35
+ };
+ namcos1_driver_init(&worldcourt_specific);
+}
+
+/*******************************************************************************
+* Blazer specific (CUS144) *
+*******************************************************************************/
+DRIVER_INIT( blazer )
+{
+ const struct namcos1_specific blazer_specific=
+ {
+ key_type1_r,key_type1_w, 0x13
+ };
+ namcos1_driver_init(&blazer_specific);
+}
+
+/*******************************************************************************
+* Puzzle Club specific *
+*******************************************************************************/
+DRIVER_INIT( puzlclub )
+{
+ const struct namcos1_specific puzlclub_specific=
+ {
+ key_type1_r,key_type1_w, 0x35
+ };
+ namcos1_driver_init(&puzlclub_specific);
+}
+
+/*******************************************************************************
+* Pac-Mania specific (CUS151) *
+*******************************************************************************/
+DRIVER_INIT( pacmania )
+{
+ const struct namcos1_specific pacmania_specific=
+ {
+ key_type2_r,key_type2_w, 0x12
+ };
+ namcos1_driver_init(&pacmania_specific);
+}
+
+/*******************************************************************************
+* Alice in Wonderland / Marchen Maze specific (CUS152) *
+*******************************************************************************/
+DRIVER_INIT( alice )
+{
+ const struct namcos1_specific alice_specific=
+ {
+ key_type2_r,key_type2_w, 0x25
+ };
+ namcos1_driver_init(&alice_specific);
+}
+
+/*******************************************************************************
+* Galaga '88 specific (CUS153) *
+*******************************************************************************/
+DRIVER_INIT( galaga88 )
+{
+ const struct namcos1_specific galaga88_specific=
+ {
+ key_type2_r,key_type2_w, 0x31
+ };
+ namcos1_driver_init(&galaga88_specific);
+}
+
+/*******************************************************************************
+* World Stadium specific (CUS154) *
+*******************************************************************************/
+DRIVER_INIT( ws )
+{
+ const struct namcos1_specific ws_specific=
+ {
+ key_type2_r,key_type2_w, 0x07
+ };
+ namcos1_driver_init(&ws_specific);
+}
+
+/*******************************************************************************
+* Bakutotsu Kijuutei specific (CUS155) *
+*******************************************************************************/
+DRIVER_INIT( bakutotu )
+{
+ const struct namcos1_specific bakutotu_specific=
+ {
+ key_type2_r,key_type2_w, 0x22
+ };
+ namcos1_driver_init(&bakutotu_specific);
+
+#if 0
+ // resolves CPU deadlocks caused by sloppy coding(see driver\namcos1.c)
+ {
+ UINT8 target[8] = {0x34,0x37,0x35,0x37,0x96,0x00,0x2e,0xed};
+ UINT8 *rombase, *srcptr, *endptr, *scanptr;
+
+ rombase = memory_region(REGION_USER1);
+ srcptr = rombase + 0x1e000;
+ endptr = srcptr + 0xa000;
+
+ while ( (scanptr = memchr(srcptr, 0x34, endptr-srcptr)) )
+ {
+ if (!memcmp(scanptr, target, 8))
+ {
+ scanptr[7] = 0xfc;
+ srcptr = scanptr + 8;
+
+ logerror ("faulty loop patched at %06x\n", scanptr-rombase+7);
+ }
+ else
+ srcptr = scanptr + 1;
+ }
+ }
+#endif
+}
+
+/*******************************************************************************
+* Splatter House specific (CUS181) *
+*******************************************************************************/
+DRIVER_INIT( splatter )
+{
+ const struct namcos1_specific splatter_specific=
+ {
+ key_type3_r,key_type3_w, 181, 3, 4,-1,-1,-1,-1
+ };
+
+ namcos1_driver_init(&splatter_specific);
+}
+
+/*******************************************************************************
+* Rompers specific (CUS182) *
+*******************************************************************************/
+DRIVER_INIT( rompers )
+{
+ const struct namcos1_specific rompers_specific=
+ {
+ key_type3_r,key_type3_w, 182, 7,-1,-1,-1,-1,-1
+ };
+ namcos1_driver_init(&rompers_specific);
+}
+
+/*******************************************************************************
+* Blast Off specific (CUS183) *
+*******************************************************************************/
+DRIVER_INIT( blastoff )
+{
+ const struct namcos1_specific blastoff_specific=
+ {
+ key_type3_r,key_type3_w, 183, 0, 7, 3, 5,-1,-1
+ };
+ namcos1_driver_init(&blastoff_specific);
+}
+
+/*******************************************************************************
+* World Stadium '89 specific (CUS184) *
+*******************************************************************************/
+DRIVER_INIT( ws89 )
+{
+ const struct namcos1_specific ws89_specific=
+ {
+ key_type3_r,key_type3_w, 184, 2,-1,-1,-1,-1,-1
+ };
+ namcos1_driver_init(&ws89_specific);
+}
+
+/*******************************************************************************
+* Tank Force specific (CUS185) *
+*******************************************************************************/
+DRIVER_INIT( tankfrce )
+{
+ const struct namcos1_specific tankfrce_specific=
+ {
+ key_type3_r,key_type3_w, 185, 5,-1, 1,-1, 2,-1
+ };
+ namcos1_driver_init(&tankfrce_specific);
+}
+
+/*******************************************************************************
+* Dangerous Seed specific (CUS308) *
+*******************************************************************************/
+DRIVER_INIT( dangseed )
+{
+ const struct namcos1_specific dangseed_specific=
+ {
+ key_type3_r,key_type3_w, 308, 6,-1, 5,-1, 0, 4
+ };
+ namcos1_driver_init(&dangseed_specific);
+}
+
+/*******************************************************************************
+* Pistol Daimyo no Bouken specific (CUS309) *
+*******************************************************************************/
+DRIVER_INIT( pistoldm )
+{
+ const struct namcos1_specific pistoldm_specific=
+ {
+ key_type3_r,key_type3_w, 309, 1, 2, 0,-1, 4,-1
+ };
+ namcos1_driver_init(&pistoldm_specific);
+}
+
+/*******************************************************************************
+* World Stadium '90 specific (CUS310) *
+*******************************************************************************/
+DRIVER_INIT( ws90 )
+{
+ const struct namcos1_specific ws90_specific=
+ {
+ key_type3_r,key_type3_w, 310, 4,-1, 7,-1, 3,-1
+ };
+ namcos1_driver_init(&ws90_specific);
+}
+
+/*******************************************************************************
+* Souko Ban DX specific (CUS311) *
+*******************************************************************************/
+DRIVER_INIT( soukobdx )
+{
+ const struct namcos1_specific soukobdx_specific=
+ {
+ key_type3_r,key_type3_w, 311, 2, 3/*?*/, 0,-1, 4,-1
+ };
+ namcos1_driver_init(&soukobdx_specific);
+}
+
+
+
+/*******************************************************************************
+* Quester specific *
+*******************************************************************************/
+static READ8_HANDLER( quester_paddle_r )
+{
+ static int qnum=0, qstrobe=0;
+
+ if (offset == 0)
+ {
+ int ret;
+
+ if (!qnum)
+ ret = (readinputportbytag("CONTROL0")&0x90) | qstrobe | (readinputportbytag("PADDLE0")&0x0f);
+ else
+ ret = (readinputportbytag("CONTROL0")&0x90) | qstrobe | (readinputportbytag("PADDLE1")&0x0f);
+
+ qstrobe ^= 0x40;
+
+ return ret;
+ }
+ else
+ {
+ int ret;
+
+ if (!qnum)
+ ret = (readinputportbytag("CONTROL1")&0x90) | qnum | (readinputportbytag("PADDLE0")>>4);
+ else
+ ret = (readinputportbytag("CONTROL1")&0x90) | qnum | (readinputportbytag("PADDLE1")>>4);
+
+ if (!qstrobe) qnum ^= 0x20;
+
+ return ret;
+ }
+}
+
+DRIVER_INIT( quester )
+{
+ namcos1_driver_init(NULL);
+ memory_install_read8_handler(3, ADDRESS_SPACE_PROGRAM, 0x1400, 0x1401, 0, 0, quester_paddle_r);
+}
+
+
+
+/*******************************************************************************
+* Beraboh Man specific *
+*******************************************************************************/
+
+static READ8_HANDLER( berabohm_buttons_r )
+{
+ int res;
+ static int input_count, strobe, strobe_count;
+
+
+ if (offset == 0)
+ {
+ int inp = input_count;
+
+ if (inp == 4) res = readinputportbytag("CONTROL0");
+ else
+ {
+ char portname[4];
+
+#ifdef PRESSURE_SENSITIVE
+ static int counter[4];
+
+ sprintf(portname,"IN%d",inp); /* IN0-IN3 */
+ res = readinputportbytag(portname);
+ if (res & 0x80)
+ {
+ if (counter[inp] >= 0)
+ res = 0x40 | counter[inp];
+ else
+ {
+ if (res & 0x40) res = 0x40;
+ else res = 0x00;
+ }
+ }
+ else if (res & 0x40)
+ {
+ if (counter[inp] < 0x3f)
+ {
+ counter[inp] += 4;
+ res = 0x00;
+ }
+ else res = 0x7f;
+ }
+ else
+ counter[inp] = -1;
+#else
+ sprintf(portname,"IN%d",inp); /* IN0-IN3 */
+ res = readinputportbytag(portname);
+ if (res & 1) res = 0x7f; /* weak */
+ else if (res & 2) res = 0x48; /* medium */
+ else if (res & 4) res = 0x40; /* strong */
+#endif
+ }
+
+ return res;
+ }
+ else
+ {
+ res = readinputportbytag("CONTROL1") & 0x8f;
+
+ /* the strobe cannot happen too often, otherwise the MCU will waste too
+ much time reading the inputs and won't have enough cycles to play two
+ digital sounds at once. This value is enough to read all inputs at least
+ once per frame */
+ if (++strobe_count > 4)
+ {
+ strobe_count = 0;
+ strobe ^= 0x40;
+ if (strobe == 0)
+ {
+ input_count = (input_count + 1) % 5;
+ if (input_count == 3) res |= 0x10;
+ }
+ }
+
+ res |= strobe;
+
+ return res;
+ }
+}
+
+DRIVER_INIT( berabohm )
+{
+ namcos1_driver_init(NULL);
+ memory_install_read8_handler(3, ADDRESS_SPACE_PROGRAM, 0x1400, 0x1401, 0, 0, berabohm_buttons_r);
+}
+
+
+
+/*******************************************************************************
+* Face Off specific *
+*******************************************************************************/
+
+static READ8_HANDLER( faceoff_inputs_r )
+{
+ int res;
+ static int input_count, strobe_count, stored_input[2];
+
+ if (offset == 0)
+ {
+ res = (readinputportbytag("CONTROL0") & 0x80) | stored_input[0];
+
+ return res;
+ }
+ else
+ {
+ res = readinputportbytag("CONTROL1") & 0x80;
+
+ /* the strobe cannot happen too often, otherwise the MCU will waste too
+ much time reading the inputs and won't have enough cycles to play two
+ digital sounds at once. This value is enough to read all inputs at least
+ once per frame */
+ if (++strobe_count > 8)
+ {
+ strobe_count = 0;
+
+ res |= input_count;
+
+ switch (input_count)
+ {
+ case 0:
+ stored_input[0] = readinputportbytag("IN0") & 0x1f;
+ stored_input[1] = (readinputportbytag("IN3") & 0x07) << 3;
+
+ case 3:
+ stored_input[0] = readinputportbytag("IN2") & 0x1f;
+
+ case 4:
+ stored_input[0] = readinputportbytag("IN1") & 0x1f;
+ stored_input[1] = readinputportbytag("IN3") & 0x18;
+ }
+
+ input_count = (input_count + 1) & 7;
+ }
+ else
+ {
+ res |= 0x40 | stored_input[1];
+ }
+
+ return res;
+ }
+}
+
+DRIVER_INIT( faceoff )
+{
+ namcos1_driver_init(NULL);
+ memory_install_read8_handler(3, ADDRESS_SPACE_PROGRAM, 0x1400, 0x1401, 0, 0, faceoff_inputs_r);
+}