branches/alto2/src/emu/cpu/alto2/a2ether.c
| r26318 | r26319 | |
| 9 | 9 | *****************************************************************************/ |
| 10 | 10 | #include "alto2cpu.h" |
| 11 | 11 | |
| 12 | | /** @brief the ethernet ID of this machine */ |
| 13 | | UINT8 ether_id = 254; |
| 12 | #define DEBUG_PACKETS 1 |
| 14 | 13 | |
| 15 | | /** @brief hardware status: write latch full/filled (? set by EODFCT) */ |
| 16 | | #define GET_ETH_WLF(st) X_BIT(st,16,4) |
| 14 | #define GET_ETH_WLF(st) X_BIT(st,16,4) //!< hardware status: write latch full/filled (? set by EODFCT) |
| 17 | 15 | #define PUT_ETH_WLF(st,val) X_WRBITS(st,16,4,4,val) |
| 18 | 16 | |
| 19 | | /** @brief hardware status: output end of transmission (set by EEFCT) */ |
| 20 | | #define GET_ETH_OEOT(st) X_BIT(st,16,5) |
| 17 | #define GET_ETH_OEOT(st) X_BIT(st,16,5) //!< hardware status: output end of transmission (set by EEFCT) |
| 21 | 18 | #define PUT_ETH_OEOT(st,val) X_WRBITS(st,16,5,5,val) |
| 22 | 19 | |
| 23 | | /** @brief hardware status: input gone */ |
| 24 | | #define GET_ETH_IGONE(st) X_BIT(st,16,6) |
| 20 | #define GET_ETH_IGONE(st) X_BIT(st,16,6) //!< hardware status: input gone |
| 25 | 21 | #define PUT_ETH_IGONE(st,val) X_WRBITS(st,16,6,6,val) |
| 26 | 22 | |
| 27 | | /** @brief hardware status: input busy (set by EISFCT, bit isn't visible to microcode) */ |
| 28 | | #define GET_ETH_IBUSY(st) X_BIT(st,16,7) |
| 23 | #define GET_ETH_IBUSY(st) X_BIT(st,16,7) //!< hardware status: input busy (set by EISFCT, bit isn't visible to microcode) |
| 29 | 24 | #define PUT_ETH_IBUSY(st,val) X_WRBITS(st,16,7,7,val) |
| 30 | 25 | |
| 31 | | /** @brief hardware status: output gone */ |
| 32 | | #define GET_ETH_OGONE(st) X_BIT(st,16,8) |
| 26 | #define GET_ETH_OGONE(st) X_BIT(st,16,8) //!< hardware status: output gone |
| 33 | 27 | #define PUT_ETH_OGONE(st,val) X_WRBITS(st,16,8,8,val) |
| 34 | 28 | |
| 35 | | /** @brief hardware status: output busy (set by EOSFCT, bit isn't visible to microcode) */ |
| 36 | | #define GET_ETH_OBUSY(st) X_BIT(st,16,9) |
| 29 | #define GET_ETH_OBUSY(st) X_BIT(st,16,9) //!< hardware status: output busy (set by EOSFCT, bit isn't visible to microcode) |
| 37 | 30 | #define PUT_ETH_OBUSY(st,val) X_WRBITS(st,16,9,9,val) |
| 38 | 31 | |
| 39 | | /** @brief hardware status: input data late */ |
| 40 | | #define GET_ETH_IDL(st) X_BIT(st,16,10) |
| 32 | #define GET_ETH_IDL(st) X_BIT(st,16,10) //!< hardware status: input data late |
| 41 | 33 | #define PUT_ETH_IDL(st,val) X_WRBITS(st,16,10,10,val) |
| 42 | 34 | |
| 43 | | /** @brief hardware status: collision */ |
| 44 | | #define GET_ETH_COLL(st) X_BIT(st,16,11) |
| 35 | #define GET_ETH_COLL(st) X_BIT(st,16,11) //!< hardware status: collision |
| 45 | 36 | #define PUT_ETH_COLL(st,val) X_WRBITS(st,16,11,11,val) |
| 46 | 37 | |
| 47 | | /** @brief hardware status: CRC error */ |
| 48 | | #define GET_ETH_CRC(st) X_BIT(st,16,12) |
| 38 | #define GET_ETH_CRC(st) X_BIT(st,16,12) //!< hardware status: CRC error |
| 49 | 39 | #define PUT_ETH_CRC(st,val) X_WRBITS(st,16,12,12,val) |
| 50 | 40 | |
| 51 | | /** @brief hardware status: input command (set from BUS[14] on SIO, reset by EPFCT) */ |
| 52 | | #define GET_ETH_ICMD(st) X_BIT(st,16,13) |
| 41 | #define GET_ETH_ICMD(st) X_BIT(st,16,13) //!< hardware status: input command (set from BUS[14] on SIO, reset by EPFCT) |
| 53 | 42 | #define PUT_ETH_ICMD(st,val) X_WRBITS(st,16,13,13,val) |
| 54 | 43 | |
| 55 | | /** @brief hardware status: output command (set from BUS[15] on SIO, reset by EPFCT) */ |
| 56 | | #define GET_ETH_OCMD(st) X_BIT(st,16,14) |
| 44 | #define GET_ETH_OCMD(st) X_BIT(st,16,14) //!< hardware status: output command (set from BUS[15] on SIO, reset by EPFCT) |
| 57 | 45 | #define PUT_ETH_OCMD(st,val) X_WRBITS(st,16,14,14,val) |
| 58 | 46 | |
| 59 | | /** @brief hardware status: IT flip flop & ISRFULL' */ |
| 60 | | #define GET_ETH_IT(st) ALTO2_GET(st,16,15,15) |
| 47 | #define GET_ETH_IT(st) X_BIT(st,16,15) //!< hardware status: IT flip flop & ISRFULL' |
| 61 | 48 | #define PUT_ETH_IT(st,val) X_WRBITS(st,16,15,15,val) |
| 62 | 49 | |
| 63 | | /** @brief missing PROM ether.u49; buffer empty (active low) */ |
| 50 | //! PROM ether.u49; buffer empty (active low) |
| 64 | 51 | #define ETHER_A49_BE (m_ether_a49[16 * m_eth.fifo_wr + m_eth.fifo_rd] & (1 << 0)) |
| 65 | 52 | |
| 66 | | /** @brief missing PROM ether.u49; buffer next(?) empty (active low) */ |
| 53 | //! PROM ether.u49; buffer next(?) empty (active low) |
| 67 | 54 | #define ETHER_A49_BNE (m_ether_a49[16 * m_eth.fifo_wr + m_eth.fifo_rd] & (1 << 1)) |
| 68 | 55 | |
| 69 | | /** @brief missing PROM ether.u49; buffer next next(?) empty (active low) */ |
| 56 | //! PROM ether.u49; buffer next next(?) empty (active low) |
| 70 | 57 | #define ETHER_A49_BNNE (m_ether_a49[16 * m_eth.fifo_wr + m_eth.fifo_rd] & (1 << 2)) |
| 71 | 58 | |
| 72 | | /** @brief missing PROM ether.u49; buffer full (active low) */ |
| 59 | //! PROM ether.u49; buffer full (active low) |
| 73 | 60 | #define ETHER_A49_BF (m_ether_a49[16 * m_eth.fifo_wr + m_eth.fifo_rd] & (1 << 3)) |
| 74 | 61 | |
| 75 | | |
| 76 | | #define BREATHLEN 0400 /* ethernet packet length */ |
| 77 | | #define BREATHADDR 0177400 /* dest,,source */ |
| 78 | | #define BREATHTYPE 0000602 /* ethernet packet type */ |
| 62 | #define BREATHLEN ALTO2_ETHER_PACKET_SIZE //!< ethernet packet length |
| 63 | #define BREATHADDR 0177400 //!< destination and source |
| 64 | #define BREATHTYPE 0000602 //!< ethernet packet type |
| 79 | 65 | static const UINT16 duckbreath_data[BREATHLEN] = |
| 80 | 66 | { |
| 81 | | BREATHADDR, /* 3MB dest,,source */ |
| 67 | BREATHADDR, /* 3MB destination and source */ |
| 82 | 68 | BREATHTYPE, /* ether packet type */ |
| 83 | 69 | /* the rest is the contents of a breath of life packet. |
| 84 | | * see <altosource>etherboot.dm (etherboot.asm) for alto |
| 85 | | * assembly code. |
| 70 | * see <altosource>etherboot.dm (etherboot.asm) for the |
| 71 | * Alto assembly code. |
| 86 | 72 | */ |
| 87 | 73 | 0022574, 0100000, 0040437, 0102000, 0034431, 0164000, |
| 88 | 74 | 0061005, 0102460, 0024567, 0034572, 0061006, 0024565, 0034570, 0061006, |
| r26318 | r26319 | |
| 118 | 104 | 0014623, 0004644, 0020634, 0061004, 0002000, 0176764, 0001401, 0041002 |
| 119 | 105 | }; |
| 120 | 106 | |
| 107 | #if DEBUG_PACKETS |
| 108 | static void dump_ascii(const UINT16 *src, size_t size) |
| 109 | { |
| 110 | printf(" ["); |
| 111 | for (size_t offs = 0; offs < size; offs++) { |
| 112 | char ch1 = src[offs] / 256; |
| 113 | char ch2 = src[offs] % 256; |
| 114 | printf("%c", ch1 < 32 || ch1 > 126 ? '.' : ch1); |
| 115 | printf("%c", ch2 < 32 || ch2 > 126 ? '.' : ch2); |
| 116 | } |
| 117 | printf("]\n"); |
| 118 | } |
| 119 | |
| 120 | size_t dump_packet(const UINT16 *src, size_t addr, size_t size) |
| 121 | { |
| 122 | size_t offs; |
| 123 | for (offs = 0; offs < size; offs++) { |
| 124 | UINT16 word = src[offs]; |
| 125 | if (offs % 8) { |
| 126 | printf(" %06o", word); |
| 127 | } else { |
| 128 | if (offs > 0) |
| 129 | dump_ascii(&src[offs-8], 8); |
| 130 | printf("\t%05o: %06o", static_cast<unsigned>(addr + offs), word); |
| 131 | } |
| 132 | } |
| 133 | if (offs % 8) { |
| 134 | dump_ascii(&src[offs - (offs % 8)], offs % 8); |
| 135 | } else if (offs > 0) { |
| 136 | dump_ascii(&src[offs - 8], 8); |
| 137 | } |
| 138 | return size; |
| 139 | } |
| 140 | #endif |
| 141 | |
| 121 | 142 | /** |
| 122 | | * @brief check for the various reasons to wakeup the Ethernet task |
| 143 | * @brief check for the various reasons to wakeup the ethernet task |
| 123 | 144 | */ |
| 124 | 145 | void alto2_cpu_device::eth_wakeup() |
| 125 | 146 | { |
| 126 | | register int busy, idr, odr, etac; |
| 147 | register int etac = m_task == task_ether; |
| 127 | 148 | |
| 128 | | etac = m_task == task_ether; |
| 129 | | |
| 130 | 149 | LOG((LOG_ETH,0,"eth_wakeup: ibusy=%d obusy=%d ", GET_ETH_IBUSY(m_eth.status), GET_ETH_OBUSY(m_eth.status))); |
| 131 | | busy = GET_ETH_IBUSY(m_eth.status) | GET_ETH_OBUSY(m_eth.status); |
| 132 | | /* if not busy, reset the FIFO read and write counters */ |
| 133 | | if (busy == 0) { |
| 150 | register int busy = GET_ETH_IBUSY(m_eth.status) | GET_ETH_OBUSY(m_eth.status); |
| 151 | if (0 == busy) { |
| 152 | // if not busy, reset the FIFO read and write counters |
| 134 | 153 | m_eth.fifo_rd = 0; |
| 135 | 154 | m_eth.fifo_wr = 0; |
| 136 | 155 | } |
| r26318 | r26319 | |
| 178 | 197 | * |
| 179 | 198 | * IDR' = (IBUSY & (BNNE & (BNE' & ETAC')')')' |
| 180 | 199 | */ |
| 181 | | idr = GET_ETH_IBUSY(m_eth.status) && (ETHER_A49_BNNE || (ETHER_A49_BNE == 0 && etac)); |
| 200 | register int idr = GET_ETH_IBUSY(m_eth.status) && (ETHER_A49_BNNE || (ETHER_A49_BNE == 0 && etac)); |
| 182 | 201 | if (idr) { |
| 183 | 202 | m_task_wakeup |= 1 << task_ether; |
| 184 | 203 | LOG((LOG_ETH,0,"input data ready\n")); |
| r26318 | r26319 | |
| 194 | 213 | * |
| 195 | 214 | * ODR' = (OBUSY & OEOT' & (BF' & WLF')')' |
| 196 | 215 | */ |
| 197 | | odr = GET_ETH_OBUSY(m_eth.status) && (GET_ETH_OEOT(m_eth.status) || (GET_ETH_WLF(m_eth.status) && ETHER_A49_BF == 0)); |
| 216 | register int odr = GET_ETH_OBUSY(m_eth.status) && (GET_ETH_OEOT(m_eth.status) || (GET_ETH_WLF(m_eth.status) && ETHER_A49_BF == 0)); |
| 198 | 217 | if (odr) { |
| 199 | 218 | m_task_wakeup |= 1 << task_ether; |
| 200 | 219 | LOG((LOG_ETH,0,"output data ready\n")); |
| r26318 | r26319 | |
| 204 | 223 | /* |
| 205 | 224 | * EWFCT (ether wake function) conditions to wakeup the Ether task: |
| 206 | 225 | * EWFCT flip flop set by the F1 EWFCT |
| 207 | | * The task is activated by the display.c code together with the |
| 208 | | * next wakeup of the MRT (memory refresh task). |
| 226 | * The task is activated by the display code together with the |
| 227 | * next wakeup of the memory refresh task (MRT). |
| 209 | 228 | */ |
| 210 | 229 | if (m_ewfct) { |
| 211 | 230 | m_task_wakeup |= 1 << task_ether; |
| r26318 | r26319 | |
| 213 | 232 | return; |
| 214 | 233 | } |
| 215 | 234 | |
| 216 | | /* otherwise no more wakeup for the Ether task */ |
| 235 | // otherwise no more wakeups for the ether task |
| 217 | 236 | LOG((LOG_ETH,0,"-/-\n")); |
| 218 | 237 | m_task_wakeup &= ~(1 << task_ether); |
| 219 | 238 | } |
| r26318 | r26319 | |
| 305 | 324 | * H H H X^16+x^11+x^4+1 CRC-CCITT reverse |
| 306 | 325 | * |
| 307 | 326 | * </PRE> |
| 308 | | * The Alto Ethernet interface seems to be using the last one of polynomials, |
| 309 | | * or perhaps something entirely different. |
| 327 | * The Alto ethernet interface seems to be using the last one of the polynomials, |
| 328 | * or perhaps something entirely different? |
| 310 | 329 | * |
| 311 | 330 | * TODO: verify polynomial generator; build a lookup table to make it faster. |
| 312 | 331 | * |
| r26318 | r26319 | |
| 337 | 356 | UINT32 data; |
| 338 | 357 | |
| 339 | 358 | if (arg == 0) { |
| 340 | | /* first word: set the IBUSY flip flop */ |
| 359 | // first word: set the IBUSY flip flop |
| 341 | 360 | PUT_ETH_IBUSY(m_eth.status, 1); |
| 361 | m_eth.rx_count = 0; |
| 342 | 362 | } |
| 343 | 363 | |
| 344 | 364 | data = duckbreath_data[arg++]; |
| r26318 | r26319 | |
| 347 | 367 | m_eth.fifo[m_eth.fifo_wr] = data; |
| 348 | 368 | m_eth.fifo_wr = (m_eth.fifo_wr + 1) % ALTO2_ETHER_FIFO_SIZE; |
| 349 | 369 | |
| 370 | if (m_eth.rx_count < ALTO2_ETHER_PACKET_SIZE) |
| 371 | m_eth.rx_packet[m_eth.rx_count] = data; |
| 372 | m_eth.rx_count++; |
| 373 | |
| 350 | 374 | PUT_ETH_WLF(m_eth.status, 1); |
| 351 | 375 | if (ETHER_A49_BF == 0) { |
| 352 | 376 | /* fifo is overrun: set input data late flip flop */ |
| r26318 | r26319 | |
| 362 | 386 | * and set the CRC error flag if they differ. |
| 363 | 387 | */ |
| 364 | 388 | m_eth.rx_crc = 0; |
| 365 | | /* set the IGONE flip flop */ |
| 389 | |
| 390 | // set the IGONE flip flop |
| 366 | 391 | PUT_ETH_IGONE(m_eth.status, 1); |
| 367 | | |
| 368 | | m_eth.tx_timer->adjust(attotime::from_seconds(m_duckbreath_sec), 0); |
| 392 | #if DEBUG_PACKETS |
| 393 | dump_packet(m_eth.rx_packet, 0, m_eth.rx_count); |
| 394 | #endif |
| 395 | m_eth.rx_timer->adjust(attotime::from_seconds(m_duckbreath_sec), 0); |
| 369 | 396 | } else { |
| 370 | | /* 5.44us per word (?) */ |
| 371 | | m_eth.tx_timer->adjust(attotime::from_usec(5.44), arg); |
| 397 | // receive at a rate of 5.44us per word |
| 398 | m_eth.rx_timer->adjust(attotime::from_usec(5.44), arg); |
| 372 | 399 | } |
| 373 | | |
| 374 | 400 | eth_wakeup(); |
| 375 | 401 | } |
| 376 | 402 | |
| r26318 | r26319 | |
| 384 | 410 | { |
| 385 | 411 | UINT32 data; |
| 386 | 412 | |
| 387 | | /* last word is the CRC */ |
| 388 | | if (arg == -1) { |
| 389 | | if (m_eth.tx_timer) |
| 390 | | m_eth.tx_timer->enable(false); |
| 391 | | /* TODO: send the CRC as final word of the packet */ |
| 413 | // the last word sent is the CRC |
| 414 | if (-1 == arg) { |
| 415 | m_eth.tx_timer->reset(); |
| 392 | 416 | LOG((LOG_ETH,0," CRC:%06o\n", m_eth.tx_crc)); |
| 417 | #if DEBUG_PACKETS |
| 418 | dump_packet(m_eth.tx_packet, 0, m_eth.tx_count); |
| 419 | #endif |
| 420 | // TODO: send the CRC as final word of the packet |
| 393 | 421 | m_eth.tx_crc = 0; |
| 394 | 422 | PUT_ETH_OGONE(m_eth.status, 1); // set the OGONE flip flop |
| 395 | 423 | eth_wakeup(); |
| r26318 | r26319 | |
| 398 | 426 | |
| 399 | 427 | data = m_eth.fifo[m_eth.fifo_rd]; |
| 400 | 428 | m_eth.tx_crc = f9401_7(m_eth.tx_crc, data); |
| 401 | | if (m_eth.fifo_rd % 8) |
| 402 | | LOG((LOG_ETH,0," %06o", data)); |
| 403 | | else |
| 404 | | LOG((LOG_ETH,0,"\n%06o: %06o", m_eth.tx_count, data)); |
| 405 | 429 | m_eth.fifo_rd = (m_eth.fifo_rd + 1) % ALTO2_ETHER_FIFO_SIZE; |
| 430 | |
| 431 | if (m_eth.tx_count < ALTO2_ETHER_PACKET_SIZE) |
| 432 | m_eth.tx_packet[m_eth.tx_count] = data; |
| 406 | 433 | m_eth.tx_count++; |
| 407 | 434 | |
| 408 | | /* is the FIFO empty now? */ |
| 435 | // is the FIFO empty now? |
| 409 | 436 | if (ETHER_A49_BE) { |
| 410 | 437 | /* clear the OBUSY and WLF flip flops */ |
| 411 | 438 | PUT_ETH_OBUSY(m_eth.status, 0); |
| 412 | 439 | PUT_ETH_WLF(m_eth.status, 0); |
| 413 | | // FIXME: Use MAME timer |
| 414 | | // m_eth.tx_id = timer_insert(TIME_US(5.44), tx_packet, -1, "tx packet CRC"); |
| 440 | m_eth.tx_timer->adjust(attotime::from_usec(5.44), -1); |
| 415 | 441 | eth_wakeup(); |
| 416 | 442 | return; |
| 417 | 443 | } |
| 418 | 444 | |
| 419 | | /* next word */ |
| 420 | | // FIXME: Use MAME timer |
| 421 | | // m_eth.tx_id = timer_insert(TIME_US(5.44), tx_packet, arg + 1, "tx packet"); |
| 445 | /* transmit teh next word after 5.44µs */ |
| 446 | m_eth.tx_timer->adjust(attotime::from_usec(5.44), arg + 1); |
| 422 | 447 | eth_wakeup(); |
| 423 | 448 | } |
| 424 | 449 | |
| 450 | /** |
| 451 | * @brief ethernet start function - called from the emulator task |
| 452 | */ |
| 425 | 453 | void alto2_cpu_device::eth_startf() |
| 426 | 454 | { |
| 427 | 455 | PUT_ETH_ICMD(m_eth.status, X_BIT(m_bus,16,14)); |
| r26318 | r26319 | |
| 431 | 459 | } |
| 432 | 460 | |
| 433 | 461 | /** |
| 434 | | * @brief bs_eidfct early: Ethernet input data function |
| 462 | * @brief ethernet input data function |
| 435 | 463 | * |
| 436 | 464 | * Gates the contents of the FIFO to BUS[0-15], and increments |
| 437 | 465 | * the read pointer at the end of the cycle. |
| r26318 | r26319 | |
| 443 | 471 | LOG((LOG_ETH,3, " ←EIDFCT; pull %06o from FIFO[%02o]\n", r, m_eth.fifo_rd)); |
| 444 | 472 | m_eth.fifo_rd = (m_eth.fifo_rd + 1) % ALTO2_ETHER_FIFO_SIZE; |
| 445 | 473 | m_bus &= r; |
| 446 | | m_eth.rx_count++; |
| 447 | | |
| 448 | 474 | eth_wakeup(); |
| 449 | 475 | } |
| 450 | 476 | |
| 451 | 477 | /** |
| 452 | | * @brief f1_eth_block early: block the Ether task |
| 478 | * @brief block the ethernet task |
| 453 | 479 | */ |
| 454 | 480 | void alto2_cpu_device::f1_early_eth_block() |
| 455 | 481 | { |
| r26318 | r26319 | |
| 458 | 484 | } |
| 459 | 485 | |
| 460 | 486 | /** |
| 461 | | * @brief f1_eilfct early: Ethernet input look function |
| 487 | * @brief ethernet input look function |
| 462 | 488 | * |
| 463 | 489 | * Gates the contents of the FIFO to BUS[0-15], but does not |
| 464 | 490 | * increment the read pointer; |
| r26318 | r26319 | |
| 471 | 497 | } |
| 472 | 498 | |
| 473 | 499 | /** |
| 474 | | * @brief f1_epfct early: Ethernet post function |
| 500 | * @brief ethernet post function |
| 475 | 501 | * |
| 476 | 502 | * Gates the interface status to BUS[8-15]. Resets the interface |
| 477 | 503 | * at the end of the function. |
| 478 | 504 | * |
| 479 | 505 | * The schematics suggest that just BUS[10-15] is modified. |
| 480 | 506 | * |
| 481 | | * Also a comment from the microcode: |
| 507 | * Also a comment from the microcode suggests this: |
| 508 | *<PRE> |
| 482 | 509 | * ;Ether Post Function - EPFCT. Gate the hardware status |
| 483 | 510 | * ;(LOW TRUE) to Bus [10:15], reset interface. |
| 484 | | * |
| 511 | *</PRE> |
| 485 | 512 | */ |
| 486 | 513 | void alto2_cpu_device::f1_early_epfct() |
| 487 | 514 | { |
| 488 | 515 | UINT16 r = ~X_RDBITS(m_eth.status,16,10,15) & 0177777; |
| 489 | 516 | |
| 490 | 517 | LOG((LOG_ETH,3, " ←EPFCT; BUS[8-15] = STATUS (%#o)\n", r)); |
| 518 | LOG((LOG_ETH,5, " IDL : %u\n", GET_ETH_IDL(m_eth.status))); |
| 519 | LOG((LOG_ETH,5, " COLL : %u\n", GET_ETH_COLL(m_eth.status))); |
| 520 | LOG((LOG_ETH,5, " CRC : %u\n", GET_ETH_CRC(m_eth.status))); |
| 521 | LOG((LOG_ETH,5, " ICMD : %u\n", GET_ETH_ICMD(m_eth.status))); |
| 522 | LOG((LOG_ETH,5, " OCMD : %u\n", GET_ETH_OCMD(m_eth.status))); |
| 523 | LOG((LOG_ETH,5, " IT : %u\n", GET_ETH_IT(m_eth.status))); |
| 524 | |
| 491 | 525 | m_bus &= r; |
| 492 | 526 | |
| 493 | 527 | m_eth.status = 0; |
| 528 | m_eth.tx_count = 0; |
| 494 | 529 | eth_wakeup(); |
| 495 | 530 | } |
| 496 | 531 | |
| 497 | 532 | /** |
| 498 | | * @brief f1_ewfct late: Ethernet countdown wakeup function |
| 533 | * @brief ethernet countdown wakeup function |
| 499 | 534 | * |
| 500 | 535 | * Sets a flip flop in the interface that will cause a wakeup to the |
| 501 | 536 | * Ether task on the next tick of SWAKMRT (memory refresh task). |
| r26318 | r26319 | |
| 512 | 547 | } |
| 513 | 548 | |
| 514 | 549 | /** |
| 515 | | * @brief f2_eodfct late: Ethernet output data function |
| 550 | * @brief ethernet output data function |
| 516 | 551 | * |
| 517 | 552 | * Loads the FIFO from BUS[0-15], then increments the write |
| 518 | 553 | * pointer at the end of the cycle. |
| r26318 | r26319 | |
| 526 | 561 | |
| 527 | 562 | PUT_ETH_WLF(m_eth.status, 1); |
| 528 | 563 | PUT_ETH_OBUSY(m_eth.status, 1); |
| 529 | | /* if the FIFO is full */ |
| 530 | | if (ETHER_A49_BF == 0) { |
| 531 | | if (!m_eth.tx_timer) { |
| 532 | | m_eth.tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(alto2_cpu_device::tx_packet),this)); |
| 533 | | } |
| 534 | | } |
| 564 | // if the FIFO is full, kick off the timer |
| 565 | if (0 == ETHER_A49_BF) |
| 566 | m_eth.tx_timer->adjust(attotime::from_usec(5.44), 0); |
| 535 | 567 | eth_wakeup(); |
| 536 | 568 | } |
| 537 | 569 | |
| 538 | 570 | /** |
| 539 | | * @brief f2_eosfct late: Ethernet output start function |
| 571 | * @brief f2_eosfct late: ethernet output start function |
| 540 | 572 | * |
| 541 | 573 | * Sets the OBUSY flip flop in the interface, starting data |
| 542 | 574 | * wakeups to fill the FIFO for output. When the FIFO is full, |
| r26318 | r26319 | |
| 552 | 584 | } |
| 553 | 585 | |
| 554 | 586 | /** |
| 555 | | * @brief f2_erbfct late: Ethernet reset branch function |
| 587 | * @brief f2_erbfct late: ethernet reset branch function |
| 556 | 588 | * |
| 557 | 589 | * This command dispatch function merges the ICMD and OCMD flip flops |
| 558 | 590 | * into NEXT[6-7]. These flip flops are the means of communication |
| 559 | | * between the emulator task and the Ethernet task. The emulator |
| 591 | * between the emulator task and the ethernet task. The emulator |
| 560 | 592 | * task sets them up from BUS[14-15] with the STARTF function, |
| 561 | | * causing the Ethernet task to wakeup, dispatch on them and then |
| 593 | * causing the ethernet task to wakeup, dispatch on them and then |
| 562 | 594 | * reset them with EPFCT. |
| 563 | 595 | */ |
| 564 | 596 | void alto2_cpu_device::f2_late_erbfct() |
| r26318 | r26319 | |
| 572 | 604 | } |
| 573 | 605 | |
| 574 | 606 | /** |
| 575 | | * @brief f2_eefct late: Ethernet end of transmission function |
| 607 | * @brief ethernet end of transmission function |
| 576 | 608 | * |
| 577 | 609 | * This function is issued when all of the main memory output buffer |
| 578 | 610 | * has been transferred to the FIFO. EEFCT disables further data |
| r26318 | r26319 | |
| 580 | 612 | */ |
| 581 | 613 | void alto2_cpu_device::f2_late_eefct() |
| 582 | 614 | { |
| 583 | | /* start transmitting the packet */ |
| 584 | 615 | PUT_ETH_OBUSY(m_eth.status, 1); |
| 585 | 616 | PUT_ETH_OEOT(m_eth.status, 1); |
| 586 | | if (m_eth.tx_timer) { |
| 587 | | m_eth.tx_timer->enable(); |
| 588 | | } else { |
| 589 | | m_eth.tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(alto2_cpu_device::tx_packet),this)); |
| 590 | | m_eth.tx_timer->adjust(attotime::from_usec(5.44), 0); |
| 591 | | } |
| 617 | // end transmitting the packet |
| 618 | m_eth.tx_timer->adjust(attotime::from_usec(5.44), -1); |
| 592 | 619 | eth_wakeup(); |
| 593 | 620 | } |
| 594 | 621 | |
| 595 | 622 | /** |
| 596 | | * @brief f2_ebfct late: Ethernet branch function |
| 623 | * @brief ethernet branch function |
| 597 | 624 | * |
| 598 | | * ORs a 1 into NEXT[7] if an input data late is detected, or an SIO |
| 599 | | * with AC0[14-15] non-zero is issued, or if the transmitter or |
| 600 | | * receiver is gone. ORs a 1 into NEXT[6] if a collision is detected. |
| 625 | * ORs a 1 into NEXT[6] if a collision is detected. |
| 626 | * ORs a 1 into NEXT[7] if an input data late is detected, |
| 627 | * or a SIO with AC0[14-15] non-zero is issued, |
| 628 | * or if the transmitter is gone |
| 629 | * or if the receiver is gone. |
| 601 | 630 | */ |
| 602 | 631 | void alto2_cpu_device::f2_late_ebfct() |
| 603 | 632 | { |
| r26318 | r26319 | |
| 613 | 642 | } |
| 614 | 643 | |
| 615 | 644 | /** |
| 616 | | * @brief f2_ecbfct late: Ethernet countdown branch function |
| 645 | * @brief f2_ecbfct late: ethernet countdown branch function |
| 617 | 646 | * |
| 618 | 647 | * ORs a one into NEXT[7] if the FIFO is not empty. |
| 619 | 648 | */ |
| r26318 | r26319 | |
| 627 | 656 | } |
| 628 | 657 | |
| 629 | 658 | /** |
| 630 | | * @brief f2_eisfct late: Ethernet input start function |
| 659 | * @brief f2_eisfct late: ethernet input start function |
| 631 | 660 | * |
| 632 | 661 | * Sets the IBUSY flip flop in the interface, causing it to hunt |
| 633 | 662 | * for the beginning of a packet: silence on the Ether followed |
| r26318 | r26319 | |
| 641 | 670 | eth_wakeup(); |
| 642 | 671 | } |
| 643 | 672 | |
| 644 | | /** @brief called by the CPU when the Ethernet task becomes active |
| 673 | /** @brief called by the CPU when the ethernet task becomes active |
| 645 | 674 | * |
| 646 | 675 | * Reset the Ether wake flip flop |
| 647 | 676 | */ |
| r26318 | r26319 | |
| 651 | 680 | } |
| 652 | 681 | |
| 653 | 682 | /** |
| 654 | | * @brief Ethernet task slot initialization |
| 683 | * @brief ethernet task slot initialization |
| 655 | 684 | */ |
| 656 | 685 | void alto2_cpu_device::init_ether(int task) |
| 657 | 686 | { |
| 658 | 687 | // intialize all ethernet variables |
| 659 | 688 | memset(&m_eth, 0, sizeof(m_eth)); |
| 660 | 689 | |
| 690 | // FIXME: read configuration for m_eth.duckbreath enable |
| 691 | |
| 661 | 692 | set_bs(task, bs_ether_eidfct, &alto2_cpu_device::bs_early_eidfct, 0); |
| 662 | 693 | |
| 663 | 694 | set_f1(task, f1_block, &alto2_cpu_device::f1_early_eth_block, 0); |
| r26318 | r26319 | |
| 674 | 705 | set_f2(task, f2_ether_eisfct, 0, &alto2_cpu_device::f2_late_eisfct); |
| 675 | 706 | |
| 676 | 707 | m_active_callback[task] = &alto2_cpu_device::activate_eth; |
| 708 | |
| 709 | m_eth.rx_packet = auto_alloc_array(machine(), UINT16, sizeof(UINT16)*ALTO2_ETHER_PACKET_SIZE); |
| 710 | m_eth.tx_packet = auto_alloc_array(machine(), UINT16, sizeof(UINT16)*ALTO2_ETHER_PACKET_SIZE); |
| 711 | |
| 712 | m_eth.tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(alto2_cpu_device::tx_packet),this)); |
| 713 | m_eth.tx_timer->reset(); |
| 714 | |
| 715 | m_eth.rx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(alto2_cpu_device::rx_duckbreath),this)); |
| 716 | if (m_eth.duckbreath) |
| 717 | m_eth.rx_timer->adjust(attotime::from_seconds(m_duckbreath_sec), 0); |
| 718 | else |
| 719 | m_eth.rx_timer->reset(); |
| 677 | 720 | } |
| 678 | 721 | |
| 679 | 722 | void alto2_cpu_device::exit_ether() |
branches/alto2/src/mess/drivers/alto2.c
| r26318 | r26319 | |
| 10 | 10 | |
| 11 | 11 | /* Input Ports */ |
| 12 | 12 | |
| 13 | #define PORT_KEY(_bit,_code,_char1,_char2,_name) \ |
| 14 | PORT_BIT(_bit, IP_ACTIVE_LOW, IPT_KEYBOARD) \ |
| 15 | PORT_CODE(_code) PORT_NAME(_name) \ |
| 16 | PORT_CHAR(_char1) PORT_CHAR(_char2) \ |
| 17 | |
| 18 | #define SPACING " " |
| 19 | |
| 13 | 20 | static INPUT_PORTS_START( alto2 ) |
| 14 | 21 | PORT_START("ROW0") |
| 15 | | PORT_BIT(A2_KEY_5, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') //!< normal: 5 shifted: % |
| 16 | | PORT_BIT(A2_KEY_4, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') //!< normal: 4 shifted: $ |
| 17 | | PORT_BIT(A2_KEY_6, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6 ~") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('~') //!< normal: 6 shifted: ~ |
| 18 | | PORT_BIT(A2_KEY_E, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("e E") PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') //!< normal: e shifted: E |
| 19 | | PORT_BIT(A2_KEY_7, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7 &") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') //!< normal: 7 shifted: & |
| 20 | | PORT_BIT(A2_KEY_D, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("d D") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') //!< normal: d shifted: D |
| 21 | | PORT_BIT(A2_KEY_U, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("u U") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') //!< normal: u shifted: U |
| 22 | | PORT_BIT(A2_KEY_V, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("v V") PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') //!< normal: v shifted: V |
| 23 | | PORT_BIT(A2_KEY_0, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0 )") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') //!< normal: 0 shifted: ) |
| 24 | | PORT_BIT(A2_KEY_K, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("k K") PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') //!< normal: k shifted: K |
| 25 | | PORT_BIT(A2_KEY_MINUS, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("- _") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') //!< normal: - shifted: _ |
| 26 | | PORT_BIT(A2_KEY_P, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("p P") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') //!< normal: p shifted: P |
| 27 | | PORT_BIT(A2_KEY_SLASH, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') //!< normal: / shifted: ? |
| 28 | | PORT_BIT(A2_KEY_BACKSLASH, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\ |") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') //!< normal: \ shifted: | |
| 29 | | PORT_BIT(A2_KEY_LF, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LF") PORT_CODE(KEYCODE_DOWN) PORT_CHAR('\012') //!< normal: LF shifted: ? |
| 30 | | PORT_BIT(A2_KEY_BS, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BS") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR('\010') //!< normal: BS shifted: ? |
| 22 | PORT_KEY(A2_KEY_5, KEYCODE_5, '5', '%', "5" SPACING "%") //!< normal: 5 shifted: % |
| 23 | PORT_KEY(A2_KEY_4, KEYCODE_4, '4', '$', "4" SPACING "$") //!< normal: 4 shifted: $ |
| 24 | PORT_KEY(A2_KEY_6, KEYCODE_6, '6', '~', "6" SPACING "~") //!< normal: 6 shifted: ~ |
| 25 | PORT_KEY(A2_KEY_E, KEYCODE_E, 'e', 'E', "e" SPACING "E") //!< normal: e shifted: E |
| 26 | PORT_KEY(A2_KEY_7, KEYCODE_7, '7', '&', "7" SPACING "&") //!< normal: 7 shifted: & |
| 27 | PORT_KEY(A2_KEY_D, KEYCODE_D, 'd', 'D', "d" SPACING "D") //!< normal: d shifted: D |
| 28 | PORT_KEY(A2_KEY_U, KEYCODE_U, 'u', 'U', "u" SPACING "U") //!< normal: u shifted: U |
| 29 | PORT_KEY(A2_KEY_V, KEYCODE_V, 'v', 'V', "v" SPACING "V") //!< normal: v shifted: V |
| 30 | PORT_KEY(A2_KEY_0, KEYCODE_0, '0', ')', "0" SPACING ")") //!< normal: 0 shifted: ) |
| 31 | PORT_KEY(A2_KEY_K, KEYCODE_K, 'k', 'K', "k" SPACING "K") //!< normal: k shifted: K |
| 32 | PORT_KEY(A2_KEY_MINUS, KEYCODE_MINUS, '-', '_', "-" SPACING "_") //!< normal: - shifted: _ |
| 33 | PORT_KEY(A2_KEY_P, KEYCODE_P, 'p', 'P', "p" SPACING "P") //!< normal: p shifted: P |
| 34 | PORT_KEY(A2_KEY_SLASH, KEYCODE_SLASH, '/', '?', "/" SPACING "?") //!< normal: / shifted: ? |
| 35 | PORT_KEY(A2_KEY_BACKSLASH, KEYCODE_BACKSLASH, '\\', '|', "\\" SPACING "|") //!< normal: \ shifted: | |
| 36 | PORT_KEY(A2_KEY_LF, KEYCODE_DOWN, '\012', 0, "LF" ) //!< normal: LF shifted: ? |
| 37 | PORT_KEY(A2_KEY_BS, KEYCODE_BACKSPACE, '\010', 0, "BS" ) //!< normal: BS shifted: ? |
| 31 | 38 | |
| 32 | 39 | PORT_START("ROW1") |
| 33 | | PORT_BIT(A2_KEY_3, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') //!< normal: 3 shifted: # |
| 34 | | PORT_BIT(A2_KEY_2, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2 @") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') //!< normal: 2 shifted: @ |
| 35 | | PORT_BIT(A2_KEY_W, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("w W") PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') //!< normal: w shifted: W |
| 36 | | PORT_BIT(A2_KEY_Q, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("q Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') //!< normal: q shifted: Q |
| 37 | | PORT_BIT(A2_KEY_S, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("s S") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') //!< normal: s shifted: S |
| 38 | | PORT_BIT(A2_KEY_A, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("a A") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') //!< normal: a shifted: A |
| 39 | | PORT_BIT(A2_KEY_9, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9 (") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') //!< normal: 9 shifted: ( |
| 40 | | PORT_BIT(A2_KEY_I, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("i I") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') //!< normal: i shifted: I |
| 41 | | PORT_BIT(A2_KEY_X, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("x X") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') //!< normal: x shifted: X |
| 42 | | PORT_BIT(A2_KEY_O, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("o O") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') //!< normal: o shifted: O |
| 43 | | PORT_BIT(A2_KEY_L, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("l L") PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') //!< normal: l shifted: L |
| 44 | | PORT_BIT(A2_KEY_COMMA, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') //!< normal: , shifted: < |
| 45 | | PORT_BIT(A2_KEY_QUOTE, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("' \"") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\x27') PORT_CHAR('"') //!< normal: ' shifted: " |
| 46 | | PORT_BIT(A2_KEY_RBRACKET, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("] }") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') //!< normal: ] shifted: } |
| 47 | | PORT_BIT(A2_KEY_BLANK_MID, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M[ ]") PORT_CODE(KEYCODE_END) //!< middle blank key |
| 48 | | PORT_BIT(A2_KEY_BLANK_TOP, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T[ ]") PORT_CODE(KEYCODE_PGUP) //!< top blank key |
| 40 | PORT_KEY(A2_KEY_3, KEYCODE_3, '3', '#', "3" SPACING "#") //!< normal: 3 shifted: # |
| 41 | PORT_KEY(A2_KEY_2, KEYCODE_2, '2', '@', "2" SPACING "@") //!< normal: 2 shifted: @ |
| 42 | PORT_KEY(A2_KEY_W, KEYCODE_W, 'w', 'W', "w" SPACING "W") //!< normal: w shifted: W |
| 43 | PORT_KEY(A2_KEY_Q, KEYCODE_Q, 'q', 'Q', "q" SPACING "Q") //!< normal: q shifted: Q |
| 44 | PORT_KEY(A2_KEY_S, KEYCODE_S, 's', 'S', "s" SPACING "S") //!< normal: s shifted: S |
| 45 | PORT_KEY(A2_KEY_A, KEYCODE_A, 'a', 'A', "a" SPACING "A") //!< normal: a shifted: A |
| 46 | PORT_KEY(A2_KEY_9, KEYCODE_9, '9', '(', "9" SPACING "(") //!< normal: 9 shifted: ( |
| 47 | PORT_KEY(A2_KEY_I, KEYCODE_I, 'i', 'I', "i" SPACING "I") //!< normal: i shifted: I |
| 48 | PORT_KEY(A2_KEY_X, KEYCODE_X, 'x', 'X', "x" SPACING "X") //!< normal: x shifted: X |
| 49 | PORT_KEY(A2_KEY_O, KEYCODE_O, 'o', 'O', "o" SPACING "O") //!< normal: o shifted: O |
| 50 | PORT_KEY(A2_KEY_L, KEYCODE_L, 'l', 'L', "l" SPACING "L") //!< normal: l shifted: L |
| 51 | PORT_KEY(A2_KEY_COMMA, KEYCODE_COMMA, ',', '<', "," SPACING "<") //!< normal: , shifted: < |
| 52 | PORT_KEY(A2_KEY_QUOTE, KEYCODE_QUOTE, '\x27', '"', "'" SPACING "\"") //!< normal: ' shifted: " |
| 53 | PORT_KEY(A2_KEY_RBRACKET, KEYCODE_CLOSEBRACE, ']', '}', "]" SPACING "}") //!< normal: ] shifted: } |
| 54 | PORT_KEY(A2_KEY_BLANK_MID, KEYCODE_END, 0, 0, "MID" ) //!< middle blank key |
| 55 | PORT_KEY(A2_KEY_BLANK_TOP, KEYCODE_PGUP, 0, 0, "TOP" ) //!< top blank key |
| 49 | 56 | |
| 50 | 57 | PORT_START("ROW2") |
| 51 | | PORT_BIT(A2_KEY_1, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') //!< normal: 1 shifted: ! |
| 52 | | PORT_BIT(A2_KEY_ESCAPE, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR('\x1b') //!< normal: ESC shifted: ? |
| 53 | | PORT_BIT(A2_KEY_TAB, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR('\011') //!< normal: TAB shifted: ? |
| 54 | | PORT_BIT(A2_KEY_F, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("f F") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') //!< normal: f shifted: F |
| 55 | | PORT_BIT(A2_KEY_CTRL, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) //!< CTRL |
| 56 | | PORT_BIT(A2_KEY_C, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("c C") PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') //!< normal: c shifted: C |
| 57 | | PORT_BIT(A2_KEY_J, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("j J") PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') //!< normal: j shifted: J |
| 58 | | PORT_BIT(A2_KEY_B, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("b B") PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') //!< normal: b shifted: B |
| 59 | | PORT_BIT(A2_KEY_Z, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("z Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') //!< normal: z shifted: Z |
| 60 | | PORT_BIT(A2_KEY_LSHIFT, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LSHIFT") PORT_CODE(KEYCODE_LSHIFT) //!< LSHIFT |
| 61 | | PORT_BIT(A2_KEY_PERIOD, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') //!< normal: . shifted: > |
| 62 | | PORT_BIT(A2_KEY_SEMICOLON, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("; :") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':')//!< normal: ; shifted: : |
| 63 | | PORT_BIT(A2_KEY_RETURN, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR('\013') //!< RETURN |
| 64 | | PORT_BIT(A2_KEY_LEFTARROW, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("← ↑") PORT_CODE(KEYCODE_LEFT) //!< normal: left arrow shifted: up arrow (caret) |
| 65 | | PORT_BIT(A2_KEY_DEL, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) //!< normal: DEL shifted: ? |
| 66 | | PORT_BIT(A2_KEY_MSW_2_17, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2/17") PORT_CODE(KEYCODE_MENU) //!< unused on Microswitch KDB |
| 58 | PORT_KEY(A2_KEY_1, KEYCODE_1, '1', '!', "1" SPACING "!") //!< normal: 1 shifted: ! |
| 59 | PORT_KEY(A2_KEY_ESCAPE, KEYCODE_ESC, '\x1b', 0, "ESC" ) //!< normal: ESC shifted: ? |
| 60 | PORT_KEY(A2_KEY_TAB, KEYCODE_TAB, '\011', 0, "TAB" ) //!< normal: TAB shifted: ? |
| 61 | PORT_KEY(A2_KEY_F, KEYCODE_F, 'f', 'F', "f" SPACING "F") //!< normal: f shifted: F |
| 62 | PORT_KEY(A2_KEY_CTRL, KEYCODE_LCONTROL, 0, 0, "CTRL" ) //!< CTRL |
| 63 | PORT_KEY(A2_KEY_C, KEYCODE_C, 'c', 'C', "c" SPACING "C") //!< normal: c shifted: C |
| 64 | PORT_KEY(A2_KEY_J, KEYCODE_J, 'j', 'J', "j" SPACING "J") //!< normal: j shifted: J |
| 65 | PORT_KEY(A2_KEY_B, KEYCODE_B, 'b', 'B', "b" SPACING "B") //!< normal: b shifted: B |
| 66 | PORT_KEY(A2_KEY_Z, KEYCODE_Z, 'z', 'Z', "z" SPACING "Z") //!< normal: z shifted: Z |
| 67 | PORT_KEY(A2_KEY_LSHIFT, KEYCODE_LSHIFT, 0, 0, "LSHIFT" ) //!< LSHIFT |
| 68 | PORT_KEY(A2_KEY_PERIOD, KEYCODE_STOP, '.', '>', "." SPACING ">") //!< normal: . shifted: > |
| 69 | PORT_KEY(A2_KEY_SEMICOLON, KEYCODE_COLON, ';', ':', ";" SPACING ":") //!< normal: ; shifted: : |
| 70 | PORT_KEY(A2_KEY_RETURN, KEYCODE_ENTER, '\013', 0, "RETURN" ) //!< RETURN |
| 71 | PORT_KEY(A2_KEY_LEFTARROW, KEYCODE_LEFT, 0, 0, "←" SPACING "↑") //!< normal: left arrow shifted: up arrow (caret) |
| 72 | PORT_KEY(A2_KEY_DEL, KEYCODE_DEL, 0, 0, "DEL" ) //!< normal: DEL shifted: ? |
| 73 | PORT_KEY(A2_KEY_MSW_2_17, KEYCODE_MENU, 0, 0, "MSW2/17" ) //!< unused on Microswitch KDB |
| 67 | 74 | |
| 68 | 75 | PORT_START("ROW3") |
| 69 | | PORT_BIT(A2_KEY_R, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("r R") PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') //!< normal: r shifted: R |
| 70 | | PORT_BIT(A2_KEY_T, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("t T") PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') //!< normal: t shifted: T |
| 71 | | PORT_BIT(A2_KEY_G, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("g G") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') //!< normal: g shifted: G |
| 72 | | PORT_BIT(A2_KEY_Y, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("y Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') //!< normal: y shifted: Y |
| 73 | | PORT_BIT(A2_KEY_H, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("h H") PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') //!< normal: h shifted: H |
| 74 | | PORT_BIT(A2_KEY_8, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8 *") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') //!< normal: 8 shifted: * |
| 75 | | PORT_BIT(A2_KEY_N, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("n N") PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') //!< normal: n shifted: N |
| 76 | | PORT_BIT(A2_KEY_M, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("m M") PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') //!< normal: m shifted: M |
| 77 | | PORT_BIT(A2_KEY_LOCK, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LOCK") PORT_CODE(KEYCODE_SCRLOCK) //!< LOCK |
| 78 | | PORT_BIT(A2_KEY_SPACE, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') //!< SPACE |
| 79 | | PORT_BIT(A2_KEY_L, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') //!< normal: [ shifted: { |
| 80 | | PORT_BIT(A2_KEY_EQUALS, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("= +") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') //!< normal: = shifted: + |
| 81 | | PORT_BIT(A2_KEY_RSHIFT, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RSHIFT") PORT_CODE(KEYCODE_RSHIFT) //!< RSHIFT |
| 82 | | PORT_BIT(A2_KEY_BLANK_BOT, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B[ ]") PORT_CODE(KEYCODE_PGDN) //!< bottom blank key |
| 83 | | PORT_BIT(A2_KEY_MSW_3_16, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3/16") PORT_CODE(KEYCODE_HOME) //!< unused on Microswitch KDB |
| 84 | | PORT_BIT(A2_KEY_MSW_3_17, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3/17") PORT_CODE(KEYCODE_INSERT) //!< unused on Microswitch KDB |
| 76 | PORT_KEY(A2_KEY_R, KEYCODE_R, 'r', 'R', "r" SPACING "R") //!< normal: r shifted: R |
| 77 | PORT_KEY(A2_KEY_T, KEYCODE_T, 't', 'T', "t" SPACING "T") //!< normal: t shifted: T |
| 78 | PORT_KEY(A2_KEY_G, KEYCODE_G, 'g', 'G', "g" SPACING "G") //!< normal: g shifted: G |
| 79 | PORT_KEY(A2_KEY_Y, KEYCODE_Y, 'y', 'Y', "y" SPACING "Y") //!< normal: y shifted: Y |
| 80 | PORT_KEY(A2_KEY_H, KEYCODE_H, 'h', 'H', "h" SPACING "H") //!< normal: h shifted: H |
| 81 | PORT_KEY(A2_KEY_8, KEYCODE_8, '8', '*', "8" SPACING "*") //!< normal: 8 shifted: * |
| 82 | PORT_KEY(A2_KEY_N, KEYCODE_N, 'n', 'N', "n" SPACING "N") //!< normal: n shifted: N |
| 83 | PORT_KEY(A2_KEY_M, KEYCODE_M, 'm', 'M', "m" SPACING "M") //!< normal: m shifted: M |
| 84 | PORT_KEY(A2_KEY_LOCK, KEYCODE_SCRLOCK, 0, 0, "LOCK" ) //!< LOCK |
| 85 | PORT_KEY(A2_KEY_SPACE, KEYCODE_SPACE, ' ', 0, "SPACE" ) //!< SPACE |
| 86 | PORT_KEY(A2_KEY_LBRACKET, KEYCODE_OPENBRACE, '[', '{', "[" SPACING "{") //!< normal: [ shifted: { |
| 87 | PORT_KEY(A2_KEY_EQUALS, KEYCODE_EQUALS, '=', '+', "=" SPACING "+") //!< normal: = shifted: + |
| 88 | PORT_KEY(A2_KEY_RSHIFT, KEYCODE_RSHIFT, 0, 0, "RSHIFT" ) //!< RSHIFT |
| 89 | PORT_KEY(A2_KEY_BLANK_BOT, KEYCODE_PGDN, 0, 0, "BOT" ) //!< bottom blank key |
| 90 | PORT_KEY(A2_KEY_MSW_3_16, KEYCODE_HOME, 0, 0, "MSW3/16" ) //!< unused on Microswitch KDB |
| 91 | PORT_KEY(A2_KEY_MSW_3_17, KEYCODE_INSERT, 0, 0, "MSW3/17" ) //!< unused on Microswitch KDB |
| 85 | 92 | |
| 86 | 93 | PORT_START("ROW4") |
| 87 | | PORT_BIT(A2_KEY_FR2, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FR2") PORT_CODE(KEYCODE_F6) //!< ADL right function key 2 |
| 88 | | PORT_BIT(A2_KEY_FL2, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FL2") PORT_CODE(KEYCODE_F2) //!< ADL left function key 2 |
| 94 | PORT_KEY(A2_KEY_FR2, KEYCODE_F6, 0, 0, "FR2" ) //!< ADL right function key 2 |
| 95 | PORT_KEY(A2_KEY_FL2, KEYCODE_F2, 0, 0, "FL2" ) //!< ADL left function key 2 |
| 89 | 96 | |
| 90 | 97 | PORT_START("ROW5") |
| 91 | | PORT_BIT(A2_KEY_FR4, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FR4") PORT_CODE(KEYCODE_F8) //!< ADL right funtion key 4 |
| 92 | | PORT_BIT(A2_KEY_BW, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BW") PORT_CODE(KEYCODE_F10) //!< ADL BW (?) |
| 98 | PORT_KEY(A2_KEY_FR4, KEYCODE_F8, 0, 0, "FR4" ) //!< ADL right funtion key 4 |
| 99 | PORT_KEY(A2_KEY_BW, KEYCODE_F10, 0, 0, "BW" ) //!< ADL BW (?) |
| 93 | 100 | |
| 94 | 101 | PORT_START("ROW6") |
| 95 | | PORT_BIT(A2_KEY_FR3, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FR3") PORT_CODE(KEYCODE_F7) //!< ADL right function key 3 |
| 96 | | PORT_BIT(A2_KEY_FL1, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FL1") PORT_CODE(KEYCODE_F1) //!< ADL left function key 1 |
| 97 | | PORT_BIT(A2_KEY_FL3, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FL3") PORT_CODE(KEYCODE_F3) //!< ADL left function key 3 |
| 102 | PORT_KEY(A2_KEY_FR3, KEYCODE_F7, 0, 0, "FR3" ) //!< ADL right function key 3 |
| 103 | PORT_KEY(A2_KEY_FL1, KEYCODE_F1, 0, 0, "FL1" ) //!< ADL left function key 1 |
| 104 | PORT_KEY(A2_KEY_FL3, KEYCODE_F3, 0, 0, "FL3" ) //!< ADL left function key 3 |
| 98 | 105 | |
| 99 | 106 | PORT_START("ROW7") |
| 100 | | PORT_BIT(A2_KEY_FR1, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FR1") PORT_CODE(KEYCODE_F5) //!< ADL right function key 1 |
| 101 | | PORT_BIT(A2_KEY_FL4, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FL4") PORT_CODE(KEYCODE_F4) //!< ADL left function key 4 |
| 102 | | PORT_BIT(A2_KEY_FR5, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FR5") PORT_CODE(KEYCODE_F9) //!< ADL right function key 5 |
| 107 | PORT_KEY(A2_KEY_FR1, KEYCODE_F5, 0, 0, "FR1" ) //!< ADL right function key 1 |
| 108 | PORT_KEY(A2_KEY_FL4, KEYCODE_F4, 0, 0, "FL4" ) //!< ADL left function key 4 |
| 109 | PORT_KEY(A2_KEY_FR5, KEYCODE_F9, 0, 0, "FR5" ) //!< ADL right function key 5 |
| 103 | 110 | |
| 104 | 111 | PORT_START("mouseb") // Mouse buttons |
| 105 | 112 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Mouse RED (left)") PORT_CODE(MOUSECODE_BUTTON1) PORT_CHANGED_MEMBER( ":maincpu", alto2_cpu_device, mouse_buttons, 0 ) |
| r26318 | r26319 | |
| 113 | 120 | PORT_BIT( 0xffff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(50) PORT_KEYDELTA(1) PORT_PLAYER(1) PORT_CHANGED_MEMBER( ":maincpu", alto2_cpu_device, mouse_motion_y, 0 ) |
| 114 | 121 | |
| 115 | 122 | PORT_START("CONFIG") /* Memory switch on AIM board */ |
| 116 | | PORT_CONFNAME( 1, 1, "Memory switch") |
| 117 | | PORT_CONFSETTING( 0, "on") |
| 118 | | PORT_CONFSETTING( 1, "off") |
| 123 | PORT_CONFNAME( 0x01, 0x01, "Memory switch") |
| 124 | PORT_CONFSETTING( 0x00, "on") |
| 125 | PORT_CONFSETTING( 0x01, "off") |
| 119 | 126 | INPUT_PORTS_END |
| 120 | 127 | |
| 121 | 128 | /* ROM */ |