diff --git a/src/mame/drivers/armedf.c b/src/mame/drivers/armedf.c index 22ba228b802..e744546a93b 100644 --- a/src/mame/drivers/armedf.c +++ b/src/mame/drivers/armedf.c @@ -24,8 +24,8 @@ TODO: - simulate the mcu/blitter (particularly needed in terrafu and legion) -- or figure out which chip it is, decap it, and emulate it. - time over doesn't kill the player in Kodure Ookami; -- attract mode has a glitch with the "Terra Force" title screen at the left-right edges of the screen. - could be due of protection; +- intro in Terra Force isn't right, the square panels should be cleared after every + animation is played, almost likely to not be protection related; - priorities, especially with the text layer (Terra Force); @@ -181,26 +181,219 @@ static WRITE16_HANDLER( io_w ) flip_screen_set(space->machine(), state->m_vreg & 0x1000); } +static void terrafu_sm_transfer(address_space *space,UINT16 src,UINT16 dst,UINT8 size) +{ + armedf_state *state = space->machine().driver_data(); + UINT8 * data = (UINT8 *)space->machine().region("gfx5")->base(); + int i; + + for(i=0;im_text_videoram[i+dst+0x000] = data[i+0x0+src] & 0xff; + state->m_text_videoram[i+dst+0x400] = data[i+0xc+src] & 0xff; + } +} + +static void terrafu_sm_onoff(address_space *space,UINT16 dst,UINT8 condition) +{ + armedf_state *state = space->machine().driver_data(); + UINT8 * data = (UINT8 *)space->machine().region("gfx5")->base(); + int i; +// char on_string[] = { "O", "N", " " }; + const UINT8 on_string[4] = { "ON " }; + + for(i=0;i<3;i++) + { + state->m_text_videoram[i+dst+0x000] = (condition) ? (data[i+0x0+0x316] & 0xff) : (on_string[i] & 0xff); + state->m_text_videoram[i+dst+0x400] = 0x10; + } +} + +/* Note: just before any string in the "MCU" rom, there's an offset, it indicates where the string should go in the tilemap. + This is currently hard-coded */ +static void terrafu_mcu_exec(address_space *space,UINT16 mcu_cmd) +{ + armedf_state *state = space->machine().driver_data(); + UINT8 * data = (UINT8 *)space->machine().region("gfx5")->base(); + int i; + int credit_count = (state->m_text_videoram[0xf] & 0xff); + UINT8 fl_cond = space->machine().primary_screen->frame_number() & 0x10; /* for insert coin "flickering" */ + + switch(mcu_cmd) + { + case 0x0e00: + break; + case 0x0e1c: /* gameplay, unknown ... */ + break; + case 0x0e80: /* attract demo */ + for(i=0;i<0x10;i++) /* CREDIT */ + { + state->m_text_videoram[i+0x050+0x0000] = data[i+0x00+0x0025] & 0xff; + state->m_text_videoram[i+0x050+0x0400] = data[i+0x10+0x0025] & 0xff; + } + state->m_text_videoram[0x05f+0x000] = ((credit_count) + 0x10); + state->m_text_videoram[0x05f+0x400] = (0x40); + + for(i=0;i<0x10;i++) /* INSERT COIN */ + { + state->m_text_videoram[i+0x16a+0x0000] = (fl_cond) ? 0x20 : data[i+0x00+0x0003] & 0xff; + state->m_text_videoram[i+0x16a+0x0400] = data[i+0x10+0x0003] & 0xff; + } + + for(i=0;i<0x10;i++) /* GAME OVER */ + { + state->m_text_videoram[i+0x1a8+0x0000] = data[i+0x00+0x0135] & 0xff; + state->m_text_videoram[i+0x1a8+0x0400] = data[i+0x10+0x0135] & 0xff; + } + break; + case 0x0000: /* title screen / continue */ + for(i=0;i<0x10;i++) + { + state->m_text_videoram[i+0x050+0x0000] = data[i+0x00+0x0025] & 0xff; + state->m_text_videoram[i+0x050+0x0400] = data[i+0x10+0x0025] & 0xff; + } + state->m_text_videoram[0x05f+0x000] = (credit_count + 0x10); + state->m_text_videoram[0x05f+0x400] = (0x40); + + if(credit_count == 0) + { + for(i=0;i<0x10;i++) /* INSERT COIN */ + { + state->m_text_videoram[i+0x16a+0x0000] = (fl_cond) ? 0x20 : data[i+0x00+0x0003] & 0xff; + state->m_text_videoram[i+0x16a+0x0400] = data[i+0x10+0x0003] & 0xff; + } + } + else + { + for(i=0;i<0x18;i++) /* PUSH START BUTTON (0x1a8? Gets wrong on the continue with this ...) */ + { + state->m_text_videoram[i+0x128+0x0000] = data[i+0x00+0x004b] & 0xff; + state->m_text_videoram[i+0x128+0x0400] = data[i+0x18+0x004b] & 0xff; + } + } + + if(credit_count == 1) + { + for(i=0;i<0x18;i++) /* ONE PLAYER ONLY */ + { + state->m_text_videoram[i+0x168+0x0000] = data[i+0x00+0x007d] & 0xff; + state->m_text_videoram[i+0x168+0x0400] = data[i+0x18+0x007d] & 0xff; + } + } + else if(credit_count > 1) + { + for(i=0;i<0x18;i++) /* ONE OR TWO PLAYERS */ + { + state->m_text_videoram[i+0x168+0x0000] = data[i+0x00+0x00af] & 0xff; + state->m_text_videoram[i+0x168+0x0400] = data[i+0x18+0x00af] & 0xff; + } + } + + break; + case 0x0280: /* layer clearances */ + case 0x0282: + for(i=0;i<0x400;i++) + { + state->m_text_videoram[i+0x000+0x0000] = data[i+0x000+0x2800] & 0xff; + state->m_text_videoram[i+0x000+0x0400] = data[i+0x400+0x2800] & 0xff; + } + break; + case 0x0200: /* Nichibutsu logo */ + case 0x0201: + for(i=0;i<0x400;i++) + { + state->m_text_videoram[i+0x000+0x0000] = data[i+0x000+0x2000] & 0xff; + state->m_text_videoram[i+0x000+0x0400] = data[i+0x400+0x2000] & 0xff; + } + break; + case 0x600: /* service mode */ + for(i=0;i<0x400;i++) + { + if((state->m_text_videoram[i+0x000+0x0000] & 0xff00) == 0xff00) /* uhm, avoids bonus awards overwrite? */ + continue; + + state->m_text_videoram[i+0x000+0x0000] = data[i+0x000+0x3000] & 0xff; + state->m_text_videoram[i+0x000+0x0400] = data[i+0x400+0x3000] & 0xff; + } + state->m_text_videoram[0x252+0x000] = ((state->m_text_videoram[0x11] & 0xf0) >> 4) + 0x10; + state->m_text_videoram[0x253+0x000] = (state->m_text_videoram[0x11] & 0x0f) + 0x10; + state->m_text_videoram[0x252+0x400] = (0x40); + state->m_text_videoram[0x253+0x400] = (0x40); + + /* + [0x02] & 0x01 p1 up + [0x02] & 0x02 p1 down + [0x02] & 0x04 p1 left + [0x02] & 0x08 p1 right + [0x02] & 0x10 p1 button 1 + [0x02] & 0x20 p1 button 2 + [0x02] & 0x40 p1 button 3 + [0x03] & 0x01 p2 up + [0x03] & 0x02 p2 down + [0x03] & 0x04 p2 left + [0x03] & 0x08 p2 right + [0x03] & 0x10 p2 button 1 + [0x03] & 0x20 p2 button 2 + [0x03] & 0x40 p2 button 3 + [0x04] & 0x10 service + [0x04] & 0x04 coin A + [0x04] & 0x08 coin B + [0x04] & 0x01 start 1 + [0x04] & 0x02 start 2 + [0x05] DSW1 + [0x06] DSW2 + [0x07] & 0x40 demo sounds ON / OFF + [0x07] & 0x7 lives setting + [0x07] & 0x80 cabinet (upright / table) + [0x07] & 0x30 difficulty (easy / normal / hard / hardest) + [0x0f] coinage A + [0x10] coinage B + */ + state->m_text_videoram[0x3bb|0x000] = (state->m_text_videoram[7] & 0x7) + 0x10; + state->m_text_videoram[0x3bb|0x400] = (0x40); + + terrafu_sm_transfer(space,0x1fa + (((state->m_text_videoram[7] & 0x30) >> 4) * 0x18),0x390,12); + terrafu_sm_transfer(space,0x264 + (((state->m_text_videoram[7] & 0x80) >> 7) * 0x18),0x330,12); + terrafu_sm_transfer(space,0x296 + (((state->m_text_videoram[7] & 0x40) >> 6) * 0x18),0x310,12); + + state->m_text_videoram[0x2ee|0x000] = ((state->m_text_videoram[0xf] & 0xf0) >> 4) + 0x10; + state->m_text_videoram[0x2ee|0x400] = (0x40); + state->m_text_videoram[0x2f5|0x000] = ((state->m_text_videoram[0xf] & 0x0f) >> 0) + 0x10; + state->m_text_videoram[0x2f5|0x400] = (0x40); + state->m_text_videoram[0x2ce|0x000] = ((state->m_text_videoram[0x10] & 0xf0) >> 4) + 0x10; + state->m_text_videoram[0x2ce|0x400] = (0x40); + state->m_text_videoram[0x2d5|0x000] = ((state->m_text_videoram[0x10] & 0x0f) >> 0) + 0x10; + state->m_text_videoram[0x2d5|0x400] = (0x40); + + for(i=0;i<8;i++) /* dips */ + { + terrafu_sm_onoff(space,0x074 + (i * 0x20),(state->m_text_videoram[0x05] >> (7-i)) & 1); + terrafu_sm_onoff(space,0x079 + (i * 0x20),(state->m_text_videoram[0x06] >> (7-i)) & 1); + } + + /* TODO: inputs layout? */ + + break; + //default: + //printf("%04x\n",mcu_cmd); + } +} + static WRITE16_HANDLER( terraf_io_w ) { armedf_state *state = space->machine().driver_data(); + if(data & 0x4000 && ((state->m_vreg & 0x4000) == 0)) //0 -> 1 transition, terrafu only? + { + terrafu_mcu_exec(space,(state->m_text_videoram[0] << 8) | (state->m_text_videoram[1] & 0xff)); + + tilemap_mark_all_tiles_dirty(state->m_tx_tilemap); + } + COMBINE_DATA(&state->m_vreg); /* bits 0 and 1 of armedf_vreg are coin counters */ /* bit 12 seems to handle screen flipping */ flip_screen_set(space->machine(), state->m_vreg & 0x1000); - - if ((state->m_vreg & 0x4000) && !(state->m_vreg & 0x0100)) - { - int i; - for (i = 0x10; i < 0x1000; i++) - { - state->m_text_videoram[i] = 0x20; - } - tilemap_mark_all_tiles_dirty(state->m_tx_tilemap); - //logerror("vreg WIPE TX\n"); - } - //logerror("VReg = %04x\n", state->m_vreg); } static WRITE16_HANDLER( terrafb_io_w ) @@ -1646,9 +1839,9 @@ static DRIVER_INIT( cclimbr2 ) /* YEAR, NAME, PARENT, MACHINE, INPUT, INIT, MONITOR, COMPANY, FULLNAME, FLAGS */ GAME( 1987, legion, 0, legion, legion, legion, ROT270, "Nichibutsu", "Chouji Meikyuu Legion (ver 2.03)", GAME_SUPPORTS_SAVE | GAME_IMPERFECT_GRAPHICS | GAME_UNEMULATED_PROTECTION ) GAME( 1987, legiono, legion, legiono, legion, legiono, ROT270, "Nichibutsu", "Chouji Meikyuu Legion (ver 1.05)", GAME_SUPPORTS_SAVE ) /* bootleg? */ -GAME( 1987, terraf, 0, terraf, terraf, terraf, ROT0, "Nichibutsu", "Terra Force (Japan set 1)", GAME_SUPPORTS_SAVE | GAME_IMPERFECT_GRAPHICS | GAME_UNEMULATED_PROTECTION ) +GAME( 1987, terraf, 0, terraf, terraf, terraf, ROT0, "Nichibutsu", "Terra Force (set 1)", GAME_SUPPORTS_SAVE | GAME_IMPERFECT_GRAPHICS ) //world bootleg? GAME( 1987, terrafb, terraf, terrafb, terraf, terrafb, ROT0, "bootleg", "Terra Force (Japan bootleg with additional Z80)", GAME_SUPPORTS_SAVE | GAME_IMPERFECT_GRAPHICS ) -GAME( 1987, terrafa, terraf, terraf, terraf, terrafu, ROT0, "Nichibutsu", "Terra Force (Japan set 2)", GAME_SUPPORTS_SAVE | GAME_IMPERFECT_GRAPHICS | GAME_UNEMULATED_PROTECTION ) +GAME( 1987, terrafa, terraf, terraf, terraf, terrafu, ROT0, "Nichibutsu", "Terra Force (set 2)", GAME_SUPPORTS_SAVE | GAME_IMPERFECT_GRAPHICS | GAME_UNEMULATED_PROTECTION ) //world? GAME( 1987, terrafu, terraf, terraf, terraf, terrafu, ROT0, "Nichibutsu USA", "Terra Force (US)", GAME_SUPPORTS_SAVE | GAME_IMPERFECT_GRAPHICS | GAME_UNEMULATED_PROTECTION ) GAME( 1987, kodure, 0, kodure, kodure, kodure, ROT0, "Nichibutsu", "Kodure Ookami (Japan)", GAME_SUPPORTS_SAVE | GAME_IMPERFECT_GRAPHICS | GAME_UNEMULATED_PROTECTION | GAME_NOT_WORKING ) GAME( 1988, cclimbr2, 0, cclimbr2, cclimbr2, cclimbr2, ROT0, "Nichibutsu", "Crazy Climber 2 (Japan)", GAME_SUPPORTS_SAVE ) diff --git a/src/mame/video/armedf.c b/src/mame/video/armedf.c index 5f3271b8a92..c34c5f2289d 100644 --- a/src/mame/video/armedf.c +++ b/src/mame/video/armedf.c @@ -332,7 +332,7 @@ SCREEN_UPDATE( armedf ) tilemap_set_enable(state->m_fg_tilemap, state->m_vreg & 0x400); tilemap_set_enable(state->m_tx_tilemap, state->m_vreg & 0x100); - if ((state->m_scroll_type == 0)||(state->m_scroll_type == 5 )) + if ((state->m_scroll_type == 5 )) { if (state->m_old_mcu_mode != state->m_vreg) {