trunk/src/mame/drivers/maygayv1.c
| r29467 | r29468 | |
| 128 | 128 | #include "cpu/m68000/m68000.h" |
| 129 | 129 | #include "video/awpvid.h" |
| 130 | 130 | #include "cpu/mcs51/mcs51.h" |
| 131 | #include "machine/i8279.h" |
| 131 | 132 | #include "machine/6821pia.h" |
| 132 | 133 | #include "machine/mc68681.h" |
| 133 | 134 | #include "sound/2413intf.h" |
| r29467 | r29468 | |
| 202 | 203 | }; |
| 203 | 204 | |
| 204 | 205 | |
| 205 | | struct i8279_t |
| 206 | | { |
| 207 | | UINT8 command; |
| 208 | | UINT8 mode; |
| 209 | | UINT8 prescale; |
| 210 | | UINT8 inhibit; |
| 211 | | UINT8 clear; |
| 212 | | UINT8 fifo[8]; |
| 213 | | UINT8 ram[16]; |
| 214 | | }; |
| 215 | | |
| 216 | 206 | class maygayv1_state : public driver_device |
| 217 | 207 | { |
| 218 | 208 | public: |
| r29467 | r29468 | |
| 230 | 220 | required_device<mc68681_device> m_duart68681; |
| 231 | 221 | required_device<palette_device> m_palette; |
| 232 | 222 | |
| 223 | int m_lamp_strobe; |
| 224 | int m_old_lamp_strobe; |
| 233 | 225 | int m_vsync_latch_preset; |
| 234 | 226 | UINT8 m_p1; |
| 235 | 227 | UINT8 m_p3; |
| 236 | 228 | int m_d68681_val; |
| 237 | 229 | i82716_t m_i82716; |
| 238 | | i8279_t m_i8279; |
| 239 | 230 | DECLARE_WRITE16_MEMBER(i82716_w); |
| 240 | 231 | DECLARE_READ16_MEMBER(i82716_r); |
| 241 | 232 | DECLARE_WRITE16_MEMBER(write_odd); |
| 242 | 233 | DECLARE_READ16_MEMBER(read_odd); |
| 243 | | DECLARE_READ16_MEMBER(maygay_8279_r); |
| 244 | | DECLARE_WRITE16_MEMBER(maygay_8279_w); |
| 245 | 234 | DECLARE_WRITE16_MEMBER(vsync_int_ctrl); |
| 246 | 235 | DECLARE_READ8_MEMBER(mcu_r); |
| 247 | 236 | DECLARE_WRITE8_MEMBER(mcu_w); |
| 248 | 237 | DECLARE_READ8_MEMBER(b_read); |
| 249 | 238 | DECLARE_WRITE8_MEMBER(b_writ); |
| 239 | DECLARE_WRITE8_MEMBER(strobe_w); |
| 240 | DECLARE_WRITE8_MEMBER(lamp_data_w); |
| 241 | DECLARE_READ8_MEMBER(kbd_r); |
| 250 | 242 | DECLARE_DRIVER_INIT(screenpl); |
| 251 | 243 | virtual void machine_start(); |
| 252 | 244 | virtual void machine_reset(); |
| r29467 | r29468 | |
| 506 | 498 | return 0; |
| 507 | 499 | } |
| 508 | 500 | |
| 501 | /************************************* |
| 502 | * |
| 503 | * 8279 display/keyboard driver |
| 504 | * |
| 505 | *************************************/ |
| 509 | 506 | |
| 510 | | /* TODO */ |
| 511 | | static void update_outputs(i8279_t &i8279, UINT16 which) |
| 507 | WRITE8_MEMBER( maygayv1_state::strobe_w ) |
| 512 | 508 | { |
| 513 | | int i; |
| 514 | | |
| 515 | | /* update the items in the bitmask */ |
| 516 | | for (i = 0; i < 16; i++) |
| 517 | | if (which & (1 << i)) |
| 518 | | { |
| 519 | | /* |
| 520 | | int val; |
| 521 | | |
| 522 | | val = i8279.ram[i] & 0xff; |
| 523 | | |
| 524 | | val = i8279.ram[i] & 0x0f; |
| 525 | | if (i8279.inhibit & 0x01) |
| 526 | | val = i8279.clear & 0x0f; |
| 527 | | |
| 528 | | if(val) printf("%x\n", val); |
| 529 | | |
| 530 | | val = i8279.ram[i] >> 4; |
| 531 | | if (i8279.inhibit & 0x02) |
| 532 | | val = i8279.clear >> 4; |
| 533 | | |
| 534 | | if(val) printf("%x\n", val); |
| 535 | | */ |
| 536 | | } |
| 509 | m_lamp_strobe = data; |
| 537 | 510 | } |
| 538 | 511 | |
| 539 | | READ16_MEMBER(maygayv1_state::maygay_8279_r) |
| 512 | WRITE8_MEMBER( maygayv1_state::lamp_data_w ) |
| 540 | 513 | { |
| 541 | | i8279_t &i8279 = m_i8279; |
| 542 | | static const char *const portnames[] = { "STROBE1","STROBE2","STROBE3","STROBE4","STROBE5","STROBE6","STROBE7","STROBE8" }; |
| 543 | | UINT8 result = 0xff; |
| 544 | | UINT8 addr; |
| 545 | | |
| 546 | | /* read data */ |
| 547 | | if ((offset & 1) == 0) |
| 514 | //The two A/B ports are merged back into one, to make one row of 8 lamps. |
| 515 | |
| 516 | if (m_old_lamp_strobe != m_lamp_strobe) |
| 548 | 517 | { |
| 549 | | switch (i8279.command & 0xe0) |
| 550 | | { |
| 551 | | /* read sensor RAM */ |
| 552 | | case 0x40: |
| 553 | | addr = i8279.command & 0x07; |
| 518 | // Because of the nature of the lamping circuit, there is an element of persistance |
| 519 | // As a consequence, the lamp column data can change before the input strobe without |
| 520 | // causing the relevant lamps to black out. |
| 554 | 521 | |
| 555 | | result = ioport(portnames[addr])->read(); |
| 556 | | |
| 557 | | /* handle autoincrement */ |
| 558 | | if (i8279.command & 0x10) |
| 559 | | i8279.command = (i8279.command & 0xf0) | ((addr + 1) & 0x0f); |
| 560 | | |
| 561 | | break; |
| 562 | | |
| 563 | | /* read display RAM */ |
| 564 | | case 0x60: |
| 565 | | |
| 566 | | /* set the value of the corresponding outputs */ |
| 567 | | addr = i8279.command & 0x0f; |
| 568 | | result = i8279.ram[addr]; |
| 569 | | |
| 570 | | /* handle autoincrement */ |
| 571 | | if (i8279.command & 0x10) |
| 572 | | i8279.command = (i8279.command & 0xf0) | ((addr + 1) & 0x0f); |
| 573 | | break; |
| 522 | for (int i = 0; i < 8; i++) |
| 523 | { |
| 524 | output_set_lamp_value((8*m_lamp_strobe)+i, ((data & (1 << i)) !=0)); |
| 574 | 525 | } |
| 526 | m_old_lamp_strobe = m_lamp_strobe; |
| 575 | 527 | } |
| 576 | | /* read status word */ |
| 577 | | else |
| 578 | | { |
| 579 | | printf("read 0xfc%02x\n", offset); |
| 580 | | result = 0x10; |
| 581 | | } |
| 582 | | return result; |
| 528 | |
| 583 | 529 | } |
| 584 | 530 | |
| 585 | | |
| 586 | | WRITE16_MEMBER(maygayv1_state::maygay_8279_w) |
| 531 | READ8_MEMBER( maygayv1_state::kbd_r ) |
| 587 | 532 | { |
| 588 | | i8279_t &i8279 = m_i8279; |
| 589 | | UINT8 addr; |
| 533 | static const char *const portnames[] = { "STROBE1","STROBE2","STROBE3","STROBE4","STROBE5","STROBE6","STROBE7","STROBE8" }; |
| 590 | 534 | |
| 591 | | data >>= 8; |
| 592 | | |
| 593 | | /* write data */ |
| 594 | | if ((offset & 1) == 0) |
| 595 | | { |
| 596 | | switch (i8279.command & 0xe0) |
| 597 | | { |
| 598 | | /* write display RAM */ |
| 599 | | case 0x80: |
| 600 | | |
| 601 | | /* set the value of the corresponding outputs */ |
| 602 | | addr = i8279.command & 0x0f; |
| 603 | | if (!(i8279.inhibit & 0x04)) |
| 604 | | i8279.ram[addr] = (i8279.ram[addr] & 0xf0) | (data & 0x0f); |
| 605 | | if (!(i8279.inhibit & 0x08)) |
| 606 | | i8279.ram[addr] = (i8279.ram[addr] & 0x0f) | (data & 0xf0); |
| 607 | | update_outputs(i8279, 1 << addr); |
| 608 | | |
| 609 | | /* handle autoincrement */ |
| 610 | | if (i8279.command & 0x10) |
| 611 | | i8279.command = (i8279.command & 0xf0) | ((addr + 1) & 0x0f); |
| 612 | | break; |
| 613 | | } |
| 614 | | } |
| 615 | | |
| 616 | | /* write command */ |
| 617 | | else |
| 618 | | { |
| 619 | | i8279.command = data; |
| 620 | | |
| 621 | | switch (data & 0xe0) |
| 622 | | { |
| 623 | | /* command 0: set mode */ |
| 624 | | /* |
| 625 | | Display modes: |
| 626 | | |
| 627 | | 00 = 8 x 8-bit character display -- left entry |
| 628 | | 01 = 16 x 8-bit character display -- left entry |
| 629 | | 10 = 8 x 8-bit character display -- right entry |
| 630 | | 11 = 16 x 8-bit character display -- right entry |
| 631 | | |
| 632 | | Keyboard modes: |
| 633 | | |
| 634 | | 000 = Encoded scan keyboard -- 2 key lockout |
| 635 | | 001 = Decoded scan keyboard -- 2 key lockout |
| 636 | | 010 = Encoded scan keyboard -- N-key rollover |
| 637 | | 011 = Decoded scan keyboard -- N-key rollover |
| 638 | | 100 = Encoded scan sensor matrix |
| 639 | | 101 = Decoded scan sensor matrix |
| 640 | | 110 = Strobed input, encoded display scan |
| 641 | | 111 = Strobed input, decoded display scan |
| 642 | | */ |
| 643 | | case 0x00: |
| 644 | | logerror("8279: display mode = %d, keyboard mode = %d\n", (data >> 3) & 3, data & 7); |
| 645 | | i8279.mode = data & 0x1f; |
| 646 | | break; |
| 647 | | |
| 648 | | /* command 1: program clock */ |
| 649 | | case 0x20: |
| 650 | | logerror("8279: clock prescaler set to %02X\n", data & 0x1f); |
| 651 | | i8279.prescale = data & 0x1f; |
| 652 | | break; |
| 653 | | |
| 654 | | /* command 2: read FIFO/sensor RAM */ |
| 655 | | /* command 3: read display RAM */ |
| 656 | | /* command 4: write display RAM */ |
| 657 | | case 0x40: |
| 658 | | case 0x60: |
| 659 | | case 0x80: |
| 660 | | break; |
| 661 | | |
| 662 | | /* command 5: display write inhibit/blanking */ |
| 663 | | case 0xa0: |
| 664 | | i8279.inhibit = data & 0x0f; |
| 665 | | update_outputs(i8279, ~0); |
| 666 | | logerror("8279: clock prescaler set to %02X\n", data & 0x1f); |
| 667 | | break; |
| 668 | | |
| 669 | | /* command 6: clear */ |
| 670 | | case 0xc0: |
| 671 | | i8279.clear = (data & 0x08) ? ((data & 0x04) ? 0xff : 0x20) : 0x00; |
| 672 | | if (data & 0x11) |
| 673 | | memset(i8279.ram, i8279.clear, sizeof(i8279.ram)); |
| 674 | | break; |
| 675 | | |
| 676 | | /* command 7: end interrupt/error mode set */ |
| 677 | | case 0xe0: |
| 678 | | break; |
| 679 | | } |
| 680 | | } |
| 535 | return ioport(portnames[m_lamp_strobe&0x07])->read(); |
| 681 | 536 | } |
| 682 | 537 | |
| 538 | static I8279_INTERFACE( v1_i8279_intf ) |
| 539 | { |
| 540 | DEVCB_NULL, // irq |
| 541 | DEVCB_DRIVER_MEMBER(maygayv1_state, strobe_w), // scan SL lines |
| 542 | DEVCB_DRIVER_MEMBER(maygayv1_state, lamp_data_w), // display A&B |
| 543 | DEVCB_NULL, // BD |
| 544 | DEVCB_DRIVER_MEMBER(maygayv1_state,kbd_r), // kbd RL lines |
| 545 | DEVCB_NULL, // Shift key |
| 546 | DEVCB_NULL // Ctrl-Strobe line |
| 547 | }; |
| 683 | 548 | |
| 549 | |
| 684 | 550 | WRITE16_MEMBER(maygayv1_state::vsync_int_ctrl) |
| 685 | 551 | { |
| 686 | 552 | m_vsync_latch_preset = data & 0x0100; |
| r29467 | r29468 | |
| 694 | 560 | AM_RANGE(0x000000, 0x07ffff) AM_ROM |
| 695 | 561 | AM_RANGE(0x080000, 0x083fff) AM_RAM AM_SHARE("nvram") |
| 696 | 562 | AM_RANGE(0x100000, 0x17ffff) AM_ROM AM_REGION("maincpu", 0x80000) |
| 697 | | AM_RANGE(0x820000, 0x820003) AM_READWRITE(maygay_8279_r, maygay_8279_w) |
| 563 | AM_RANGE(0x820000, 0x820001) AM_DEVREADWRITE8("i8279", i8279_device, data_r, data_w ,0xff) |
| 564 | AM_RANGE(0x820002, 0x820003) AM_DEVREADWRITE8("i8279", i8279_device, status_r, cmd_w,0xff) |
| 698 | 565 | AM_RANGE(0x800000, 0x800003) AM_DEVWRITE8("ymsnd", ym2413_device, write, 0xff00) |
| 699 | 566 | AM_RANGE(0x860000, 0x86000d) AM_READWRITE(read_odd, write_odd) |
| 700 | 567 | AM_RANGE(0x86000e, 0x86000f) AM_WRITE(vsync_int_ctrl) |
| r29467 | r29468 | |
| 1041 | 908 | MCFG_MC68681_IRQ_CALLBACK(WRITELINE(maygayv1_state, duart_irq_handler)) |
| 1042 | 909 | MCFG_MC68681_A_TX_CALLBACK(WRITELINE(maygayv1_state, duart_txa)) |
| 1043 | 910 | |
| 911 | MCFG_I8279_ADD("i8279", MASTER_CLOCK/4, v1_i8279_intf) // unknown clock |
| 912 | |
| 1044 | 913 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 1045 | 914 | |
| 1046 | 915 | MCFG_SOUND_ADD("ymsnd",YM2413, MASTER_CLOCK / 4) |
trunk/src/mame/drivers/maygay1b.c
| r29467 | r29468 | |
| 68 | 68 | 3x trimmer |
| 69 | 69 | |
| 70 | 70 | |
| 71 | | TODO: Convert to stock i8279 implementation, as currently inputs aren't read. |
| 72 | | Fix meter reading (possibly related to above) |
| 71 | TODO: I/O is generally a nightmare, probably needs a rebuild at the address level. |
| 72 | Inputs need a sort out. |
| 73 | Some games require dongles for security, need to figure this out. |
| 73 | 74 | ******************************************************************************************/ |
| 74 | 75 | #include "emu.h" |
| 75 | 76 | #include "includes/maygay1b.h" |
| 76 | 77 | |
| 77 | 78 | #include "maygay1b.lh" |
| 78 | 79 | |
| 79 | | |
| 80 | | void maygay1b_state::m1_draw_lamps(int data,int strobe, int col) |
| 81 | | { |
| 82 | | int i; |
| 83 | | |
| 84 | | for ( i = 0; i < 8; i++ ) |
| 85 | | { |
| 86 | | m_lamppos = (strobe*8) + col + i; |
| 87 | | |
| 88 | | if ((data>>i)&1) |
| 89 | | m_Lamps[m_lamppos] = 1; |
| 90 | | else |
| 91 | | m_Lamps[m_lamppos] = 0; |
| 92 | | |
| 93 | | output_set_lamp_value(m_lamppos, m_Lamps[m_lamppos]); |
| 94 | | } |
| 95 | | } |
| 96 | | |
| 97 | | |
| 98 | | /************************************* |
| 99 | | * |
| 100 | | * 8279 display/keyboard driver |
| 101 | | * |
| 102 | | *************************************/ |
| 103 | | |
| 104 | | void maygay1b_state::update_outputs(i8279_state *chip, UINT16 which) |
| 105 | | { |
| 106 | | static const UINT8 ls48_map[16] = |
| 107 | | { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7c,0x07,0x7f,0x67,0x58,0x4c,0x62,0x69,0x78,0x00 }; |
| 108 | | int i; |
| 109 | | |
| 110 | | /* update the items in the bitmask */ |
| 111 | | for (i = 0; i < 16; i++) |
| 112 | | if (which & (1 << i)) |
| 113 | | { |
| 114 | | int val; |
| 115 | | |
| 116 | | val = chip->ram[i] & 0x0f; |
| 117 | | if (chip->inhibit & 0x01) |
| 118 | | val = chip->clear & 0x0f; |
| 119 | | output_set_digit_value(i * 2 + 0, ls48_map[val]); |
| 120 | | |
| 121 | | val = chip->ram[i] >> 4; |
| 122 | | if (chip->inhibit & 0x02) |
| 123 | | val = chip->clear >> 4; |
| 124 | | output_set_digit_value(i * 2 + 1, ls48_map[val]); |
| 125 | | } |
| 126 | | } |
| 127 | | |
| 128 | | READ8_MEMBER(maygay1b_state::m1_8279_r) |
| 129 | | { |
| 130 | | i8279_state *chip = m_i8279 + 0; |
| 131 | | static const char *const portnames[] = { "SW1","STROBE5","STROBE7","STROBE3","SW2","STROBE4","STROBE6","STROBE2" }; |
| 132 | | UINT8 result = 0xff; |
| 133 | | UINT8 addr; |
| 134 | | |
| 135 | | /* read data */ |
| 136 | | if ((offset & 1) == 0) |
| 137 | | { |
| 138 | | switch (chip->command & 0xe0) |
| 139 | | { |
| 140 | | /* read sensor RAM */ |
| 141 | | case 0x40: |
| 142 | | addr = chip->command & 0x07; |
| 143 | | result = ioport("SW1")->read(); |
| 144 | | /* handle autoincrement */ |
| 145 | | if (chip->command & 0x10) |
| 146 | | chip->command = (chip->command & 0xf0) | ((addr + 1) & 0x0f); |
| 147 | | |
| 148 | | break; |
| 149 | | |
| 150 | | |
| 151 | | /* read display RAM */ |
| 152 | | case 0x60: |
| 153 | | |
| 154 | | /* set the value of the corresponding outputs */ |
| 155 | | addr = chip->command & 0x0f; |
| 156 | | result = chip->ram[addr]; |
| 157 | | |
| 158 | | /* handle autoincrement */ |
| 159 | | if (chip->command & 0x10) |
| 160 | | chip->command = (chip->command & 0xf0) | ((addr + 1) & 0x0f); |
| 161 | | break; |
| 162 | | } |
| 163 | | } |
| 164 | | |
| 165 | | /* read status word */ |
| 166 | | else |
| 167 | | { |
| 168 | | if ( chip->read_sensor ) |
| 169 | | { |
| 170 | | result = ioport(portnames[chip->sense_address])->read(); |
| 171 | | // break |
| 172 | | } |
| 173 | | if ( chip->sense_auto_inc ) |
| 174 | | { |
| 175 | | chip->sense_address = (chip->sense_address + 1 ) & 7; |
| 176 | | } |
| 177 | | else |
| 178 | | { |
| 179 | | result = chip->ram[chip->disp_address]; |
| 180 | | if ( chip->disp_auto_inc ) |
| 181 | | chip->disp_address++; |
| 182 | | } |
| 183 | | } |
| 184 | | return result; |
| 185 | | } |
| 186 | | |
| 187 | | WRITE8_MEMBER(maygay1b_state::m1_8279_w) |
| 188 | | { |
| 189 | | i8279_state *chip = m_i8279 + 0; |
| 190 | | UINT8 addr; |
| 191 | | |
| 192 | | /* write data */ |
| 193 | | if ((offset & 1) == 0) |
| 194 | | { |
| 195 | | switch (chip->command & 0xe0) |
| 196 | | { |
| 197 | | /* write display RAM */ |
| 198 | | case 0x80: |
| 199 | | |
| 200 | | /* set the value of the corresponding outputs */ |
| 201 | | addr = chip->command & 0x0f; |
| 202 | | if (!(chip->inhibit & 0x04)) |
| 203 | | chip->ram[addr] = (chip->ram[addr] & 0xf0) | (data & 0x0f); |
| 204 | | if (!(chip->inhibit & 0x08)) |
| 205 | | chip->ram[addr] = (chip->ram[addr] & 0x0f) | (data & 0xf0); |
| 206 | | update_outputs(chip, 1 << addr); |
| 207 | | |
| 208 | | /* handle autoincrement */ |
| 209 | | if (chip->command & 0x10) |
| 210 | | chip->command = (chip->command & 0xf0) | ((addr + 1) & 0x0f); |
| 211 | | break; |
| 212 | | } |
| 213 | | } |
| 214 | | |
| 215 | | /* write command */ |
| 216 | | else |
| 217 | | { |
| 218 | | chip->command = data; |
| 219 | | |
| 220 | | switch (data & 0xe0) |
| 221 | | { |
| 222 | | /* command 0: set mode */ |
| 223 | | /* |
| 224 | | Display modes: |
| 225 | | |
| 226 | | 00 = 8 x 8-bit character display -- left entry |
| 227 | | 01 = 16 x 8-bit character display -- left entry |
| 228 | | 10 = 8 x 8-bit character display -- right entry |
| 229 | | 11 = 16 x 8-bit character display -- right entry |
| 230 | | |
| 231 | | Keyboard modes: |
| 232 | | |
| 233 | | 000 = Encoded scan keyboard -- 2 key lockout |
| 234 | | 001 = Decoded scan keyboard -- 2 key lockout |
| 235 | | 010 = Encoded scan keyboard -- N-key rollover |
| 236 | | 011 = Decoded scan keyboard -- N-key rollover |
| 237 | | 100 = Encoded scan sensor matrix |
| 238 | | 101 = Decoded scan sensor matrix |
| 239 | | 110 = Strobed input, encoded display scan |
| 240 | | 111 = Strobed input, decoded display scan |
| 241 | | */ |
| 242 | | case 0x00: |
| 243 | | logerror("8279A: display mode = %d, keyboard mode = %d\n", (data >> 3) & 3, data & 7); |
| 244 | | chip->mode = data & 0x1f; |
| 245 | | break; |
| 246 | | |
| 247 | | /* command 1: program clock */ |
| 248 | | case 0x20: |
| 249 | | logerror("8279A: clock prescaler set to %02X\n", data & 0x1f); |
| 250 | | chip->prescale = data & 0x1f; |
| 251 | | break; |
| 252 | | |
| 253 | | /* command 2: read FIFO/sensor RAM */ |
| 254 | | case 0x40: |
| 255 | | chip->sense_address = data & 0x07; |
| 256 | | chip->sense_auto_inc = data & 0x10; |
| 257 | | chip->read_sensor = 1; |
| 258 | | break; |
| 259 | | /* command 3: read display RAM */ |
| 260 | | case 0x60: |
| 261 | | chip->disp_address = data & 0x0f; |
| 262 | | chip->disp_auto_inc = data & 0x10; |
| 263 | | chip->read_sensor = 0; |
| 264 | | break; |
| 265 | | /* command 4: write display RAM */ |
| 266 | | case 0x80: |
| 267 | | chip->disp_address = data & 0x0f; |
| 268 | | chip->disp_auto_inc = data & 0x10; |
| 269 | | chip->write_display = 1; |
| 270 | | break; |
| 271 | | |
| 272 | | /* command 5: display write inhibit/blanking */ |
| 273 | | case 0xa0: |
| 274 | | chip->inhibit = data & 0x0f; |
| 275 | | update_outputs(chip, 0); |
| 276 | | logerror("8279: clock prescaler set to %02X\n", data & 0x1f); |
| 277 | | break; |
| 278 | | |
| 279 | | break; |
| 280 | | |
| 281 | | /* command 6: clear */ |
| 282 | | case 0xc0: |
| 283 | | chip->clear = (data & 0x08) ? ((data & 0x04) ? 0xff : 0x20) : 0x00; |
| 284 | | if (data & 0x11) |
| 285 | | memset(chip->ram, chip->clear, sizeof(chip->ram)); |
| 286 | | break; |
| 287 | | |
| 288 | | /* command 7: end interrupt/error mode set */ |
| 289 | | case 0xe0: |
| 290 | | break; |
| 291 | | } |
| 292 | | } |
| 293 | | if ( chip->write_display ) |
| 294 | | { // Data |
| 295 | | assert(chip->disp_address < ARRAY_LENGTH(chip->ram)); |
| 296 | | if ( chip->ram[chip->disp_address] != data ) |
| 297 | | { |
| 298 | | m1_draw_lamps(chip->ram[chip->disp_address],chip->disp_address, 0); |
| 299 | | } |
| 300 | | chip->ram[chip->disp_address] = data; |
| 301 | | |
| 302 | | if ( chip->disp_auto_inc ) |
| 303 | | chip->disp_address ++; |
| 304 | | } |
| 305 | | } |
| 306 | | |
| 307 | | READ8_MEMBER(maygay1b_state::m1_8279_2_r) |
| 308 | | { |
| 309 | | i8279_state *chip = m_i8279 + 1; |
| 310 | | UINT8 result = 0xff; |
| 311 | | UINT8 addr; |
| 312 | | |
| 313 | | /* read data */ |
| 314 | | if ((offset & 1) == 0) |
| 315 | | { |
| 316 | | switch (chip->command & 0xe0) |
| 317 | | { |
| 318 | | /* read sensor RAM */ |
| 319 | | case 0x40: |
| 320 | | //result = ~ioport("DSW1")->read(); /* DSW 1 - inverted! */ |
| 321 | | break; |
| 322 | | |
| 323 | | /* read display RAM */ |
| 324 | | case 0x60: |
| 325 | | |
| 326 | | /* set the value of the corresponding outputs */ |
| 327 | | addr = chip->command & 0x0f; |
| 328 | | result = chip->ram[addr]; |
| 329 | | |
| 330 | | /* handle autoincrement */ |
| 331 | | if (chip->command & 0x10) |
| 332 | | chip->command = (chip->command & 0xf0) | ((addr + 1) & 0x0f); |
| 333 | | break; |
| 334 | | } |
| 335 | | } |
| 336 | | |
| 337 | | /* read status word */ |
| 338 | | else |
| 339 | | { |
| 340 | | logerror("read 0xfc%02x\n", offset); |
| 341 | | result = 0x10; |
| 342 | | } |
| 343 | | return result; |
| 344 | | } |
| 345 | | |
| 346 | | |
| 347 | | WRITE8_MEMBER(maygay1b_state::m1_8279_2_w) |
| 348 | | { |
| 349 | | i8279_state *chip = m_i8279 + 1; |
| 350 | | UINT8 addr; |
| 351 | | |
| 352 | | /* write data */ |
| 353 | | if ((offset & 1) == 0) |
| 354 | | { |
| 355 | | switch (chip->command & 0xe0) |
| 356 | | { |
| 357 | | /* write display RAM */ |
| 358 | | case 0x80: |
| 359 | | |
| 360 | | /* set the value of the corresponding outputs */ |
| 361 | | addr = chip->command & 0x0f; |
| 362 | | if (!(chip->inhibit & 0x04)) |
| 363 | | chip->ram[addr] = (chip->ram[addr] & 0xf0) | (data & 0x0f); |
| 364 | | if (!(chip->inhibit & 0x08)) |
| 365 | | chip->ram[addr] = (chip->ram[addr] & 0x0f) | (data & 0xf0); |
| 366 | | update_outputs(chip, 1 << addr); |
| 367 | | |
| 368 | | /* handle autoincrement */ |
| 369 | | if (chip->command & 0x10) |
| 370 | | chip->command = (chip->command & 0xf0) | ((addr + 1) & 0x0f); |
| 371 | | break; |
| 372 | | } |
| 373 | | } |
| 374 | | |
| 375 | | /* write command */ |
| 376 | | else |
| 377 | | { |
| 378 | | chip->command = data; |
| 379 | | |
| 380 | | switch (data & 0xe0) |
| 381 | | { |
| 382 | | /* command 0: set mode */ |
| 383 | | /* |
| 384 | | Display modes: |
| 385 | | |
| 386 | | 00 = 8 x 8-bit character display -- left entry |
| 387 | | 01 = 16 x 8-bit character display -- left entry |
| 388 | | 10 = 8 x 8-bit character display -- right entry |
| 389 | | 11 = 16 x 8-bit character display -- right entry |
| 390 | | |
| 391 | | Keyboard modes: |
| 392 | | |
| 393 | | 000 = Encoded scan keyboard -- 2 key lockout |
| 394 | | 001 = Decoded scan keyboard -- 2 key lockout |
| 395 | | 010 = Encoded scan keyboard -- N-key rollover |
| 396 | | 011 = Decoded scan keyboard -- N-key rollover |
| 397 | | 100 = Encoded scan sensor matrix |
| 398 | | 101 = Decoded scan sensor matrix |
| 399 | | 110 = Strobed input, encoded display scan |
| 400 | | 111 = Strobed input, decoded display scan |
| 401 | | */ |
| 402 | | case 0x00: |
| 403 | | logerror("8279A: display mode = %d, keyboard mode = %d\n", (data >> 3) & 3, data & 7); |
| 404 | | chip->mode = data & 0x1f; |
| 405 | | break; |
| 406 | | |
| 407 | | /* command 1: program clock */ |
| 408 | | case 0x20: |
| 409 | | logerror("8279A: clock prescaler set to %02X\n", data & 0x1f); |
| 410 | | chip->prescale = data & 0x1f; |
| 411 | | break; |
| 412 | | |
| 413 | | /* command 2: read FIFO/sensor RAM */ |
| 414 | | case 0x40: |
| 415 | | chip->sense_address = data & 0x07; |
| 416 | | chip->sense_auto_inc = data & 0x10; |
| 417 | | chip->read_sensor = 1; |
| 418 | | break; |
| 419 | | /* command 3: read display RAM */ |
| 420 | | case 0x60: |
| 421 | | chip->disp_address = data & 0x0f; |
| 422 | | chip->disp_auto_inc = data & 0x10; |
| 423 | | chip->read_sensor = 0; |
| 424 | | break; |
| 425 | | /* command 4: write display RAM */ |
| 426 | | case 0x80: |
| 427 | | chip->disp_address = data & 0x0f; |
| 428 | | chip->disp_auto_inc = data & 0x10; |
| 429 | | chip->write_display = 1; |
| 430 | | break; |
| 431 | | |
| 432 | | /* command 5: display write inhibit/blanking */ |
| 433 | | case 0xa0: |
| 434 | | break; |
| 435 | | |
| 436 | | /* command 6: clear */ |
| 437 | | case 0xc0: |
| 438 | | break; |
| 439 | | |
| 440 | | /* command 7: end interrupt/error mode set */ |
| 441 | | case 0xe0: |
| 442 | | break; |
| 443 | | } |
| 444 | | } |
| 445 | | if ( chip->write_display ) |
| 446 | | { // Data |
| 447 | | if ( chip->ram[chip->disp_address] != data ) |
| 448 | | { |
| 449 | | m1_draw_lamps(chip->ram[chip->disp_address],chip->disp_address, 128); |
| 450 | | } |
| 451 | | chip->ram[chip->disp_address] = data; |
| 452 | | if ( chip->disp_auto_inc ) |
| 453 | | chip->disp_address ++; |
| 454 | | } |
| 455 | | |
| 456 | | } |
| 457 | | |
| 458 | 80 | /////////////////////////////////////////////////////////////////////////// |
| 459 | 81 | // called if board is reset /////////////////////////////////////////////// |
| 460 | 82 | /////////////////////////////////////////////////////////////////////////// |
| r29467 | r29468 | |
| 495 | 117 | return i; |
| 496 | 118 | } |
| 497 | 119 | |
| 120 | READ8_MEMBER( maygay1b_state::m1_firq_clr_r ) |
| 121 | { |
| 122 | static int i = 0xff; |
| 123 | i ^= 0xff; |
| 124 | m_maincpu->set_input_line(M6809_FIRQ_LINE, CLEAR_LINE); |
| 125 | LOG(("6809 firq clr\n")); |
| 126 | return i; |
| 127 | } |
| 128 | |
| 498 | 129 | // NMI is periodic? or triggered by a write? |
| 499 | 130 | TIMER_DEVICE_CALLBACK_MEMBER( maygay1b_state::maygay1b_nmitimer_callback ) |
| 500 | 131 | { |
| r29467 | r29468 | |
| 784 | 415 | |
| 785 | 416 | READ8_MEMBER(maygay1b_state::m1_meter_r) |
| 786 | 417 | { |
| 787 | | //ay8910_device *ay8910 = machine().device<ay8910_device>("aysnd"); |
| 788 | | //return ay8910->data_r(space, offset); |
| 789 | | |
| 790 | | //TODO: Game should read the meter state through Port A of the AY chip, but our timings aren't good enough (?) |
| 418 | //TODO: Can we just return the AY port A data? |
| 791 | 419 | return m_meter; |
| 792 | 420 | } |
| 421 | WRITE8_MEMBER(maygay1b_state::m1_lockout_w) |
| 422 | { |
| 423 | int i; |
| 424 | for (i=0; i<6; i++) |
| 425 | { |
| 426 | coin_lockout_w(machine(), i, data & (1 << i) ); |
| 427 | } |
| 428 | } |
| 793 | 429 | |
| 794 | 430 | static ADDRESS_MAP_START( m1_memmap, AS_PROGRAM, 8, maygay1b_state ) |
| 795 | 431 | AM_RANGE(0x0000, 0x1fff) AM_RAM AM_SHARE("nvram") |
| r29467 | r29468 | |
| 798 | 434 | AM_RANGE(0x2010, 0x2010) AM_WRITE(reel34_w) |
| 799 | 435 | AM_RANGE(0x2020, 0x2020) AM_WRITE(reel56_w) |
| 800 | 436 | |
| 801 | | // there is actually an 8279 and an 8051.. |
| 802 | | AM_RANGE(0x2030, 0x2031) AM_READWRITE(m1_8279_r,m1_8279_w) |
| 803 | | AM_RANGE(0x2040, 0x2041) AM_READWRITE(m1_8279_2_r,m1_8279_2_w) |
| 437 | // there is actually an 8279 and an 8051 (which I guess is the MCU?). |
| 438 | AM_RANGE(0x2030, 0x2030) AM_DEVREADWRITE("i8279", i8279_device, data_r, data_w ) |
| 439 | AM_RANGE(0x2031, 0x2031) AM_DEVREADWRITE("i8279", i8279_device, status_r, cmd_w) |
| 440 | |
| 441 | //8051 |
| 442 | AM_RANGE(0x2040, 0x2040) AM_DEVREADWRITE("i8279_2", i8279_device, data_r, data_w ) |
| 443 | AM_RANGE(0x2041, 0x2041) AM_DEVREADWRITE("i8279_2", i8279_device, status_r, cmd_w) |
| 804 | 444 | // AM_RANGE(0x2050, 0x2050)// SCAN on M1B |
| 805 | 445 | |
| 806 | 446 | AM_RANGE(0x2070, 0x207f) AM_DEVREADWRITE("duart68681", mc68681_device, read, write ) |
| r29467 | r29468 | |
| 817 | 457 | AM_RANGE(0x2404, 0x2405) AM_READ(latch_st_lo) |
| 818 | 458 | AM_RANGE(0x2406, 0x2407) AM_READ(latch_st_hi) |
| 819 | 459 | |
| 460 | AM_RANGE(0x2410, 0x2410) AM_READ(m1_firq_clr_r) |
| 461 | |
| 820 | 462 | AM_RANGE(0x2412, 0x2412) AM_READ(m1_firq_trg_r) // firq, sample playback? |
| 821 | 463 | |
| 822 | 464 | AM_RANGE(0x2420, 0x2421) AM_WRITE(latch_ch2_w ) // oki |
| r29467 | r29468 | |
| 831 | 473 | DEVCB_NULL, |
| 832 | 474 | DEVCB_NULL, |
| 833 | 475 | DEVCB_DRIVER_MEMBER(maygay1b_state,m1_meter_w), |
| 834 | | DEVCB_NULL, |
| 476 | DEVCB_DRIVER_MEMBER(maygay1b_state,m1_lockout_w), |
| 835 | 477 | }; |
| 836 | 478 | |
| 479 | /************************************* |
| 480 | * |
| 481 | * 8279 display/keyboard driver |
| 482 | * |
| 483 | *************************************/ |
| 484 | |
| 485 | WRITE8_MEMBER( maygay1b_state::scanlines_w ) |
| 486 | { |
| 487 | m_lamp_strobe = data; |
| 488 | } |
| 489 | |
| 490 | WRITE8_MEMBER( maygay1b_state::lamp_data_w ) |
| 491 | { |
| 492 | //The two A/B ports are merged back into one, to make one row of 8 lamps. |
| 493 | |
| 494 | if (m_old_lamp_strobe != m_lamp_strobe) |
| 495 | { |
| 496 | // Because of the nature of the lamping circuit, there is an element of persistance |
| 497 | // As a consequence, the lamp column data can change before the input strobe without |
| 498 | // causing the relevant lamps to black out. |
| 499 | |
| 500 | for (int i = 0; i < 8; i++) |
| 501 | { |
| 502 | output_set_lamp_value((8*m_lamp_strobe)+i, ((data & (1 << i)) !=0)); |
| 503 | } |
| 504 | m_old_lamp_strobe = m_lamp_strobe; |
| 505 | } |
| 506 | |
| 507 | } |
| 508 | |
| 509 | READ8_MEMBER( maygay1b_state::kbd_r ) |
| 510 | { |
| 511 | ioport_port * portnames[] = { m_sw1_port, m_s2_port, m_s3_port, m_s4_port, m_s5_port, m_s6_port, m_s7_port, m_sw2_port}; |
| 512 | return (portnames[m_lamp_strobe&0x07])->read(); |
| 513 | } |
| 514 | |
| 515 | static I8279_INTERFACE( m1_i8279_intf ) |
| 516 | { |
| 517 | DEVCB_NULL, // irq |
| 518 | DEVCB_DRIVER_MEMBER(maygay1b_state, scanlines_w), // scan SL lines |
| 519 | DEVCB_DRIVER_MEMBER(maygay1b_state, lamp_data_w), // display A&B |
| 520 | DEVCB_NULL, // BD |
| 521 | DEVCB_DRIVER_MEMBER(maygay1b_state,kbd_r), // kbd RL lines |
| 522 | DEVCB_NULL, // Shift key |
| 523 | DEVCB_NULL // Ctrl-Strobe line |
| 524 | }; |
| 525 | |
| 526 | |
| 527 | |
| 528 | |
| 529 | WRITE8_MEMBER( maygay1b_state::lamp_data_2_w ) |
| 530 | { |
| 531 | //The two A/B ports are merged back into one, to make one row of 8 lamps. |
| 532 | |
| 533 | if (m_old_lamp_strobe2 != m_lamp_strobe2) |
| 534 | { |
| 535 | // Because of the nature of the lamping circuit, there is an element of persistance |
| 536 | // As a consequence, the lamp column data can change before the input strobe without |
| 537 | // causing the relevant lamps to black out. |
| 538 | |
| 539 | for (int i = 0; i < 8; i++) |
| 540 | { |
| 541 | output_set_lamp_value((8*m_lamp_strobe)+i+128, ((data & (1 << i)) !=0)); |
| 542 | } |
| 543 | m_old_lamp_strobe2 = m_lamp_strobe2; |
| 544 | } |
| 545 | |
| 546 | } |
| 547 | |
| 548 | static I8279_INTERFACE( m1_i8279_2_intf ) |
| 549 | { |
| 550 | DEVCB_NULL, // irq |
| 551 | DEVCB_NULL, // scan SL lines |
| 552 | DEVCB_DRIVER_MEMBER(maygay1b_state, lamp_data_2_w), // display A&B |
| 553 | DEVCB_NULL, // BD |
| 554 | DEVCB_NULL, // kbd RL lines |
| 555 | DEVCB_NULL, // Shift key |
| 556 | DEVCB_NULL // Ctrl-Strobe line |
| 557 | }; |
| 558 | |
| 837 | 559 | // machine driver for maygay m1 board ///////////////////////////////// |
| 838 | 560 | |
| 839 | 561 | |
| r29467 | r29468 | |
| 851 | 573 | MCFG_PIA_WRITEPA_HANDLER(WRITE8(maygay1b_state, m1_pia_porta_w)) |
| 852 | 574 | MCFG_PIA_WRITEPB_HANDLER(WRITE8(maygay1b_state, m1_pia_portb_w)) |
| 853 | 575 | |
| 854 | | MCFG_MSC1937_ADD("vfd",0,RIGHT_TO_LEFT) |
| 576 | MCFG_S16LF01_ADD("vfd",0) |
| 855 | 577 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 856 | 578 | MCFG_SOUND_ADD("aysnd",YM2149, M1_MASTER_CLOCK) |
| 857 | 579 | MCFG_SOUND_CONFIG(ay8910_config) |
| r29467 | r29468 | |
| 863 | 585 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) |
| 864 | 586 | |
| 865 | 587 | MCFG_TIMER_DRIVER_ADD_PERIODIC("nmitimer", maygay1b_state, maygay1b_nmitimer_callback, attotime::from_hz(75)) // freq? |
| 588 | MCFG_I8279_ADD("i8279", M1_MASTER_CLOCK/4, m1_i8279_intf) // unknown clock |
| 866 | 589 | |
| 590 | MCFG_I8279_ADD("i8279_2", M1_MASTER_CLOCK/4, m1_i8279_2_intf) // unknown clock |
| 591 | |
| 867 | 592 | MCFG_NVRAM_ADD_0FILL("nvram") |
| 868 | 593 | |
| 869 | 594 | MCFG_DEFAULT_LAYOUT(layout_maygay1b) |
trunk/src/mame/includes/maygay1b.h
| r29467 | r29468 | |
| 8 | 8 | #define M1_DUART_CLOCK (XTAL_3_6864MHz) |
| 9 | 9 | |
| 10 | 10 | #include "cpu/m6809/m6809.h" |
| 11 | #include "machine/i8279.h" |
| 12 | |
| 11 | 13 | #include "video/awpvid.h" //Fruit Machines Only |
| 12 | 14 | #include "machine/6821pia.h" |
| 13 | 15 | #include "machine/mc68681.h" |
| r29467 | r29468 | |
| 19 | 21 | #include "sound/okim6376.h" |
| 20 | 22 | #include "machine/nvram.h" |
| 21 | 23 | |
| 22 | | struct i8279_state |
| 23 | | { |
| 24 | | UINT8 command; |
| 25 | | UINT8 mode; |
| 26 | | UINT8 prescale; |
| 27 | | UINT8 inhibit; |
| 28 | | UINT8 clear; |
| 29 | | UINT8 ram[16]; |
| 30 | | UINT8 read_sensor; |
| 31 | | UINT8 write_display; |
| 32 | | UINT8 sense_address; |
| 33 | | UINT8 sense_auto_inc; |
| 34 | | UINT8 disp_address; |
| 35 | | UINT8 disp_auto_inc; |
| 36 | | }; |
| 37 | | |
| 38 | | |
| 39 | 24 | class maygay1b_state : public driver_device |
| 40 | 25 | { |
| 41 | 26 | public: |
| r29467 | r29468 | |
| 43 | 28 | : driver_device(mconfig, type, tag), |
| 44 | 29 | m_maincpu(*this, "maincpu"), |
| 45 | 30 | m_vfd(*this, "vfd"), |
| 31 | m_ay(*this, "aysnd"), |
| 46 | 32 | m_msm6376(*this, "msm6376"), |
| 47 | | m_duart68681(*this, "duart68681") { |
| 48 | | m_NMIENABLE = 0; |
| 49 | | } |
| 33 | m_duart68681(*this, "duart68681"), |
| 34 | m_sw1_port(*this, "SW1"), |
| 35 | m_sw2_port(*this, "SW2"), |
| 36 | m_s2_port(*this, "STROBE2"), |
| 37 | m_s3_port(*this, "STROBE3"), |
| 38 | m_s4_port(*this, "STROBE4"), |
| 39 | m_s5_port(*this, "STROBE5"), |
| 40 | m_s6_port(*this, "STROBE6"), |
| 41 | m_s7_port(*this, "STROBE7") |
| 42 | {} |
| 50 | 43 | |
| 51 | 44 | required_device<cpu_device> m_maincpu; |
| 52 | | optional_device<roc10937_t> m_vfd; |
| 45 | optional_device<s16lf01_t> m_vfd; |
| 46 | required_device<ay8910_device> m_ay; |
| 53 | 47 | optional_device<okim6376_device> m_msm6376; |
| 54 | 48 | required_device<mc68681_device> m_duart68681; |
| 49 | required_ioport m_sw1_port; |
| 50 | required_ioport m_sw2_port; |
| 51 | required_ioport m_s2_port; |
| 52 | required_ioport m_s3_port; |
| 53 | required_ioport m_s4_port; |
| 54 | required_ioport m_s5_port; |
| 55 | required_ioport m_s6_port; |
| 56 | required_ioport m_s7_port; |
| 55 | 57 | |
| 56 | 58 | UINT8 m_lamppos; |
| 59 | int m_lamp_strobe; |
| 60 | int m_old_lamp_strobe; |
| 61 | int m_lamp_strobe2; |
| 62 | int m_old_lamp_strobe2; |
| 57 | 63 | int m_alpha_clock; |
| 58 | 64 | int m_RAMEN; |
| 59 | 65 | int m_ALARMEN; |
| r29467 | r29468 | |
| 65 | 71 | TIMER_DEVICE_CALLBACK_MEMBER( maygay1b_nmitimer_callback ); |
| 66 | 72 | UINT8 m_Lamps[256]; |
| 67 | 73 | int m_optic_pattern; |
| 68 | | i8279_state m_i8279[2]; |
| 69 | | DECLARE_READ8_MEMBER(m1_8279_r); |
| 70 | | DECLARE_WRITE8_MEMBER(m1_8279_w); |
| 71 | | DECLARE_READ8_MEMBER(m1_8279_2_r); |
| 72 | | DECLARE_WRITE8_MEMBER(m1_8279_2_w); |
| 74 | DECLARE_WRITE8_MEMBER(scanlines_w); |
| 75 | DECLARE_WRITE8_MEMBER(lamp_data_w); |
| 76 | DECLARE_WRITE8_MEMBER(lamp_data_2_w); |
| 77 | DECLARE_READ8_MEMBER(kbd_r); |
| 73 | 78 | DECLARE_WRITE8_MEMBER(reel12_w); |
| 74 | 79 | DECLARE_WRITE8_MEMBER(reel34_w); |
| 75 | 80 | DECLARE_WRITE8_MEMBER(reel56_w); |
| r29467 | r29468 | |
| 78 | 83 | DECLARE_READ8_MEMBER(latch_st_hi); |
| 79 | 84 | DECLARE_READ8_MEMBER(latch_st_lo); |
| 80 | 85 | DECLARE_WRITE8_MEMBER(m1ab_no_oki_w); |
| 81 | | void m1_draw_lamps(int data,int strobe, int col); |
| 82 | 86 | DECLARE_WRITE8_MEMBER(m1_pia_porta_w); |
| 83 | 87 | DECLARE_WRITE8_MEMBER(m1_pia_portb_w); |
| 88 | DECLARE_WRITE8_MEMBER(m1_lockout_w); |
| 84 | 89 | DECLARE_WRITE8_MEMBER(m1_meter_w); |
| 85 | 90 | DECLARE_READ8_MEMBER(m1_meter_r); |
| 91 | DECLARE_READ8_MEMBER(m1_firq_clr_r); |
| 86 | 92 | DECLARE_READ8_MEMBER(m1_firq_trg_r); |
| 87 | 93 | DECLARE_WRITE_LINE_MEMBER(duart_irq_handler); |
| 88 | 94 | DECLARE_READ8_MEMBER(m1_duart_r); |
| 89 | 95 | DECLARE_DRIVER_INIT(m1); |
| 90 | 96 | virtual void machine_start(); |
| 91 | 97 | virtual void machine_reset(); |
| 92 | | void update_outputs(i8279_state *chip, UINT16 which); |
| 93 | 98 | void m1_stepper_reset(); |
| 94 | 99 | }; |
trunk/src/emu/machine/roc10937.c
| r29467 | r29468 | |
| 32 | 32 | */ |
| 33 | 33 | |
| 34 | 34 | static const UINT16 roc10937charset[]= |
| 35 | | { // FEDC BA98 7654 3210 |
| 35 | { // FEDC BA98 7654 3210 |
| 36 | 36 | 0x507F, // 0101 0000 0111 1111 @. |
| 37 | 37 | 0x44CF, // 0100 0100 1100 1111 A. |
| 38 | 38 | 0x153F, // 0001 0101 0011 1111 B. |
| r29467 | r29468 | |
| 95 | 95 | // -. |
| 96 | 96 | 0x2001, // 0010 0000 0000 0001 - |
| 97 | 97 | // /. |
| 98 | | 0x2430, // 0010 0100 0011 0000 <. |
| 98 | 0x2430, // 0010 0010 0011 0000 <. |
| 99 | 99 | 0x4430, // 0100 0100 0011 0000 =. |
| 100 | 100 | 0x8830, // 1000 1000 0011 0000 >. |
| 101 | 101 | 0x1407, // 0001 0100 0000 0111 ?. |
| 102 | 102 | }; |
| 103 | 103 | |
| 104 | |
| 104 | 105 | /////////////////////////////////////////////////////////////////////////// |
| 105 | 106 | static const int roc10937poslut[]= |
| 106 | 107 | { |
| r29467 | r29468 | |
| 128 | 129 | device_t(mconfig, type, name, tag, owner, clock, shortname, source) |
| 129 | 130 | { |
| 130 | 131 | m_port_val=0; |
| 131 | | m_reversed=0; |
| 132 | 132 | } |
| 133 | 133 | |
| 134 | 134 | |
| r29467 | r29468 | |
| 138 | 138 | roc.m_port_val = val; |
| 139 | 139 | } |
| 140 | 140 | |
| 141 | | void rocvfd_t::static_set_zero(device_t &device, bool reversed) |
| 142 | | { |
| 143 | | rocvfd_t &roc = downcast<rocvfd_t &>(device); |
| 144 | | roc.m_reversed = reversed; |
| 145 | | } |
| 146 | | |
| 147 | 141 | void rocvfd_t::device_start() |
| 148 | 142 | { |
| 149 | 143 | save_item(NAME(m_port_val)); |
| 150 | | save_item(NAME(m_reversed)); |
| 151 | 144 | save_item(NAME(m_cursor_pos)); |
| 152 | 145 | save_item(NAME(m_window_size)); |
| 153 | 146 | save_item(NAME(m_shift_count)); |
| r29467 | r29468 | |
| 196 | 189 | } |
| 197 | 190 | } |
| 198 | 191 | |
| 192 | //Display on Rockwell chips is naturally backwards, due to the way it is wired. We emulate this by flipping the display at update time |
| 199 | 193 | void rocvfd_t::update_display() |
| 200 | 194 | { |
| 201 | 195 | for (int i =0; i<16; i++) |
| 202 | 196 | { |
| 203 | | if (m_reversed) |
| 204 | | { |
| 205 | | m_outputs[i] = set_display(m_chars[15-i]); |
| 206 | | } |
| 207 | | else |
| 208 | | { |
| 209 | | m_outputs[i] = set_display(m_chars[i]); |
| 210 | | } |
| 197 | m_outputs[i] = set_display(m_chars[15-i]); |
| 211 | 198 | output_set_indexed_value("vfd", (m_port_val*16) + i, m_outputs[i]); |
| 212 | 199 | } |
| 213 | 200 | } |
| r29467 | r29468 | |
| 232 | 219 | : rocvfd_t(mconfig, ROC10937, "Rockwell 10937 VFD controller and compatible", tag, owner, clock, "roc10937", __FILE__) |
| 233 | 220 | { |
| 234 | 221 | m_port_val=0; |
| 235 | | m_reversed=0; |
| 236 | 222 | } |
| 237 | 223 | |
| 238 | 224 | const device_type MSC1937 = &device_creator<msc1937_t>; |
| r29467 | r29468 | |
| 241 | 227 | : rocvfd_t(mconfig, MSC1937, "OKI MSC1937 VFD controller", tag, owner, clock, "msc1937", __FILE__) |
| 242 | 228 | { |
| 243 | 229 | m_port_val=0; |
| 244 | | m_reversed=0; |
| 245 | 230 | } |
| 246 | 231 | |
| 247 | 232 | void rocvfd_t::write_char(int data) |
| r29467 | r29468 | |
| 301 | 286 | : rocvfd_t(mconfig, ROC10957, "Rockwell 10957 VFD controller and compatible", tag, owner, clock, "roc10957", __FILE__) |
| 302 | 287 | { |
| 303 | 288 | m_port_val=0; |
| 304 | | m_reversed=0; |
| 305 | 289 | } |
| 306 | 290 | |
| 307 | 291 | void roc10957_t::write_char(int data) |
| r29467 | r29468 | |
| 363 | 347 | } |
| 364 | 348 | } |
| 365 | 349 | } |
| 350 | |
| 351 | const device_type S16LF01 = &device_creator<s16lf01_t>; |
| 352 | |
| 353 | s16lf01_t::s16lf01_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 354 | : rocvfd_t(mconfig, S16LF01, "Samsung 16LF01 Series VFD controller and compatible", tag, owner, clock, "s16lf01", __FILE__) |
| 355 | { |
| 356 | m_port_val=0; |
| 357 | } |
| 358 | |
| 359 | //Samsung chips fix the issue with the reversal of the drive. |
| 360 | void s16lf01_t::update_display() |
| 361 | { |
| 362 | for (int i =0; i<16; i++) |
| 363 | { |
| 364 | m_outputs[i] = set_display(m_chars[i]); |
| 365 | output_set_indexed_value("vfd", (m_port_val*16) + i, m_outputs[i]); |
| 366 | } |
| 367 | } |
trunk/src/emu/machine/roc10937.h
| r29467 | r29468 | |
| 1 | 1 | /********************************************************************** |
| 2 | 2 | |
| 3 | | Rockwell 10937/10957 interface and emulation by J.Wallace |
| 4 | | OKI MSC1937 is a clone of this chip |
| 3 | Rockwell 10937/10957 interface and simlar chips |
| 4 | Emulation by J.Wallace |
| 5 | OKI MSC1937 is a clone of this chip, with many others. |
| 5 | 6 | |
| 6 | 7 | **********************************************************************/ |
| 7 | 8 | #pragma once |
| r29467 | r29468 | |
| 9 | 10 | #ifndef ROC10937_H |
| 10 | 11 | #define ROC10937_H |
| 11 | 12 | |
| 12 | | #define LEFT_TO_RIGHT 1 |
| 13 | | #define RIGHT_TO_LEFT 0 |
| 13 | #define MCFG_ROC10937_ADD(_tag,_val) \ |
| 14 | MCFG_DEVICE_ADD(_tag, ROC10937,60)\ |
| 15 | MCFG_ROC10937_PORT(_val) |
| 14 | 16 | |
| 15 | | #define MCFG_ROC10937_ADD(_tag,_val,_reversed) \ |
| 16 | | MCFG_DEVICE_ADD(_tag, ROC10937,60)\ |
| 17 | | MCFG_ROC10937_PORT(_val) \ |
| 18 | | MCFG_ROC10937_REVERSE(_reversed) |
| 19 | 17 | #define MCFG_ROC10937_PORT(_val) \ |
| 20 | 18 | roc10937_t::static_set_value(*device, _val); |
| 21 | | #define MCFG_ROC10937_REVERSE(_reversed) \ |
| 22 | | roc10937_t::static_set_zero(*device, _reversed); |
| 23 | 19 | #define MCFG_ROC10937_REMOVE(_tag) \ |
| 24 | 20 | MCFG_DEVICE_REMOVE(_tag) |
| 25 | 21 | |
| 26 | | #define MCFG_ROC10957_ADD(_tag,_val,_reversed) \ |
| 22 | #define MCFG_ROC10957_ADD(_tag,_val) \ |
| 27 | 23 | MCFG_DEVICE_ADD(_tag, ROC10957,60)\ |
| 28 | | MCFG_ROC10957_PORT(_val) \ |
| 29 | | MCFG_ROC10957_REVERSE(_reversed) |
| 24 | MCFG_ROC10957_PORT(_val) |
| 25 | |
| 30 | 26 | #define MCFG_ROC10957_PORT(_val) \ |
| 31 | 27 | roc10957_t::static_set_value(*device, _val); |
| 32 | | #define MCFG_ROC10957_REVERSE(_reversed) \ |
| 33 | | roc10957_t::static_set_zero(*device, _reversed); |
| 34 | 28 | #define MCFG_ROC10957_REMOVE(_tag) \ |
| 35 | 29 | MCFG_DEVICE_REMOVE(_tag) |
| 36 | 30 | |
| 37 | | #define MCFG_MSC1937_ADD(_tag,_val,_reversed) \ |
| 31 | #define MCFG_MSC1937_ADD(_tag,_val) \ |
| 38 | 32 | MCFG_DEVICE_ADD(_tag, ROC10937,60)\ |
| 39 | | MCFG_MSC1937_PORT(_val) \ |
| 40 | | MCFG_MSC1937_REVERSE(_reversed) |
| 33 | MCFG_MSC1937_PORT(_val) |
| 34 | |
| 41 | 35 | #define MCFG_MSC1937_PORT(_val) \ |
| 42 | 36 | MCFG_ROC10937_PORT(_val) |
| 43 | 37 | |
| 44 | | #define MCFG_MSC1937_REVERSE(_reversed) \ |
| 45 | | roc10937_t::static_set_zero(*device, _reversed); |
| 46 | 38 | #define MCFG_MSC1937_REMOVE(_tag) \ |
| 47 | 39 | MCFG_DEVICE_REMOVE(_tag) |
| 48 | 40 | |
| 41 | #define MCFG_S16LF01_ADD(_tag,_val) \ |
| 42 | MCFG_DEVICE_ADD(_tag, S16LF01,60)\ |
| 43 | MCFG_S16LF01_PORT(_val) |
| 49 | 44 | |
| 45 | #define MCFG_S16LF01_PORT(_val) \ |
| 46 | MCFG_ROC10937_PORT(_val) |
| 47 | |
| 50 | 48 | class rocvfd_t : public device_t { |
| 51 | 49 | public: |
| 52 | 50 | rocvfd_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); |
| 53 | 51 | |
| 54 | 52 | // inline configuration helpers |
| 55 | 53 | static void static_set_value(device_t &device, int val); |
| 56 | | static void static_set_zero(device_t &device, bool reversed); |
| 57 | 54 | virtual void update_display(); |
| 58 | 55 | UINT8 m_port_val; |
| 59 | | bool m_reversed; |
| 60 | 56 | void blank(int data); |
| 61 | 57 | void shift_data(int data); |
| 62 | 58 | void write_char(int data); |
| r29467 | r29468 | |
| 110 | 106 | |
| 111 | 107 | }; |
| 112 | 108 | |
| 109 | class s16lf01_t : public rocvfd_t { |
| 110 | public: |
| 111 | s16lf01_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 112 | |
| 113 | virtual void update_display(); |
| 114 | protected: |
| 115 | |
| 116 | }; |
| 117 | |
| 113 | 118 | extern const device_type ROC10937; |
| 114 | 119 | extern const device_type MSC1937; |
| 115 | 120 | extern const device_type ROC10957; |
| 121 | extern const device_type S16LF01; |
| 116 | 122 | |
| 117 | 123 | #endif |