diff options
Diffstat (limited to 'src/mame/drivers/genesis.c')
-rw-r--r-- | src/mame/drivers/genesis.c | 814 |
1 files changed, 814 insertions, 0 deletions
diff --git a/src/mame/drivers/genesis.c b/src/mame/drivers/genesis.c new file mode 100644 index 00000000000..ed7b462d77d --- /dev/null +++ b/src/mame/drivers/genesis.c @@ -0,0 +1,814 @@ +/* Some Generic Sega Genesis stuff used by Megatech / Megaplay etc. */ + +/* + +Genesis hardware games are in + +megatech.c +megaplay.c +gene_sm.c +segac2.c + +*/ + +#include "driver.h" +#include "genesis.h" + +#define MASTER_CLOCK 53693100 + + +/******************** Sega Genesis ******************************/ + +/* Genesis based */ +static UINT32 z80_68000_latch = 0; +static UINT32 z80_latch_bitcount = 0; + +/* interrupt states */ +static UINT8 irq2_int; /* INT2 */ +static UINT8 scanline_int; /* INT4 - programmable */ +static UINT8 vblank_int; /* INT6 - on every VBLANK */ + +static emu_timer * scan_timer; + + +static int z80running; +UINT16 *genesis_68k_ram; +UINT8 *genesis_z80_ram; + + + +/****************************************************************************** + Interrupt handling +******************************************************************************* + + The Genesis uses 2 Different Interrupts, IRQ4 and IRQ6. + The C2 system uses IRQ2 as well. + + IRQ6 = Vblank, this happens after the last visible line of the display has + been drawn (after line 224) + + IRQ4 = H-Int, this happens based upon the value in H-Int Counter. If the + Horizontal Interrupt is enabled and the Counter Value = 0 there + will be a Level 4 Interrupt Triggered + + IRQ2 = sound int, generated by the YM3438 + + -------- + + More H-Counter Information: + + Providing Horizontal Interrupts are active the H-Counter will be loaded + with the value stored in register #10 (0x0A) at the following times: + (1) At the top of the display, before drawing the first line + (2) When the counter has expired + (3) During the VBlank Period (lines 224-261) + The Counter is decreased by 1 after every line. + +******************************************************************************/ + +/* call this whenever the interrupt state has changed */ +static void update_interrupts(void) +{ + int level = 0; + + /* determine which interrupt is active */ + if (irq2_int) level = 2; + if (scanline_int) level = 4; + if (vblank_int) level = 6; + + /* either set or clear the appropriate lines */ + if (level) + cpunum_set_input_line(0, level, ASSERT_LINE); + else + cpunum_set_input_line(0, 7, CLEAR_LINE); +} + + +/* timer callback to turn off the IRQ4 signal after a short while */ +static TIMER_CALLBACK( vdp_int4_off ) +{ + scanline_int = 0; + update_interrupts(); +} + + +/* timer callback to handle reloading the H counter and generate IRQ4 */ +static TIMER_CALLBACK( vdp_reload_counter ) +{ + int scanline = param; + + /* generate an int if they're enabled */ + if (genesis_vdp_regs[0] & 0x10)/* && !(misc_io_data[7] & 0x10))*/ + if (scanline != 0 || genesis_vdp_regs[10] == 0) + { + scanline_int = 1; + update_interrupts(); + timer_set(video_screen_get_time_until_pos(0, scanline + 1, 0), 0, vdp_int4_off); + } + + /* advance to the next scanline */ + /* behavior 2: 0 count means interrupt after one scanline */ + /* (this behavior matches the Sega C2 emulator) */ + scanline += genesis_vdp_regs[10] + 1; + if (scanline >= 224) + scanline = 0; + + /* set a timer */ + timer_adjust(scan_timer, video_screen_get_time_until_pos(0, scanline, 320), scanline, attotime_zero); +} + + +/* timer callback to turn off the IRQ6 signal after a short while */ +static TIMER_CALLBACK( vdp_int6_off ) +{ + vblank_int = 0; + update_interrupts(); +} + + +/* interrupt callback to generate the VBLANK interrupt */ +INTERRUPT_GEN( genesis_vblank_interrupt ) +{ + /* generate the interrupt */ + vblank_int = 1; + update_interrupts(); + + /* set a timer to turn it off */ + timer_set(video_screen_get_time_until_pos(0, video_screen_get_vpos(0), 22), 0, vdp_int6_off); +} + + +/* interrupt callback to generate the YM3438 interrupt */ +void genesis_irq2_interrupt(int state) +{ + irq2_int = state; + update_interrupts(); +} + + +MACHINE_START( genesis ) +{ + state_save_register_global(irq2_int); + state_save_register_global(scanline_int); + state_save_register_global(vblank_int); +} + + +MACHINE_RESET( genesis ) +{ + /* C2 doesn't have a Z80, so we can't just assume */ + if (machine->drv->cpu[1].type == CPU_Z80) + { + /* the following ensures that the Z80 begins without running away from 0 */ + /* 0x76 is just a forced 'halt' as soon as the CPU is initially run */ + genesis_z80_ram[0] = 0x76; + genesis_z80_ram[0x38] = 0x76; + + cpunum_set_input_line(1, INPUT_LINE_HALT, ASSERT_LINE); + + z80running = 0; + } + + logerror("Machine init\n"); + + /* set the first scanline 0 timer to go off */ + scan_timer = timer_alloc(vdp_reload_counter); + timer_adjust(scan_timer, video_screen_get_time_until_pos(0, 0, 320), 0, attotime_zero); +} + + +/* from MESS */ +READ16_HANDLER(genesis_ctrl_r) +{ +/* int returnval; */ + +/* logerror("genesis_ctrl_r %x\n", offset); */ + switch (offset) + { + case 0: /* DRAM mode is write only */ + return 0xffff; + break; + case 0x80: /* return Z80 CPU Function Stop Accessible or not */ + /* logerror("Returning z80 state\n"); */ + return (z80running ? 0x0100 : 0x0); + break; + case 0x100: /* Z80 CPU Reset - write only */ + return 0xffff; + break; + } + return 0x00; + +} + +/* from MESS */ +WRITE16_HANDLER(genesis_ctrl_w) +{ + data &= ~mem_mask; + +/* logerror("genesis_ctrl_w %x, %x\n", offset, data); */ + + switch (offset) + { + case 0: /* set DRAM mode... we have to ignore this for production cartridges */ + return; + break; + case 0x80: /* Z80 BusReq */ + if (data == 0x100) + { + z80running = 0; + cpunum_set_input_line(1, INPUT_LINE_HALT, ASSERT_LINE); /* halt Z80 */ + /* logerror("z80 stopped by 68k BusReq\n"); */ + } + else + { + z80running = 1; +// memory_set_bankptr(1, &genesis_z80_ram[0]); + + cpunum_set_input_line(1, INPUT_LINE_HALT, CLEAR_LINE); + /* logerror("z80 started, BusReq ends\n"); */ + } + return; + break; + case 0x100: /* Z80 CPU Reset */ + if (data == 0x00) + { + cpunum_set_input_line(1, INPUT_LINE_HALT, ASSERT_LINE); + cpunum_set_input_line(1, INPUT_LINE_RESET, PULSE_LINE); + + cpunum_set_input_line(1, INPUT_LINE_HALT, ASSERT_LINE); + /* logerror("z80 reset, ram is %p\n", &genesis_z80_ram[0]); */ + z80running = 0; + return; + } + else + { + /* logerror("z80 out of reset\n"); */ + } + return; + + break; + } +} + +READ16_HANDLER ( genesis_68k_to_z80_r ) +{ + offset *= 2; + offset &= 0x7fff; + + /* Shared Ram */ + if ((offset >= 0x0000) && (offset <= 0x3fff)) + { + offset &=0x1fff; +// logerror("soundram_r returning %x\n",(gen_z80_shared[offset] << 8) + gen_z80_shared[offset+1]); + return (genesis_z80_ram[offset] << 8) + genesis_z80_ram[offset+1]; + } + + + /* YM2610 */ + if ((offset >= 0x4000) && (offset <= 0x5fff)) + { + switch (offset & 3) + { + case 0: + if (ACCESSING_MSB) return YM3438_status_port_0_A_r(0) << 8; + else return YM3438_read_port_0_r(0); + break; + case 2: + if (ACCESSING_MSB) return YM3438_status_port_0_B_r(0) << 8; + else return 0; + break; + } + } + + /* Bank Register */ + if ((offset >= 0x6000) && (offset <= 0x60ff)) + { + + } + + /* Unused / Illegal */ + if ((offset >= 0x6100) && (offset <= 0x7eff)) + { + /* nothing */ + } + + /* VDP */ + if ((offset >= 0x7f00) && (offset <= 0x7fff)) + { + + } + + return 0x0000; +} + + +READ16_HANDLER ( megaplay_68k_to_z80_r ) +{ + offset *= 2; + offset &= 0x7fff; + + /* Shared Ram */ + if ((offset >= 0x0000) && (offset <= 0x1fff)) + { + offset &=0x1fff; +// logerror("soundram_r returning %x\n",(gen_z80_shared[offset] << 8) + gen_z80_shared[offset+1]); + return (genesis_z80_ram[offset] << 8) + genesis_z80_ram[offset+1]; + } + + if ((offset >= 0x2000) && (offset <= 0x3fff)) + { + offset &=0x1fff; +// if(offset == 0) +// return (readinputport(8) << 8) ^ 0xff00; + return (ic36_ram[offset] << 8) + ic36_ram[offset+1]; + } + + + /* YM2610 */ + if ((offset >= 0x4000) && (offset <= 0x5fff)) + { + switch (offset & 3) + { + case 0: + if (ACCESSING_MSB) return YM3438_status_port_0_A_r(0) << 8; + else return YM3438_read_port_0_r(0); + break; + case 2: + if (ACCESSING_MSB) return YM3438_status_port_0_B_r(0) << 8; + else return 0; + break; + } + } + + /* Bank Register */ + if ((offset >= 0x6000) && (offset <= 0x60ff)) + { + + } + + /* Unused / Illegal */ + if ((offset >= 0x6100) && (offset <= 0x7eff)) + { + /* nothing */ + } + + /* VDP */ + if ((offset >= 0x7f00) && (offset <= 0x7fff)) + { + + } + + return 0x0000; +} + +WRITE16_HANDLER ( genesis_68k_to_z80_w ) +{ + offset *= 2; + offset &= 0x7fff; + + /* Shared Ram */ + if ((offset >= 0x0000) && (offset <= 0x3fff)) + { + offset &=0x1fff; + + if (ACCESSING_LSB) genesis_z80_ram[offset+1] = data & 0xff; + if (ACCESSING_MSB) genesis_z80_ram[offset] = (data >> 8) & 0xff; + } + + + /* YM2610 */ + if ((offset >= 0x4000) && (offset <= 0x5fff)) + { + switch (offset & 3) + { + case 0: + if (ACCESSING_MSB) YM3438_control_port_0_A_w (0, (data >> 8) & 0xff); + else YM3438_data_port_0_A_w (0, (data >> 0) & 0xff); + break; + case 2: + if (ACCESSING_MSB) YM3438_control_port_0_B_w (0, (data >> 8) & 0xff); + else YM3438_data_port_0_B_w (0, (data >> 0) & 0xff); + break; + } + } + + /* Bank Register */ + if ((offset >= 0x6000) && (offset <= 0x60ff)) + { + + } + + /* Unused / Illegal */ + if ((offset >= 0x6100) && (offset <= 0x7eff)) + { + /* nothing */ + } + + /* VDP */ + if ((offset >= 0x7f00) && (offset <= 0x7fff)) + { + offset &= 0x1f; + + if ( (offset >= 0x10) && (offset <=0x17) ) + { + if (ACCESSING_LSB) SN76496_0_w(0, data & 0xff); + if (ACCESSING_MSB) SN76496_0_w(0, (data >>8) & 0xff); + } + + } +} + +/* Gen I/O */ + +/* +cgfm info + +$A10001 Version +$A10003 Port A data +$A10005 Port B data +$A10007 Port C data +$A10009 Port A control +$A1000B Port B control +$A1000D Port C control +$A1000F Port A TxData +$A10011 Port A RxData +$A10013 Port A serial control +$A10015 Port B TxData +$A10017 Port B RxData +$A10019 Port B serial control +$A1001B Port C TxData +$A1001D Port C RxData +$A1001F Port C serial control + +*/ + +UINT16 *genesis_io_ram; + +READ16_HANDLER ( genesis_io_r ) +{ + /* 8-bit only, data is mirrored in both halves */ + + UINT8 return_value = 0; + + switch (offset) + { + case 0: + /* Charles MacDonald ( http://cgfm2.emuviews.com/ ) + D7 : Console is 1= Export (USA, Europe, etc.) 0= Domestic (Japan) + D6 : Video type is 1= PAL, 0= NTSC + D5 : Sega CD unit is 1= not present, 0= connected. + D4 : Unused (always returns zero) + D3 : Bit 3 of version number + D2 : Bit 2 of version number + D1 : Bit 1 of version number + D0 : Bit 0 of version number + */ + return_value = 0x80; /* ? megatech is usa? */ + break; + + case 1: /* port A data (joypad 1) */ + + if (genesis_io_ram[offset] & 0x40) + { + int iport = readinputport(9); + return_value = iport & 0x3f; + } + else + { + int iport1 = readinputport(12); + int iport2 = readinputport(7) >> 1; + return_value = (iport1 & 0x10) + (iport2 & 0x20); + if(iport1 & 0x10 || iport2 & 0x20) + return_value+=1; + } + + return_value = (genesis_io_ram[offset] & 0x80) | return_value; +// logerror ("reading joypad 1 , type %02x %02x\n",genesis_io_ram[offset] & 0x80, return_value &0x7f); + if(bios_ctrl_inputs & 0x04) return_value = 0xff; + break; + + case 2: /* port B data (joypad 2) */ + + if (genesis_io_ram[offset] & 0x40) + { + int iport1 = (readinputport(9) & 0xc0) >> 6; + int iport2 = (readinputport(8) & 0x0f) << 2; + return_value = (iport1 + iport2) & 0x3f; + } + else + { + int iport1 = readinputport(12) << 2; + int iport2 = readinputport(7) >> 2; + return_value = (iport1 & 0x10) + (iport2 & 0x20); + if(iport1 & 0x10 || iport2 & 0x20) + return_value+=1; + } + return_value = (genesis_io_ram[offset] & 0x80) | return_value; +// logerror ("reading joypad 2 , type %02x %02x\n",genesis_io_ram[offset] & 0x80, return_value &0x7f); + if(bios_ctrl_inputs & 0x04) return_value = 0xff; + break; + + default: + return_value = 0xe0; + + } + return return_value | return_value << 8; +} + +READ16_HANDLER ( megaplay_genesis_io_r ) +{ + /* 8-bit only, data is mirrored in both halves */ + + UINT8 return_value = 0; + + switch (offset) + { + case 0: + /* Charles MacDonald ( http://cgfm2.emuviews.com/ ) + D7 : Console is 1= Export (USA, Europe, etc.) 0= Domestic (Japan) + D6 : Video type is 1= PAL, 0= NTSC + D5 : Sega CD unit is 1= not present, 0= connected. + D4 : Unused (always returns zero) + D3 : Bit 3 of version number + D2 : Bit 2 of version number + D1 : Bit 1 of version number + D0 : Bit 0 of version number + */ + return_value = 0x80; /* ? megatech is usa? */ + break; + + case 1: /* port A data (joypad 1) */ + + if (genesis_io_ram[offset] & 0x40) + return_value = readinputport(1) & (genesis_io_ram[4]^0xff); + else + { + return_value = readinputport(2) & (genesis_io_ram[4]^0xff); + return_value |= readinputport(1) & 0x03; + } + return_value = (genesis_io_ram[offset] & 0x80) | return_value; +// logerror ("reading joypad 1 , type %02x %02x\n",genesis_io_ram[offset] & 0xb0, return_value &0x7f); + break; + + case 2: /* port B data (joypad 2) */ + + if (genesis_io_ram[offset] & 0x40) + return_value = readinputport(3) & (genesis_io_ram[5]^0xff); + else + { + return_value = readinputport(4) & (genesis_io_ram[5]^0xff); + return_value |= readinputport(3) & 0x03; + } + return_value = (genesis_io_ram[offset] & 0x80) | return_value; +// logerror ("reading joypad 2 , type %02x %02x\n",genesis_io_ram[offset] & 0xb0, return_value &0x7f); + break; + +// case 3: /* port C data */ +// return_value = bios_6402 << 3; +// break; + + default: + return_value = genesis_io_ram[offset]; + + } + return return_value | return_value << 8; +} + +WRITE16_HANDLER ( genesis_io_w ) +{ +// logerror ("write io offset :%02x data %04x PC: 0x%06x\n",offset,data,activecpu_get_previouspc()); + + switch (offset) + { + case 0x00: + /*??*/ + break; + + case 0x01:/* port A data */ + genesis_io_ram[offset] = (data & (genesis_io_ram[0x04])) | (genesis_io_ram[offset] & ~(genesis_io_ram[0x04])); + break; + + case 0x02: /* port B data */ + genesis_io_ram[offset] = (data & (genesis_io_ram[0x05])) | (genesis_io_ram[offset] & ~(genesis_io_ram[0x05])); + break; + + case 0x03: /* port C data */ + genesis_io_ram[offset] = (data & (genesis_io_ram[0x06])) | (genesis_io_ram[offset] & ~(genesis_io_ram[0x06])); + bios_6204 = data & 0x07; + break; + + case 0x04: /* port A control */ + genesis_io_ram[offset] = data; + break; + + case 0x05: /* port B control */ + genesis_io_ram[offset] = data; + break; + + case 0x06: /* port C control */ + genesis_io_ram[offset] = data; + break; + + case 0x07: /* port A TxData */ + genesis_io_ram[offset] = data; + break; + + default: + genesis_io_ram[offset] = data; + } + +} + +#if 0 +static ADDRESS_MAP_START( genesis_readmem, ADDRESS_SPACE_PROGRAM, 16 ) + AM_RANGE(0x000000, 0x3fffff) AM_READ(MRA16_ROM) /* Cartridge Program Rom */ + AM_RANGE(0xa10000, 0xa1001f) AM_READ(genesis_io_r) /* Genesis Input */ + AM_RANGE(0xa00000, 0xa0ffff) AM_READ(genesis_68k_to_z80_r) + AM_RANGE(0xc00000, 0xc0001f) AM_READ(genesis_vdp_r) /* VDP Access */ + AM_RANGE(0xfe0000, 0xfeffff) AM_READ(MRA16_BANK3) /* Main Ram */ + AM_RANGE(0xff0000, 0xffffff) AM_READ(MRA16_RAM) /* Main Ram */ +ADDRESS_MAP_END + + +static ADDRESS_MAP_START( genesis_writemem, ADDRESS_SPACE_PROGRAM, 16 ) + AM_RANGE(0x000000, 0x3fffff) AM_WRITE(MWA16_ROM) /* Cartridge Program Rom */ + AM_RANGE(0xa10000, 0xa1001f) AM_WRITE(genesis_io_w) AM_BASE(&genesis_io_ram) /* Genesis Input */ + AM_RANGE(0xa11000, 0xa11203) AM_WRITE(genesis_ctrl_w) + AM_RANGE(0xa00000, 0xa0ffff) AM_WRITE(genesis_68k_to_z80_w) + AM_RANGE(0xc00000, 0xc0001f) AM_WRITE(genesis_vdp_w) /* VDP Access */ + AM_RANGE(0xfe0000, 0xfeffff) AM_WRITE(MWA16_BANK3) /* Main Ram */ + AM_RANGE(0xff0000, 0xffffff) AM_WRITE(MWA16_RAM) AM_BASE(&genesis_68k_ram)/* Main Ram */ +ADDRESS_MAP_END +#endif + +/* Z80 Sound Hardware - based on MESS code, to be improved, it can do some strange things */ + +#ifdef LSB_FIRST + #define BYTE_XOR(a) ((a) ^ 1) +#else + #define BYTE_XOR(a) (a) +#endif + + + +static WRITE8_HANDLER ( genesis_bank_select_w ) /* note value will be meaningless unless all bits are correctly set in */ +{ + if (offset !=0 ) return; +// if (!z80running) logerror("undead Z80 latch write!\n"); + if (z80_latch_bitcount == 0) z80_68000_latch = 0; + + z80_68000_latch = z80_68000_latch | ((( ((UINT8)data) & 0x01) << (15+z80_latch_bitcount))); + logerror("value %x written to latch\n", data); + z80_latch_bitcount++; + if (z80_latch_bitcount == 9) + { + z80_latch_bitcount = 0; + logerror("latch set, value %x\n", z80_68000_latch); + } +} + +READ8_HANDLER ( genesis_z80_r ) +{ + offset += 0x4000; + + /* YM2610 */ + if ((offset >= 0x4000) && (offset <= 0x5fff)) + { + switch (offset & 3) + { + case 0: return YM3438_status_port_0_A_r(0); + case 1: return YM3438_read_port_0_r(0); + case 2: return YM3438_status_port_0_B_r(0); + case 3: return 0; + } + } + + /* Bank Register */ + if ((offset >= 0x6000) && (offset <= 0x60ff)) + { + + } + + /* Unused / Illegal */ + if ((offset >= 0x6100) && (offset <= 0x7eff)) + { + /* nothing */ + } + + /* VDP */ + if ((offset >= 0x7f00) && (offset <= 0x7fff)) + { + + } + + return 0x00; +} + +WRITE8_HANDLER ( genesis_z80_w ) +{ + offset += 0x4000; + + /* YM2610 */ + if ((offset >= 0x4000) && (offset <= 0x5fff)) + { + switch (offset & 3) + { + case 0: YM3438_control_port_0_A_w (0, data); + break; + case 1: YM3438_data_port_0_A_w (0, data); + break; + case 2: YM3438_control_port_0_B_w (0, data); + break; + case 3: YM3438_data_port_0_B_w (0, data); + break; + } + } + + /* Bank Register */ + if ((offset >= 0x6000) && (offset <= 0x60ff)) + { + genesis_bank_select_w(offset & 0xff, data); + } + + /* Unused / Illegal */ + if ((offset >= 0x6100) && (offset <= 0x7eff)) + { + /* nothing */ + } + + /* VDP */ + if ((offset >= 0x7f00) && (offset <= 0x7fff)) + { + + } +} + +READ8_HANDLER ( genesis_z80_bank_r ) +{ + int address = (z80_68000_latch) + (offset & 0x7fff); + + if (!z80running) logerror("undead Z80->68000 read!\n"); + + if (z80_latch_bitcount != 0) logerror("reading whilst latch being set!\n"); + + logerror("z80 read from address %x\n", address); + + /* Read the data out of the 68k ROM */ + if (address < 0x400000) return memory_region(REGION_CPU1)[BYTE_XOR(address)]; + /* else read the data out of the 68k RAM */ +// else if (address > 0xff0000) return genesis_68k_ram[BYTE_XOR(offset)]; + + return -1; +} + + +#if 0 +static ADDRESS_MAP_START( genesis_z80_readmem, ADDRESS_SPACE_PROGRAM, 8 ) + AM_RANGE(0x0000, 0x1fff) AM_READ(MRA8_BANK1) + AM_RANGE(0x2000, 0x3fff) AM_READ(MRA8_BANK2) /* mirror */ + AM_RANGE(0x4000, 0x7fff) AM_READ(genesis_z80_r) + AM_RANGE(0x8000, 0xffff) AM_READ(genesis_z80_bank_r) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( genesis_z80_writemem, ADDRESS_SPACE_PROGRAM, 8 ) + AM_RANGE(0x0000, 0x1fff) AM_WRITE(MWA8_BANK1) AM_BASE(&genesis_z80_ram) + AM_RANGE(0x2000, 0x3fff) AM_WRITE(MWA8_BANK2) /* mirror */ + AM_RANGE(0x4000, 0x7fff) AM_WRITE(genesis_z80_w) + // AM_RANGE(0x8000, 0xffff) AM_WRITE(genesis_z80_bank_w) +ADDRESS_MAP_END + +static MACHINE_DRIVER_START( genesis_base ) + /*basic machine hardware */ + MDRV_CPU_ADD_TAG("main", M68000, MASTER_CLOCK / 7) + MDRV_CPU_PROGRAM_MAP(genesis_readmem, genesis_writemem) + MDRV_CPU_VBLANK_INT(genesis_vblank_interrupt,1) + + MDRV_CPU_ADD_TAG("sound", Z80, MASTER_CLOCK / 15) + MDRV_CPU_PROGRAM_MAP(genesis_z80_readmem, genesis_z80_writemem) + MDRV_CPU_VBLANK_INT(irq0_line_hold, 1) /* from vdp at scanline 0xe0 */ + + MDRV_SCREEN_REFRESH_RATE(60) + + MDRV_INTERLEAVE(100) + + MDRV_MACHINE_START(genesis) + MDRV_MACHINE_RESET(genesis) + + /* video hardware */ + MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER | VIDEO_HAS_SHADOWS | VIDEO_HAS_HIGHLIGHTS) + MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) + MDRV_SCREEN_SIZE(342,262) + MDRV_SCREEN_VISIBLE_AREA(0, 319, 0, 223) + MDRV_PALETTE_LENGTH(2048) + + MDRV_VIDEO_START(genesis) + MDRV_VIDEO_UPDATE(genesis) + + /* sound hardware */ + MDRV_SPEAKER_STANDARD_MONO("mono") + + MDRV_SOUND_ADD(YM3438, MASTER_CLOCK/7) + MDRV_SOUND_ROUTE(0, "mono", 0.50) + MDRV_SOUND_ROUTE(1, "mono", 0.50) +MACHINE_DRIVER_END +#endif |