Previous | 199869 Revisions | Next |
r18343 Sunday 7th October, 2012 at 21:56:29 UTC by Luca Elia |
---|
suna8.c: fixed sound samples width, improves speech in e.g. rranger [Luca Elia] Promoted starfigh to playable state [Luca Elia] * Address line scrambling of data ROMs * ROM bank latching and mirroring * Sound latch and NMI disable * Patched some further protection * Added graphics banking New games added or promoted from NOT_WORKING status --------------------------------------------------- Star Fighter (v1) [Luca Elia] |
[src/mame/audio] | suna8.c |
[src/mame/drivers] | suna8.c |
[src/mame/includes] | suna8.h |
[src/mame/video] | suna8.c |
r18342 | r18343 | |
---|---|---|
7 | 7 | |
8 | 8 | Main CPU: Encrypted Z80 (Epoxy Module) |
9 | 9 | Sound CPU: Z80 [Music] + Z80 [8 Bit PCM, Optional] |
10 | Sound Chips: AY8910 + YM3812/YM2203 + DAC x 4 [Optional] | |
10 | Sound Chips: AY8910 + YM3812/YM2203 + DAC x 4 [Optional] + Samples [Optional] | |
11 | 11 | |
12 | 12 | |
13 | --------------------------------------------------------------------------- | |
14 | Year + Game Game PCB Epoxy CPU Notes | |
15 | --------------------------------------------------------------------------- | |
16 | 88 Hard Head KRB-14 60138-0083 S562008 Encryption + Protection | |
17 | 88 Rough Ranger K030087 ? S562008 | |
18 | 89 Spark Man KRB-16 60136-081 T568009 Not Working (Protection) | |
19 | 90 Star Fighter KRB-17 60484-0082 T568009 Not Working | |
20 | 91 Hard Head 2 ? ? T568009 Encryption + Protection | |
21 | 92 Brick Zone ? ? Yes Encryption + Protection | |
22 | --------------------------------------------------------------------------- | |
13 | -------------------------------------------------------------------------------------- | |
14 | Year + Game Game PCB Epoxy CPU Samples Notes | |
15 | -------------------------------------------------------------------------------------- | |
16 | 88 Hard Head KRB-14 60138-0083 S562008 Yes Encryption + Protection | |
17 | 88 Rough Ranger K030087 ? S562008 Yes | |
18 | 89 Spark Man KRB-16 60136-081 T568009 Yes Not Working (Protection) | |
19 | 90 Star Fighter KRB-17 60484-0082 T568009 Yes Encryption + Protection | |
20 | 91 Hard Head 2 ? ? T568009 - Encryption + Protection | |
21 | 92 Brick Zone ? ? Yes - Encryption + Protection | |
22 | -------------------------------------------------------------------------------------- | |
23 | 23 | |
24 | To Do: | |
25 | ||
26 | - Samples playing in starfigh, sparkman (AY8910 ports A&B) | |
27 | ||
28 | 24 | Notes: |
29 | 25 | |
30 | 26 | - sparkman: to get past the roms test screen put a watchpoint at ca40. |
r18342 | r18343 | |
67 | 63 | { |
68 | 64 | static const UINT8 swaptable[8] = |
69 | 65 | { |
70 | 1,1,0,1,1,1,1,0 | |
66 | 1,1,0,1,1,1,1,0 | |
71 | 67 | }; |
72 | 68 | int table = ((i & 0x0c00) >> 10) | ((i & 0x4000) >> 12); |
73 | 69 | |
r18342 | r18343 | |
249 | 245 | 8?, 9n?,an, bn y,y,?,? (player anims) |
250 | 246 | cn, dy, en, fn y,y,n,n |
251 | 247 | */ |
252 | static const UINT8 swaptable[ | |
248 | static const UINT8 swaptable[0x50] = | |
253 | 249 | { |
254 | 250 | 1,1,1,1,0,0,1,1, 0,0,0,0,0,0,0,0, // 8000-ffff not used |
255 | 251 | 1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0, |
256 | 252 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
257 | 253 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
258 | 1,1,0,0,0,0,0,0,1,1,0,0,1,1,0,0 | |
254 | 1,1,0,0,0,0,0,0,1,1,0,0,1,1,0,0 | |
259 | 255 | }; |
260 | 256 | int addr = i; |
261 | 257 | |
r18342 | r18343 | |
271 | 267 | static const UINT8 swaptable[32] = |
272 | 268 | { |
273 | 269 | 1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1, |
274 | 1,1,0,1,1,1,1,1,1,1,1,1,0,1,0,0 | |
270 | 1,1,0,1,1,1,1,1,1,1,1,1,0,1,0,0 | |
275 | 271 | }; |
276 | 272 | static const UINT8 xortable[32] = |
277 | 273 | { |
278 | 274 | 0x04,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x04,0x45,0x00,0x04,0x00,0x04,0x00,0x00, |
279 | 0x04,0x45,0x00,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x04,0x00,0x00 | |
275 | 0x04,0x45,0x00,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x04,0x00,0x00 | |
280 | 276 | }; |
281 | 277 | int table = (i & 1) | ((i & 0x400) >> 9) | ((i & 0x7000) >> 10); |
282 | 278 | |
r18342 | r18343 | |
320 | 316 | |
321 | 317 | /* Address lines scrambling */ |
322 | 318 | memcpy(decrypt, RAM, size); |
323 | for (i = 0; i < 0x | |
319 | for (i = 0; i < 0x50000; i++) | |
324 | 320 | { |
325 | static const UINT8 swaptable[ | |
321 | static const UINT8 swaptable[0x50] = | |
326 | 322 | { |
327 | 1,1,1,1,1,1,0,0, | |
323 | 1,1,1,1, 1,1,0,0, 0,0,0,0, 0,0,0,0, // 8000-ffff not used | |
324 | 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | |
325 | 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | |
326 | 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, | |
327 | 0,0,0,0, 0,0,0,0, 1,1,0,0, 0,0,0,0 // bank $0e, 9c80 (boss 1) and 8350 (first wave) | |
328 | 328 | }; |
329 | 329 | int addr = i; |
330 | 330 | |
331 | if (swaptable[(i & 0x7000) >> 12]) | |
332 | addr = BITSWAP16(addr, 15,14,13,12,11,10,9,8,6,7,5,4,3,2,1,0); | |
331 | if (swaptable[(i & 0xff000) >> 12]) | |
332 | addr = BITSWAP24(addr, 23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,6,7,5,4,3,2,1,0); | |
333 | 333 | |
334 | 334 | RAM[i] = decrypt[addr]; |
335 | 335 | } |
r18342 | r18343 | |
340 | 340 | static const UINT8 swaptable[32] = |
341 | 341 | { |
342 | 342 | 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, |
343 | 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
343 | 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
344 | 344 | }; |
345 | 345 | static const UINT8 xortable[32] = |
346 | 346 | { |
347 | 347 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x41,0x01,0x00,0x00,0x00,0x00, |
348 | 0x01,0x01,0x41,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 | |
348 | 0x01,0x01,0x41,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 | |
349 | 349 | }; |
350 | 350 | int table = (i & 0x7c00) >> 10; |
351 | 351 | |
r18342 | r18343 | |
367 | 367 | RAM[i] = BITSWAP8(RAM[i], 5,6,7,4,3,2,1,0) ^ 0x45; |
368 | 368 | } |
369 | 369 | |
370 | ||
371 | // !!!!!! PATCHES !!!!!! | |
372 | ||
373 | decrypt[0x07c0] = 0xc9; // c080 bit 7 protection check | |
374 | ||
375 | // decrypt[0x083e] = 0x00; // sound latch disabling | |
376 | // decrypt[0x083f] = 0x00; // "" | |
377 | // decrypt[0x0840] = 0x00; // "" | |
378 | ||
379 | // decrypt[0x0cef] = 0xc9; // rombank latch check, corrupt d12d | |
380 | ||
381 | decrypt[0x2696] = 0xc9; // work ram writes disable, corrupt next routine | |
382 | decrypt[0x4e9a] = 0x00; // work ram writes disable, flip background sprite | |
383 | ||
370 | 384 | machine().root_device().membank("bank1")->configure_entries(0, 16, machine().root_device().memregion("maincpu")->base() + 0x10000, 0x4000); |
371 | 385 | } |
372 | 386 | |
r18342 | r18343 | |
392 | 406 | { |
393 | 407 | static const UINT8 swaptable[8] = |
394 | 408 | { |
395 | 1,1,1,1,0,0,1,1 | |
409 | 1,1,1,1,0,0,1,1 | |
396 | 410 | }; |
397 | 411 | int addr = i; |
398 | 412 | |
r18342 | r18343 | |
408 | 422 | static const UINT8 swaptable[32] = |
409 | 423 | { |
410 | 424 | 0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1, |
411 | 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0 | |
425 | 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0 | |
412 | 426 | }; |
413 | 427 | static const UINT8 xortable[32] = |
414 | 428 | { |
415 | 429 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
416 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00 | |
430 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00 | |
417 | 431 | }; |
418 | 432 | int table = (i & 0x7c00) >> 10; |
419 | 433 | |
r18342 | r18343 | |
706 | 720 | m_spritebank = (data >> 1) & 1; |
707 | 721 | |
708 | 722 | logerror("CPU #0 - PC %04X: protection_val = %02X\n",space.device().safe_pc(),data); |
709 | // | |
723 | // if (data & ~0x03) logerror("CPU #0 - PC %04X: unknown spritebank bits: %02X\n",space.device().safe_pc(),data); | |
710 | 724 | } |
711 | 725 | |
712 | 726 | /* |
r18342 | r18343 | |
814 | 828 | set_led_status(machine(), 0, data & 0x01); |
815 | 829 | set_led_status(machine(), 1, data & 0x02); |
816 | 830 | coin_counter_w(machine(), 0, data & 0x04); |
817 | if (data & ~0x07) logerror("CPU#0 | |
831 | if (data & ~0x07) logerror("CPU #0 - PC %04X: unknown leds bits: %02X\n",space.device().safe_pc(),data); | |
818 | 832 | } |
819 | 833 | |
820 | 834 | /* |
r18342 | r18343 | |
908 | 922 | Star Fighter |
909 | 923 | ***************************************************************************/ |
910 | 924 | |
925 | /* | |
926 | C280-C2FF: 7--- ---- | |
927 | -6-- ---- Disable Sound Latch Writes? | |
928 | --54 ---- | |
929 | ---- 3210 ROM Bank (Latched) | |
930 | */ | |
931 | WRITE8_MEMBER(suna8_state::starfigh_rombank_latch_w) | |
932 | { | |
933 | logerror("CPU #0 - PC %04X: rom bank latch %04X = %02X\n",space.device().safe_pc(), 0xc280 + offset, data); | |
934 | m_rombank_latch = data; | |
935 | } | |
936 | ||
937 | /* | |
938 | C500: Sound Latch | |
939 | */ | |
940 | WRITE8_MEMBER(suna8_state::starfigh_sound_latch_w) | |
941 | { | |
942 | if ( !(m_rombank_latch & 0x20) ) | |
943 | soundlatch_byte_w(space, 0, data); | |
944 | } | |
945 | ||
946 | /* | |
947 | C080: | |
948 | */ | |
949 | READ8_MEMBER(suna8_state::starfigh_cheats_r) | |
950 | { | |
951 | return ioport("CHEATS")->read(); | |
952 | } | |
953 | ||
954 | /* | |
955 | C380-C3FF: | |
956 | */ | |
911 | 957 | WRITE8_MEMBER(suna8_state::starfigh_spritebank_latch_w) |
912 | 958 | { |
913 | m_spritebank_latch = (data >> 2) & 1; | |
959 | // bit 1 = disable RAM writes. See code at 2696, 4e8f | |
960 | m_spritebank_latch = (data >> 2) & 1; | |
961 | m_nmi_enable = (data >> 5) & 1; // see code at 1c2, 491, 4aa, 4e9b | |
914 | 962 | if (data & ~0x04) logerror("CPU #0 - PC %04X: unknown spritebank bits: %02X\n",space.device().safe_pc(),data); |
915 | 963 | } |
916 | 964 | |
965 | /* | |
966 | C200: | |
967 | */ | |
917 | 968 | WRITE8_MEMBER(suna8_state::starfigh_spritebank_w) |
918 | 969 | { |
919 | 970 | m_spritebank = m_spritebank_latch; |
920 | 971 | } |
921 | 972 | |
973 | /* | |
974 | C400: 7654 ---- | |
975 | ---- 3--- Gfx banking (bosses) | |
976 | ---- -2-- Coin Counter | |
977 | ---- --1- Start 2 Led | |
978 | ---- ---0 Start 1 Led | |
979 | ||
980 | Writes to C400 also set ROM bank from latch | |
981 | */ | |
982 | WRITE8_MEMBER(suna8_state::starfigh_leds_w) | |
983 | { | |
984 | set_led_status(machine(), 0, data & 0x01); | |
985 | set_led_status(machine(), 1, data & 0x02); | |
986 | coin_counter_w(machine(), 0, data & 0x04); | |
987 | m_gfxbank = (data & 0x08) ? 4 : 0; | |
988 | if (data & ~0x0f) logerror("CPU #0 - PC %04X: unknown leds bits: %02X\n",space.device().safe_pc(),data); | |
989 | ||
990 | // ROM Bank: | |
991 | ||
992 | int bank = m_rombank_latch & 0x0f; | |
993 | ||
994 | membank("bank1")->set_entry(bank); | |
995 | ||
996 | m_rombank = m_rombank_latch; | |
997 | logerror("CPU #0 - PC %04X: rom bank = %02X\n",space.device().safe_pc(), m_rombank); | |
998 | } | |
999 | ||
922 | 1000 | static ADDRESS_MAP_START( starfigh_map, AS_PROGRAM, 8, suna8_state ) |
923 | 1001 | AM_RANGE(0x0000, 0x7fff) AM_ROM // ROM |
924 | AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("bank1") // Banked ROM | |
925 | AM_RANGE(0xc000, 0xc000) AM_READ_PORT("P1") // P1 (Inputs) | |
926 | AM_RANGE(0xc001, 0xc001) AM_READ_PORT("P2") // P2 | |
927 | AM_RANGE(0xc002, 0xc002) AM_READ_PORT("DSW1") // DSW 1 | |
928 | AM_RANGE(0xc003, 0xc003) AM_READ_PORT("DSW2") // DSW 2 | |
1002 | AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("bank1") // Banked ROM | |
1003 | ||
1004 | AM_RANGE(0xc000, 0xc000) AM_READ_PORT("P1") // P1 (Inputs) | |
1005 | AM_RANGE(0xc001, 0xc001) AM_READ_PORT("P2") // P2 | |
1006 | AM_RANGE(0xc002, 0xc002) AM_READ_PORT("DSW1") // DSW 1 | |
1007 | AM_RANGE(0xc003, 0xc003) AM_READ_PORT("DSW2") // DSW 2 | |
1008 | AM_RANGE(0xc080, 0xc080) AM_READ(starfigh_cheats_r ) // Cheats? | |
1009 | ||
929 | 1010 | AM_RANGE(0xc200, 0xc200) AM_WRITE(starfigh_spritebank_w ) // Sprite RAM Bank |
930 | AM_RANGE(0xc380, 0xc3ff) AM_WRITE(starfigh_spritebank_latch_w ) // Sprite RAM Bank | |
931 | AM_RANGE(0xc280, 0xc280) AM_WRITE(hardhea2_rombank_w ) // ROM Bank (?mirrored up to c2ff?) | |
1011 | AM_RANGE(0xc280, 0xc2ff) AM_WRITE(starfigh_rombank_latch_w ) // ROM Bank Latch (?mirrored up to c2ff?) | |
932 | 1012 | AM_RANGE(0xc300, 0xc300) AM_WRITE(hardhea2_flipscreen_w ) // Flip Screen |
933 | AM_RANGE(0xc400, 0xc400) AM_WRITE(hardhea2_leds_w ) // Leds + Coin Counter | |
934 | AM_RANGE(0xc500, 0xc500) AM_WRITE(soundlatch_byte_w ) // To Sound CPU | |
1013 | AM_RANGE(0xc380, 0xc3ff) AM_WRITE(starfigh_spritebank_latch_w ) // Sprite RAM Bank Latch | |
1014 | AM_RANGE(0xc400, 0xc47f) AM_WRITE(starfigh_leds_w ) // Leds + Coin Counter + ROM Bank | |
1015 | // c480 write? | |
1016 | AM_RANGE(0xc500, 0xc500) AM_WRITE(starfigh_sound_latch_w ) // To Sound CPU (can be disabled) | |
1017 | // (c522 + R & 0x1f) write? | |
1018 | ||
935 | 1019 | AM_RANGE(0xc600, 0xc7ff) AM_READWRITE(banked_paletteram_r, paletteram_RRRRGGGGBBBBxxxx_byte_be_w) AM_SHARE("paletteram" ) // Palette (Banked??) |
936 | AM_RANGE(0xc800, 0xdfff) AM_RAM // RAM | |
1020 | AM_RANGE(0xc800, 0xdfff) AM_RAM // RAM | |
937 | 1021 | AM_RANGE(0xe000, 0xffff) AM_READWRITE(suna8_banked_spriteram_r, suna8_banked_spriteram_w) // Sprites (Banked) |
938 | 1022 | ADDRESS_MAP_END |
939 | 1023 | |
r18342 | r18343 | |
997 | 1081 | { |
998 | 1082 | set_led_status(machine(), 0, data & 0x01); |
999 | 1083 | set_led_status(machine(), 1, data & 0x02); |
1000 | //if (data & ~0x03) logerror("CPU#0 | |
1084 | //if (data & ~0x03) logerror("CPU #0 - PC %04X: unknown leds bits: %02X\n",space.device().safe_pc(),data); | |
1001 | 1085 | } |
1002 | 1086 | |
1003 | 1087 | WRITE8_MEMBER(suna8_state::sparkman_coin_counter_w) |
r18342 | r18343 | |
1406 | 1490 | |
1407 | 1491 | |
1408 | 1492 | /*************************************************************************** |
1409 | Hard Head 2 | |
1493 | Hard Head 2 | |
1410 | 1494 | ***************************************************************************/ |
1411 | 1495 | |
1412 | 1496 | static INPUT_PORTS_START( hardhea2 ) |
r18342 | r18343 | |
1480 | 1564 | |
1481 | 1565 | |
1482 | 1566 | /*************************************************************************** |
1567 | Star Fighter | |
1568 | ***************************************************************************/ | |
1569 | ||
1570 | static INPUT_PORTS_START( starfigh ) | |
1571 | ||
1572 | PORT_START("P1") // Player 1 - $c000 | |
1573 | JOY(1) | |
1574 | ||
1575 | PORT_START("P2") // Player 2 - $c001 | |
1576 | JOY(2) | |
1577 | ||
1578 | PORT_START("DSW1") // DSW 1 - $c002 | |
1579 | PORT_DIPNAME( 0x07, 0x07, DEF_STR( Coinage ) ) | |
1580 | PORT_DIPSETTING( 0x00, DEF_STR( 5C_1C ) ) | |
1581 | PORT_DIPSETTING( 0x01, DEF_STR( 4C_1C ) ) | |
1582 | PORT_DIPSETTING( 0x02, DEF_STR( 3C_1C ) ) | |
1583 | PORT_DIPSETTING( 0x03, DEF_STR( 2C_1C ) ) | |
1584 | PORT_DIPSETTING( 0x07, DEF_STR( 1C_1C ) ) | |
1585 | PORT_DIPSETTING( 0x06, DEF_STR( 1C_2C ) ) | |
1586 | PORT_DIPSETTING( 0x05, DEF_STR( 1C_3C ) ) | |
1587 | PORT_DIPSETTING( 0x04, DEF_STR( 1C_4C ) ) | |
1588 | PORT_DIPNAME( 0x38, 0x18, DEF_STR( Difficulty ) ) | |
1589 | PORT_DIPSETTING( 0x38, DEF_STR( Easiest ) ) | |
1590 | PORT_DIPSETTING( 0x30, DEF_STR( Very_Easy) ) | |
1591 | PORT_DIPSETTING( 0x28, DEF_STR( Easy ) ) | |
1592 | PORT_DIPSETTING( 0x20, "Moderate" ) | |
1593 | PORT_DIPSETTING( 0x18, DEF_STR( Normal ) ) | |
1594 | PORT_DIPSETTING( 0x10, DEF_STR( Harder ) ) | |
1595 | PORT_DIPSETTING( 0x08, DEF_STR( Very_Hard ) ) | |
1596 | PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) ) | |
1597 | PORT_SERVICE( 0x40, IP_ACTIVE_LOW ) | |
1598 | PORT_DIPNAME( 0x80, 0x00, DEF_STR( Demo_Sounds ) ) | |
1599 | PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) | |
1600 | PORT_DIPSETTING( 0x00, DEF_STR( On ) ) | |
1601 | ||
1602 | PORT_START("DSW2") // DSW 2 - $c003 | |
1603 | PORT_DIPNAME( 0x01, 0x01, DEF_STR( Flip_Screen ) ) | |
1604 | PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) | |
1605 | PORT_DIPSETTING( 0x00, DEF_STR( On ) ) | |
1606 | PORT_DIPNAME( 0x02, 0x02, DEF_STR( Cabinet ) ) | |
1607 | PORT_DIPSETTING( 0x02, DEF_STR( Upright ) ) | |
1608 | PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) ) | |
1609 | PORT_DIPNAME( 0x04, 0x04, "Play Together" ) | |
1610 | PORT_DIPSETTING( 0x00, DEF_STR( No ) ) | |
1611 | PORT_DIPSETTING( 0x04, DEF_STR( Yes ) ) | |
1612 | PORT_DIPNAME( 0x38, 0x38, DEF_STR( Bonus_Life ) ) | |
1613 | PORT_DIPSETTING( 0x30, "10K" ) | |
1614 | PORT_DIPSETTING( 0x28, "30K" ) | |
1615 | PORT_DIPSETTING( 0x18, "50K, Every 50K" ) | |
1616 | PORT_DIPSETTING( 0x20, "50K" ) | |
1617 | PORT_DIPSETTING( 0x10, "100K, Every 50K" ) | |
1618 | PORT_DIPSETTING( 0x08, "100K, Every 100K" ) | |
1619 | PORT_DIPSETTING( 0x00, "200K, Every 100K" ) | |
1620 | PORT_DIPSETTING( 0x38, DEF_STR( None ) ) | |
1621 | PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Lives ) ) | |
1622 | PORT_DIPSETTING( 0x80, "2" ) | |
1623 | PORT_DIPSETTING( 0xc0, "3" ) | |
1624 | PORT_DIPSETTING( 0x40, "4" ) | |
1625 | PORT_DIPSETTING( 0x00, "5" ) | |
1626 | ||
1627 | PORT_START("CHEATS") // ??? - $c080 | |
1628 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) | |
1629 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) | |
1630 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) | |
1631 | PORT_CONFNAME( 0x08, 0x08, "3: Copyright Screen Color + ?" ) // also changes a table | |
1632 | PORT_CONFSETTING( 0x08, "Green" ) | |
1633 | PORT_CONFSETTING( 0x00, "Blue" ) | |
1634 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) | |
1635 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) | |
1636 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen") // 0 = skip color cycling (red) | |
1637 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SPECIAL ) // read in protection check, see code at 787 | |
1638 | ||
1639 | INPUT_PORTS_END | |
1640 | ||
1641 | ||
1642 | /*************************************************************************** | |
1483 | 1643 | Spark Man |
1484 | 1644 | ***************************************************************************/ |
1485 | 1645 | |
r18342 | r18343 | |
1737 | 1897 | soundirq /* IRQ Line */ |
1738 | 1898 | }; |
1739 | 1899 | |
1740 | TIMER_DEVICE_CALLBACK_MEMBER(suna8_state::brickzn_interrupt) | |
1741 | { | |
1742 | int scanline = param; | |
1743 | ||
1744 | if(scanline == 240) | |
1745 | m_maincpu->set_input_line(0, HOLD_LINE); | |
1746 | if(scanline == 112) | |
1747 | m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); | |
1748 | ||
1749 | // TODO: NMI enable | |
1750 | } | |
1751 | ||
1752 | ||
1753 | 1900 | MACHINE_RESET_MEMBER(suna8_state,brickzn) |
1754 | 1901 | { |
1755 | 1902 | m_protection_val = m_prot2 = m_prot2_prev = 0xff; |
r18342 | r18343 | |
1865 | 2012 | /* basic machine hardware */ |
1866 | 2013 | MCFG_CPU_ADD("maincpu", Z80, SUNA8_MASTER_CLOCK / 4) /* ? */ |
1867 | 2014 | MCFG_CPU_PROGRAM_MAP(starfigh_map) |
1868 | MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", suna8_state, | |
2015 | MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", suna8_state, hardhea2_interrupt, "screen", 0, 1) | |
1869 | 2016 | |
1870 | 2017 | /* The sound section is identical to that of hardhead */ |
1871 | 2018 | MCFG_CPU_ADD("audiocpu", Z80, SUNA8_MASTER_CLOCK / 4) /* ? */ |
r18342 | r18343 | |
1884 | 2031 | MCFG_GFXDECODE(suna8) |
1885 | 2032 | MCFG_PALETTE_LENGTH(256) |
1886 | 2033 | |
1887 | MCFG_VIDEO_START_OVERRIDE(suna8_state,suna8_textdim0) | |
2034 | MCFG_VIDEO_START_OVERRIDE(suna8_state,suna8_textdim0_gfxbank) | |
1888 | 2035 | |
1889 | 2036 | /* sound hardware */ |
1890 | 2037 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
r18342 | r18343 | |
2404 | 2551 | ROM_LOAD( "starfgtr.q10", 0x0000, 0x8000, CRC(fa510e94) SHA1(e2742385a4ba152dbc89534e4350d1d9ad49730f) ) |
2405 | 2552 | |
2406 | 2553 | ROM_REGION( 0x100000, "gfx1", ROMREGION_INVERT ) /* Sprites */ |
2407 | ROM_LOAD( "starfgtr.e4", 0x00000, 0x10000, CRC(54c0ca3d) SHA1(87f785502beb8a52d47bd48275d695ee303054f8) ) | |
2408 | ROM_RELOAD( 0x20000, 0x10000 ) | |
2409 | ROM_LOAD( "starfgtr.d4", 0x10000, 0x10000, CRC(4313ba40) SHA1(3c41f99dc40136517f172b3525987d8909f877c3) ) | |
2410 | ROM_RELOAD( 0x30000, 0x10000 ) | |
2411 | ROM_LOAD( "starfgtr.b4", 0x40000, 0x10000, CRC(ad8d0f21) SHA1(ffdb407c7fe76b5f290de6bbed2fec34e40daf3f) ) | |
2412 | ROM_RELOAD( 0x60000, 0x10000 ) | |
2413 | ROM_LOAD( "starfgtr.a4", 0x50000, 0x10000, CRC(6d8f74c8) SHA1(c40b77e27bd29d6c3a9b4d43189933c10543786b) ) | |
2414 | ROM_RELOAD( 0x70000, 0x10000 ) | |
2415 | ROM_LOAD( "starfgtr.e6", 0x80000, 0x10000, CRC(ceff00ff) SHA1(5e7df7f33f36f4bc511be48266eaec274dfb8706) ) | |
2416 | ROM_RELOAD( 0xa0000, 0x10000 ) | |
2417 | ROM_LOAD( "starfgtr.d6", 0x90000, 0x10000, CRC(7aaa358a) SHA1(56d75f4abe626de7923d5bcc9ad18c02ce162907) ) | |
2418 | ROM_RELOAD( 0xb0000, 0x10000 ) | |
2419 | ROM_LOAD( "starfgtr.b6", 0xc0000, 0x10000, CRC(47d6049c) SHA1(cae0795a19cb6bb8bdabc10c200aa6f8d78dd347) ) | |
2420 | ROM_RELOAD( 0xe0000, 0x10000 ) | |
2421 | ROM_LOAD( "starfgtr.a6", 0xd0000, 0x10000, CRC(4a33f6f3) SHA1(daa0a1a43b1b60e2f05b9934fdd6b5f285a0b93a) ) | |
2422 | ROM_RELOAD( 0xf0000, 0x10000 ) | |
2554 | // bitplanes 0-1 | |
2555 | ROM_LOAD( "starfgtr.e4", 0x00000, 0x10000, CRC(54c0ca3d) SHA1(87f785502beb8a52d47bd48275d695ee303054f8) ) // banks 00-03 | |
2556 | ROM_LOAD( "starfgtr.d4", 0x10000, 0x10000, CRC(4313ba40) SHA1(3c41f99dc40136517f172b3525987d8909f877c3) ) // banks 04-07 | |
2557 | ROM_COPY( "gfx1", 0x00000, 0x20000, 0x20000 ) // banks 08-0f == 00-07 | |
2558 | ROM_LOAD( "starfgtr.b4", 0x40000, 0x10000, CRC(ad8d0f21) SHA1(ffdb407c7fe76b5f290de6bbed2fec34e40daf3f) ) // banks 10-13 | |
2559 | ROM_LOAD( "starfgtr.a4", 0x50000, 0x10000, CRC(6d8f74c8) SHA1(c40b77e27bd29d6c3a9b4d43189933c10543786b) ) // banks 14-17 | |
2560 | ROM_COPY( "gfx1", 0x40000, 0x60000, 0x20000 ) // banks 18-1f == 10-17 | |
2561 | ||
2562 | // bitplanes 2-3 | |
2563 | ROM_LOAD( "starfgtr.e6", 0x80000, 0x10000, CRC(ceff00ff) SHA1(5e7df7f33f36f4bc511be48266eaec274dfb8706) ) | |
2564 | ROM_LOAD( "starfgtr.d6", 0x90000, 0x10000, CRC(7aaa358a) SHA1(56d75f4abe626de7923d5bcc9ad18c02ce162907) ) | |
2565 | ROM_COPY( "gfx1", 0x80000, 0xa0000, 0x20000 ) | |
2566 | ROM_LOAD( "starfgtr.b6", 0xc0000, 0x10000, CRC(47d6049c) SHA1(cae0795a19cb6bb8bdabc10c200aa6f8d78dd347) ) | |
2567 | ROM_LOAD( "starfgtr.a6", 0xd0000, 0x10000, CRC(4a33f6f3) SHA1(daa0a1a43b1b60e2f05b9934fdd6b5f285a0b93a) ) | |
2568 | ROM_COPY( "gfx1", 0xc0000, 0xe0000, 0x20000 ) | |
2423 | 2569 | ROM_END |
2424 | 2570 | |
2425 | 2571 | |
r18342 | r18343 | |
2517 | 2663 | GAME( 1988, hardhead, 0, hardhead, hardhead, suna8_state, hardhead, ROT0, "SunA", "Hard Head", 0 ) |
2518 | 2664 | GAME( 1988, hardheadb, hardhead, hardhead, hardhead, suna8_state, hardhedb, ROT0, "bootleg", "Hard Head (bootleg)", 0 ) |
2519 | 2665 | GAME( 1988, pop_hh, hardhead, hardhead, hardhead, suna8_state, hardhedb, ROT0, "bootleg", "Popper (Hard Head bootleg)", 0 ) |
2666 | GAME( 1990, starfigh, 0, starfigh, starfigh, suna8_state, starfigh, ROT90, "SunA", "Star Fighter (v1)", 0 ) | |
2520 | 2667 | GAME( 1991, hardhea2, 0, hardhea2, hardhea2, suna8_state, hardhea2, ROT0, "SunA", "Hard Head 2 (v2.0)", 0 ) |
2521 | 2668 | GAME( 1992, brickzn, 0, brickzn, brickzn, suna8_state, brickzn, ROT90, "SunA", "Brick Zone (v5.0, Joystick)", 0 ) |
2522 | 2669 | GAME( 1992, brickznv4, brickzn, brickzn, brickzn, suna8_state, brickznv4, ROT90, "SunA", "Brick Zone (v4.0, Spinner)", 0 ) |
r18342 | r18343 | |
2524 | 2671 | // Non Working Games |
2525 | 2672 | GAME( 1989, sparkman, 0, sparkman, sparkman, suna8_state, sparkman, ROT0, "SunA", "Spark Man (v2.0, set 1)", GAME_NOT_WORKING ) |
2526 | 2673 | GAME( 1989, sparkmana, sparkman, sparkman, sparkman, suna8_state, sparkman, ROT0, "SunA", "Spark Man (v2.0, set 2)", GAME_NOT_WORKING ) |
2527 | GAME( 1990, starfigh, 0, starfigh, hardhea2, suna8_state, starfigh, ROT90, "SunA", "Star Fighter (v1)", GAME_NOT_WORKING ) |
r18342 | r18343 | |
---|---|---|
1 | 1 | /* |
2 | ||
3 | 2 | SunA 8 Bit Games samples |
4 | 3 | |
5 | Format: PCM unsigned 8 bit mono 4Khz | |
6 | ||
4 | Format: PCM unsigned 4 bit mono 8kHz | |
7 | 5 | */ |
8 | 6 | |
9 | 7 | #include "emu.h" |
10 | 8 | #include "sound/samples.h" |
11 | 9 | #include "includes/suna8.h" |
12 | 10 | |
11 | #define FREQ_HZ 8000 | |
12 | #define NUMSAMPLES 0x1000 | |
13 | 13 | |
14 | 14 | WRITE8_MEMBER(suna8_state::suna8_play_samples_w) |
15 | 15 | { |
16 | if( data ) | |
16 | if ( data ) | |
17 | 17 | { |
18 | 18 | samples_device *samples = downcast<samples_device *>(machine().device("samples")); |
19 | if( ~data & 0x10 ) | |
19 | if ( ~data & 0x10 ) | |
20 | 20 | { |
21 | samples->start_raw(0, &m_samplebuf[ | |
21 | samples->start_raw(0, &m_samplebuf[NUMSAMPLES * m_sample], NUMSAMPLES, FREQ_HZ); | |
22 | 22 | } |
23 | else if( ~data & 0x08 ) | |
23 | else if ( ~data & 0x08 ) | |
24 | 24 | { |
25 | 25 | m_sample &= 3; |
26 | samples->start_raw(0, &m_samplebuf[ | |
26 | samples->start_raw(0, &m_samplebuf[NUMSAMPLES * (m_sample+7)], NUMSAMPLES, FREQ_HZ); | |
27 | 27 | } |
28 | 28 | } |
29 | 29 | } |
30 | 30 | |
31 | 31 | WRITE8_MEMBER(suna8_state::rranger_play_samples_w) |
32 | 32 | { |
33 | if | |
33 | if (data) | |
34 | 34 | { |
35 | if(( m_sample != 0 ) && ( ~data & 0x30 )) // don't play | |
35 | if (( m_sample != 0 ) && ( ~data & 0x30 )) // don't play sample zero when those bits are active | |
36 | 36 | { |
37 | 37 | samples_device *samples = downcast<samples_device *>(machine().device("samples")); |
38 | samples->start_raw(0, &m_samplebuf[ | |
38 | samples->start_raw(0, &m_samplebuf[NUMSAMPLES * m_sample], NUMSAMPLES, FREQ_HZ); | |
39 | 39 | } |
40 | 40 | } |
41 | 41 | } |
r18342 | r18343 | |
49 | 49 | { |
50 | 50 | suna8_state *state = device.machine().driver_data<suna8_state>(); |
51 | 51 | running_machine &machine = device.machine(); |
52 | int i, len = state->memregion("samples")->bytes(); | |
52 | ||
53 | int i, len = state->memregion("samples")->bytes() * 2; // 2 samples per byte | |
53 | 54 | UINT8 *ROM = state->memregion("samples")->base(); |
54 | 55 | |
55 | 56 | state->m_samplebuf = auto_alloc_array(machine, INT16, len); |
56 | 57 | |
57 | for(i=0;i<len;i++) | |
58 | state->m_samplebuf[i] = (INT8)(ROM[i] ^ 0x80) * 256; | |
58 | // Convert 4 bit to 16 bit samples | |
59 | for(i = 0; i < len; i++) | |
60 | state->m_samplebuf[i] = (INT8)(((ROM[i/2] << ((i & 1)?0:4)) & 0xf0) ^ 0x80) * 0x100; | |
59 | 61 | } |
r18342 | r18343 | |
---|---|---|
107 | 107 | |
108 | 108 | READ8_MEMBER(suna8_state::suna8_banked_spriteram_r) |
109 | 109 | { |
110 | ||
111 | 110 | offset += m_spritebank * 0x2000; |
112 | 111 | return m_spriteram[offset]; |
113 | 112 | } |
114 | 113 | |
115 | 114 | WRITE8_MEMBER(suna8_state::suna8_spriteram_w) |
116 | 115 | { |
117 | ||
118 | 116 | m_spriteram[offset] = data; |
119 | 117 | #if TILEMAPS |
120 | 118 | m_bg_tilemap->mark_tile_dirty(offset/2); |
r18342 | r18343 | |
123 | 121 | |
124 | 122 | WRITE8_MEMBER(suna8_state::suna8_banked_spriteram_w) |
125 | 123 | { |
126 | ||
127 | 124 | offset += m_spritebank * 0x2000; |
128 | 125 | m_spriteram[offset] = data; |
129 | 126 | #if TILEMAPS |
r18342 | r18343 | |
188 | 185 | |
189 | 186 | state->m_text_dim = dim; |
190 | 187 | state->m_spritebank = 0; |
188 | state->m_gfxbank = 0; | |
189 | state->m_use_gfxbank = 0; | |
191 | 190 | state->m_palettebank = 0; |
192 | 191 | |
193 | 192 | if (!state->m_text_dim) |
194 | 193 | { |
195 | 194 | state->m_generic_paletteram_8.allocate(0x200 * 2); |
196 | 195 | state->m_spriteram.allocate(0x2000 * 2); |
196 | memset(state->m_spriteram,0,0x2000 * 2); // helps debugging | |
197 | 197 | } |
198 | 198 | |
199 | 199 | #if TILEMAPS |
200 | 200 | state->m_bg_tilemap = &machine.tilemap().create(tilemap_get_info_delegate(FUNC(suna8_state::get_tile_info),state), TILEMAP_SCAN_COLS, |
201 | 201 | |
202 | 8, 8, 0x20*( | |
202 | 8, 8, 0x20*(state->m_text_dim ? 4 : 8), 0x20); | |
203 | 203 | |
204 | 204 | state->m_bg_tilemap->set_transparent_pen(15); |
205 | 205 | #endif |
206 | 206 | } |
207 | 207 | |
208 | VIDEO_START_MEMBER(suna8_state,suna8_textdim0){ suna8_vh_start_common(machine(), 0); } | |
209 | VIDEO_START_MEMBER(suna8_state,suna8_textdim8){ suna8_vh_start_common(machine(), 8); } | |
210 | VIDEO_START_MEMBER(suna8_state,suna8_textdim12){ suna8_vh_start_common(machine(), 12); } | |
208 | VIDEO_START_MEMBER(suna8_state,suna8_textdim0) { suna8_vh_start_common(machine(), 0); } | |
209 | VIDEO_START_MEMBER(suna8_state,suna8_textdim8) { suna8_vh_start_common(machine(), 8); } | |
210 | VIDEO_START_MEMBER(suna8_state,suna8_textdim12) { suna8_vh_start_common(machine(), 12); } | |
211 | 211 | |
212 | VIDEO_START_MEMBER(suna8_state,suna8_textdim0_gfxbank) { suna8_vh_start_common(machine(), 0); m_use_gfxbank = 1; } | |
213 | ||
212 | 214 | /*************************************************************************** |
213 | 215 | |
214 | 216 | |
r18342 | r18343 | |
237 | 239 | int x = spriteram[i + 2]; |
238 | 240 | int bank = spriteram[i + 3]; |
239 | 241 | |
240 | if (state->m_text_dim | |
242 | if (state->m_text_dim) | |
241 | 243 | { |
242 | / | |
244 | // Older, simpler hardware: hardhead, rranger | |
243 | 245 | flipx = 0; |
244 | 246 | flipy = 0; |
245 | 247 | gfxbank = bank & 0x3f; |
r18342 | r18343 | |
261 | 263 | } |
262 | 264 | else |
263 | 265 | { |
264 | / | |
266 | // Newer, more complex hardware: brickzn, hardhea2, sparkman?, starfigh | |
265 | 267 | switch( code & 0xc0 ) |
266 | 268 | { |
267 | 269 | case 0xc0: |
r18342 | r18343 | |
287 | 289 | flipx = code & 0x01; |
288 | 290 | flipy = bank & 0x10; |
289 | 291 | srcy = (((bank & 0x80)>>4) + (bank & 0x04) + ((~bank >> 4)&2)) * 2; |
290 | srcpg = (code >> 4) & 7; | |
291 | gfxbank = (bank & 0x3) + (srcpg & 4); // brickzn: 06,a6,a2,b2->6. starfigh: 01->01,4->0 | |
292 | srcpg = ((code >> 4) & 3) + 4; | |
293 | gfxbank = (bank & 0x3) + 4; // brickzn: 06,a6,a2,b2->6 | |
294 | if (state->m_use_gfxbank) | |
295 | { | |
296 | // starfigh: boss 2 head, should be p7 g7 x8/c y4: | |
297 | // 67 74 88 03 | |
298 | // 67 76 ac 03 | |
299 | // starfigh: boss 2 chainguns should be p6 g7: | |
300 | // a8 68/a/c/e 62 23 | |
301 | // 48 68/a/c/e 62 23 | |
302 | // starfigh: player, p4 g0: | |
303 | // 64 40 d3 20 | |
304 | // starfigh: title star, p5 g1 / p7 g0: | |
305 | // 70 56/8/a/c 0e 01 (gfxhi=1) | |
306 | // 6f 78/a/c/e 0f 04 "" | |
307 | gfxbank = (bank & 0x3); | |
308 | if (gfxbank == 3) gfxbank += state->m_gfxbank; | |
309 | } | |
292 | 310 | colorbank = (bank & 8) >> 3; |
293 | 311 | break; |
294 | 312 | case 0x00: |
r18342 | r18343 | |
297 | 315 | srcx = (code & 0xf) * 2; |
298 | 316 | flipx = 0; |
299 | 317 | flipy = 0; |
300 | gfxbank = bank & 0x03; | |
301 | 318 | srcy = (((bank & 0x80)>>4) + (bank & 0x04) + ((~bank >> 4)&3)) * 2; |
302 | 319 | srcpg = (code >> 4) & 3; |
320 | gfxbank = bank & 0x03; | |
321 | if (state->m_use_gfxbank) | |
322 | { | |
323 | // starfigh: boss 2 tail, p2 g7: | |
324 | // 61 20 1b 27 | |
325 | if (gfxbank == 3) gfxbank += state->m_gfxbank; | |
326 | } | |
303 | 327 | break; |
304 | 328 | } |
305 | 329 | multisprite = ((code & 0x80) && (bank & 0x80)); |
r18342 | r18343 | |
361 | 385 | int max_y = machine.primary_screen->height() - 8; |
362 | 386 | |
363 | 387 | /* Earlier games only */ |
364 | if (! | |
388 | if (!state->m_text_dim) return; | |
365 | 389 | |
366 | 390 | for (i = 0x1900; i < 0x19ff; i += 4) |
367 | 391 | { |
r18342 | r18343 | |
446 | 470 | if (machine().input().code_pressed_once(KEYCODE_S)) { m_trombank++; machine().tilemap().mark_all_dirty(); } |
447 | 471 | |
448 | 472 | m_rombank &= 0xf; |
449 | m_page &= | |
473 | m_page &= m_text_dim ? 3 : 7; | |
450 | 474 | m_tiles %= max_tiles; |
451 | 475 | if (m_tiles < 0) m_tiles += max_tiles; |
452 | 476 |
r18342 | r18343 | |
---|---|---|
19 | 19 | optional_shared_ptr<UINT8> m_wram; |
20 | 20 | |
21 | 21 | UINT8 m_rombank; |
22 | UINT8 m_rombank_latch; | |
22 | 23 | UINT8 m_spritebank; |
24 | UINT8 m_gfxbank; // starfigh | |
25 | UINT8 m_use_gfxbank; // "" | |
23 | 26 | UINT8 m_palettebank; |
24 | 27 | UINT8 m_paletteram_enab; |
25 | 28 | UINT8 m_prot2; |
r18342 | r18343 | |
72 | 75 | DECLARE_WRITE8_MEMBER(hardhea2_spritebank_1_w); |
73 | 76 | DECLARE_WRITE8_MEMBER(hardhea2_rambank_0_w); |
74 | 77 | DECLARE_WRITE8_MEMBER(hardhea2_rambank_1_w); |
78 | ||
79 | // starfigh | |
80 | DECLARE_WRITE8_MEMBER(starfigh_rombank_latch_w); | |
75 | 81 | DECLARE_WRITE8_MEMBER(starfigh_spritebank_latch_w); |
82 | DECLARE_WRITE8_MEMBER(starfigh_sound_latch_w); | |
76 | 83 | DECLARE_WRITE8_MEMBER(starfigh_spritebank_w); |
84 | DECLARE_READ8_MEMBER(starfigh_cheats_r); | |
85 | DECLARE_WRITE8_MEMBER(starfigh_leds_w); | |
86 | ||
77 | 87 | DECLARE_WRITE8_MEMBER(sparkman_cmd_prot_w); |
78 | 88 | DECLARE_WRITE8_MEMBER(suna8_wram_w); |
79 | 89 | DECLARE_WRITE8_MEMBER(sparkman_flipscreen_w); |
r18342 | r18343 | |
102 | 112 | DECLARE_VIDEO_START(suna8_textdim8); |
103 | 113 | DECLARE_MACHINE_RESET(brickzn); |
104 | 114 | DECLARE_VIDEO_START(suna8_textdim0); |
115 | DECLARE_VIDEO_START(suna8_textdim0_gfxbank); | |
105 | 116 | DECLARE_MACHINE_RESET(hardhea2); |
106 | 117 | UINT32 screen_update_suna8(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
107 | 118 | TIMER_DEVICE_CALLBACK_MEMBER(brickzn_interrupt); |
Previous | 199869 Revisions | Next |