src/mess/drivers/pcw.c
| r8970 | r8971 | |
| 133 | 133 | |
| 134 | 134 | static UINT16 pcw_kb_scan_row; |
| 135 | 135 | |
| 136 | | static UINT8* mcu_shared_ram; |
| 136 | static UINT8 mcu_keyboard_data[16]; |
| 137 | static UINT8 mcu_transmit_reset_seq; |
| 138 | static UINT8 mcu_transmit_count; |
| 137 | 139 | |
| 138 | 140 | static void pcw_update_interrupt_counter(void) |
| 139 | 141 | { |
| r8970 | r8971 | |
| 227 | 229 | ADDRESS_MAP_END |
| 228 | 230 | |
| 229 | 231 | |
| 230 | | /* Keyboard is read by the MCU and passed onto an area of RAM */ |
| 232 | /* Keyboard is read by the MCU and sent as serial data to the gate array ASIC */ |
| 231 | 233 | static READ8_HANDLER(pcw_keyboard_r) |
| 232 | 234 | { |
| 233 | 235 | static const char *const keynames[] = { |
| r8970 | r8971 | |
| 235 | 237 | "LINE8", "LINE9", "LINE10", "LINE11", "LINE12", "LINE13", "LINE14", "LINE15" |
| 236 | 238 | }; |
| 237 | 239 | |
| 238 | | if(offset == 10) // the MCU swaps the low 7 bits read from scan row 9, and places them in 0x3A. This should fix any issue until we know just how the MCU transmits the RAM contents. |
| 239 | | return (input_port_read(space->machine, keynames[offset]) & 0x80) | (input_port_read(space->machine, keynames[offset-1]) & 0x7f); |
| 240 | 240 | return input_port_read(space->machine, keynames[offset]); |
| 241 | 241 | } |
| 242 | 242 | |
| 243 | | static READ8_HANDLER(pcw_mcu_shared_r) |
| 243 | static READ8_HANDLER(pcw_keyboard_data_r) |
| 244 | 244 | { |
| 245 | | return mcu_shared_ram[offset]; |
| 245 | return mcu_keyboard_data[offset]; |
| 246 | 246 | } |
| 247 | 247 | |
| 248 | 248 | /* ----------------------------------------------------------------------- |
| r8970 | r8971 | |
| 262 | 262 | handler */ |
| 263 | 263 | memory_install_read8_handler(space, |
| 264 | 264 | block * 0x04000 + 0x3ff0, block * 0x04000 + 0x3fff, 0, 0, |
| 265 | | pcw_mcu_shared_r); |
| 265 | pcw_keyboard_data_r); |
| 266 | 266 | // LOG(("MEM: read block %i -> bank %i\n",block,bank)); |
| 267 | 267 | } |
| 268 | 268 | else |
| r8970 | r8971 | |
| 717 | 717 | return pcw_printer_command; |
| 718 | 718 | } |
| 719 | 719 | |
| 720 | /* |
| 721 | * Keyboard MCU (i8048) |
| 722 | * P1 = keyboard scan row select (low 8 bits) |
| 723 | * P2 = bits 7-4: keyboard scan row select (high 4 bits) |
| 724 | * bit 1: keyboard serial clock |
| 725 | * bit 0: keyboard serial data |
| 726 | */ |
| 727 | static void mcu_transmit_serial(UINT8 bit) |
| 728 | { |
| 729 | static UINT8 selected; |
| 730 | static UINT8 buffer; |
| 731 | int seq; |
| 732 | |
| 733 | /* Keyboard data is sent in serial from the MCU through the keyboard port, to the ASIC |
| 734 | Sends a string of 12-bit sequences, first 4 bits are the RAM location (from &3ff0), |
| 735 | then 8 bits for the data to be written there. */ |
| 736 | logerror("KB: Transmitting bit #%i [%i]\n",mcu_transmit_count,bit); |
| 737 | seq = mcu_transmit_count % 12; |
| 738 | if(seq < 4) |
| 739 | { |
| 740 | if(bit == 0) |
| 741 | selected &= ~(8 >> seq); |
| 742 | else |
| 743 | selected |= (8 >> seq); |
| 744 | } |
| 745 | else |
| 746 | { |
| 747 | seq -= 4; |
| 748 | if(bit == 0) |
| 749 | buffer &= ~(128 >> seq); |
| 750 | else |
| 751 | buffer |= (128 >> seq); |
| 752 | } |
| 753 | mcu_transmit_count++; |
| 754 | if(mcu_transmit_count >= 12) |
| 755 | { |
| 756 | mcu_keyboard_data[selected] = buffer; |
| 757 | mcu_transmit_count = 0; |
| 758 | logerror("KB: Recieved data byte #%i [%02x]\n",selected,buffer); |
| 759 | } |
| 760 | } |
| 761 | |
| 720 | 762 | static READ8_HANDLER(mcu_kb_scan_r) |
| 721 | 763 | { |
| 722 | 764 | return pcw_kb_scan_row & 0xff; |
| r8970 | r8971 | |
| 734 | 776 | |
| 735 | 777 | static WRITE8_HANDLER(mcu_kb_scan_high_w) |
| 736 | 778 | { |
| 779 | static UINT8 prev; |
| 780 | |
| 781 | if((prev & 0x02) && !(data & 0x02)) // bit is transmitted on high-to-low clock transition |
| 782 | { |
| 783 | mcu_transmit_serial(data & 0x01); |
| 784 | mcu_transmit_reset_seq = 0; |
| 785 | } |
| 786 | |
| 787 | if((prev & 0x01) != (data & 0x01)) // two high->low transitions on the data pin signals the beginning of a new transfer |
| 788 | { |
| 789 | mcu_transmit_reset_seq++; |
| 790 | if(mcu_transmit_reset_seq > 3) |
| 791 | mcu_transmit_count = 0; |
| 792 | } |
| 793 | |
| 737 | 794 | pcw_kb_scan_row = (pcw_kb_scan_row & 0x00ff) | ((data & 0xff) << 8); |
| 795 | prev = data; |
| 738 | 796 | } |
| 739 | 797 | |
| 740 | 798 | static READ8_HANDLER(mcu_kb_data_r) |
| r8970 | r8971 | |
| 831 | 889 | AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READ(mcu_kb_data_r) |
| 832 | 890 | ADDRESS_MAP_END |
| 833 | 891 | |
| 834 | | static ADDRESS_MAP_START(pcw_keyboard_data, ADDRESS_SPACE_DATA, 8) |
| 835 | | AM_RANGE(0x30, 0x3f) AM_RAM AM_BASE(&mcu_shared_ram) |
| 836 | | ADDRESS_MAP_END |
| 837 | 892 | |
| 838 | | |
| 839 | 893 | static TIMER_CALLBACK(setup_beep) |
| 840 | 894 | { |
| 841 | 895 | running_device *speaker = machine->device("beep"); |
| r8970 | r8971 | |
| 870 | 924 | pcw_boot = 0; // System starts up in bootstrap mode, disabled until it's possible to emulate it. |
| 871 | 925 | |
| 872 | 926 | /* copy boot code into RAM - yes, it's skipping a step */ |
| 873 | | |
| 874 | 927 | memset(messram_get_ptr(machine->device("messram")),0x00,messram_get_size(machine->device("messram"))); |
| 875 | 928 | for(x=0;x<256;x++) |
| 876 | 929 | messram_get_ptr(machine->device("messram"))[x+2] = code[x+0x300]; |
| r8970 | r8971 | |
| 1045 | 1098 | /* 2008-05 FP: not sure if this key is correct, "Caps Lock" is already mapped above. |
| 1046 | 1099 | For now, I let it with no default mapping. */ |
| 1047 | 1100 | PORT_START("LINE13") /* 0x03ffd */ |
| 1048 | | PORT_BIT(0x3f, 0xff, IPT_UNUSED) |
| 1049 | | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SHIFT LOCK") //PORT_CODE(KEYCODE_CAPSLOCK) |
| 1050 | | PORT_BIT(0x80, 0xff, IPT_UNUSED) |
| 1101 | PORT_BIT(0xff, 0xff, IPT_UNUSED) |
| 1102 | // PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SHIFT LOCK") //PORT_CODE(KEYCODE_CAPSLOCK) |
| 1103 | // PORT_BIT(0x80, 0xff, IPT_UNUSED) |
| 1051 | 1104 | |
| 1052 | 1105 | PORT_START("LINE14") /* 0x03ffe */ |
| 1053 | 1106 | PORT_BIT ( 0xff, 0xff, IPT_UNUSED ) |
| r8970 | r8971 | |
| 1119 | 1172 | |
| 1120 | 1173 | MDRV_CPU_ADD("keyboard_mcu", I8048, 1000000) // clock is a guess for now |
| 1121 | 1174 | MDRV_CPU_IO_MAP(pcw_keyboard_io) |
| 1122 | | MDRV_CPU_DATA_MAP(pcw_keyboard_data) |
| 1123 | 1175 | |
| 1124 | 1176 | MDRV_I8243_ADD("printer_8243", NULL, pcw_printer_output_w) |
| 1125 | 1177 | |