trunk/src/mame/drivers/hankin.c
| r31687 | r31688 | |
| 7 | 7 | |
| 8 | 8 | ToDo: |
| 9 | 9 | - High score isn't saved or remembered |
| 10 | | - Sound |
| 10 | - Sound needs to be verified with original |
| 11 | 11 | - Mechanical |
| 12 | 12 | |
| 13 | 13 | ***********************************************************************************/ |
| r31687 | r31688 | |
| 15 | 15 | #include "machine/genpin.h" |
| 16 | 16 | #include "cpu/m6800/m6800.h" |
| 17 | 17 | #include "machine/6821pia.h" |
| 18 | #include "sound/dac.h" |
| 18 | 19 | #include "hankin.lh" |
| 19 | 20 | |
| 20 | 21 | class hankin_state : public genpin_class |
| r31687 | r31688 | |
| 27 | 28 | , m_ic10(*this, "ic10") |
| 28 | 29 | , m_ic11(*this, "ic11") |
| 29 | 30 | , m_ic2(*this, "ic2") |
| 31 | , m_dac(*this, "dac") |
| 30 | 32 | , m_io_test(*this, "TEST") |
| 31 | 33 | , m_io_dsw0(*this, "DSW0") |
| 32 | 34 | , m_io_dsw1(*this, "DSW1") |
| r31687 | r31688 | |
| 38 | 40 | , m_io_x4(*this, "X4") |
| 39 | 41 | { } |
| 40 | 42 | |
| 41 | | DECLARE_DRIVER_INIT(hankin); |
| 42 | 43 | DECLARE_WRITE_LINE_MEMBER(ic10_ca2_w); |
| 43 | 44 | DECLARE_WRITE_LINE_MEMBER(ic10_cb2_w); |
| 44 | 45 | DECLARE_WRITE_LINE_MEMBER(ic11_ca2_w); |
| 45 | 46 | DECLARE_WRITE_LINE_MEMBER(ic11_cb2_w); |
| 47 | DECLARE_WRITE_LINE_MEMBER(ic2_ca2_w); |
| 48 | DECLARE_WRITE_LINE_MEMBER(ic2_cb2_w); |
| 46 | 49 | DECLARE_WRITE8_MEMBER(ic10_a_w); |
| 47 | 50 | DECLARE_WRITE8_MEMBER(ic10_b_w); |
| 48 | 51 | DECLARE_WRITE8_MEMBER(ic11_a_w); |
| 52 | DECLARE_WRITE8_MEMBER(ic2_b_w); |
| 53 | DECLARE_WRITE8_MEMBER(ic2_a_w); |
| 49 | 54 | DECLARE_READ8_MEMBER(ic11_b_r); |
| 55 | DECLARE_READ8_MEMBER(ic2_a_r); |
| 50 | 56 | DECLARE_INPUT_CHANGED_MEMBER(self_test); |
| 57 | TIMER_DEVICE_CALLBACK_MEMBER(timer_s); |
| 51 | 58 | TIMER_DEVICE_CALLBACK_MEMBER(timer_x); |
| 52 | 59 | private: |
| 53 | 60 | bool m_timer_x; |
| 61 | bool m_timer_sb; |
| 62 | UINT8 m_timer_s[3]; |
| 63 | UINT8 m_vol; |
| 64 | UINT8 m_ic2a; |
| 65 | UINT8 m_ic2b; |
| 54 | 66 | UINT8 m_ic10a; |
| 67 | UINT8 m_ic10b; |
| 55 | 68 | UINT8 m_ic11a; |
| 56 | 69 | bool m_ic11_ca2; |
| 57 | 70 | bool m_ic10_cb2; |
| 71 | bool m_ic2_ca2; |
| 72 | bool m_ic2_cb2; |
| 58 | 73 | UINT8 m_counter; |
| 59 | 74 | UINT8 m_digit; |
| 60 | 75 | UINT8 m_segment[5]; |
| 76 | UINT8 *m_p_prom; |
| 61 | 77 | virtual void machine_reset(); |
| 62 | 78 | required_device<m6802_cpu_device> m_maincpu; |
| 63 | 79 | required_device<m6802_cpu_device> m_audiocpu; |
| 64 | 80 | required_device<pia6821_device> m_ic10; |
| 65 | 81 | required_device<pia6821_device> m_ic11; |
| 66 | 82 | required_device<pia6821_device> m_ic2; |
| 83 | required_device<dac_device> m_dac; |
| 67 | 84 | required_ioport m_io_test; |
| 68 | 85 | required_ioport m_io_dsw0; |
| 69 | 86 | required_ioport m_io_dsw1; |
| r31687 | r31688 | |
| 117 | 134 | PORT_DIPSETTING( 0x20, "1") |
| 118 | 135 | PORT_DIPSETTING( 0x40, "2") |
| 119 | 136 | PORT_DIPSETTING( 0x60, "3") |
| 120 | | PORT_DIPNAME( 0x80, 0x00, "Game Over Tune") |
| 137 | PORT_DIPNAME( 0x80, 0x80, "Game Over Tune") |
| 121 | 138 | PORT_DIPSETTING( 0x00, DEF_STR( Off )) |
| 122 | 139 | PORT_DIPSETTING( 0x80, DEF_STR( On )) |
| 123 | 140 | |
| r31687 | r31688 | |
| 271 | 288 | |
| 272 | 289 | WRITE8_MEMBER( hankin_state::ic10_b_w ) |
| 273 | 290 | { |
| 291 | m_ic10b = data; |
| 292 | |
| 274 | 293 | if (!m_ic10_cb2) |
| 275 | 294 | { |
| 276 | 295 | switch (data & 15) |
| r31687 | r31688 | |
| 299 | 318 | { |
| 300 | 319 | output_set_value("led0", !state); |
| 301 | 320 | // also sound strobe |
| 321 | m_ic2->ca1_w(state); |
| 302 | 322 | } |
| 303 | 323 | |
| 304 | 324 | WRITE_LINE_MEMBER( hankin_state::ic10_cb2_w ) |
| r31687 | r31688 | |
| 382 | 402 | m_ic11->cb1_w(m_timer_x); |
| 383 | 403 | } |
| 384 | 404 | |
| 405 | // Sound |
| 406 | // 555 osc at 47kHz |
| 407 | // Then optional divide by 2 controlled by CA2 |
| 408 | // Then presettable 74LS161 binary divider controlled by PB0-3 |
| 409 | // Then a pair of 7493 to generate 5 address lines, enabled by CB2 |
| 410 | // The address lines are merged with PA4-7 to form a lookup on the prom |
| 411 | // Output of prom goes to a 4-bit DAC |
| 412 | // Volume is controlled by PB4-7 |
| 413 | // Variables: |
| 414 | // m_timer_s[0] inc each timer cycle, bit 0 = 47k, bit 1 = 23.5k |
| 415 | // m_timer_s[1] count in 74LS161 |
| 416 | // m_timer_s[2] count in 7493s |
| 417 | // m_timer_sb wanted output of m_timer_s[0] |
| 418 | TIMER_DEVICE_CALLBACK_MEMBER( hankin_state::timer_s ) |
| 419 | { |
| 420 | m_timer_s[0]++; |
| 421 | bool cs = (m_ic2_ca2) ? BIT(m_timer_s[0], 0) : BIT(m_timer_s[0], 1); // divide by 2 stage |
| 422 | if (cs != m_timer_sb) |
| 423 | { |
| 424 | m_timer_sb = cs; |
| 425 | m_timer_s[1]++; |
| 426 | if (m_timer_s[1] > 15) |
| 427 | { |
| 428 | m_timer_s[1] = m_ic2b & 15; // set to preset value |
| 429 | if (!m_ic2_cb2) |
| 430 | { |
| 431 | m_timer_s[2]++; |
| 432 | offs_t offs = (m_timer_s[2] & 31) | (m_ic2a << 5); |
| 433 | m_dac->write_unsigned8(m_p_prom[offs]<< m_vol); |
| 434 | } |
| 435 | else |
| 436 | m_timer_s[2] = 0; |
| 437 | } |
| 438 | } |
| 439 | } |
| 440 | |
| 385 | 441 | void hankin_state::machine_reset() |
| 386 | 442 | { |
| 443 | m_p_prom = memregion("roms")->base() + 0x1800; |
| 387 | 444 | } |
| 388 | 445 | |
| 446 | // PA0-3 = sound data from main cpu |
| 447 | READ8_MEMBER( hankin_state::ic2_a_r ) |
| 448 | { |
| 449 | return m_ic10b; |
| 450 | } |
| 451 | |
| 452 | // PA4-7 = sound data to prom |
| 453 | WRITE8_MEMBER( hankin_state::ic2_a_w ) |
| 454 | { |
| 455 | m_ic2a = data >> 4; |
| 456 | offs_t offs = (m_timer_s[2] & 31) | (m_ic2a << 5); |
| 457 | m_dac->write_unsigned8(m_p_prom[offs]<< m_vol); |
| 458 | } |
| 459 | |
| 460 | // PB0-3 = preset on 74LS161 |
| 461 | // PB4-7 = volume |
| 462 | WRITE8_MEMBER( hankin_state::ic2_b_w ) |
| 463 | { |
| 464 | m_ic2b = data; |
| 465 | m_vol = (m_ic2b & 0xf0) / 50; // 0 to 4 |
| 466 | } |
| 467 | |
| 468 | // low to divide 555 by 2 |
| 469 | WRITE_LINE_MEMBER( hankin_state::ic2_ca2_w ) |
| 470 | { |
| 471 | m_ic2_ca2 = state; |
| 472 | } |
| 473 | |
| 474 | // low to enable 7493 dividers |
| 475 | WRITE_LINE_MEMBER( hankin_state::ic2_cb2_w ) |
| 476 | { |
| 477 | m_ic2_cb2 = state; |
| 478 | } |
| 479 | |
| 389 | 480 | static MACHINE_CONFIG_START( hankin, hankin_state ) |
| 390 | 481 | /* basic machine hardware */ |
| 391 | 482 | MCFG_CPU_ADD("maincpu", M6802, 3276800) |
| r31687 | r31688 | |
| 402 | 493 | /* Sound */ |
| 403 | 494 | MCFG_FRAGMENT_ADD( genpin_audio ) |
| 404 | 495 | |
| 496 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 497 | MCFG_SOUND_ADD("dac", DAC, 0) |
| 498 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) |
| 499 | |
| 405 | 500 | /* Devices */ |
| 406 | 501 | MCFG_DEVICE_ADD("ic10", PIA6821, 0) |
| 407 | 502 | //MCFG_PIA_READPA_HANDLER(READ8(hankin_state, ic10_a_r)) |
| r31687 | r31688 | |
| 424 | 519 | MCFG_PIA_IRQB_HANDLER(DEVWRITELINE("maincpu", m6802_cpu_device, irq_line)) |
| 425 | 520 | |
| 426 | 521 | MCFG_DEVICE_ADD("ic2", PIA6821, 0) |
| 427 | | //MCFG_PIA_READPA_HANDLER(READ8(hankin_state, ic2_a_r)) |
| 428 | | //MCFG_PIA_WRITEPA_HANDLER(WRITE8(hankin_state, ic2_a_w)) |
| 522 | MCFG_PIA_READPA_HANDLER(READ8(hankin_state, ic2_a_r)) |
| 523 | MCFG_PIA_WRITEPA_HANDLER(WRITE8(hankin_state, ic2_a_w)) |
| 429 | 524 | //MCFG_PIA_READPB_HANDLER(READ8(hankin_state, ic2_b_r)) |
| 430 | | //MCFG_PIA_WRITEPB_HANDLER(WRITE8(hankin_state, ic2_b_w)) |
| 431 | | //MCFG_PIA_CA2_HANDLER(WRITELINE(hankin_state, ic2_ca2_w)) |
| 432 | | //MCFG_PIA_CB2_HANDLER(WRITELINE(hankin_state, ic2_cb2_w)) |
| 525 | MCFG_PIA_WRITEPB_HANDLER(WRITE8(hankin_state, ic2_b_w)) |
| 526 | MCFG_PIA_CA2_HANDLER(WRITELINE(hankin_state, ic2_ca2_w)) |
| 527 | MCFG_PIA_CB2_HANDLER(WRITELINE(hankin_state, ic2_cb2_w)) |
| 433 | 528 | MCFG_PIA_IRQA_HANDLER(DEVWRITELINE("audiocpu", m6802_cpu_device, irq_line)) |
| 434 | 529 | MCFG_PIA_IRQB_HANDLER(DEVWRITELINE("audiocpu", m6802_cpu_device, irq_line)) |
| 435 | 530 | |
| 436 | 531 | MCFG_TIMER_DRIVER_ADD_PERIODIC("timer_x", hankin_state, timer_x, attotime::from_hz(120)) // mains freq*2 |
| 532 | MCFG_TIMER_DRIVER_ADD_PERIODIC("timer_s", hankin_state, timer_s, attotime::from_hz(94000)) // 555 on sound board*2 |
| 437 | 533 | MACHINE_CONFIG_END |
| 438 | 534 | |
| 439 | 535 | /*-------------------------------- |
| r31687 | r31688 | |
| 492 | 588 | ROM_END |
| 493 | 589 | |
| 494 | 590 | |
| 495 | | GAME(1978, fjholden, 0, hankin, hankin, driver_device, 0, ROT0, "Hankin", "FJ Holden", GAME_MECHANICAL | GAME_NO_SOUND ) |
| 496 | | GAME(1978, orbit1, 0, hankin, hankin, driver_device, 0, ROT0, "Hankin", "Orbit 1", GAME_MECHANICAL | GAME_NO_SOUND ) |
| 497 | | GAME(1980, shark, 0, hankin, hankin, driver_device, 0, ROT0, "Hankin", "Shark", GAME_MECHANICAL | GAME_NO_SOUND ) |
| 498 | | GAME(1980, howzat, 0, hankin, hankin, driver_device, 0, ROT0, "Hankin", "Howzat!", GAME_MECHANICAL | GAME_NO_SOUND ) |
| 499 | | GAME(1981, empsback, 0, hankin, hankin, driver_device, 0, ROT0, "Hankin", "The Empire Strike Back", GAME_MECHANICAL | GAME_NO_SOUND ) |
| 591 | GAME(1978, fjholden, 0, hankin, hankin, driver_device, 0, ROT0, "Hankin", "FJ Holden", GAME_MECHANICAL ) |
| 592 | GAME(1978, orbit1, 0, hankin, hankin, driver_device, 0, ROT0, "Hankin", "Orbit 1", GAME_MECHANICAL ) |
| 593 | GAME(1980, shark, 0, hankin, hankin, driver_device, 0, ROT0, "Hankin", "Shark", GAME_MECHANICAL ) |
| 594 | GAME(1980, howzat, 0, hankin, hankin, driver_device, 0, ROT0, "Hankin", "Howzat!", GAME_MECHANICAL ) |
| 595 | GAME(1981, empsback, 0, hankin, hankin, driver_device, 0, ROT0, "Hankin", "The Empire Strike Back", GAME_MECHANICAL ) |