branches/alto2/src/emu/cpu/alto2/a2ether.c
| r26370 | r26371 | |
| 164 | 164 | #define BF(a49) ((a49 & ether_a49_BF) ? 1 : 0) //! buffer full |
| 165 | 165 | |
| 166 | 166 | #define BREATHLEN ALTO2_ETHER_PACKET_SIZE //!< ethernet packet length |
| 167 | | #define BREATHADDR 0177400 //!< destination and source |
| 168 | | #define BREATHTYPE 0000602 //!< ethernet packet type |
| 169 | | static const UINT16 duckbreath_data[BREATHLEN] = |
| 167 | #define BREATHADDR (0377<<8) //!< destination (0377) and source (0000) |
| 168 | #define BREATHTYPE 0602 //!< ethernet packet type |
| 169 | static const UINT16 breath_of_life_data[BREATHLEN] = |
| 170 | 170 | { |
| 171 | 171 | BREATHADDR, /* 3MB destination and source */ |
| 172 | 172 | BREATHTYPE, /* ether packet type */ |
| r26370 | r26371 | |
| 211 | 211 | #if DEBUG_PACKETS |
| 212 | 212 | static void dump_ascii(const UINT16 *src, size_t size) |
| 213 | 213 | { |
| 214 | | printf(" ["); |
| 214 | logerror(" ["); |
| 215 | 215 | for (size_t offs = 0; offs < size; offs++) { |
| 216 | 216 | char ch1 = src[offs] / 256; |
| 217 | 217 | char ch2 = src[offs] % 256; |
| 218 | | printf("%c", ch1 < 32 || ch1 > 126 ? '.' : ch1); |
| 219 | | printf("%c", ch2 < 32 || ch2 > 126 ? '.' : ch2); |
| 218 | logerror("%c", ch1 < 32 || ch1 > 126 ? '.' : ch1); |
| 219 | logerror("%c", ch2 < 32 || ch2 > 126 ? '.' : ch2); |
| 220 | 220 | } |
| 221 | | printf("]\n"); |
| 221 | logerror("]\n"); |
| 222 | 222 | } |
| 223 | 223 | |
| 224 | | size_t dump_packet(const UINT16 *src, size_t addr, size_t size) |
| 224 | static void dump_packet(const char* name, const UINT16 *src, size_t addr, size_t size) |
| 225 | 225 | { |
| 226 | 226 | size_t offs; |
| 227 | 227 | for (offs = 0; offs < size; offs++) { |
| 228 | 228 | UINT16 word = src[offs]; |
| 229 | 229 | if (offs % 8) { |
| 230 | | printf(" %06o", word); |
| 230 | logerror(" %06o", word); |
| 231 | 231 | } else { |
| 232 | 232 | if (offs > 0) |
| 233 | 233 | dump_ascii(&src[offs-8], 8); |
| 234 | | printf("\t%05o: %06o", static_cast<unsigned>(addr + offs), word); |
| 234 | logerror("%s\t%05o: %06o", name, static_cast<unsigned>(addr + offs), word); |
| 235 | 235 | } |
| 236 | 236 | } |
| 237 | 237 | if (offs % 8) { |
| r26370 | r26371 | |
| 239 | 239 | } else if (offs > 0) { |
| 240 | 240 | dump_ascii(&src[offs - 8], 8); |
| 241 | 241 | } |
| 242 | | return size; |
| 243 | 242 | } |
| 244 | 243 | #endif |
| 245 | 244 | |
| r26370 | r26371 | |
| 448 | 447 | } |
| 449 | 448 | |
| 450 | 449 | /** |
| 451 | | * @brief HACK: pull the next word from the duckbreath_data in the fifo |
| 450 | * @brief HACK: pull the next word from the breath_of_life_data in the fifo |
| 452 | 451 | * |
| 453 | 452 | * This is probably lacking the updates to one or more of |
| 454 | 453 | * the status flip flops. |
| 455 | 454 | */ |
| 456 | | void alto2_cpu_device::rx_duckbreath(void* ptr, INT32 arg) |
| 455 | void alto2_cpu_device::rx_breath_of_life(void* ptr, INT32 arg) |
| 457 | 456 | { |
| 458 | 457 | UINT32 data; |
| 459 | 458 | |
| r26370 | r26371 | |
| 469 | 468 | arg++; |
| 470 | 469 | } else { |
| 471 | 470 | // next data word |
| 472 | | data = duckbreath_data[arg++]; |
| 471 | data = breath_of_life_data[arg++]; |
| 473 | 472 | } |
| 474 | 473 | m_eth.rx_crc = f9401_7(m_eth.rx_crc, data); |
| 475 | 474 | m_eth.fifo[m_eth.fifo_wr] = data; |
| r26370 | r26371 | |
| 489 | 488 | */ |
| 490 | 489 | m_eth.rx_crc = 0; |
| 491 | 490 | PUT_ETH_IGONE(m_eth.status, 1); // set the IGONE flip flop |
| 492 | | m_eth.rx_timer->adjust(attotime::from_seconds(m_duckbreath_sec), 0); |
| 491 | m_eth.rx_timer->adjust(attotime::from_seconds(m_eth.breath_of_life), 0); |
| 493 | 492 | } else { |
| 494 | 493 | // receive at a rate of 5.44us per word |
| 495 | 494 | m_eth.rx_timer->adjust(attotime::from_usec(5.44), arg); |
| r26370 | r26371 | |
| 564 | 563 | m_eth.rx_packet[m_eth.rx_count] = r; |
| 565 | 564 | m_eth.rx_count++; |
| 566 | 565 | if (ALTO2_ETHER_PACKET_SIZE == m_eth.rx_count) { |
| 567 | | dump_packet(m_eth.rx_packet, 0, m_eth.rx_count); |
| 566 | dump_packet("RX", m_eth.rx_packet, 0, m_eth.rx_count); |
| 568 | 567 | m_eth.rx_count = 0; |
| 569 | 568 | } |
| 570 | 569 | #endif |
| r26370 | r26371 | |
| 666 | 665 | m_eth.tx_packet[m_eth.tx_count] = m_bus; |
| 667 | 666 | m_eth.tx_count++; |
| 668 | 667 | if (ALTO2_ETHER_PACKET_SIZE == m_eth.tx_count) { |
| 669 | | dump_packet(m_eth.tx_packet, 0, m_eth.tx_count); |
| 668 | dump_packet("TX", m_eth.tx_packet, 0, m_eth.tx_count); |
| 670 | 669 | m_eth.tx_count = 0; |
| 671 | 670 | } |
| 672 | 671 | #endif |
| r26370 | r26371 | |
| 831 | 830 | m_eth.tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(alto2_cpu_device::tx_packet),this)); |
| 832 | 831 | m_eth.tx_timer->reset(); |
| 833 | 832 | |
| 834 | | m_eth.rx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(alto2_cpu_device::rx_duckbreath),this)); |
| 835 | | if (m_eth.duckbreath) |
| 836 | | m_eth.rx_timer->adjust(attotime::from_seconds(m_eth.duckbreath), 0); |
| 833 | m_eth.rx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(alto2_cpu_device::rx_breath_of_life),this)); |
| 834 | if (m_eth.breath_of_life) |
| 835 | m_eth.rx_timer->adjust(attotime::from_seconds(m_eth.breath_of_life), 0); |
| 837 | 836 | else |
| 838 | 837 | m_eth.rx_timer->reset(); |
| 839 | 838 | } |
| r26370 | r26371 | |
| 843 | 842 | // nothing to do yet |
| 844 | 843 | } |
| 845 | 844 | |
| 846 | | //! delay between two duckbreaths in seconds |
| 847 | | static const int duckbreath_sec[8] = { |
| 845 | //! delay between two breath_of_lifes in seconds |
| 846 | static const int breath_of_life_sec[8] = { |
| 848 | 847 | 0, 5, 10, 15, 30, 60, 90, 120 |
| 849 | 848 | }; |
| 850 | 849 | void alto2_cpu_device::reset_ether() |
| r26370 | r26371 | |
| 862 | 861 | ioport_port* config = ioport(":CONFIG"); |
| 863 | 862 | // config should be valid, unless the driver doesn't define it |
| 864 | 863 | if (config) |
| 865 | | m_eth.duckbreath = duckbreath_sec[(config->read() >> 4) & 7]; |
| 864 | m_eth.breath_of_life = breath_of_life_sec[(config->read() >> 4) & 7]; |
| 866 | 865 | else |
| 867 | | m_eth.duckbreath = 0; |
| 868 | | logerror("Ethernet duckbreath %d sec\n", m_eth.duckbreath); |
| 866 | m_eth.breath_of_life = 0; |
| 867 | logerror("Ethernet breath_of_life %d sec\n", m_eth.breath_of_life); |
| 869 | 868 | } |