src/mess/machine/mbee.c
| r9346 | r9347 | |
| 29 | 29 | |
| 30 | 30 | ************************************************************/ |
| 31 | 31 | |
| 32 | | static WRITE8_DEVICE_HANDLER( mbee_pio_interrupt ) |
| 32 | static void mbee_pio_interrupt(running_device *device, int state) |
| 33 | 33 | { |
| 34 | | cputag_set_input_line(device->machine, "maincpu", 0, data ); |
| 34 | cputag_set_input_line(device->machine, "maincpu", 0, state ); |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | 37 | static WRITE8_DEVICE_HANDLER( pio_ardy ) |
| r9346 | r9347 | |
| 57 | 57 | d4 rs232 input (0=mark) |
| 58 | 58 | d3 rs232 CTS (0=clear to send) |
| 59 | 59 | d2 rs232 clock or DTR |
| 60 | | d1 cass out |
| 60 | d1 cass out and (on 256tc) keyboard irq |
| 61 | 61 | d0 cass in */ |
| 62 | 62 | |
| 63 | 63 | cassette_output(mbee_cassette, (data & 0x02) ? -1.0 : +1.0); |
| r9346 | r9347 | |
| 67 | 67 | |
| 68 | 68 | static READ8_DEVICE_HANDLER( pio_port_b_r ) |
| 69 | 69 | { |
| 70 | | UINT8 data = 0; |
| 70 | UINT8 data = z80pio_pb_r(mbee_z80pio,0) & 0x7e; |
| 71 | 71 | |
| 72 | 72 | if (cassette_input(mbee_cassette) > 0.03) |
| 73 | 73 | data |= 0x01; |
| r9346 | r9347 | |
| 81 | 81 | |
| 82 | 82 | const z80pio_interface mbee_z80pio_intf = |
| 83 | 83 | { |
| 84 | | DEVCB_HANDLER(mbee_pio_interrupt), /* callback when change interrupt status */ |
| 84 | DEVCB_LINE(mbee_pio_interrupt), /* callback when change interrupt status */ |
| 85 | 85 | DEVCB_NULL, |
| 86 | 86 | DEVCB_HANDLER(pio_port_a_w), |
| 87 | 87 | DEVCB_HANDLER(pio_ardy), |
| r9346 | r9347 | |
| 136 | 136 | /* d7..d4 not used |
| 137 | 137 | d3 density (1=MFM) |
| 138 | 138 | d2 side (1=side 1) |
| 139 | | d1..d0 drive select (0 to 3 - although no microbee ever had more than 2 drives) */ |
| 139 | d1..d0 drive select (0 to 3) */ |
| 140 | 140 | |
| 141 | 141 | wd17xx_set_drive(mbee_fdc, data & 3); |
| 142 | 142 | wd17xx_set_side(mbee_fdc, (data & 4) ? 1 : 0); |
| r9346 | r9347 | |
| 149 | 149 | |
| 150 | 150 | ************************************************************/ |
| 151 | 151 | |
| 152 | static UINT8 mbee256_was_pressed[15] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; |
| 153 | static UINT8 mbee256_q[20]; |
| 154 | static UINT8 mbee256_q_pos = 0; |
| 155 | |
| 156 | static TIMER_CALLBACK( mbee256_kbd ) |
| 157 | { |
| 158 | /* Keyboard scanner is a '3870' chip. It is not clocked, but is triggered by each read of port 18. |
| 159 | When a key is detected, it sets bit 1 of port 2 (one of the pio input lines). The next read of |
| 160 | port 18 will clear this line. The 3870 can store up to 9 keys, and has separate scan codes for |
| 161 | keys being pressed and being released. With no data sheet available, the following is a guess. */ |
| 162 | |
| 163 | UINT8 i, j, scancode; |
| 164 | UINT8 pressed[15] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; |
| 165 | char kbdrow[6]; |
| 166 | |
| 167 | |
| 168 | /* see what is pressed */ |
| 169 | for (i = 0; i < 15; i++) |
| 170 | { |
| 171 | sprintf(kbdrow,"LINE%d",i); |
| 172 | pressed[i] = (input_port_read(machine, kbdrow)); |
| 173 | } |
| 174 | |
| 175 | /* find what has changed */ |
| 176 | for (i = 0; i < 15; i++) |
| 177 | { |
| 178 | if (pressed[i] != mbee256_was_pressed[i]) |
| 179 | { |
| 180 | /* get scankey value */ |
| 181 | for (j = 0; j < 8; j++) |
| 182 | { |
| 183 | if (BIT(pressed[i]^mbee256_was_pressed[i], j)) |
| 184 | { |
| 185 | scancode = (i << 3) | j | (BIT(pressed[i], j) ? 0x80 : 0); |
| 186 | /* put it in the queue */ |
| 187 | mbee256_q[mbee256_q_pos] = scancode; |
| 188 | if (mbee256_q_pos < 20) mbee256_q_pos++; |
| 189 | } |
| 190 | } |
| 191 | } |
| 192 | mbee256_was_pressed[i] = pressed[i]; |
| 193 | } |
| 194 | |
| 195 | /* if anything queued, cause an interrupt */ |
| 196 | if (mbee256_q_pos) |
| 197 | { |
| 198 | i = z80pio_pb_r(mbee_z80pio,0); |
| 199 | z80pio_pb_w(mbee_z80pio, 0, i | 2); |
| 200 | } |
| 201 | } |
| 202 | |
| 152 | 203 | READ8_HANDLER( mbee256_18_r ) // read |
| 153 | 204 | { |
| 154 | | UINT8 data = z80pio_pb_r(mbee_z80pio,0); |
| 155 | | z80pio_pb_w(mbee_z80pio, 0, data & 0xfd); |
| 156 | | // get next char and return it |
| 157 | | return 0; |
| 205 | UINT8 i, ret = 121, data = z80pio_pb_r(mbee_z80pio,0); |
| 206 | if (mbee256_q_pos) |
| 207 | { |
| 208 | if (mbee256_q_pos) mbee256_q_pos--; // bump pointer |
| 209 | ret = mbee256_q[0]; // get oldest key |
| 210 | z80pio_pb_w(mbee_z80pio, 0, data & 0xfd); // clear irq |
| 211 | for (i = 0; i < mbee256_q_pos; i++) mbee256_q[i] = mbee256_q[i+1]; // ripple queue |
| 212 | } |
| 213 | |
| 214 | /* time delay of 0.01uf cap and 1.5k resistor */ |
| 215 | timer_set(space->machine, ATTOTIME_IN_USEC(15), NULL, 0, mbee256_kbd); |
| 216 | |
| 217 | /* get next char and return it */ |
| 218 | |
| 219 | return ret; |
| 158 | 220 | } |
| 159 | 221 | |
| 160 | 222 | |
| r9346 | r9347 | |
| 235 | 297 | |
| 236 | 298 | MACHINE_RESET( mbee256 ) |
| 237 | 299 | { |
| 300 | UINT8 i; |
| 238 | 301 | timer_set(machine, ATTOTIME_IN_USEC(4), NULL, 0, mbee_reset); |
| 239 | 302 | memory_set_bank(machine, "boot", 1); |
| 240 | 303 | memory_set_bank(machine, "bankl", 1); |
| r9346 | r9347 | |
| 245 | 308 | mbee_printer = machine->device("centronics"); |
| 246 | 309 | mbee_fdc = machine->device("wd179x"); |
| 247 | 310 | mbee_rtc = machine->device<mc146818_device>("rtc"); |
| 311 | for (i = 0; i < 15; i++) mbee256_was_pressed[i] = 0; |
| 312 | mbee256_q_pos = 0; |
| 248 | 313 | } |
| 249 | 314 | |
| 250 | 315 | INTERRUPT_GEN( mbee_interrupt ) |