diff --git a/.gitattributes b/.gitattributes index 6a32537ce08..825d3091535 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2203,6 +2203,7 @@ src/mame/includes/leland.h svneol=native#text/plain src/mame/includes/lemmings.h svneol=native#text/plain src/mame/includes/lethalj.h svneol=native#text/plain src/mame/includes/liberatr.h svneol=native#text/plain +src/mame/includes/lockon.h svneol=native#text/plain src/mame/includes/lwings.h svneol=native#text/plain src/mame/includes/m107.h svneol=native#text/plain src/mame/includes/m52.h svneol=native#text/plain @@ -2874,6 +2875,7 @@ src/mame/video/lethalj.c svneol=native#text/plain src/mame/video/liberate.c svneol=native#text/plain src/mame/video/liberatr.c svneol=native#text/plain src/mame/video/lkage.c svneol=native#text/plain +src/mame/video/lockon.c svneol=native#text/plain src/mame/video/lordgun.c svneol=native#text/plain src/mame/video/lsasquad.c svneol=native#text/plain src/mame/video/lvcards.c svneol=native#text/plain diff --git a/src/emu/cpu/nec/nec.c b/src/emu/cpu/nec/nec.c index b7bbb5dfc66..5a9a89ec70a 100644 --- a/src/emu/cpu/nec/nec.c +++ b/src/emu/cpu/nec/nec.c @@ -152,6 +152,7 @@ typedef struct UINT32 pending_irq; UINT32 nmi_state; UINT32 irq_state; + UINT32 poll_state; UINT8 no_interrupt; int (*irq_callback)(int irqline); @@ -224,6 +225,8 @@ static void nec_reset (void) Mod_RM.RM.w[i] = (WREGS)( i & 7 ); Mod_RM.RM.b[i] = (BREGS)reg_name[i & 7]; } + + I.poll_state = 1; } static void nec_exit (void) @@ -637,7 +640,7 @@ OP( 0x97, i_xchg_axdi ) { XchgAWReg(IY); CLK(3); } OP( 0x98, i_cbw ) { I.regs.b[AH] = (I.regs.b[AL] & 0x80) ? 0xff : 0; CLK(2); } OP( 0x99, i_cwd ) { I.regs.w[DW] = (I.regs.b[AH] & 0x80) ? 0xffff : 0; CLK(4); } OP( 0x9a, i_call_far ) { UINT32 tmp, tmp2; FETCHWORD(tmp); FETCHWORD(tmp2); PUSH(I.sregs[PS]); PUSH(I.ip); I.ip = (WORD)tmp; I.sregs[PS] = (WORD)tmp2; CHANGE_PC; CLKW(29,29,13,29,21,9,I.regs.w[SP]); } -OP( 0x9b, i_wait ) { logerror("%06x: Hardware POLL\n",activecpu_get_pc()); } +OP( 0x9b, i_wait ) { if (!I.poll_state) I.ip--; CLK(5); } OP( 0x9c, i_pushf ) { UINT16 tmp = CompressFlags(); PUSH( tmp ); CLKS(12,8,3); } OP( 0x9d, i_popf ) { UINT32 tmp; POP(tmp); ExpandFlags(tmp); CLKS(12,8,5); if (I.TF) nec_trap(); } OP( 0x9e, i_sahf ) { UINT32 tmp = (CompressFlags() & 0xff00) | (I.regs.b[AH] & 0xd5); ExpandFlags(tmp); CLKS(3,3,2); } @@ -998,6 +1001,11 @@ static void set_irq_line(int irqline, int state) } } +static void set_poll_line(int state) +{ + I.poll_state = state; +} + #ifdef MAME_DEBUG static offs_t nec_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram) { @@ -1022,6 +1030,7 @@ static void nec_init(int index, int clock, const void *config, int (*irqcallback state_save_register_item(names[type], index, I.pending_irq); state_save_register_item(names[type], index, I.nmi_state); state_save_register_item(names[type], index, I.irq_state); + state_save_register_item(names[type], index, I.poll_state); state_save_register_item(names[type], index, I.AuxVal); state_save_register_item(names[type], index, I.OverVal); state_save_register_item(names[type], index, I.ZeroVal); @@ -1252,8 +1261,9 @@ static void nec_set_info(UINT32 state, cpuinfo *info) switch (state) { /* --- the following bits of info are set as 64-bit signed integers --- */ - case CPUINFO_INT_INPUT_STATE + 0: set_irq_line(0, info->i); break; - case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: set_irq_line(INPUT_LINE_NMI, info->i); break; + case CPUINFO_INT_INPUT_STATE + 0: set_irq_line(0, info->i); break; + case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: set_irq_line(INPUT_LINE_NMI, info->i); break; + case CPUINFO_INT_INPUT_STATE + NEC_INPUT_LINE_POLL: set_poll_line(info->i); break; case CPUINFO_INT_PC: case CPUINFO_INT_REGISTER + NEC_PC: @@ -1330,8 +1340,9 @@ static void nec_get_info(UINT32 state, cpuinfo *info) case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break; case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break; - case CPUINFO_INT_INPUT_STATE + 0: info->i = (I.pending_irq & INT_IRQ) ? ASSERT_LINE : CLEAR_LINE; break; - case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: info->i = I.nmi_state; break; + case CPUINFO_INT_INPUT_STATE + 0: info->i = (I.pending_irq & INT_IRQ) ? ASSERT_LINE : CLEAR_LINE; break; + case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: info->i = I.nmi_state; break; + case CPUINFO_INT_INPUT_STATE + NEC_INPUT_LINE_POLL: info->i = I.poll_state; break; case CPUINFO_INT_PREVIOUSPC: /* not supported */ break; diff --git a/src/emu/cpu/nec/nec.h b/src/emu/cpu/nec/nec.h index b97251ccddc..cd6ccbf519c 100644 --- a/src/emu/cpu/nec/nec.h +++ b/src/emu/cpu/nec/nec.h @@ -3,7 +3,8 @@ typedef enum { DS1, PS, SS, DS0 } SREGS; typedef enum { AW, CW, DW, BW, SP, BP, IX, IY } WREGS; -#define NEC_NMI_INT_VECTOR 2 +#define NEC_NMI_INT_VECTOR 2 +#define NEC_INPUT_LINE_POLL 20 /* Cpu types, steps of 8 to help the cycle count calculation */ #define V33 0 diff --git a/src/mame/drivers/lockon.c b/src/mame/drivers/lockon.c index 456d3879879..68660a9f272 100644 --- a/src/mame/drivers/lockon.c +++ b/src/mame/drivers/lockon.c @@ -1,763 +1,767 @@ -/*==================================================================== - Lock-On (Tatsumi 1986) - ====================== +/*************************************************************************** - Preliminary Driver by Philip J Bennett - ====================================== + Tatsumi Lock-On hardware -To do -====== + driver by Phil Bennett -Almost everything video related :) + Known bugs: + * None -o Scene tilemap scrolling -o Colours -o Objects -o HUD layer -o Ground layer -o Layer mixing - -=====================================================================*/ +***************************************************************************/ #include "driver.h" #include "deprecat.h" #include "sound/2203intf.h" +#include "sound/flt_vol.h" +#include "lockon.h" -static UINT16 *lockon_vram0; -static UINT16 *lockon_vram1; -static UINT16 *lockon_vram2; -static UINT16 *object_ram; -static UINT16 *ground_ram; -static UINT8 *z80_ram; -static UINT16 *v30_gnd; -static UINT16 *v30_obj; -static UINT16 *clut_ram; - -static int v30_obj_addr=0; -static int v30_gnd_addr=0; -static int main_inten=0; - -static size_t objectram_size; -static size_t lockon_ground_size; - -static tilemap *lockon_tilemap0; -static tilemap *lockon_tilemap1; -static tilemap *lockon_tilemap2; +#define V30_GND_ADDR ((lockon_ctrl_reg & 0x3) << 16) +#define V30_OBJ_ADDR ((lockon_ctrl_reg & 0x18) << 13) -/* -Three sources are mixed at the RGB output PROMs: +/************************************* + * + * Forward definitions + * + *************************************/ -* Characters -* HUD -* Objects/scene/ground +static WRITE8_HANDLER( sound_vol ); +static READ8_HANDLER( adc_r ); -A = !( ((VCDDB6 || VCDDB1) && !VCDDB7) || HUDPT0 ) -B = !( (!HUDPT0 || !VCDDB7) && (VCDDB6 || VCDDB1) ) -A B Layer Colours -0 0 Characters 0-255 -0 1 Characters 256-511 -1 0 HUD 512-767 -1 1 Objects/scene/ground 768-1023 -*/ +/************************************* + * + * Globals + * + *************************************/ -/* Very preliminary! */ -static void draw_sprites(running_machine *machine, mame_bitmap *bitmap,const rectangle *cliprect) +UINT32 lockon_main_inten; +UINT8 lockon_ctrl_reg; + + +/************************************* + * + * Machine functions + * + *************************************/ + + +/************************************* + + Main control register + + 76543210 + |......xx| Ground CPU A17-A16 + |.....x..| /Ground CPU bus req. + |...xx...| Object CPU A17-A16 + |..x.....| /Object CPU bus req. + |.x......| /Z80 bus req. + |x.......| Display enable + +*************************************/ + +static WRITE16_HANDLER( adrst_w ) { - int offs=0; - int index_x=0, index_y=0; + lockon_ctrl_reg = data & 0xff; - UINT16 *ROM_LUTA = (UINT16 *)memory_region(REGION_USER1); - UINT8 *ROM_LUTB = (UINT8 *)memory_region(REGION_USER2); - UINT8 *ROM_LUTC = (UINT8 *)memory_region(REGION_USER2)+0x8000; // Selected by bit 7... - - for (offs = 0x0; offs <= (objectram_size/2); offs += 4) - { - int offs0 = (object_ram[offs+3] & 0x3f) << 8; // Lower 6-bits go into upper ROM portion - int bit7 = (object_ram[offs+3] >> 7) & 0x1; // Selects which ROM to use in calculating lookup - int lut; - - if(!object_ram[offs+2]) - continue; - if((object_ram[offs+3] >> 8) == 0xfc || (object_ram[offs+3] >> 8) == 0xff) // ? - break; - - if(!bit7) - lut = (ROM_LUTC[offs0 | (index_y<<4) | index_x]) & 0x7f; - else - lut = (ROM_LUTB[offs0 | (index_y<<4) | index_x]) & 0x7f; - - // Bits 12,13,14 = bank - // Bits 0-11 obj - for(index_y=0; index_y<8; index_y++) - { - int index_x; - for(index_x=0; index_x<8; index_x++) - { - - /* Index into the object lookup table */ - int ref = object_ram[offs+2] + lut; - - int pix = ROM_LUTA[ref+index_x+(16*index_y)]; // ??? - - int flip_x = 0;//(object_ram[offs+1] >> 7) & 0x1; // Bit 15 - int flip_y = 0;//(object_ram[offs+1] >> 6) & 0x1; // Bit 14 - - int scale_x = 0xffff; //+ object_ram[offs+1] & 0xff; //0x1ffff; - int scale_y = 0xffff; //+ object_ram[offs+1] >> 8; //0x1ffff; - - int sy = 255-(object_ram[offs] & 0xff)+(index_y*8)*(scale_y/0xffff); - int sx = (object_ram[offs] >> 8)+(index_x*8)*(scale_x/0xffff); - - int bank = ((pix >> 12) & 0x7); - int index = pix & 0xfff; - - int color = 1; - - const gfx_element *gfx = machine->gfx[bank]; - - drawgfxzoom(bitmap, gfx, - index, - color, - flip_x,flip_y, // FlipX, flipY - sx,sy, - cliprect,TRANSPARENCY_PEN,1, - scale_x,scale_y); - } - } - } + /* Bus mastering for shared access */ + cpunum_set_input_line(Machine, GROUND_CPU, INPUT_LINE_HALT, data & 0x04 ? ASSERT_LINE : CLEAR_LINE); + cpunum_set_input_line(Machine, OBJECT_CPU, INPUT_LINE_HALT, data & 0x20 ? ASSERT_LINE : CLEAR_LINE); + cpunum_set_input_line(Machine, SOUND_CPU, INPUT_LINE_HALT, data & 0x40 ? CLEAR_LINE : ASSERT_LINE); } -/* Characters */ -static WRITE16_HANDLER( lockon_vram_0_w ) -{ - COMBINE_DATA(&lockon_vram0[offset]); - tilemap_mark_tile_dirty(lockon_tilemap0,offset); -} - -/* Scene */ -static WRITE16_HANDLER( lockon_vram_1_w ) -{ - COMBINE_DATA(&lockon_vram1[offset]); - tilemap_mark_tile_dirty(lockon_tilemap1,offset); -} - -/* HUD */ -static WRITE16_HANDLER( lockon_vram_2_w ) -{ - COMBINE_DATA(&lockon_vram2[offset]); - tilemap_mark_tile_dirty(lockon_tilemap2,offset); -} - -/* 8*8 characters */ -static TILE_GET_INFO( get_lockon_tile_info0 ) -{ - int tileno, color; - tileno = lockon_vram0[tile_index]; - color = 0; - - SET_TILE_INFO(4,tileno,color,0); -} - -/* Scene tiles */ -static TILE_GET_INFO( get_lockon_tile_info1 ) -{ - int tileno, color; - tileno = lockon_vram1[tile_index]; - color = 0; - - SET_TILE_INFO(5,tileno,color,0); -} - -/* HUD tiles */ -static TILE_GET_INFO( get_lockon_tile_info2 ) -{ - int tileno, color; - tileno = lockon_vram2[tile_index]; - color = 0; - - SET_TILE_INFO(6,tileno,color,0); -} - - -static VIDEO_START( lockon ) -{ - lockon_tilemap0 = tilemap_create(get_lockon_tile_info0,tilemap_scan_rows,TILEMAP_TYPE_PEN, 8,8,64,32); - lockon_tilemap1 = tilemap_create(get_lockon_tile_info1,tilemap_scan_rows,TILEMAP_TYPE_PEN, 8,8,64,32); - lockon_tilemap2 = tilemap_create(get_lockon_tile_info2,tilemap_scan_rows,TILEMAP_TYPE_PEN, 8,8,16,16); // HUD -> wrong - tilemap_set_transparent_pen(lockon_tilemap0,0x00); -} - -static VIDEO_UPDATE( lockon ) -{ - tilemap_draw(bitmap,cliprect,lockon_tilemap1,0,0); // Scene - tilemap_draw(bitmap,cliprect,lockon_tilemap0,0,0); // Characters - //tilemap_draw(bitmap,cliprect,lockon_tilemap2,0,0); // HUD - draw_sprites(machine,bitmap,cliprect); - return 0; -} - -/* Wrong last time I checked */ -static INPUT_PORTS_START( lockon ) - PORT_START_TAG("DSW") - PORT_DIPNAME( 0x0003, 0x0000, DEF_STR( Lives ) ) - PORT_DIPSETTING( 0x0000, "5" ) - PORT_DIPSETTING( 0x0001, "4" ) - PORT_DIPSETTING( 0x0002, "2" ) - PORT_DIPSETTING( 0x0003, "3" ) - - PORT_DIPNAME( 0x0006, 0x0008, DEF_STR( Difficulty ) ) - PORT_DIPSETTING( 0x0008, DEF_STR( Easy ) ) - PORT_DIPSETTING( 0x0006, DEF_STR( Normal ) ) - PORT_DIPSETTING( 0x0004, DEF_STR( Hard ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( Hardest ) ) - - PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Bonus_Life ) ) - PORT_DIPSETTING( 0x0010, "150K & every 200K" ) - PORT_DIPSETTING( 0x0000, "200K & every 200K" ) - - PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Allow_Continue ) ) - PORT_DIPSETTING( 0x0020, DEF_STR( No ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( Yes ) ) - - PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Demo_Sounds ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0040, DEF_STR( On ) ) - - PORT_DIPNAME( 0x0300, 0x0000, "Coins" ) - PORT_DIPSETTING( 0x0000, "Free" ) - PORT_DIPSETTING( 0x0100, "4" ) - PORT_DIPSETTING( 0x0200, "2" ) - PORT_DIPSETTING( 0x0300, "3" ) - - PORT_START - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN3 ) // Service coin - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME( DEF_STR( Service_Mode )) PORT_CODE(KEYCODE_F2) PORT_TOGGLE - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) // 'Trigger A' - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 ) // 'Trigger B' - PORT_DIPNAME( 0x40, 0x00, "Jumper 1" ) - PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x80, 0x00, "Jumper 0" ) - PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - - PORT_START_TAG("analog_bank") - PORT_BIT( 0xff, 0x7f, IPT_AD_STICK_X ) PORT_SENSITIVITY(25) PORT_KEYDELTA(15) PORT_PLAYER(1) - - PORT_START_TAG("analog_pitch") - PORT_BIT( 0xff, 0x7f, IPT_AD_STICK_Y ) PORT_SENSITIVITY(25) PORT_KEYDELTA(15) PORT_PLAYER(1) - - PORT_START_TAG("analog_missile") - PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_BUTTON3 ) // Digital input read by ADC - - PORT_START_TAG("analog_hover") - PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_BUTTON4 ) // Digital input read by ADC -INPUT_PORTS_END - - -static READ8_HANDLER(adc_r) -{ - switch(offset) - { - case 0: return readinputportbytag("analog_bank"); - case 1: return readinputportbytag("analog_pitch"); - case 2: return readinputportbytag("analog_missile"); - case 3: return readinputportbytag("analog_hover"); - default: return 0; - } -} - -static READ16_HANDLER(unk_read) -{ - return 1; // Main CPU jumps to 18002 otherwise -} - - -static INTERRUPT_GEN( lockon_irq ) -{ - if(main_inten) - cpunum_set_input_line_and_vector(machine, 0, 0, HOLD_LINE, 0x60/4); - - // Ground CPU takes an interrupt on BUFEND - this is incorrect. - cpunum_set_input_line_and_vector(machine, 1, 0, HOLD_LINE, 0x60/4); -} - -/* - Main CPU control register - ------------------------- - - Bit 0 = MGAB16 Ground CPU A16 - Bit 1 = MGAB17 Ground CPU A17 - Bit 2 = MGABREQ Object CPU Bus Request - Bit 3 = MOAB16 Object CPU A16 - - Bit 4 = MOAB17 Object CPU A17 - Bit 5 = OMLBRQ Object CPU Bus Request - Bit 6 = /ZBRQ Z80 Bus Request - Bit 7 = /ZCCLR Clear screen -*/ - -static WRITE16_HANDLER(adrst_w) -{ - if (ACCESSING_LSB) - { - v30_gnd_addr = (data & 0x3); - v30_obj_addr = (data & 0x18) >> 3; - - if (data & 0x04) - cpunum_set_input_line(Machine, 1, INPUT_LINE_HALT, ASSERT_LINE); - else - cpunum_set_input_line(Machine, 1, INPUT_LINE_HALT, CLEAR_LINE); - - if (data & 0x20) - cpunum_set_input_line(Machine, 2, INPUT_LINE_HALT, ASSERT_LINE); - else - cpunum_set_input_line(Machine, 2, INPUT_LINE_HALT, CLEAR_LINE); - - /* Suspend the Z80 when writing to shared RAM */ - if (data & 0x40) - cpunum_set_input_line(Machine, 3, INPUT_LINE_HALT, CLEAR_LINE); - else - cpunum_set_input_line(Machine, 3, INPUT_LINE_HALT, ASSERT_LINE); - } -} - -static READ16_HANDLER(z80_shared_r) -{ - return z80_ram[offset] | 0xff00; -} - -static WRITE16_HANDLER(z80_shared_w) -{ - if (ACCESSING_LSB) - z80_ram[offset] = data; -} - -static READ16_HANDLER(main_gnd_r) +static READ16_HANDLER( main_gnd_r ) { UINT16 result; - cpuintrf_push_context(1); - result = program_read_word((offset * 2) | (v30_gnd_addr << 16)); + + cpuintrf_push_context(GROUND_CPU); + result = program_read_word(V30_GND_ADDR | offset * 2); cpuintrf_pop_context(); + return result; } -static WRITE16_HANDLER(main_gnd_w) +static WRITE16_HANDLER( main_gnd_w ) { - cpuintrf_push_context(1); + cpuintrf_push_context(GROUND_CPU); + if (ACCESSING_LSB) - program_write_byte((offset * 2 + 0) | (v30_gnd_addr << 16), data); + program_write_byte(V30_GND_ADDR | (offset * 2 + 0), data); if (ACCESSING_MSB) - program_write_byte((offset * 2 + 1) | (v30_gnd_addr << 16), data >> 8); + program_write_byte(V30_GND_ADDR | (offset * 2 + 1), data >> 8); + cpuintrf_pop_context(); } -static READ16_HANDLER(main_obj_r) +static READ16_HANDLER( main_obj_r ) { UINT16 result; - cpuintrf_push_context(2); - result = program_read_word((offset * 2) | (v30_obj_addr << 16)); + + cpuintrf_push_context(OBJECT_CPU); + result = program_read_word(V30_OBJ_ADDR | offset * 2); cpuintrf_pop_context(); + return result; } -static WRITE16_HANDLER(main_obj_w) +static WRITE16_HANDLER( main_obj_w ) { - cpuintrf_push_context(2); + cpuintrf_push_context(OBJECT_CPU); + if (ACCESSING_LSB) - program_write_byte((offset * 2 + 0) | (v30_obj_addr << 16), data); + program_write_byte(V30_OBJ_ADDR | (offset * 2 + 0), data); if (ACCESSING_MSB) - program_write_byte((offset * 2 + 1) | (v30_obj_addr << 16), data >> 8); + program_write_byte(V30_OBJ_ADDR | (offset * 2 + 1), data >> 8); + cpuintrf_pop_context(); } - -static WRITE16_HANDLER(testcs_w) +static WRITE16_HANDLER( tst_w ) { - if (offset < 0x400) + if (offset < 0x800) { - cpuintrf_push_context(1); + cpuintrf_push_context(GROUND_CPU); if (ACCESSING_LSB) - program_write_byte((offset*2+0) | (v30_gnd_addr << 16), data); + program_write_byte(V30_GND_ADDR | (offset * 2 + 0), data); if (ACCESSING_MSB) - program_write_byte((offset*2+1) | (v30_gnd_addr << 16), data >> 8); + program_write_byte(V30_GND_ADDR | (offset * 2 + 1), data >> 8); cpuintrf_pop_context(); - cpuintrf_push_context(2); + cpuintrf_push_context(OBJECT_CPU); if (ACCESSING_LSB) - program_write_byte((offset*2+0) | (v30_obj_addr << 16), data); + program_write_byte(V30_OBJ_ADDR | (offset * 2 + 0), data); if (ACCESSING_MSB) - program_write_byte((offset*2+1) | (v30_obj_addr << 16), data >> 8); + program_write_byte(V30_OBJ_ADDR | (offset * 2 + 1), data >> 8); cpuintrf_pop_context(); } } -/* -The ground register is as follows: - -0 27512x4 A14 -1 27512x4 A15 -2 Select 27512 A -3 Select 27512 B -4 LO3_04A A12 -5 LO3_04A A13 -6 LO3_04A A14 -7 CS - ROMs -*/ -static WRITE16_HANDLER(ground_bank_w) +static READ16_HANDLER( main_z80_r ) { -// Nothing here yet + UINT16 val; + + cpuintrf_push_context(SOUND_CPU); + val = program_read_byte(offset); + cpuintrf_pop_context(); + + return 0xff00 | val; +} + +static WRITE16_HANDLER( main_z80_w ) +{ + cpuintrf_push_context(SOUND_CPU); + program_write_byte(offset, data); + cpuintrf_pop_context(); +} + +static WRITE16_HANDLER( inten_w ) +{ + lockon_main_inten = 1; +} + +static WRITE16_HANDLER( emres_w ) +{ + watchdog_reset_r(0); + lockon_main_inten = 0; } -#ifdef UNUSED_FUNCTION -/* Allow /CUDISP to interrupt main CPU */ -static WRITE8_HANDLER(sound_atten) -{ - mame_printf_debug("%x\n",data); -} -#endif - -/* Allow /CUDISP to interrupt main CPU */ -static WRITE16_HANDLER(inten_w) -{ - main_inten = TRUE; -} - -/* Reset watchdog and mask /CUDISP interrupt */ -static WRITE16_HANDLER(emres_w) -{ - // Implement watchdog reset here. - main_inten = FALSE; -} - +/************************************* + * + * CPU memory maps + * + *************************************/ static ADDRESS_MAP_START( main_v30, ADDRESS_SPACE_PROGRAM, 16 ) - AM_RANGE(0x00000, 0x03fff) AM_RAM // IC69/IC70 - AM_RANGE(0x04000, 0x04003) AM_NOP // CRT Controller - AM_RANGE(0x06000, 0x06001) AM_READ_PORT("DSW") - AM_RANGE(0x08000, 0x081ff) AM_READWRITE(MRA16_RAM,lockon_vram_2_w) AM_BASE(&lockon_vram2) // HUD RAM (IC30/IC31) - AM_RANGE(0x09000, 0x09fff) AM_READWRITE(MRA16_RAM,lockon_vram_0_w) AM_BASE(&lockon_vram0) // Character RAM - AM_RANGE(0x0a000, 0x0a001) AM_WRITE(adrst_w) // /ADRST: CPU access register - AM_RANGE(0x0b000, 0x0bfff) AM_RAM // /BKBCS - ground control registers - AM_RANGE(0x0c000, 0x0cfff) AM_RAM AM_BASE(&clut_ram) // /CCRS - 8kB palette RAM - write only - AM_RANGE(0x0e000, 0x0e001) AM_WRITE(inten_w) // /INTEN: /CUDISP interrupt enable - AM_RANGE(0x0f000, 0x0f001) AM_WRITE(emres_w) // /EMRES: Watchdog reset and interrupt mask - AM_RANGE(0x10000, 0x1ffff) AM_WRITE(testcs_w) // /TESTCS: Write to both object and ground CPU RAM - AM_RANGE(0x18000, 0x18001) AM_READ(unk_read) // Not sure what this is - AM_RANGE(0x20000, 0x2dfff) AM_ROM // Z80 ROM - AM_RANGE(0x2f000, 0x2ffff) AM_READWRITE(z80_shared_r, z80_shared_w) // Z80 shared RAM - AM_RANGE(0x30000, 0x3ffff) AM_READWRITE(main_gnd_r, main_gnd_w) // Ground CPU memory access - AM_RANGE(0x40000, 0x4ffff) AM_READWRITE(main_obj_r, main_obj_w) // Object CPU memory access - AM_RANGE(0x50000, 0x5ffff) AM_ROM // IC76/IC77 - AM_RANGE(0x60000, 0x6ffff) AM_ROM // IC88/IC89 - AM_RANGE(0xf0000, 0xfffff) AM_ROM // IC95/IC96 + ADDRESS_MAP_FLAGS( AMEF_UNMAP(1) ) + AM_RANGE(0x00000, 0x03fff) AM_RAM + AM_RANGE(0x04000, 0x04003) AM_READWRITE(lockon_crtc_r, lockon_crtc_w) + AM_RANGE(0x06000, 0x06001) AM_READ(input_port_0_word_r) + AM_RANGE(0x08000, 0x081ff) AM_RAM AM_BASE(&lockon_hud_ram) AM_SIZE(&lockon_hudram_size) + AM_RANGE(0x09000, 0x09fff) AM_READWRITE(MRA16_RAM, lockon_char_w) AM_BASE(&lockon_char_ram) + AM_RANGE(0x0a000, 0x0a001) AM_WRITE(adrst_w) + AM_RANGE(0x0b000, 0x0bfff) AM_WRITE(lockon_rotate_w) + AM_RANGE(0x0c000, 0x0cfff) AM_WRITE(lockon_fb_clut_w) + AM_RANGE(0x0e000, 0x0e001) AM_WRITE(inten_w) + AM_RANGE(0x0f000, 0x0f001) AM_WRITE(emres_w) + AM_RANGE(0x10000, 0x1ffff) AM_READWRITE(MRA16_NOP, tst_w) + AM_RANGE(0x20000, 0x2ffff) AM_READWRITE(main_z80_r, main_z80_w) + AM_RANGE(0x30000, 0x3ffff) AM_READWRITE(main_gnd_r, main_gnd_w) + AM_RANGE(0x40000, 0x4ffff) AM_READWRITE(main_obj_r, main_obj_w) + AM_RANGE(0x50000, 0x5ffff) AM_MIRROR(0x80000) AM_ROM + AM_RANGE(0x60000, 0x6ffff) AM_MIRROR(0x80000) AM_ROM + AM_RANGE(0x70000, 0x7ffff) AM_MIRROR(0x80000) AM_ROM ADDRESS_MAP_END + static ADDRESS_MAP_START( ground_v30, ADDRESS_SPACE_PROGRAM, 16 ) ADDRESS_MAP_FLAGS( AMEF_UNMAP(1) ) - AM_RANGE(0x00000, 0x03fff) AM_RAM AM_BASE(&v30_gnd) // IC31/IC34) - AM_RANGE(0x04000, 0x04fff) AM_READWRITE(MRA16_RAM,lockon_vram_1_w) AM_BASE(&lockon_vram1) // Scene RAM (IC112/IC113) - AM_RANGE(0x08000, 0x08fff) AM_RAM AM_BASE(&ground_ram) AM_SIZE(&lockon_ground_size) // Ground RAM (IC98/IC99) - AM_RANGE(0x0c000, 0x0c001) AM_RAM // /SHNH CS: Horizontal Scroll - AM_RANGE(0x0c002, 0x0c003) AM_RAM // /SHNV CS: Vertical Scroll - AM_RANGE(0x0c004, 0x0c005) AM_RAM AM_WRITE(ground_bank_w) // /UNB CS: Ground ROM Bank select - AM_RANGE(0x20000, 0x2ffff) AM_ROM // Ground ROM (IC30/IC33) - AM_RANGE(0x30000, 0x3ffff) AM_ROM // Program ROM mirror (use macros?) - AM_RANGE(0xe0000, 0xeffff) AM_ROM // Ground ROM mirror - AM_RANGE(0xf0000, 0xfffff) AM_ROM + AM_RANGE(0x00000, 0x03fff) AM_RAM + AM_RANGE(0x04000, 0x04fff) AM_RAM AM_BASE(&lockon_scene_ram) + AM_RANGE(0x08000, 0x08fff) AM_RAM AM_BASE(&lockon_ground_ram) AM_SIZE(&lockon_groundram_size) + AM_RANGE(0x0C000, 0x0C001) AM_WRITE(lockon_scene_h_scr_w) + AM_RANGE(0x0C002, 0x0C003) AM_WRITE(lockon_scene_v_scr_w) + AM_RANGE(0x0C004, 0x0C005) AM_WRITE(lockon_ground_ctrl_w) + AM_RANGE(0x20000, 0x2ffff) AM_MIRROR(0xc0000) AM_ROM + AM_RANGE(0x30000, 0x3ffff) AM_MIRROR(0xc0000) AM_ROM ADDRESS_MAP_END + static ADDRESS_MAP_START( object_v30, ADDRESS_SPACE_PROGRAM, 16 ) - AM_RANGE(0x00000, 0x03fff) AM_RAM AM_BASE(&v30_obj) // Work RAM (IC29, IC44) - AM_RANGE(0x04000, 0x04001) AM_RAM // Read = assert CPU /POLL input (halt on WAIT instruction) - AM_RANGE(0x08000, 0x081ff) AM_RAM // TZA112 sprite chip write? - AM_RANGE(0x0c000, 0x0c1ff) AM_RAM AM_BASE(&object_ram) AM_SIZE(&objectram_size) // Object RAM (IC39/IC54) - AM_RANGE(0x20000, 0x2ffff) AM_ROM // Program ROM mirror - AM_RANGE(0xf0000, 0xfffff) AM_ROM // Program ROM + ADDRESS_MAP_FLAGS( AMEF_UNMAP(1) ) + AM_RANGE(0x00000, 0x03fff) AM_RAM + AM_RANGE(0x04000, 0x04001) AM_READWRITE(lockon_obj_4000_r, lockon_obj_4000_w) + AM_RANGE(0x08000, 0x08fff) AM_WRITE(lockon_tza112_w) + AM_RANGE(0x0c000, 0x0c1ff) AM_RAM AM_BASE(&lockon_object_ram) AM_SIZE(&lockon_objectram_size) + AM_RANGE(0x30000, 0x3ffff) AM_MIRROR(0xc0000) AM_ROM ADDRESS_MAP_END + static ADDRESS_MAP_START( sound_prg, ADDRESS_SPACE_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x1fff) AM_ROM - AM_RANGE(0xf810, 0xf810) AM_WRITE(MWA8_NOP) // /TS - AM_RANGE(0x7000, 0x7000) AM_WRITE(MWA8_NOP) // Attenuate YM3014 output (not used?) - AM_RANGE(0x7400, 0x7403) AM_READWRITE(adc_r,MWA8_NOP) // M58990 ADC - AM_RANGE(0x7800, 0x7fff) AM_RAM AM_BASE(&z80_ram) + ADDRESS_MAP_FLAGS( AMEF_UNMAP(1) ) + AM_RANGE(0x0000, 0x6fff) AM_ROM + AM_RANGE(0x7000, 0x7000) AM_WRITE(sound_vol) + AM_RANGE(0x7400, 0x7403) AM_READWRITE(adc_r, MWA8_NOP) + AM_RANGE(0x7800, 0x7fff) AM_MIRROR(0x8000) AM_RAM ADDRESS_MAP_END static ADDRESS_MAP_START( sound_io, ADDRESS_SPACE_IO, 8 ) ADDRESS_MAP_FLAGS( AMEF_ABITS(8) ) AM_RANGE(0x00, 0x00) AM_READWRITE(YM2203_status_port_0_r, YM2203_control_port_0_w) AM_RANGE(0x01, 0x01) AM_READWRITE(YM2203_read_port_0_r, YM2203_write_port_0_w) + AM_RANGE(0x02, 0x02) AM_NOP ADDRESS_MAP_END +/************************************* + * + * Port definitions + * + *************************************/ + +static INPUT_PORTS_START( lockon ) + PORT_START_TAG("DSW") + /* DSW A */ + PORT_DIPNAME( 0x0003, 0x0000, DEF_STR( Lives ) ) + PORT_DIPSETTING( 0x0001, "2" ) + PORT_DIPSETTING( 0x0000, "3" ) + PORT_DIPSETTING( 0x0002, "4" ) + PORT_DIPSETTING( 0x0003, "5" ) + PORT_DIPNAME( 0x000c, 0x0000, DEF_STR( Difficulty ) ) + PORT_DIPSETTING( 0x0004, DEF_STR( Easy ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( Medium ) ) + PORT_DIPSETTING( 0x0008, DEF_STR( Hard ) ) + PORT_DIPSETTING( 0x000c, DEF_STR( Hardest ) ) + + PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Bonus_Life ) ) + PORT_DIPSETTING( 0x0000, "150K & every 200K" ) + PORT_DIPSETTING( 0x0010, "200K & every 200K" ) + + PORT_DIPNAME( 0x0020, 0x0000, DEF_STR( Allow_Continue ) ) + PORT_DIPSETTING( 0x0020, DEF_STR( No ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( Yes ) ) + + PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Demo_Sounds ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0040, DEF_STR( On ) ) + + /* DSW B */ + PORT_DIPNAME( 0x0700, 0x0000, DEF_STR( Coin_A ) ) + PORT_DIPSETTING( 0x0200, DEF_STR( 3C_1C ) ) + PORT_DIPSETTING( 0x0100, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x0600, DEF_STR( 2C_3C ) ) + PORT_DIPSETTING( 0x0300, DEF_STR( 1C_2C ) ) + PORT_DIPSETTING( 0x0400, DEF_STR( 1C_5C ) ) + PORT_DIPSETTING( 0x0500, DEF_STR( 1C_6C ) ) + PORT_DIPSETTING( 0x0700, DEF_STR( Free_Play ) ) + + PORT_DIPNAME( 0x3800, 0x0000, DEF_STR( Coin_B ) ) + PORT_DIPSETTING( 0x3000, DEF_STR( 4C_1C ) ) + PORT_DIPSETTING( 0x0800, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x1000, DEF_STR( 1C_2C ) ) + PORT_DIPSETTING( 0x2000, DEF_STR( 1C_3C ) ) + PORT_DIPSETTING( 0x2800, DEF_STR( 1C_4C ) ) + PORT_DIPSETTING( 0x1800, DEF_STR( 1C_5C ) ) + PORT_DIPSETTING( 0x3800, DEF_STR( 1C_6C ) ) + + /* + Wire jumper beside the dipswitches on PCB TF011. + To access the menu, press the service coin during + test mode. + */ + PORT_DIPNAME( 0x4000, 0x4000, "Enable H/W Tests Menu" ) + PORT_DIPSETTING( 0x4000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + +PORT_START_TAG("YM2203") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN3 ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME( DEF_STR( Service_Mode )) PORT_CODE(KEYCODE_F2) PORT_TOGGLE + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 ) + PORT_DIPNAME( 0x40, 0x00, "Jumper 1" ) + PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x80, 0x00, "Jumper 0" ) + PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + +PORT_START_TAG("ADC_BANK") + PORT_BIT( 0xff, 0x7f, IPT_AD_STICK_X ) PORT_MINMAX(0,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(15) +PORT_START_TAG("ADC_PITCH") + PORT_BIT( 0xff, 0x7f, IPT_AD_STICK_Y ) PORT_MINMAX(0,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(15) +PORT_START_TAG("ADC_MISSILE") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_BUTTON3 ) +PORT_START_TAG("ADC_HOVER") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_BUTTON4 ) +INPUT_PORTS_END + + +static INPUT_PORTS_START( lockone ) + PORT_INCLUDE( lockon ) + + PORT_MODIFY("DSW") + PORT_DIPNAME( 0x0700, 0x0000, DEF_STR( Coin_A ) ) + PORT_DIPSETTING( 0x0300, DEF_STR( 4C_1C ) ) + PORT_DIPSETTING( 0x0200, DEF_STR( 3C_1C ) ) + PORT_DIPSETTING( 0x0100, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x0600, DEF_STR( 2C_3C ) ) + PORT_DIPSETTING( 0x0700, DEF_STR( 2C_4C ) ) + PORT_DIPSETTING( 0x0400, DEF_STR( 1C_2C ) ) + PORT_DIPSETTING( 0x0500, DEF_STR( 1C_3C ) ) + + PORT_DIPNAME( 0x0800, 0x0000, "Buy-In" ) + PORT_DIPSETTING( 0x0800, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( 1C_1C ) ) + + PORT_DIPNAME( 0x1000, 0x0000, DEF_STR( Unused ) ) + PORT_DIPSETTING( 0x1000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x2000, 0x0000, DEF_STR( Unused ) ) + PORT_DIPSETTING( 0x2000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) +INPUT_PORTS_END + + +/************************************* + * + * M58990P ADC + * + *************************************/ + +static READ8_HANDLER( adc_r ) +{ + switch (offset) + { + case 0: return readinputportbytag("ADC_BANK"); + case 1: return readinputportbytag("ADC_PITCH"); + case 2: return readinputportbytag("ADC_MISSILE"); + case 3: return readinputportbytag("ADC_HOVER"); + default: return 0; + } +} + +/************************************* + * + * Graphics definitions + * + *************************************/ + static const gfx_layout char_layout = { 8,8, 1024, 2, { 0, 8*8*1024 }, - { 0,1,2,3,4,5,6,7 }, + { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, 8*8 }; -static const gfx_layout object_layout = -{ - 8,8, - 4096, - 8, - { 0, 0x8000*8, 0x8000*2*8, 0x8000*3*8, 0x8000*4*8, 0x8000*5*8, 0x8000*6*8, 0x8000*7*8 }, - { 0,1,2,3,4,5,6,7 }, - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, - 8*8 -}; - -static const gfx_layout scene_layout = -{ - 8,8, - 4096, - 3, - { 0, 0x10000*8, 0x20000*8 }, - { 0,1,2,3,4,5,6,7 }, - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, - 8*8 -}; - -static const gfx_layout hud_layout = -{ - 8,8, - 1024, - 1, - { 0 }, - { 0,1,2,3,4,5,6,7 }, - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, - 8*8 -}; - -static const gfx_layout ground_layout = -{ - 8,8, - 8192, - 3, - { 0, 0x10000*8, 0x20000*8 }, - { 0,1,2,3,4,5,6,7 }, - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, - 8*8 -}; - - static GFXDECODE_START( lockon ) - GFXDECODE_ENTRY( REGION_GFX1, 0, object_layout, 0, 16 ) - GFXDECODE_ENTRY( REGION_GFX2, 0, object_layout, 0, 16 ) - GFXDECODE_ENTRY( REGION_GFX3, 0, object_layout, 0, 16 ) - GFXDECODE_ENTRY( REGION_GFX4, 0, object_layout, 0, 16 ) - GFXDECODE_ENTRY( REGION_GFX5, 0, char_layout, 0, 16 ) - GFXDECODE_ENTRY( REGION_GFX6, 0, scene_layout, 0, 16 ) - GFXDECODE_ENTRY( REGION_GFX7, 0, hud_layout, 0, 16 ) - GFXDECODE_ENTRY( REGION_GFX8, 0, ground_layout, 0, 16 ) + GFXDECODE_ENTRY( REGION_GFX1, 0, char_layout, 0, 128 ) GFXDECODE_END -static void YM2203_irq(int irq) + +/************************************* + * + * Sound related + * + *************************************/ + +static WRITE8_HANDLER( sound_vol ) { - cpunum_set_input_line(Machine, 3, 0, irq ? ASSERT_LINE : CLEAR_LINE ); +#define LO_SHUNT 250.0 +#define LO_R0 5600.0 +#define LO_R1 10000.0 +#define LO_R2 22000.0 +#define LO_R3 47000.0 +#define LO_R0S (1/(1/LO_SHUNT + 1/LO_R0)) +#define LO_R1S (1/(1/LO_SHUNT + 1/LO_R1)) +#define LO_R2S (1/(1/LO_SHUNT + 1/LO_R2)) +#define LO_R3S (1/(1/LO_SHUNT + 1/LO_R3)) +#define LO_RI 100000.0 +#define LO_RP 100000.0 + + static const double gains[16] = + { + -( 1 / (1/LO_RP + 1/(LO_R3 + LO_R2 + LO_R1 + LO_R0)) ) / LO_RI, + -( 1 / (1/LO_RP + 1/(LO_R3 + LO_R2 + LO_R1 + LO_R0S)) ) / LO_RI, + -( 1 / (1/LO_RP + 1/(LO_R3 + LO_R2 + LO_R1S + LO_R0)) ) / LO_RI, + -( 1 / (1/LO_RP + 1/(LO_R3 + LO_R2 + LO_R1S + LO_R0S)) ) / LO_RI, + -( 1 / (1/LO_RP + 1/(LO_R3 + LO_R2S + LO_R1 + LO_R0)) ) / LO_RI, + -( 1 / (1/LO_RP + 1/(LO_R3 + LO_R2S + LO_R1 + LO_R0S)) ) / LO_RI, + -( 1 / (1/LO_RP + 1/(LO_R3 + LO_R2S + LO_R1S + LO_R0)) ) / LO_RI, + -( 1 / (1/LO_RP + 1/(LO_R3 + LO_R2S + LO_R1S + LO_R0S)) ) / LO_RI, + -( 1 / (1/LO_RP + 1/(LO_R3S + LO_R2 + LO_R1 + LO_R0)) ) / LO_RI, + -( 1 / (1/LO_RP + 1/(LO_R3S + LO_R2 + LO_R1 + LO_R0S)) ) / LO_RI, + -( 1 / (1/LO_RP + 1/(LO_R3S + LO_R2 + LO_R1S + LO_R0)) ) / LO_RI, + -( 1 / (1/LO_RP + 1/(LO_R3S + LO_R2 + LO_R1S + LO_R0S)) ) / LO_RI, + -( 1 / (1/LO_RP + 1/(LO_R3S + LO_R2S + LO_R1 + LO_R0)) ) / LO_RI, + -( 1 / (1/LO_RP + 1/(LO_R3S + LO_R2S + LO_R1 + LO_R0S)) ) / LO_RI, + -( 1 / (1/LO_RP + 1/(LO_R3S + LO_R2S + LO_R1S + LO_R0)) ) / LO_RI, + -( 1 / (1/LO_RP + 1/(LO_R3S + LO_R2S + LO_R1S + LO_R0S)) ) / LO_RI, + }; + + double lgain = gains[data & 0xf]; + double rgain = gains[data >> 4]; + + flt_volume_set_volume(0, lgain); + flt_volume_set_volume(2, lgain); + flt_volume_set_volume(4, lgain); + + flt_volume_set_volume(1, rgain); + flt_volume_set_volume(3, rgain); + flt_volume_set_volume(5, rgain); } -static WRITE8_HANDLER(YM2203_out_b) +static void ym2203_irq(int irq) { - coin_counter_w(0,data & 0x80); - coin_counter_w(1,data & 0x40); - coin_counter_w(2,data & 0x20); - set_led_status(1,!(data & 0x10)); // 'LOCK-ON' lamp + cpunum_set_input_line(Machine, SOUND_CPU, 0, irq ? ASSERT_LINE : CLEAR_LINE ); +} + +static WRITE8_HANDLER( ym2203_out_b ) +{ + coin_counter_w(0, data & 0x80); + coin_counter_w(1, data & 0x40); + coin_counter_w(2, data & 0x20); + + /* 'Lock-On' lamp */ + set_led_status(1, !(data & 0x10)); } static const struct YM2203interface ym2203_interface = { - input_port_2_r, + input_port_1_r, 0, 0, - YM2203_out_b, - YM2203_irq + ym2203_out_b, + ym2203_irq }; + +/************************************* + * + * Machine driver + * + *************************************/ + static MACHINE_DRIVER_START( lockon ) - MDRV_CPU_ADD(V30,8000000) - MDRV_CPU_PROGRAM_MAP(main_v30,0) + MDRV_CPU_ADD(V30, XTAL_16MHz / 2) + MDRV_CPU_PROGRAM_MAP(main_v30, 0) - MDRV_CPU_ADD(V30,8000000) - MDRV_CPU_PROGRAM_MAP(ground_v30,0) + MDRV_CPU_ADD(V30, XTAL_16MHz / 2) + MDRV_CPU_PROGRAM_MAP(ground_v30, 0) - MDRV_CPU_ADD(V30,8000000) - MDRV_CPU_PROGRAM_MAP(object_v30,0) + MDRV_CPU_ADD(V30, XTAL_16MHz / 2) + MDRV_CPU_PROGRAM_MAP(object_v30, 0) - MDRV_CPU_ADD(Z80,4000000) - MDRV_CPU_PROGRAM_MAP(sound_prg,0) - MDRV_CPU_IO_MAP(sound_io,0) + MDRV_CPU_ADD(Z80, XTAL_16MHz / 4) + MDRV_CPU_PROGRAM_MAP(sound_prg, 0) + MDRV_CPU_IO_MAP(sound_io, 0) - MDRV_CPU_VBLANK_INT(lockon_irq,1) - MDRV_SCREEN_REFRESH_RATE(60) - MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION) - MDRV_INTERLEAVE(100) + MDRV_WATCHDOG_TIME_INIT(attotime_mul(PERIOD_OF_555_ASTABLE(10000, 4700, 10000e-12), 4096)) + MDRV_INTERLEAVE(10) - MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) + MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER | VIDEO_UPDATE_AFTER_VBLANK) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_SIZE(320, 240) - MDRV_SCREEN_VISIBLE_AREA(0, 319, 0, 239) - MDRV_GFXDECODE(lockon) + MDRV_SCREEN_RAW_PARAMS(PIXEL_CLOCK, HTOTAL, HBEND, HBSTART, VTOTAL, VBEND, VBSTART) - MDRV_PALETTE_LENGTH(1024) + MDRV_GFXDECODE(lockon) + MDRV_PALETTE_INIT(lockon) + MDRV_PALETTE_LENGTH(1024 + 2048) MDRV_VIDEO_START(lockon) MDRV_VIDEO_UPDATE(lockon) + MDRV_VIDEO_EOF(lockon) - MDRV_SPEAKER_STANDARD_STEREO("left","right") + MDRV_SPEAKER_STANDARD_STEREO("left", "right") - MDRV_SOUND_ADD(YM2203, 4000000) + MDRV_SOUND_ADD(YM2203, XTAL_16MHz / 4) MDRV_SOUND_CONFIG(ym2203_interface) - MDRV_SOUND_ROUTE(0, "left", 0.2) - MDRV_SOUND_ROUTE(1, "left", 0.4) - MDRV_SOUND_ROUTE(2, "left", 0.4) - MDRV_SOUND_ROUTE(3, "left", 0.4) - MDRV_SOUND_ROUTE(0, "right", 0.2) - MDRV_SOUND_ROUTE(1, "right", 0.4) - MDRV_SOUND_ROUTE(2, "right", 0.4) - MDRV_SOUND_ROUTE(3, "right", 0.4) + MDRV_SOUND_ROUTE(0, "left", 0.40) + MDRV_SOUND_ROUTE(0, "right", 0.40) + MDRV_SOUND_ROUTE(1, "f2203.1l", 1.0) + MDRV_SOUND_ROUTE(1, "f2203.1r", 1.0) + MDRV_SOUND_ROUTE(2, "f2203.2l", 1.0) + MDRV_SOUND_ROUTE(2, "f2203.2r", 1.0) + MDRV_SOUND_ROUTE(3, "f2203.3l", 1.0) + MDRV_SOUND_ROUTE(3, "f2203.3r", 1.0) + + MDRV_SOUND_ADD_TAG("f2203.1l", FILTER_VOLUME, 0) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 1.0) + MDRV_SOUND_ADD_TAG("f2203.1r", FILTER_VOLUME, 0) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 1.0) + MDRV_SOUND_ADD_TAG("f2203.2l", FILTER_VOLUME, 0) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 1.0) + MDRV_SOUND_ADD_TAG("f2203.2r", FILTER_VOLUME, 0) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 1.0) + MDRV_SOUND_ADD_TAG("f2203.3l", FILTER_VOLUME, 0) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 1.0) + MDRV_SOUND_ADD_TAG("f2203.3r", FILTER_VOLUME, 0) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 1.0) MACHINE_DRIVER_END +/************************************* + * + * ROM definition(s) + * + *************************************/ + ROM_START( lockon ) + /* TF012 V30 (Main) */ ROM_REGION( 0x100000, REGION_CPU1, 0 ) - ROM_LOAD16_BYTE( "lo1_02c", 0x50000, 0x8000, CRC(bbf17263) SHA1(96821a0ecd6efe6764380fef094f87c1d6e1d299) ) - ROM_LOAD16_BYTE( "lo1_03c", 0x50001, 0x8000, CRC(fa58fd36) SHA1(16af24027610bf6d3fdc4c3df3bf6d94c6776420) ) + ROM_LOAD16_BYTE( "lo1_02c.89", 0x60000, 0x8000, CRC(bbf17263) SHA1(96821a0ecd6efe6764380fef094f87c1d6e1d299) ) + ROM_LOAD16_BYTE( "lo1_03c.88", 0x60001, 0x8000, CRC(fa58fd36) SHA1(16af24027610bf6d3fdc4c3df3bf6d94c6776420) ) - ROM_LOAD16_BYTE( "lo1_04c", 0x60000, 0x8000, CRC(4a88576e) SHA1(80a8bd89cedebf080b2c08a6e81d3c2754024d8a) ) - ROM_LOAD16_BYTE( "lo1_05c", 0x60001, 0x8000, CRC(5a171b02) SHA1(f41f641136574e6af67c2245eb5a84799984474a) ) + ROM_LOAD16_BYTE( "lo1_04c.77", 0x50000, 0x8000, CRC(4a88576e) SHA1(80a8bd89cedebf080b2c08a6e81d3c2754024d8a) ) + ROM_LOAD16_BYTE( "lo1_05c.76", 0x50001, 0x8000, CRC(5a171b02) SHA1(f41f641136574e6af67c2245eb5a84799984474a) ) - ROM_LOAD16_BYTE( "lo1_00c", 0xf0000, 0x8000, CRC(e2db493b) SHA1(7491c634b698973ea54c25612d1e79c7efea8a45) ) - ROM_LOAD16_BYTE( "lo1_01c", 0xf0001, 0x8000, CRC(3e6065e0) SHA1(d870f5b466fab90d5c51dd27ecc807e7b38b5f79)) + ROM_LOAD16_BYTE( "lo1_00c.96", 0x70000, 0x8000, CRC(e2db493b) SHA1(7491c634b698973ea54c25612d1e79c7efea8a45) ) + ROM_LOAD16_BYTE( "lo1_01c.95", 0x70001, 0x8000, CRC(3e6065e0) SHA1(d870f5b466fab90d5c51dd27ecc807e7b38b5f79) ) - // Z80 - ROM_LOAD16_BYTE( "lo1_08b", 0x20000, 0x8000, CRC(73860ec9) SHA1(a94afa274321b9f9ac2184e133132f9829fb9485) ) - - // TF013 V30 (Ground) + /* TF013 V30 (Ground) */ ROM_REGION( 0x100000, REGION_CPU2, 0 ) - ROM_LOAD16_BYTE( "lo3_01a", 0x20000, 0x8000, CRC(3eacdb6b) SHA1(7934c36dac9253dec4d8910954f6f2ae85951fe9) ) - ROM_RELOAD( 0xe0000, 0x8000 ) - ROM_LOAD16_BYTE( "lo3_03a", 0x20001, 0x8000, CRC(4ce96d71) SHA1(cedbc33e86a93d11d5e11c2ef18bcf6390790a88) ) - ROM_RELOAD( 0xe0001, 0x8000 ) + ROM_LOAD16_BYTE( "lo3_01a.30", 0x20000, 0x8000, CRC(3eacdb6b) SHA1(7934c36dac9253dec4d8910954f6f2ae85951fe9) ) + ROM_LOAD16_BYTE( "lo3_03a.33", 0x20001, 0x8000, CRC(4ce96d71) SHA1(cedbc33e86a93d11d5e11c2ef18bcf6390790a88) ) + ROM_LOAD16_BYTE( "lo3_00b.29", 0x30000, 0x8000, CRC(1835dccb) SHA1(8dfb0fea61a3e61f4da3b7f0da02cd19df2e68be) ) + ROM_LOAD16_BYTE( "lo3_02b.32", 0x30001, 0x8000, CRC(2b8931d3) SHA1(f6f40b7857f3d47da8626450b1c1d3c46a1072ab) ) - ROM_LOAD16_BYTE( "lo3_00b", 0xf0000, 0x8000, CRC(1835dccb) SHA1(8dfb0fea61a3e61f4da3b7f0da02cd19df2e68be) ) - ROM_RELOAD( 0x30000, 0x8000 ) - ROM_LOAD16_BYTE( "lo3_02b", 0xf0001, 0x8000, CRC(2b8931d3) SHA1(f6f40b7857f3d47da8626450b1c1d3c46a1072ab) ) - ROM_RELOAD( 0x30001, 0x8000 ) - - // TF014 V30 (Object) + /* TF014 V30 (Object) */ ROM_REGION( 0x100000, REGION_CPU3, 0 ) - ROM_LOAD16_BYTE( "lo4_00b", 0xf0000, 0x8000, CRC(5f6b5a50) SHA1(daf82cafcae86d05587c191b0ff194ca7950e130) ) - ROM_RELOAD( 0x30000, 0x8000 ) + ROM_LOAD16_BYTE( "lo4_00b", 0x30000, 0x8000, CRC(5f6b5a50) SHA1(daf82cafcae86d05587c191b0ff194ca7950e130) ) + ROM_LOAD16_BYTE( "lo4_01b", 0x30001, 0x8000, CRC(7e88bcf2) SHA1(d541458ba6178ec3bce0e9b872b9fa1d8edb107c) ) - ROM_LOAD16_BYTE( "lo4_01b", 0xf0001, 0x8000, CRC(7e88bcf2) SHA1(d541458ba6178ec3bce0e9b872b9fa1d8edb107c) ) - ROM_RELOAD( 0x30001, 0x8000 ) - - // TF014 Z80 (Sound) + /* TF014 Z80 (Sound) */ ROM_REGION( 0x10000, REGION_CPU4, 0 ) - ROM_LOAD( "lo1_08b", 0x00000, 0x8000, CRC(73860ec9) SHA1(a94afa274321b9f9ac2184e133132f9829fb9485) ) + ROM_LOAD( "lo1_08b.24", 0x00000, 0x8000, CRC(73860ec9) SHA1(a94afa274321b9f9ac2184e133132f9829fb9485) ) - // 8x8x8 object chunks - ROM_REGION( 0x400000, REGION_GFX1, ROMREGION_DISPOSE ) - ROM_LOAD( "lo5_00a", 0x00000, 0x8000, CRC(e9f23ce6) SHA1(4030384a0e8f47e8eea9483482ed1be264aec992) ) - ROM_LOAD( "lo5_04a", 0x08000, 0x8000, CRC(099323bc) SHA1(001d30f4c3c27277fadac89dcf616ff89eb0ea1c) ) - ROM_LOAD( "lo5_08a", 0x10000, 0x8000, CRC(9dedeff5) SHA1(53b0917a4fde4053182d38ea7f99f66e52543c10) ) - ROM_LOAD( "lo5_12a", 0x18000, 0x8000, CRC(2f5164ab) SHA1(df775b9e1c3c605a85d44404e4db42e33e80e664) ) - ROM_LOAD( "lo5_16a", 0x20000, 0x8000, CRC(c4500159) SHA1(e695e31e363cc954aab449f9d3dbc027e27fe7bf) ) - ROM_LOAD( "lo5_20a", 0x28000, 0x8000, CRC(3c1a67b5) SHA1(399935830b32a457ad0de243dd3eb4d368d5c6a6) ) - ROM_LOAD( "lo5_24a", 0x30000, 0x8000, CRC(1892d083) SHA1(8ee92be93ac222ecc2d9f4fcda3099b1db67516c) ) - ROM_LOAD( "lo5_28a", 0x38000, 0x8000, CRC(1186f9b4) SHA1(55598552dafa8cccfb423fc3b65a7fa15831d75b) ) + /* 8x8x2 characters */ + ROM_REGION( 0x4000, REGION_GFX1, ROMREGION_DISPOSE ) + ROM_LOAD( "lo1_07a", 0x00000, 0x2000, CRC(73673b79) SHA1(246b80f0c465cefb7ce1c87dc90a58f0f0ea3e0d) ) + ROM_LOAD( "lo1_06a", 0x02000, 0x2000, CRC(c8205913) SHA1(c791ff14418873ce68b502440c3d7ccc1f9cc00e) ) - // 8x8x8 object chunks - ROM_REGION( 0x400000, REGION_GFX2, ROMREGION_DISPOSE ) - ROM_LOAD( "lo5_01a", 0x00000, 0x8000, CRC(528d1395) SHA1(0221f81900757c10f288807f5c9549b9fdf5390f) ) - ROM_LOAD( "lo5_06a", 0x08000, 0x8000, CRC(be539b01) SHA1(1eebcbc592c51a676409b5be6c5d6609cd7118c9) ) - ROM_LOAD( "lo5_10a", 0x10000, 0x8000, CRC(23eeec5a) SHA1(08edd997d773684d329ef554776bc7acff1ac4ce) ) - ROM_LOAD( "lo5_14a", 0x18000, 0x8000, CRC(e63cd59e) SHA1(0518461acdc6c65dca8f21ca29bf528197e7cabe) ) - ROM_LOAD( "lo5_17a", 0x20000, 0x8000, CRC(ccf138d3) SHA1(971e7abe5b4d1a9dc8fc71b1ded5d2b81bcffaf2) ) - ROM_LOAD( "lo5_21a", 0x28000, 0x8000, CRC(39ce2000) SHA1(05f8e6f364ad714232fcea5b535ed5e181febd1e) ) - ROM_LOAD( "lo5_25a", 0x30000, 0x8000, CRC(7f3418bd) SHA1(5e595500f996b71aa73c637a6fddced30d78e222) ) - ROM_LOAD( "lo5_29a", 0x38000, 0x8000, CRC(45353d8d) SHA1(45cacd36700d24ae9f6eeaebed2fc860ef2d2978) ) + /* 8x8x3 scene tiles and CLUT */ + ROM_REGION( 0x40000, REGION_GFX2, 0 ) + ROM_LOAD( "lo3_12a.120", 0x00000, 0x10000, CRC(a34262a7) SHA1(08204a4474ab1b07b9114da8af03442737922d3b) ) + ROM_LOAD( "lo3_11a.119", 0x10000, 0x10000, CRC(018efa36) SHA1(99eec3f06146627c7f7177b854424e7162ab7c8e) ) + ROM_LOAD( "lo3_10a.118", 0x20000, 0x10000, CRC(d5f4a8f3) SHA1(fcfaef46ef89c4b97970418a75d110271e94d55f) ) + ROM_LOAD( "lo3_13a.121", 0x30000, 0x10000, CRC(e44774a7) SHA1(010d95ea497690ddd2406b8fef1b0aee375a165e) ) - // 8x8x8 object chunks - ROM_REGION( 0x400000, REGION_GFX3, ROMREGION_DISPOSE ) - ROM_LOAD( "lo5_02a", 0x00000, 0x8000, CRC(07aa32a1) SHA1(712b1983747acdd754d3abe934642cbc02ee13f2) ) - ROM_LOAD( "lo5_05a", 0x08000, 0x8000, CRC(f6b775a2) SHA1(e0146866f2e89675181c5d9d5aba23116daac420) ) - ROM_LOAD( "lo5_09a", 0x10000, 0x8000, CRC(953289bc) SHA1(197066af45c1193c36cd59b4b72b14f1c3bdd33e) ) - ROM_LOAD( "lo5_13a", 0x18000, 0x8000, CRC(67fbb061) SHA1(78b071cd54642ee7b6d7b9f6b759a1412bb9eef5) ) - ROM_LOAD( "lo5_18a", 0x20000, 0x8000, CRC(89884b24) SHA1(23c1fcc97f3a1abcaad413f4448db26f7c55fd5e) ) - ROM_LOAD( "lo5_22a", 0x28000, 0x8000, CRC(b1ed0361) SHA1(4bdf439026a858fdd929d5a7baac7d76f51550c5) ) - ROM_LOAD( "lo5_26a", 0x30000, 0x8000, CRC(a0b5c040) SHA1(ef63f89a368bc73eb77fc02d83b499a0231c1989) ) - ROM_LOAD( "lo5_30a", 0x38000, 0x8000, CRC(7d3993c5) SHA1(fb18daffcfc46bc1e1cfdee928eea861494af221) ) + /* 8x8x1 HUD sprites */ + ROM_REGION( 0x2000, REGION_GFX3, 0 ) + ROM_LOAD( "lo2_00.53", 0x00000, 0x2000, CRC(8affea15) SHA1(b7bcf0abde9c933e3f2c75c1f5e2ca3417d50ca1) ) - // 8x8x8 object chunks - ROM_REGION( 0x400000, REGION_GFX4, ROMREGION_DISPOSE ) - ROM_LOAD( "lo5_03a", 0x00000, 0x8000, CRC(7aca5d83) SHA1(95456b6c5adc5b776fbd33fd95cc62d4a83c34b6) ) - ROM_LOAD( "lo5_07a", 0x08000, 0x8000, CRC(313f127f) SHA1(0782b8dd5f3a3384c3e7bc9cacaadf6804e06a38) ) - ROM_LOAD( "lo5_11a", 0x10000, 0x8000, CRC(9df0b287) SHA1(6ea3b32a7826186c854cc079711ddea4ebf2ab7c) ) - ROM_LOAD( "lo5_15a", 0x18000, 0x8000, CRC(66f9c5db) SHA1(cc68da9312ee0a3441b62d14107e1b7de9b04de3) ) - ROM_LOAD( "lo5_19a", 0x20000, 0x8000, CRC(5aaa6a53) SHA1(f8ff547979883ac9a969e76d90d028ec4286ec4c) ) - ROM_LOAD( "lo5_23a", 0x28000, 0x8000, CRC(1487895b) SHA1(9d617f37932ca17d902307a97d16cf3b4bb5bc4e) ) - ROM_LOAD( "lo5_27a", 0x30000, 0x8000, CRC(119ff70a) SHA1(e64d41bc7822c9e99fd025b771551a6c511d13f2) ) - ROM_LOAD( "lo5_31a", 0x38000, 0x8000, CRC(d3595292) SHA1(9c45be919296626796b07f70b871fba5d444dbb3) ) + /* Ground GFX and LUTs */ + ROM_REGION( 0x60000, REGION_GFX4, 0 ) + ROM_LOAD( "lo3_07a.94", 0x00000, 0x10000, CRC(cebc50e1) SHA1(f8b06ce576c3d41b0a8e2cc3ac60d3515d434812) ) + ROM_LOAD( "lo3_06a.92", 0x10000, 0x10000, CRC(f6b6ebdd) SHA1(30e92da3bf83c4bb30faf00cbf01664b993f137c) ) + ROM_LOAD( "lo3_05a.90", 0x20000, 0x10000, CRC(5b6f4c8e) SHA1(fc8b2c929c60fb0177ed3e407e3f0aacc5df8401) ) + ROM_LOAD( "lo3_08.104", 0x30000, 0x10000, CRC(f418cecd) SHA1(6cf2d13c9df86bad9c24609cb8387e817b5d4281) ) + ROM_LOAD( "lo3_09.105", 0x40000, 0x10000, CRC(3c245568) SHA1(9ff6a23d83627f55c9d4f68e0bd89927bfe10664) ) + ROM_LOAD( "lo3_04a.88", 0x50000, 0x10000, CRC(80b67ba9) SHA1(fdbef463b26cd13c43596310f585432c6e0896d0) ) - // 8x8x2 characters - ROM_REGION( 0x20000, REGION_GFX5, ROMREGION_DISPOSE ) - ROM_LOAD( "lo1_06a", 0x00000, 0x2000, CRC(c8205913) SHA1(c791ff14418873ce68b502440c3d7ccc1f9cc00e) ) - ROM_LOAD( "lo1_07a", 0x02000, 0x2000, CRC(73673b79) SHA1(246b80f0c465cefb7ce1c87dc90a58f0f0ea3e0d) ) + /* 8x8x4 object tiles */ + ROM_REGION( 0x100000, REGION_GFX5, 0 ) + ROM_LOAD( "lo5_28a.76", 0x00000, 0x8000, CRC(1186f9b4) SHA1(55598552dafa8cccfb423fc3b65a7fa15831d75b) ) + ROM_LOAD( "lo5_20a.48", 0x08000, 0x8000, CRC(3c1a67b5) SHA1(399935830b32a457ad0de243dd3eb4d368d5c6a6) ) + ROM_LOAD( "lo5_08a.58", 0x10000, 0x8000, CRC(9dedeff5) SHA1(53b0917a4fde4053182d38ea7f99f66e52543c10) ) + ROM_LOAD( "lo5_00a.14", 0x18000, 0x8000, CRC(e9f23ce6) SHA1(4030384a0e8f47e8eea9483482ed1be264aec992) ) + ROM_LOAD( "lo5_24a.62", 0x20000, 0x8000, CRC(1892d083) SHA1(8ee92be93ac222ecc2d9f4fcda3099b1db67516c) ) + ROM_LOAD( "lo5_16a.32", 0x28000, 0x8000, CRC(c4500159) SHA1(e695e31e363cc954aab449f9d3dbc027e27fe7bf) ) + ROM_LOAD( "lo5_04a.28", 0x30000, 0x8000, CRC(099323bc) SHA1(001d30f4c3c27277fadac89dcf616ff89eb0ea1c) ) + ROM_LOAD( "lo5_12a.8", 0x38000, 0x8000, CRC(2f5164ab) SHA1(df775b9e1c3c605a85d44404e4db42e33e80e664) ) - // 8x8x3 'scene' tiles - ROM_REGION( 0x40000, REGION_GFX6, ROMREGION_DISPOSE ) - ROM_LOAD( "lo3_10a", 0x00000, 0x10000, CRC(d5f4a8f3) SHA1(fcfaef46ef89c4b97970418a75d110271e94d55f) ) - ROM_LOAD( "lo3_11a", 0x10000, 0x10000, CRC(018efa36) SHA1(99eec3f06146627c7f7177b854424e7162ab7c8e) ) - ROM_LOAD( "lo3_12a", 0x20000, 0x10000, CRC(a34262a7) SHA1(08204a4474ab1b07b9114da8af03442737922d3b) ) + ROM_LOAD( "lo5_29a.77", 0x40000, 0x8000, CRC(45353d8d) SHA1(45cacd36700d24ae9f6eeaebed2fc860ef2d2978) ) + ROM_LOAD( "lo5_21a.49", 0x48000, 0x8000, CRC(39ce2000) SHA1(05f8e6f364ad714232fcea5b535ed5e181febd1e) ) + ROM_LOAD( "lo5_10a.72", 0x50000, 0x8000, CRC(23eeec5a) SHA1(08edd997d773684d329ef554776bc7acff1ac4ce) ) + ROM_LOAD( "lo5_01a.15", 0x58000, 0x8000, CRC(528d1395) SHA1(0221f81900757c10f288807f5c9549b9fdf5390f) ) + ROM_LOAD( "lo5_25a.93", 0x60000, 0x8000, CRC(7f3418bd) SHA1(5e595500f996b71aa73c637a6fddced30d78e222) ) + ROM_LOAD( "lo5_17a.33", 0x68000, 0x8000, CRC(ccf138d3) SHA1(971e7abe5b4d1a9dc8fc71b1ded5d2b81bcffaf2) ) + ROM_LOAD( "lo5_06a.44", 0x70000, 0x8000, CRC(be539b01) SHA1(1eebcbc592c51a676409b5be6c5d6609cd7118c9) ) + ROM_LOAD( "lo5_14a.22", 0x78000, 0x8000, CRC(e63cd59e) SHA1(0518461acdc6c65dca8f21ca29bf528197e7cabe) ) - // 8x8x1 HUD tiles - ROM_REGION( 0x40000, REGION_GFX7, ROMREGION_DISPOSE ) - ROM_LOAD( "lo2_00", 0x00000, 0x2000, CRC(8affea15) SHA1(b7bcf0abde9c933e3f2c75c1f5e2ca3417d50ca1) ) + ROM_LOAD( "lo5_30a.78", 0x80000, 0x8000, CRC(7d3993c5) SHA1(fb18daffcfc46bc1e1cfdee928eea861494af221) ) + ROM_LOAD( "lo5_22a.50", 0x88000, 0x8000, CRC(b1ed0361) SHA1(4bdf439026a858fdd929d5a7baac7d76f51550c5) ) + ROM_LOAD( "lo5_09a.59", 0x90000, 0x8000, CRC(953289bc) SHA1(197066af45c1193c36cd59b4b72b14f1c3bdd33e) ) + ROM_LOAD( "lo5_02a.16", 0x98000, 0x8000, CRC(07aa32a1) SHA1(712b1983747acdd754d3abe934642cbc02ee13f2) ) + ROM_LOAD( "lo5_26a.64", 0xa0000, 0x8000, CRC(a0b5c040) SHA1(ef63f89a368bc73eb77fc02d83b499a0231c1989) ) + ROM_LOAD( "lo5_18a.34", 0xa8000, 0x8000, CRC(89884b24) SHA1(23c1fcc97f3a1abcaad413f4448db26f7c55fd5e) ) + ROM_LOAD( "lo5_05a.29", 0xb0000, 0x8000, CRC(f6b775a2) SHA1(e0146866f2e89675181c5d9d5aba23116daac420) ) + ROM_LOAD( "lo5_13a.9", 0xb8000, 0x8000, CRC(67fbb061) SHA1(78b071cd54642ee7b6d7b9f6b759a1412bb9eef5) ) - // 8x8 ground GFX - ROM_REGION( 0x400000, REGION_GFX8, ROMREGION_DISPOSE ) - ROM_LOAD( "lo3_05a", 0x00000, 0x10000, CRC(5b6f4c8e) SHA1(fc8b2c929c60fb0177ed3e407e3f0aacc5df8401) ) - ROM_LOAD( "lo3_06a", 0x10000, 0x10000, CRC(f6b6ebdd) SHA1(30e92da3bf83c4bb30faf00cbf01664b993f137c) ) - ROM_LOAD( "lo3_07a", 0x20000, 0x10000, CRC(cebc50e1) SHA1(f8b06ce576c3d41b0a8e2cc3ac60d3515d434812) ) + ROM_LOAD( "lo5_31a.79", 0xc0000, 0x8000, CRC(d3595292) SHA1(9c45be919296626796b07f70b871fba5d444dbb3) ) + ROM_LOAD( "lo5_23a.51", 0xc8000, 0x8000, CRC(1487895b) SHA1(9d617f37932ca17d902307a97d16cf3b4bb5bc4e) ) + ROM_LOAD( "lo5_11a.73", 0xd0000, 0x8000, CRC(9df0b287) SHA1(6ea3b32a7826186c854cc079711ddea4ebf2ab7c) ) + ROM_LOAD( "lo5_03a.17", 0xd8000, 0x8000, CRC(7aca5d83) SHA1(95456b6c5adc5b776fbd33fd95cc62d4a83c34b6) ) + ROM_LOAD( "lo5_27a.65", 0xe0000, 0x8000, CRC(119ff70a) SHA1(e64d41bc7822c9e99fd025b771551a6c511d13f2) ) + ROM_LOAD( "lo5_19a.35", 0xe8000, 0x8000, CRC(5aaa6a53) SHA1(f8ff547979883ac9a969e76d90d028ec4286ec4c) ) + ROM_LOAD( "lo5_07a.45", 0xf0000, 0x8000, CRC(313f127f) SHA1(0782b8dd5f3a3384c3e7bc9cacaadf6804e06a38) ) + ROM_LOAD( "lo5_15a.23", 0xf8000, 0x8000, CRC(66f9c5db) SHA1(cc68da9312ee0a3441b62d14107e1b7de9b04de3) ) - // Object chunk LUTs - ROM_REGION( 0x30000, REGION_USER1, 0 ) - ROM_LOAD16_BYTE( "lo4_04a", 0x00000, 0x10000, CRC(098f4151) SHA1(cf38e3c5f3442fbfa97870d25f7c89c465f847a9) ) - ROM_LOAD16_BYTE( "lo4_05a", 0x00001, 0x10000, CRC(3b21667c) SHA1(b8337f733ede35145602ee3f0de25c2d4db1b2a5) ) + /* Object LUTs */ + ROM_REGION( 0x10000, REGION_USER1, 0 ) + ROM_LOAD( "lo4_02.109", 0x0000, 0x8000, CRC(0832edde) SHA1(77f9efbe029773417dbc3836a36687e37b5bee4b) ) + ROM_LOAD( "lo4_03.108", 0x8000, 0x8000, CRC(1efac891) SHA1(faf305a30cab1c6bf8a9d6e2682b2c3745aec956) ) - // Object LUTs - ROM_REGION( 0x30000, REGION_USER2, 0 ) - ROM_LOAD( "lo4_02", 0x0000, 0x8000, CRC(0832edde) SHA1(77f9efbe029773417dbc3836a36687e37b5bee4b) ) - ROM_LOAD( "lo4_03", 0x8000, 0x8000, CRC(1efac891) SHA1(faf305a30cab1c6bf8a9d6e2682b2c3745aec956) ) + /* Object chunk LUTs */ + ROM_REGION16_LE( 0x20000, REGION_USER2, 0 ) + ROM_LOAD16_BYTE( "lo4_04a.119", 0x00000, 0x10000, CRC(098f4151) SHA1(cf38e3c5f3442fbfa97870d25f7c89c465f847a9) ) + ROM_LOAD16_BYTE( "lo4_05a.118", 0x00001, 0x10000, CRC(3b21667c) SHA1(b8337f733ede35145602ee3f0de25c2d4db1b2a5) ) - // Ground LUTs - ROM_REGION( 0x30000, REGION_USER3, 0 ) - ROM_LOAD( "lo3_08", 0x00000, 0x10000, CRC(f418cecd) SHA1(6cf2d13c9df86bad9c24609cb8387e817b5d4281) ) - ROM_LOAD( "lo3_09", 0x10000, 0x10000, CRC(3c245568) SHA1(9ff6a23d83627f55c9d4f68e0bd89927bfe10664) ) - ROM_LOAD( "lo3_04a", 0x00000, 0x10000, CRC(80b67ba9) SHA1(fdbef463b26cd13c43596310f585432c6e0896d0) ) + /* Colour PROMs */ + ROM_REGION( 0x1800, REGION_PROMS, 0 ) + ROM_LOAD( "lo1a.5", 0x000, 0x400, CRC(82391f30) SHA1(d7153c1f3a3e54de4d4d6f432fbcd66449b96b6e) ) + ROM_LOAD( "lo2a.2", 0x400, 0x400, CRC(2bfc6288) SHA1(03d293ddc0c614b606be823826a4375b3d35901f) ) - // Scene tiles CLUT - ROM_REGION( 0x10000, REGION_USER4, 0 ) - ROM_LOAD( "lo3_13a", 0x0000, 0x10000, CRC(e44774a7) SHA1(010d95ea497690ddd2406b8fef1b0aee375a165e) ) - - // Colour PROMs - ROM_REGION( 0x1000, REGION_PROMS, 0 ) - ROM_LOAD( "lo1a", 0x400, 0x400, CRC(82391f30) SHA1(d7153c1f3a3e54de4d4d6f432fbcd66449b96b6e) ) - ROM_LOAD( "lo2a", 0x000, 0x400, CRC(2bfc6288) SHA1(03d293ddc0c614b606be823826a4375b3d35901f) ) + /* Object scale PROMs */ + ROM_LOAD_NIB_LOW ( "lo_3.69", 0x800, 0x800, CRC(9d9c41a9) SHA1(aabeefe95274f10400b4b7810ea50afcc4f19fde) ) + ROM_LOAD_NIB_HIGH( "lo_4.68", 0x800, 0x800, CRC(ca4874ef) SHA1(c742f79729b0dc4d227379e9109c7ed21b4c38bb) ) ROM_END -GAME( 1986, lockon, 0, lockon, lockon, 0, ROT0, "Tatsumi", "Lock-On", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS ) +ROM_START( lockone ) + /* TF012 V30 (Main) */ + ROM_REGION( 0x100000, REGION_CPU1, 0 ) + ROM_LOAD16_BYTE( "lo1_02c.89", 0x60000, 0x8000, CRC(bbf17263) SHA1(96821a0ecd6efe6764380fef094f87c1d6e1d299) ) + ROM_LOAD16_BYTE( "lo1_03c.88", 0x60001, 0x8000, CRC(fa58fd36) SHA1(16af24027610bf6d3fdc4c3df3bf6d94c6776420) ) + + ROM_LOAD16_BYTE( "lo1_04c.77", 0x50000, 0x8000, CRC(4a88576e) SHA1(80a8bd89cedebf080b2c08a6e81d3c2754024d8a) ) + ROM_LOAD16_BYTE( "lo1_05c.76", 0x50001, 0x8000, CRC(5a171b02) SHA1(f41f641136574e6af67c2245eb5a84799984474a) ) + + ROM_LOAD16_BYTE( "lo1_00e.96", 0x70000, 0x8000, CRC(25eec97f) SHA1(884d4e75111d532afed9755bd678cb7678385a86) ) + ROM_LOAD16_BYTE( "lo1_01e.95", 0x70001, 0x8000, CRC(03f0391d) SHA1(53795eab8f1b33c86a72d2f0f1cbcf7faab0011b) ) + + /* TF013 V30 (Ground) */ + ROM_REGION( 0x100000, REGION_CPU2, 0 ) + ROM_LOAD16_BYTE( "lo3_01a.30", 0x20000, 0x8000, CRC(3eacdb6b) SHA1(7934c36dac9253dec4d8910954f6f2ae85951fe9) ) + ROM_LOAD16_BYTE( "lo3_03a.33", 0x20001, 0x8000, CRC(4ce96d71) SHA1(cedbc33e86a93d11d5e11c2ef18bcf6390790a88) ) + ROM_LOAD16_BYTE( "lo3_00b.29", 0x30000, 0x8000, CRC(1835dccb) SHA1(8dfb0fea61a3e61f4da3b7f0da02cd19df2e68be) ) + ROM_LOAD16_BYTE( "lo3_02b.32", 0x30001, 0x8000, CRC(2b8931d3) SHA1(f6f40b7857f3d47da8626450b1c1d3c46a1072ab) ) + + /* TF014 V30 (Object) */ + ROM_REGION( 0x100000, REGION_CPU3, 0 ) + ROM_LOAD16_BYTE( "lo4_00b", 0x30000, 0x8000, CRC(5f6b5a50) SHA1(daf82cafcae86d05587c191b0ff194ca7950e130) ) + ROM_LOAD16_BYTE( "lo4_01b", 0x30001, 0x8000, CRC(7e88bcf2) SHA1(d541458ba6178ec3bce0e9b872b9fa1d8edb107c) ) + + /* TF014 Z80 (Sound) */ + ROM_REGION( 0x10000, REGION_CPU4, 0 ) + ROM_LOAD( "lo1_08b.24", 0x00000, 0x8000, CRC(73860ec9) SHA1(a94afa274321b9f9ac2184e133132f9829fb9485) ) + + /* 8x8x2 characters */ + ROM_REGION( 0x4000, REGION_GFX1, ROMREGION_DISPOSE ) + ROM_LOAD( "lo1_07a", 0x00000, 0x2000, CRC(73673b79) SHA1(246b80f0c465cefb7ce1c87dc90a58f0f0ea3e0d) ) + ROM_LOAD( "lo1_06a", 0x02000, 0x2000, CRC(c8205913) SHA1(c791ff14418873ce68b502440c3d7ccc1f9cc00e) ) + + /* 8x8x3 scene tiles and CLUT */ + ROM_REGION( 0x40000, REGION_GFX2, 0 ) + ROM_LOAD( "lo3_12a.120", 0x00000, 0x10000, CRC(a34262a7) SHA1(08204a4474ab1b07b9114da8af03442737922d3b) ) + ROM_LOAD( "lo3_11a.119", 0x10000, 0x10000, CRC(018efa36) SHA1(99eec3f06146627c7f7177b854424e7162ab7c8e) ) + ROM_LOAD( "lo3_10a.118", 0x20000, 0x10000, CRC(d5f4a8f3) SHA1(fcfaef46ef89c4b97970418a75d110271e94d55f) ) + ROM_LOAD( "lo3_13a.121", 0x30000, 0x10000, CRC(e44774a7) SHA1(010d95ea497690ddd2406b8fef1b0aee375a165e) ) + + /* 8x8x1 HUD sprites */ + ROM_REGION( 0x2000, REGION_GFX3, 0 ) + ROM_LOAD( "lo2_00.53", 0x00000, 0x2000, CRC(8affea15) SHA1(b7bcf0abde9c933e3f2c75c1f5e2ca3417d50ca1) ) + + /* Ground GFX and LUTs */ + ROM_REGION( 0x60000, REGION_GFX4, 0 ) + ROM_LOAD( "lo3_07a.94", 0x00000, 0x10000, CRC(cebc50e1) SHA1(f8b06ce576c3d41b0a8e2cc3ac60d3515d434812) ) + ROM_LOAD( "lo3_06a.92", 0x10000, 0x10000, CRC(f6b6ebdd) SHA1(30e92da3bf83c4bb30faf00cbf01664b993f137c) ) + ROM_LOAD( "lo3_05a.90", 0x20000, 0x10000, CRC(5b6f4c8e) SHA1(fc8b2c929c60fb0177ed3e407e3f0aacc5df8401) ) + ROM_LOAD( "lo3_08.104", 0x30000, 0x10000, CRC(f418cecd) SHA1(6cf2d13c9df86bad9c24609cb8387e817b5d4281) ) + ROM_LOAD( "lo3_09.105", 0x40000, 0x10000, CRC(3c245568) SHA1(9ff6a23d83627f55c9d4f68e0bd89927bfe10664) ) + ROM_LOAD( "lo3_04a.88", 0x50000, 0x10000, CRC(80b67ba9) SHA1(fdbef463b26cd13c43596310f585432c6e0896d0) ) + + /* 8x8x4 object tiles */ + ROM_REGION( 0x100000, REGION_GFX5, 0 ) + ROM_LOAD( "lo5_28a.76", 0x00000, 0x8000, CRC(1186f9b4) SHA1(55598552dafa8cccfb423fc3b65a7fa15831d75b) ) + ROM_LOAD( "lo5_20a.48", 0x08000, 0x8000, CRC(3c1a67b5) SHA1(399935830b32a457ad0de243dd3eb4d368d5c6a6) ) + ROM_LOAD( "lo5_08a.58", 0x10000, 0x8000, CRC(9dedeff5) SHA1(53b0917a4fde4053182d38ea7f99f66e52543c10) ) + ROM_LOAD( "lo5_00a.14", 0x18000, 0x8000, CRC(e9f23ce6) SHA1(4030384a0e8f47e8eea9483482ed1be264aec992) ) + ROM_LOAD( "lo5_24a.62", 0x20000, 0x8000, CRC(1892d083) SHA1(8ee92be93ac222ecc2d9f4fcda3099b1db67516c) ) + ROM_LOAD( "lo5_16a.32", 0x28000, 0x8000, CRC(c4500159) SHA1(e695e31e363cc954aab449f9d3dbc027e27fe7bf) ) + ROM_LOAD( "lo5_04a.28", 0x30000, 0x8000, CRC(099323bc) SHA1(001d30f4c3c27277fadac89dcf616ff89eb0ea1c) ) + ROM_LOAD( "lo5_12a.8", 0x38000, 0x8000, CRC(2f5164ab) SHA1(df775b9e1c3c605a85d44404e4db42e33e80e664) ) + + ROM_LOAD( "lo5_29a.77", 0x40000, 0x8000, CRC(45353d8d) SHA1(45cacd36700d24ae9f6eeaebed2fc860ef2d2978) ) + ROM_LOAD( "lo5_21a.49", 0x48000, 0x8000, CRC(39ce2000) SHA1(05f8e6f364ad714232fcea5b535ed5e181febd1e) ) + ROM_LOAD( "lo5_10a.72", 0x50000, 0x8000, CRC(23eeec5a) SHA1(08edd997d773684d329ef554776bc7acff1ac4ce) ) + ROM_LOAD( "lo5_01a.15", 0x58000, 0x8000, CRC(528d1395) SHA1(0221f81900757c10f288807f5c9549b9fdf5390f) ) + ROM_LOAD( "lo5_25a.93", 0x60000, 0x8000, CRC(7f3418bd) SHA1(5e595500f996b71aa73c637a6fddced30d78e222) ) + ROM_LOAD( "lo5_17a.33", 0x68000, 0x8000, CRC(ccf138d3) SHA1(971e7abe5b4d1a9dc8fc71b1ded5d2b81bcffaf2) ) + ROM_LOAD( "lo5_06a.44", 0x70000, 0x8000, CRC(be539b01) SHA1(1eebcbc592c51a676409b5be6c5d6609cd7118c9) ) + ROM_LOAD( "lo5_14a.22", 0x78000, 0x8000, CRC(e63cd59e) SHA1(0518461acdc6c65dca8f21ca29bf528197e7cabe) ) + + ROM_LOAD( "lo5_30a.78", 0x80000, 0x8000, CRC(7d3993c5) SHA1(fb18daffcfc46bc1e1cfdee928eea861494af221) ) + ROM_LOAD( "lo5_22a.50", 0x88000, 0x8000, CRC(b1ed0361) SHA1(4bdf439026a858fdd929d5a7baac7d76f51550c5) ) + ROM_LOAD( "lo5_09a.59", 0x90000, 0x8000, CRC(953289bc) SHA1(197066af45c1193c36cd59b4b72b14f1c3bdd33e) ) + ROM_LOAD( "lo5_02a.16", 0x98000, 0x8000, CRC(07aa32a1) SHA1(712b1983747acdd754d3abe934642cbc02ee13f2) ) + ROM_LOAD( "lo5_26a.64", 0xa0000, 0x8000, CRC(a0b5c040) SHA1(ef63f89a368bc73eb77fc02d83b499a0231c1989) ) + ROM_LOAD( "lo5_18a.34", 0xa8000, 0x8000, CRC(89884b24) SHA1(23c1fcc97f3a1abcaad413f4448db26f7c55fd5e) ) + ROM_LOAD( "lo5_05a.29", 0xb0000, 0x8000, CRC(f6b775a2) SHA1(e0146866f2e89675181c5d9d5aba23116daac420) ) + ROM_LOAD( "lo5_13a.9", 0xb8000, 0x8000, CRC(67fbb061) SHA1(78b071cd54642ee7b6d7b9f6b759a1412bb9eef5) ) + + ROM_LOAD( "lo5_31a.79", 0xc0000, 0x8000, CRC(d3595292) SHA1(9c45be919296626796b07f70b871fba5d444dbb3) ) + ROM_LOAD( "lo5_23a.51", 0xc8000, 0x8000, CRC(1487895b) SHA1(9d617f37932ca17d902307a97d16cf3b4bb5bc4e) ) + ROM_LOAD( "lo5_11a.73", 0xd0000, 0x8000, CRC(9df0b287) SHA1(6ea3b32a7826186c854cc079711ddea4ebf2ab7c) ) + ROM_LOAD( "lo5_03a.17", 0xd8000, 0x8000, CRC(7aca5d83) SHA1(95456b6c5adc5b776fbd33fd95cc62d4a83c34b6) ) + ROM_LOAD( "lo5_27a.65", 0xe0000, 0x8000, CRC(119ff70a) SHA1(e64d41bc7822c9e99fd025b771551a6c511d13f2) ) + ROM_LOAD( "lo5_19a.35", 0xe8000, 0x8000, CRC(5aaa6a53) SHA1(f8ff547979883ac9a969e76d90d028ec4286ec4c) ) + ROM_LOAD( "lo5_07a.45", 0xf0000, 0x8000, CRC(313f127f) SHA1(0782b8dd5f3a3384c3e7bc9cacaadf6804e06a38) ) + ROM_LOAD( "lo5_15a.23", 0xf8000, 0x8000, CRC(66f9c5db) SHA1(cc68da9312ee0a3441b62d14107e1b7de9b04de3) ) + + /* Object LUTs */ + ROM_REGION( 0x10000, REGION_USER1, 0 ) + ROM_LOAD( "lo4_02.109", 0x0000, 0x8000, CRC(0832edde) SHA1(77f9efbe029773417dbc3836a36687e37b5bee4b) ) + ROM_LOAD( "lo4_03.108", 0x8000, 0x8000, CRC(1efac891) SHA1(faf305a30cab1c6bf8a9d6e2682b2c3745aec956) ) + + /* Object chunk LUTs */ + ROM_REGION16_LE( 0x20000, REGION_USER2, 0 ) + ROM_LOAD16_BYTE( "lo4_04a.119", 0x00000, 0x10000, CRC(098f4151) SHA1(cf38e3c5f3442fbfa97870d25f7c89c465f847a9) ) + ROM_LOAD16_BYTE( "lo4_05a.118", 0x00001, 0x10000, CRC(3b21667c) SHA1(b8337f733ede35145602ee3f0de25c2d4db1b2a5) ) + + /* Colour PROMs */ + ROM_REGION( 0x1800, REGION_PROMS, 0 ) + ROM_LOAD( "lo1a.5", 0x000, 0x400, CRC(82391f30) SHA1(d7153c1f3a3e54de4d4d6f432fbcd66449b96b6e) ) + ROM_LOAD( "lo2a.2", 0x400, 0x400, CRC(2bfc6288) SHA1(03d293ddc0c614b606be823826a4375b3d35901f) ) + + /* Object scale PROMs */ + ROM_LOAD_NIB_LOW ( "lo_3.69", 0x800, 0x800, CRC(9d9c41a9) SHA1(aabeefe95274f10400b4b7810ea50afcc4f19fde) ) + ROM_LOAD_NIB_HIGH( "lo_4.68", 0x800, 0x800, CRC(ca4874ef) SHA1(c742f79729b0dc4d227379e9109c7ed21b4c38bb) ) +ROM_END + + +/************************************* + * + * Game driver(s) + * + *************************************/ + +GAME( 1986, lockon, 0, lockon, lockon, 0, ROT0, "Tatsumi", "Lock-On (rev. C)", 0 ) +GAME( 1986, lockone, lockon, lockon, lockone, 0, ROT0, "Tatsumi", "Lock-On (rev. E)", 0 ) diff --git a/src/mame/includes/lockon.h b/src/mame/includes/lockon.h new file mode 100644 index 00000000000..3414131cddc --- /dev/null +++ b/src/mame/includes/lockon.h @@ -0,0 +1,55 @@ +/************************************************************************* + + Lock-On hardware + +*************************************************************************/ + +/* Calculated from CRT controller writes */ +#define PIXEL_CLOCK (XTAL_21MHz / 3) +#define FRAMEBUFFER_CLOCK XTAL_10MHz +#define HBSTART 320 +#define HBEND 0 +#define HTOTAL 448 +#define VBSTART 240 +#define VBEND 0 +#define VTOTAL 280 + +enum +{ + MAIN_CPU = 0, + GROUND_CPU, + OBJECT_CPU, + SOUND_CPU +}; + +/*----------- defined in drivers/lockon.c -----------*/ +extern UINT8 lockon_ctrl_reg; +extern UINT32 lockon_main_inten; + +/*----------- defined in video/lockon.c -----------*/ +PALETTE_INIT( lockon ); +VIDEO_START( lockon ); +VIDEO_UPDATE( lockon ); +VIDEO_EOF( lockon ); +READ16_HANDLER( lockon_crtc_r ); +WRITE16_HANDLER( lockon_crtc_w ); +WRITE16_HANDLER( lockon_rotate_w ); +WRITE16_HANDLER( lockon_fb_clut_w ); +WRITE16_HANDLER( lockon_scene_h_scr_w ); +WRITE16_HANDLER( lockon_scene_v_scr_w ); +WRITE16_HANDLER( lockon_ground_ctrl_w ); +WRITE16_HANDLER( lockon_char_w ); + +WRITE16_HANDLER( lockon_tza112_w ); +READ16_HANDLER( lockon_obj_4000_r ); +WRITE16_HANDLER( lockon_obj_4000_w ); + +extern UINT16 *lockon_char_ram; +extern UINT16 *lockon_scene_ram; +extern UINT16 *lockon_object_ram; +extern UINT16 *lockon_hud_ram; +extern UINT16 *lockon_ground_ram; + +extern size_t lockon_hudram_size; +extern size_t lockon_objectram_size; +extern size_t lockon_groundram_size; diff --git a/src/mame/mame.mak b/src/mame/mame.mak index f5f21c169ec..db1b4922ca7 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -1357,9 +1357,9 @@ $(MAMEOBJ)/taito.a: \ $(VIDEO)/taitoic.o \ $(MAMEOBJ)/tatsumi.a: \ - $(DRIVERS)/lockon.o \ - $(DRIVERS)/tatsumi.o $(MACHINE)/tatsumi.o $(VIDEO)/tatsumi.o \ $(DRIVERS)/tx1.o $(MACHINE)/tx1.o $(AUDIO)/tx1.o $(VIDEO)/tx1.o \ + $(DRIVERS)/lockon.o $(VIDEO)/lockon.o \ + $(DRIVERS)/tatsumi.o $(MACHINE)/tatsumi.o $(VIDEO)/tatsumi.o \ $(MAMEOBJ)/tch.a: \ $(DRIVERS)/kickgoal.o $(VIDEO)/kickgoal.o \ @@ -1519,6 +1519,7 @@ $(MAMEOBJ)/misc.a: \ $(DRIVERS)/coolpool.o \ $(DRIVERS)/cowrace.o \ $(DRIVERS)/crystal.o $(VIDEO)/vrender0.o \ + $(DRIVERS)/cubeqst.o \ $(DRIVERS)/cybertnk.o \ $(DRIVERS)/dcheese.o $(VIDEO)/dcheese.o \ $(DRIVERS)/dgpix.o \ diff --git a/src/mame/mamedriv.c b/src/mame/mamedriv.c index 3015f770681..267e6be264e 100644 --- a/src/mame/mamedriv.c +++ b/src/mame/mamedriv.c @@ -7332,9 +7332,11 @@ Other Sun games /* Tatsumi Games */ DRIVER( tx1 ) /* (c) 1983 Tatsumi */ DRIVER( tx1a ) /* (c) 1983 Tatsumi */ + /* TX-1 V8 */ /* (c) 1984 Tatsumi */ DRIVER( buggyboy ) /* (c) 1985 Tatsumi */ DRIVER( buggybjr ) /* (c) 1986 Tatsumi */ DRIVER( lockon ) /* (c) 1986 Tatsumi */ + DRIVER( lockone ) /* (c) 1986 Tatsumi */ /* Gray Out */ /* (c) 1987 Tatsumi */ DRIVER( apache3 ) /* (c) 1988 Tatsumi */ DRIVER( roundup5 ) /* (c) 1989 Tatsumi */ diff --git a/src/mame/video/lockon.c b/src/mame/video/lockon.c new file mode 100644 index 00000000000..a4a561f7f52 --- /dev/null +++ b/src/mame/video/lockon.c @@ -0,0 +1,989 @@ +/*************************************************************************** + + Lock-On video hardware + +***************************************************************************/ + +#include "driver.h" +#include "deprecat.h" +#include "lockon.h" +#include "video/resnet.h" +#include "cpu/nec/nec.h" + +#define CURSOR_XPOS 168 +#define CURSOR_YPOS 239 +#define FRAMEBUFFER_MAX_X 431 +#define FRAMEBUFFER_MAX_Y (UINT32)((FRAMEBUFFER_CLOCK / (float)(FRAMEBUFFER_MAX_X-1)) / ((float)PIXEL_CLOCK/(HTOTAL*VTOTAL))) + + +/************************************* + * + * Globals + * + *************************************/ + +UINT16 *lockon_char_ram; +UINT16 *lockon_hud_ram; +UINT16 *lockon_scene_ram; +UINT16 *lockon_ground_ram; +UINT16 *lockon_object_ram; + +size_t lockon_hudram_size; +size_t lockon_objectram_size; +size_t lockon_groundram_size; + +UINT8 *obj_pal_ram; + +/************************************* + * + * Statics + * + *************************************/ + +static tilemap *lockon_tilemap; +static UINT8 ground_ctrl; +static UINT16 scroll_h; +static UINT16 scroll_v; + +static mame_bitmap *front_buffer; +static mame_bitmap *back_buffer; +static emu_timer *bufend_timer; +static emu_timer *cursor_timer; + +/* Rotation Control */ +static UINT16 xsal; +static UINT16 x0ll; +static UINT16 dx0ll; +static UINT16 dxll; +static UINT16 ysal; +static UINT16 y0ll; +static UINT16 dy0ll; +static UINT16 dyll; + +/* Object palette RAM control */ +static UINT32 iden; +static UINT32 obj_pal_latch; +static UINT32 obj_pal_addr; + + +/************************************* + * + * HD46505S-2 CRT Controller + * + *************************************/ + +READ16_HANDLER( lockon_crtc_r ) +{ + return 0xffff; +} + +WRITE16_HANDLER( lockon_crtc_w ) +{ +#if 0 + data &= 0xff; + + if (offset == 0) + { + switch (data) + { + case 0x00: mame_printf_debug("Horizontal Total "); break; + case 0x01: mame_printf_debug("Horizontal displayed "); break; + case 0x02: mame_printf_debug("Horizontal sync position "); break; + case 0x03: mame_printf_debug("Horizontal sync width "); break; + case 0x04: mame_printf_debug("Vertical total "); break; + case 0x05: mame_printf_debug("Vertical total adjust "); break; + case 0x06: mame_printf_debug("Vertical displayed "); break; + case 0x07: mame_printf_debug("Vertical sync position "); break; + case 0x08: mame_printf_debug("Interlace mode "); break; + case 0x09: mame_printf_debug("Max. scan line address "); break; + case 0x0a: mame_printf_debug("Cursror start "); break; + case 0x0b: mame_printf_debug("Cursor end "); break; + case 0x0c: mame_printf_debug("Start address (h) "); break; + case 0x0d: mame_printf_debug("Start address (l) "); break; + case 0x0e: mame_printf_debug("Cursor (h) "); break; + case 0x0f: mame_printf_debug("Cursor (l) "); break; + case 0x10: mame_printf_debug("Light pen (h)) "); break; + case 0x11: mame_printf_debug("Light pen (l) "); break; + } + } + else if (offset == 1) + { + mame_printf_debug("0x%.2x, (%d)\n",data, data); + } +#endif +} + +static TIMER_CALLBACK( cursor_callback ) +{ + if (lockon_main_inten) + cpunum_set_input_line_and_vector(machine, MAIN_CPU, 0, HOLD_LINE, 0xff); + + timer_adjust(cursor_timer, video_screen_get_time_until_pos(0, CURSOR_YPOS, CURSOR_XPOS), 0, attotime_zero); +} + +/************************************* + * + * Palette decoding + * + *************************************/ + +static const res_net_info lockon_net_info = +{ + RES_NET_VCC_5V | RES_NET_VBIAS_5V | RES_NET_VIN_TTL_OUT, + { + {RES_NET_AMP_NONE, 560, 0, 5, {4700, 2200, 1000, 470, 220}}, + {RES_NET_AMP_NONE, 560, 0, 5, {4700, 2200, 1000, 470, 220}}, + {RES_NET_AMP_NONE, 560, 0, 5, {4700, 2200, 1000, 470, 220}} + } +}; + +static const res_net_info lockon_pd_net_info = +{ + RES_NET_VCC_5V | RES_NET_VBIAS_5V | RES_NET_VIN_TTL_OUT, + { + {RES_NET_AMP_NONE, 560, 580, 5, {4700, 2200, 1000, 470, 220}}, + {RES_NET_AMP_NONE, 560, 580, 5, {4700, 2200, 1000, 470, 220}}, + {RES_NET_AMP_NONE, 560, 580, 5, {4700, 2200, 1000, 470, 220}} + } +}; + +PALETTE_INIT( lockon ) +{ + int i; + + for (i = 0; i < 1024; ++i) + { + UINT8 r, g, b; + UINT8 p1 = color_prom[i]; + UINT8 p2 = color_prom[i + 0x400]; + + if (p2 & 0x80) + { + r = compute_res_net( (p2 >> 2) & 0x1f, 0, &lockon_net_info ); + g = compute_res_net( ((p1 >> 5) & 0x7) | (p2 & 3) << 3, 1, &lockon_net_info ); + b = compute_res_net( (p1 & 0x1f), 2, &lockon_net_info ); + } + else + { + r = compute_res_net( (p2 >> 2) & 0x1f, 0, &lockon_pd_net_info ); + g = compute_res_net( ((p1 >> 5) & 0x7) | (p2 & 3) << 3, 1, &lockon_pd_net_info ); + b = compute_res_net( (p1 & 0x1f), 2, &lockon_pd_net_info ); + } + + palette_set_color(Machine, i, MAKE_RGB(r, g, b)); + } +} + + +/************************************* + * + * Character tilemap handling + * + *************************************/ + +WRITE16_HANDLER( lockon_char_w ) +{ + lockon_char_ram[offset] = data; + tilemap_mark_tile_dirty(lockon_tilemap, offset); +} + +static TILE_GET_INFO( get_lockon_tile_info ) +{ + UINT32 tileno = lockon_char_ram[tile_index] & 0x03ff; + UINT32 col = (lockon_char_ram[tile_index] >> 10) & 0x3f; + + col = (col & 0x1f) + (col & 0x20 ? 64 : 0); + SET_TILE_INFO(0, tileno, col, 0); +} + + +/******************************************************************************************* + + Scene tilemap hardware + +*******************************************************************************************/ + +WRITE16_HANDLER( lockon_scene_h_scr_w ) +{ + scroll_h = data & 0x1ff; +} + +WRITE16_HANDLER( lockon_scene_v_scr_w ) +{ + scroll_v = data & 0x81ff; +} + +static void scene_draw(void) +{ + UINT32 y; + + /* 3bpp characters */ + const UINT8 *const gfx1 = memory_region(REGION_GFX2); + const UINT8 *const gfx2 = gfx1 + 0x10000; + const UINT8 *const gfx3 = gfx1 + 0x20000; + const UINT8 *const clut = gfx1 + 0x30000; + + for (y = 0; y < FRAMEBUFFER_MAX_Y; ++y) + { + UINT32 x; + UINT32 d0 = 0, d1 = 0, d2 = 0; + UINT32 colour = 0; + UINT32 y_offs; + UINT32 x_offs; + UINT32 y_gran; + UINT16 *bmpaddr; + UINT32 ram_mask = 0x7ff; + + y_offs = (y + scroll_v) & 0x1ff; + + /* Clamp - stops tilemap wrapping when screen is rotated */ + if (BIT(scroll_v, 15) && y_offs & 0x100) + ram_mask = 0x7; + + x_offs = (scroll_h - 8) & 0x1ff; + y_gran = y_offs & 7; + + if (x_offs & 7) + { + UINT32 tileidx; + UINT16 addr = ((y_offs & ~7) << 3) + ((x_offs >> 3) & 0x3f); + UINT16 ram_val = lockon_scene_ram[addr & ram_mask]; + + colour = (clut[ram_val & 0x7fff] & 0x3f) << 3; + tileidx = ((ram_val & 0x0fff) << 3) + y_gran; + + d0 = *(gfx1 + tileidx); + d1 = *(gfx2 + tileidx); + d2 = *(gfx3 + tileidx); + } + + bmpaddr = BITMAP_ADDR16(back_buffer, y, 0); + + for (x = 0; x < FRAMEBUFFER_MAX_X; ++x) + { + UINT32 x_gran = (x_offs & 7) ^ 7; + UINT32 col; + + if (!(x_offs & 7)) + { + UINT32 tileidx; + UINT16 addr = ((y_offs & ~7) << 3) + ((x_offs >> 3) & 0x3f); + UINT16 ram_val = lockon_scene_ram[addr & ram_mask]; + + colour = (clut[ram_val & 0x7fff] & 0x3f) << 3; + tileidx = ((ram_val & 0x0fff) << 3) + y_gran; + + d0 = *(gfx1 + tileidx); + d1 = *(gfx2 + tileidx); + d2 = *(gfx3 + tileidx); + } + + col = colour + | (((d2 >> x_gran) & 1) << 2) + | (((d1 >> x_gran) & 1) << 1) + | ( (d0 >> x_gran) & 1); + + *bmpaddr++ = Machine->pens[0xa00 + col]; + + x_offs = (x_offs + 1) & 0x1ff; + } + + } +} + +/******************************************************************************************* + + Ground Hardware + + Each framebuffer line corresponds to a three word entry in ground RAM, + starting from offset 3: + + FEDCBA9876543210 + 0 |.............xxx| Tile line (A0-A2 GFX ROMs) + |...........xx...| Tile index (A6-A5 GFX ROMs) + |........xxx.....| ROM lut address (A6-A4) + |.xxxxxxx........| ROM lut address (A13-A7) + |x...............| /Line enable + + 1 |........xxxxxxxx| TZ2213 value + |xxxxxxxx........| X offset + + 2 |........xxxxxxxx| TZ2213 DX + |.......x........| Carry + |x...............| End of list marker + + An 8-bit ground control register controls the following: + + 76543210 + |......xx| LUT ROM A15-A14 + |....xx..| LUT ROM select + |..xx....| CLUT ROM A13-A12 + |.x......| GFX ROM A15, CLUT ROM A14 + |x.......| GFX ROM bank select (always 0 - only 1 bank is present) + + *******************************************************************************************/ + +WRITE16_HANDLER( lockon_ground_ctrl_w ) +{ + ground_ctrl = data & 0xff; +} + +static TIMER_CALLBACK( bufend_callback ) +{ + cpunum_set_input_line_and_vector(Machine, GROUND_CPU, 0, HOLD_LINE, 0xff); + cpunum_set_input_line(Machine, OBJECT_CPU, NEC_INPUT_LINE_POLL, ASSERT_LINE); +} + +/* Get data for a each 8x8x3 ground tile */ +#define GET_GROUND_DATA() \ +{ \ + UINT32 gfx_a4_3 = (ls163 & 0xc) << 1; \ + UINT32 lut_addr = lut_address + ((ls163 >> 4) & 0xf); \ + UINT32 gfx_a14_7 = lut_rom[lut_addr] << 7; \ + clut_addr = (lut_rom[lut_addr] << 4) | clut_a14_12 | clut_a4_3 | (ls163 & 0xc) >> 2; \ + gfx_addr = gfx_a15 | gfx_a14_7 | gfx_a6_5 | gfx_a4_3 | gfx_a2_0; \ + pal = (clut_rom[clut_addr] << 3); \ + rom_data1 = gfx_rom[gfx_addr]; \ + rom_data2 = gfx_rom[gfx_addr + 0x10000]; \ + rom_data3 = gfx_rom[gfx_addr + 0x20000]; \ +} + +static void ground_draw(void) +{ + /* ROM pointers */ + const UINT8 *const gfx_rom = memory_region(REGION_GFX4); + const UINT8 *const lut_rom = gfx_rom + 0x30000 + ((ground_ctrl >> 2) & 0x3 ? 0x10000 : 0); + const UINT8 *const clut_rom = gfx_rom + 0x50000; + + UINT32 lut_a15_14 = (ground_ctrl & 0x3) << 14; + UINT32 clut_a14_12 = (ground_ctrl & 0x70) << 8; + UINT32 gfx_a15 = (ground_ctrl & 0x40) << 9; + UINT32 offs = 3; + UINT32 y; + + /* TODO: Clean up and emulate CS of GFX ROMs? */ + for (y = 0; y < FRAMEBUFFER_MAX_Y; ++y) + { + UINT16 *bmpaddr = BITMAP_ADDR16(back_buffer, y, 0); + UINT8 ls163; + UINT32 clut_addr; + UINT32 gfx_addr; + UINT8 rom_data1 = 0; + UINT8 rom_data2 = 0; + UINT8 rom_data3 = 0; + UINT32 pal = 0; + UINT32 x; + + /* Draw this line? */ + if (!(lockon_ground_ram[offs] & 0x8000)) + { + UINT32 gfx_a2_0 = lockon_ground_ram[offs] & 0x0007; + UINT32 gfx_a6_5 = (lockon_ground_ram[offs] & 0x0018) << 2; + UINT32 clut_a4_3 = (lockon_ground_ram[offs] & 0x0018) >> 1; + UINT8 tz2213_x = lockon_ground_ram[offs + 1] & 0xff; + UINT8 tz2213_dx = lockon_ground_ram[offs + 2] & 0xff; + + UINT32 lut_address = lut_a15_14 + ((lockon_ground_ram[offs] & 0x7fe0) >> 1); + UINT32 cy = lockon_ground_ram[offs + 2] & 0x0100; + UINT32 color; + UINT32 gpbal2_0_prev; + + ls163 = lockon_ground_ram[offs + 1] >> 8; + + gpbal2_0_prev = ((ls163 & 3) << 1) | BIT(tz2213_x, 7); + + if (gpbal2_0_prev) + GET_GROUND_DATA(); + + for (x = 0; x < FRAMEBUFFER_MAX_X; x++) + { + UINT32 tz2213_cy; + UINT32 gpbal2_0 = ((ls163 & 3) << 1) | BIT(tz2213_x, 7); + + /* Stepped into a new tile? */ + if (gpbal2_0 < gpbal2_0_prev) + GET_GROUND_DATA(); + + gpbal2_0_prev = gpbal2_0; + + color = pal; + color += (rom_data1 >> gpbal2_0) & 0x1; + color += ((rom_data2 >> gpbal2_0) & 0x1) << 1; + color += ((rom_data3 >> gpbal2_0) & 0x1) << 2; + + *bmpaddr++ = Machine->pens[0x800 + color]; + + /* Update the counters */ + tz2213_cy = (UINT8)tz2213_dx > (UINT8)~(tz2213_x); + tz2213_x = (tz2213_x + tz2213_dx); + + /* Carry? */ + if (tz2213_cy || cy) + ++ls163; + } + } + + offs += 3; + + /* End of list marker */ + if (lockon_ground_ram[offs + 2] & 0x8000) + { + timer_adjust(bufend_timer, attotime_mul(ATTOTIME_IN_HZ(FRAMEBUFFER_CLOCK), FRAMEBUFFER_MAX_X * y), 0, attotime_zero); + } + } +} + + +/******************************************************************************************* + + Object hardware + + Customs (4 each, 1 per bitplane) + TZA118 - Scaling + TZ4203 - Objects with integrated line buffer. + + FEDCBA9876543210 + 0 |......xxxxxxxxxx| Y position + |....xx..........| Object Y size + |..xx............| Object X size + |.x..............| Y flip + |x...............| X flip + 1 |........xxxxxxxx| X/Y scale + |.xxxxxxx........| Colour + |x...............| End of list marker + 2 |xxxxxxxxxxxxxxxx| Chunk ROM address + 3 |.....xxxxxxxxxxx| X position + +*******************************************************************************************/ + +/* + There's logic to prevent shadow pixels from being drawn against the scene tilemap, + so that shadows don't appear against the sky. +*/ +#define DRAW_OBJ_PIXEL(COLOR) \ +do { \ + if (px < FRAMEBUFFER_MAX_X) \ + if (COLOR != 0xf) \ + { \ + UINT8 clr = obj_pal_ram[(pal << 4) + COLOR]; \ + UINT16 *pix = (line + px); \ + if (!(clr == 0xff && ((*pix & 0xe00) == 0xa00))) \ + *pix = Machine->pens[0x400 + clr]; \ + } \ + px = (px + 1) & 0x7ff; \ +} while(0) + +static void objects_draw(void) +{ + UINT32 offs; + + const UINT8 *const romlut = memory_region(REGION_USER1); + const UINT16 *const chklut = (UINT16*)memory_region(REGION_USER2); + const UINT8 *const gfxrom = memory_region(REGION_GFX5); + const UINT8 *const sproms = memory_region(REGION_PROMS) + 0x800; + + for (offs = 0; offs < lockon_objectram_size; offs += 4) + { + UINT32 y; + UINT32 xpos; + UINT32 ypos; + UINT32 xsize; + UINT32 ysize; + UINT32 xflip; + UINT32 yflip; + UINT32 scale; + UINT32 pal; + UINT32 lines; + UINT32 opsta; + UINT32 opsta15_8; + + /* Retrieve the object attributes */ + ypos = lockon_object_ram[offs] & 0x03ff; + xpos = lockon_object_ram[offs + 3] & 0x07ff; + ysize = (lockon_object_ram[offs] >> 10) & 0x3; + xsize = (lockon_object_ram[offs] >> 12) & 0x3; + yflip = BIT(lockon_object_ram[offs], 14); + xflip = BIT(lockon_object_ram[offs], 15); + scale = lockon_object_ram[offs + 1] & 0xff; + pal = (lockon_object_ram[offs + 1] >> 8) & 0x7f; + opsta = lockon_object_ram[offs + 2]; + + if (iden) + { + obj_pal_ram[(pal << 4) + obj_pal_addr] = obj_pal_latch; + break; + } + + /* How many lines will this sprite occupy? The PAL @ IC154 knows... */ + lines = scale >> (3 - ysize); + + opsta15_8 = opsta & 0xff00; + + /* Account for line buffering */ + ypos -=1; + + for (y = 0; y < FRAMEBUFFER_MAX_Y; y++) + { + UINT32 cy = (y + ypos) & 0x3ff; + UINT32 optab; + UINT32 lutaddr; + UINT32 tile; + UINT8 cnt; + UINT32 yidx; + UINT16 *line = BITMAP_ADDR16(back_buffer, y, 0); + UINT32 px = xpos; + + /* Outside the limits? */ + if (cy & 0x300) + continue; + + if ((cy & 0xff) >= lines) + break; + + lutaddr = (scale & 0x80 ? 0x8000 : 0) | ((scale & 0x7f) << 8) | (cy & 0xff); + optab = romlut[lutaddr] & 0x7f; + + if (yflip) + optab ^= 7; + + yidx = (optab & 7); + + /* Now calculate the lower 7-bits of the LUT ROM address. PAL @ IC157 does this */ + cnt = (optab >> 3) * (1 << xsize); + + if (xflip) + cnt ^= 7 >> (3 - xsize); + if (yflip) + cnt ^= (0xf >> (3 - ysize)) * (1 << xsize); + + cnt = (cnt + (opsta & 0xff)); + + /* Draw! */ + for (tile = 0; tile < (1 << xsize); ++tile) + { + UINT16 sc; + UINT16 scl; + UINT32 x; + UINT32 tileaddr; + UINT16 td0, td1, td2, td3; + UINT32 j; + UINT32 bank; + + scl = scale & 0x7f; + tileaddr = (chklut[opsta15_8 + cnt] & 0x7fff); + bank = ((tileaddr >> 12) & 3) * 0x40000; + tileaddr = bank + ((tileaddr & ~0xf000) << 3); + + if (xflip) + --cnt; + else + ++cnt; + + /* Draw two 8x8 tiles */ + for (j = 0; j < 2; ++j) + { + /* Get tile data */ + UINT32 tileadd = tileaddr + (0x20000 * (j ^ xflip)); + + /* Retrieve scale values from PROMs */ + sc = sproms[(scl << 4) + (tile * 2) + j]; + + /* Data from ROMs is inverted */ + td3 = gfxrom[tileadd + yidx] ^ 0xff; + td2 = gfxrom[tileadd + 0x8000 + yidx] ^ 0xff; + td1 = gfxrom[tileadd + 0x10000 + yidx] ^ 0xff; + td0 = gfxrom[tileadd + 0x18000 + yidx] ^ 0xff; + + if (scale & 0x80) + { + for (x = 0; x < 8; ++x) + { + UINT8 col; + UINT8 pix = x; + + if (!xflip) + pix ^= 0x7; + + col = BIT(td0, pix) + | (BIT(td1, pix) << 1) + | (BIT(td2, pix) << 2) + | (BIT(td3, pix) << 3); + + DRAW_OBJ_PIXEL(col); + + if ( BIT(sc, x) ) + DRAW_OBJ_PIXEL(col); + } + } + else + { + for (x = 0; x < 8; ++x) + { + UINT8 col; + UINT8 pix = x; + + if ( BIT(sc, x) ) + { + if (!xflip) + pix ^= 0x7; + + col = BIT(td0, pix) + | (BIT(td1, pix) << 1) + | (BIT(td2, pix) << 2) + | (BIT(td3, pix) << 3); + + DRAW_OBJ_PIXEL(col); + } + } + } + } + } + } + + /* Check for the end of list marker */ + if (lockon_object_ram[offs + 1] & 0x8000) + return; + } +} + +/* The mechanism used by the object CPU to update the object ASICs palette RAM */ +WRITE16_HANDLER( lockon_tza112_w ) +{ + if (iden) + { + obj_pal_latch = data & 0xff; + obj_pal_addr = offset & 0xf; + objects_draw(); + } +} + +READ16_HANDLER( lockon_obj_4000_r ) +{ + cpunum_set_input_line(Machine, OBJECT_CPU, NEC_INPUT_LINE_POLL, CLEAR_LINE); + return 0xffff; +} + +WRITE16_HANDLER( lockon_obj_4000_w ) +{ + iden = data & 1; +} + + +/******************************************************************************************* + + Frame buffer rotation hardware + + FEDCBA9876543210 + 0 |........xxxxxxxx| X start address + |.......x........| Direction + 1 |........xxxxxxxx| TZ2213 IC65 value + |.......x........| TZ2213 IC65 /enable + 2 |........xxxxxxxx| TZ2213 IC65 delta + 3 |........xxxxxxxx| TZ2213 IC106 delta + |.......x........| TZ2213 IC106 enable + 4 |.......xxxxxxxxx| Y start address + 5 |........xxxxxxxx| TZ2213 IC66 value + 6 |........xxxxxxxx| TZ2213 IC66 delta + |.......x........| TZ2213 IC65 /enable + 7 |........xxxxxxxx| TZ2213 IC107 delta + |.......x........| TZ2213 /enable + |......x.........| Direction + +*******************************************************************************************/ + +WRITE16_HANDLER( lockon_fb_clut_w ) +{ + rgb_t color; + + color = palette_get_color(Machine, 0x300 + (data & 0xff)); + palette_set_color(Machine, 0x400 + offset, color); +} + +/* Rotation control register */ +WRITE16_HANDLER( lockon_rotate_w ) +{ + switch (offset & 7) + { + case 0: xsal = data & 0x1ff; break; + case 1: x0ll = data & 0xff; break; + case 2: dx0ll = data & 0x1ff; break; + case 3: dxll = data & 0x1ff; break; + + case 4: ysal = data & 0x1ff; break; + case 5: y0ll = data & 0xff; break; + case 6: dy0ll = data & 0x1ff; break; + case 7: dyll = data & 0x3ff; break; + } +} + +#define INCREMENT(ACC, CNT) \ +do { \ + carry = (UINT8)d##ACC > (UINT8)~ACC; \ + ACC += d##ACC; \ + if (carry) ++CNT; \ +} while(0) + +#define DECREMENT(ACC, CNT) \ +do { \ + carry = (UINT8)d##ACC > (UINT8)ACC; \ + ACC -= d##ACC; \ + if (carry) --CNT; \ +} while(0) + +static void rotate_draw(mame_bitmap *bitmap, const rectangle *cliprect) +{ + UINT32 y; + + /* Counters */ + UINT32 cxy = xsal & 0xff; + UINT32 cyy = ysal & 0x1ff; + + /* Accumulator values and deltas */ + UINT8 axy = x0ll & 0xff; + UINT8 daxy = dx0ll & 0xff; + UINT8 ayy = y0ll & 0xff; + UINT8 dayy = dy0ll & 0xff; + UINT8 dayx = dyll & 0xff; + UINT8 daxx = dxll & 0xff; + + UINT32 xy_up = BIT(xsal, 8); + UINT32 yx_up = BIT(dyll, 9); + UINT32 axx_en = !BIT(dxll, 8); + UINT32 ayx_en = !BIT(dyll, 8); + UINT32 axy_en = !BIT(dx0ll, 8); + UINT32 ayy_en = !BIT(dy0ll, 8); + + for (y = 0; y <= cliprect->max_y; ++y) + { + UINT32 carry; + UINT16 *dst = BITMAP_ADDR16(bitmap, y, 0); + UINT32 x; + + UINT32 cx = cxy; + UINT32 cy = cyy; + + UINT8 axx = axy; + UINT8 ayx = ayy; + + for (x = 0; x <= cliprect->max_x; ++x) + { + cx &= 0x1ff; + cy &= 0x1ff; + + *dst++ = *BITMAP_ADDR16(front_buffer, cy, cx); + + if (axx_en) + INCREMENT(axx, cx); + else + ++cx; + + if (ayx_en) + { + if (yx_up) + INCREMENT(ayx, cy); + else + DECREMENT(ayx, cy); + } + else + { + if (yx_up) + ++cy; + else + --cy; + } + } + + if (axy_en) + { + if (xy_up) + INCREMENT(axy, cxy); + else + DECREMENT(axy, cxy); + } + else + { + if (xy_up) + ++cxy; + else + --cxy; + } + + if (ayy_en) + INCREMENT(ayy, cyy); + else + ++cyy; + + cxy &= 0xff; + cyy &= 0x1ff; + } +} + + +/******************************************************************************************* + + HUD Drawing Hardware + + A sprite layer that uses 8x8x1bpp tiles to form bigger sprites + + 0 |.......xxxxxxxxx| Y Position + |xxxxxxx.........| Code + 1 |.......xxxxxxxxx| X Position + |....xxx.........| Colour + |.xxx............| Sprite width (0=8, 1=16, 2=24, 3=32 pixels, etc.) + |x...............| End of list marker + +*******************************************************************************************/ + +static void hud_draw(mame_bitmap *bitmap, const rectangle *cliprect) +{ + UINT8 *tile_rom = memory_region(REGION_GFX3); + UINT32 offs; + + for (offs = 0x0; offs <= lockon_hudram_size; offs += 2) + { + UINT32 y; + UINT32 y_pos; + UINT32 x_pos; + UINT32 y_size; + UINT32 x_size; + UINT32 layout; + UINT16 colour; + UINT32 code; + UINT32 rom_a12_7; + + /* End of sprite list marker */ + if (lockon_hud_ram[offs + 1] & 0x8000) + break; + + y_pos = lockon_hud_ram[offs] & 0x1ff; + x_pos = lockon_hud_ram[offs + 1] & 0x1ff; + x_size = (lockon_hud_ram[offs + 1] >> 12) & 7; + code = (lockon_hud_ram[offs] >> 9) & 0x7f; + colour = Machine->pens[0x200 + ((lockon_hud_ram[offs + 1] >> 9) & 7)]; + layout = (code >> 5) & 3; + + rom_a12_7 = (code & 0xfe) << 6; + + /* Account for line buffering */ + y_pos -= 1; + + if (layout == 3) + y_size = 32; + else if (layout == 2) + y_size = 16; + else + y_size = 8; + + for (y = cliprect->min_y; y <= cliprect->max_y; ++y) + { + UINT32 xt; + UINT32 cy; + + cy = y_pos + y; + + if (cy < 0x200) + continue; + + if ((cy & 0xff) == y_size) + break; + + for (xt = 0; xt <= x_size; ++xt) + { + UINT32 rom_a6_3; + UINT32 px; + UINT8 gfx_strip; + + if (layout == 3) + rom_a6_3 = (BIT(cy, 4) << 3) | (BIT(cy, 3) << 2) | (BIT(xt, 1) << 1) | BIT(xt, 0); + else if (layout == 2) + rom_a6_3 = ((BIT(code, 0) << 3) | (BIT(xt, 1) << 2) | (BIT(cy, 3) << 1) | (BIT(xt, 0))); + else + rom_a6_3 = (BIT(code, 0) << 3) | (xt & 7); + + rom_a6_3 <<= 3; + + /* Get tile data */ + gfx_strip = tile_rom[rom_a12_7 | rom_a6_3 | (cy & 7)]; + + if (gfx_strip == 0) + continue; + + /* Draw */ + for (px = 0; px < 8; ++px) + { + UINT32 x = x_pos + (xt << 3) + px; + + if (x <= cliprect->max_x) + { + UINT16 *dst = BITMAP_ADDR16(bitmap, y, x); + + if (BIT(gfx_strip, px ^ 7) && *dst > 255) + *dst = colour; + } + } + } + } + } +} + + +/************************************* + * + * Driver video handlers + * + *************************************/ + +VIDEO_START( lockon ) +{ + lockon_tilemap = tilemap_create(get_lockon_tile_info, tilemap_scan_rows,TILEMAP_TYPE_PEN, 8, 8, 64, 32); + tilemap_set_transparent_pen(lockon_tilemap, 0); + + /* Allocate the two frame buffers for rotation */ + back_buffer = auto_bitmap_alloc(512, 512, BITMAP_FORMAT_INDEXED16); + front_buffer = auto_bitmap_alloc(512, 512, BITMAP_FORMAT_INDEXED16); + + /* 2kB of object ASIC palette RAM */ + obj_pal_ram = auto_malloc(2048); + + /* Timer for ground display list callback */ + bufend_timer = timer_alloc(bufend_callback, NULL); + + /* Timer for the CRTC cursor pulse */ + cursor_timer = timer_alloc(cursor_callback, NULL); + timer_adjust(cursor_timer, video_screen_get_time_until_pos(0, CURSOR_YPOS, CURSOR_XPOS), 0, attotime_zero); +} + +VIDEO_UPDATE( lockon ) +{ + /* If screen output is disabled, fill with black */ + if ( !BIT(lockon_ctrl_reg, 7) ) + { + fillbitmap(bitmap, get_black_pen(machine), cliprect); + return 0; + } + + /* Scan out the frame buffer in rotated order */ + rotate_draw(bitmap, cliprect); + + /* Draw the character tilemap */ + tilemap_draw(bitmap, cliprect, lockon_tilemap, 0, 0); + + /* Draw the HUD */ + hud_draw(bitmap, cliprect); + + return 0; +} + +VIDEO_EOF( lockon ) +{ + /* Swap the frame buffers */ + mame_bitmap *tmp = front_buffer; + front_buffer = back_buffer; + back_buffer = tmp; + + /* Draw the frame buffer layers */ + scene_draw(); + ground_draw(); + objects_draw(); + +}