From 5710758dd747d4b81a463c933efed4c610caa074 Mon Sep 17 00:00:00 2001 From: joevt Date: Fri, 26 Apr 2024 16:55:37 -0700 Subject: [PATCH] escc: Add z85c30 register names. --- devices/serial/escc.cpp | 182 +++++++++++---------- devices/serial/escc.h | 25 +-- devices/serial/z85c30.h | 350 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 444 insertions(+), 113 deletions(-) create mode 100644 devices/serial/z85c30.h diff --git a/devices/serial/escc.cpp b/devices/serial/escc.cpp index e778dd9..0f8e778 100644 --- a/devices/serial/escc.cpp +++ b/devices/serial/escc.cpp @@ -25,6 +25,7 @@ along with this program. If not, see . #include #include #include +#include #include #include @@ -59,13 +60,13 @@ EsccController::EsccController() ); this->ch_b->attach_backend(CHARIO_BE_NULL); - this->reg_ptr = 0; + this->reg_ptr = WR0; // or RR0 } void EsccController::reset() { - this->master_int_cntrl &= 0xFC; - this->master_int_cntrl |= 0xC0; + this->master_int_cntrl &= ~(WR9_NO_VECTOR | WR9_VECTOR_INCLUDES_STATUS); + this->master_int_cntrl |= WR9_FORCE_HARDWARE_RESET; this->ch_a->reset(true); this->ch_b->reset(true); @@ -77,18 +78,16 @@ uint8_t EsccController::read(uint8_t reg_offset) switch(reg_offset) { case EsccReg::Port_B_Cmd: - LOG_F(9, "ESCC: reading Port B register RR%d", this->reg_ptr); - if (this->reg_ptr == 2) { + if (this->reg_ptr == RR2) { // TODO: implement interrupt vector modifications value = this->int_vec; } else { value = this->ch_b->read_reg(this->reg_ptr); } - this->reg_ptr = 0; + this->reg_ptr = RR0; // or WR0 break; case EsccReg::Port_A_Cmd: - LOG_F(9, "ESCC: reading Port A register RR%d", this->reg_ptr); - if (this->reg_ptr == 2) { + if (this->reg_ptr == RR2) { value = this->int_vec; } else { value = this->ch_a->read_reg(this->reg_ptr); @@ -142,39 +141,42 @@ void EsccController::write(uint8_t reg_offset, uint8_t value) void EsccController::write_internal(EsccChannel *ch, uint8_t value) { - if (this->reg_ptr) { - // chip-specific registers - if (this->reg_ptr == 9) { - // see if some reset is requested - switch(value & 0xC0) { - case RESET_CH_B: - this->master_int_cntrl &= 0xDF; - this->ch_b->reset(false); - break; - case RESET_CH_A: - this->master_int_cntrl &= 0xDF; - this->ch_a->reset(false); - break; - case RESET_ESCC: - this->reset(); - break; - } - - this->master_int_cntrl = value & 0x3F; - } else if (this->reg_ptr == 2) { - this->int_vec = value; - } else { // channel-specific registers - ch->write_reg(this->reg_ptr, value); - } - this->reg_ptr = 0; - } else { - this->reg_ptr = value & 7; - switch(value >> 3) { - case WR0Cmd::Point_High: - this->reg_ptr |= 8; + switch (this->reg_ptr) { + // chip-specific registers + case WR0: + this->reg_ptr = value & WR0_REGISTER_SELECTION_CODE; + switch (value & WR0_COMMAND_CODES) { + case WR0_COMMAND_POINT_HIGH: + this->reg_ptr |= WR8; // or RR8 break; } + return; + case WR2: + this->int_vec = value; + break; + case WR9: + // see if some reset is requested + switch (value & WR9_RESET_COMMAND_BITS) { + case WR9_CHANNEL_RESET_B: + this->master_int_cntrl &= ~WR9_INTERRUPT_MASKING_WITHOUT_INTACK; + this->ch_b->reset(false); + break; + case WR9_CHANNEL_RESET_A: + this->master_int_cntrl &= ~WR9_INTERRUPT_MASKING_WITHOUT_INTACK; + this->ch_a->reset(false); + break; + case WR9_FORCE_HARDWARE_RESET: + this->reset(); + break; + } + + this->master_int_cntrl = value & WR9_INTERRUPT_CONTROL_BITS; + break; + default: + // channel-specific registers + ch->write_reg(this->reg_ptr, value); } + this->reg_ptr = WR0; // or RR0 } // ======================== ESCC Channel methods ============================== @@ -203,17 +205,21 @@ void EsccChannel::reset(bool hw_reset) { this->chario->rcv_disable(); - this->write_regs[1] &= 0x24; - this->write_regs[3] &= 0xFE; - this->write_regs[4] |= 0x04; - this->write_regs[5] &= 0x61; - this->write_regs[15] = 0xF8; + /* + We use hex values here instead of enums to more + easily compare with the z85c30 data sheet. + */ + this->write_regs[WR1] &= 0x24; + this->write_regs[WR3] &= 0xFE; + this->write_regs[WR4] |= 0x04; + this->write_regs[WR5] &= 0x61; + this->write_regs[WR15] = 0xF8; - this->read_regs[0] &= 0x3C; - this->read_regs[0] |= 0x44; - this->read_regs[1] = 0x06; - this->read_regs[3] = 0x00; - this->read_regs[10] = 0x00; + this->read_regs[RR0] &= 0x38; + this->read_regs[RR0] |= 0x44; + this->read_regs[RR1] = 0x06; + this->read_regs[RR3] = 0x00; + this->read_regs[RR10] = 0x00; // initialize DPLL this->dpll_active = 0; @@ -225,81 +231,78 @@ void EsccChannel::reset(bool hw_reset) this->brg_clock_src = 0; if (hw_reset) { - this->write_regs[10] = 0; - this->write_regs[11] = 8; - this->write_regs[14] &= 0xC0; - this->write_regs[14] |= 0x20; + this->write_regs[WR10] = 0; + this->write_regs[WR11] = 8; + this->write_regs[WR14] &= 0xC0; } else { - this->write_regs[10] &= 0x60; - this->write_regs[14] &= 0xC3; - this->write_regs[14] |= 0x20; + this->write_regs[WR10] &= 0x60; + this->write_regs[WR14] &= 0xC3; } + this->write_regs[WR14] |= 0x20; } void EsccChannel::write_reg(int reg_num, uint8_t value) { switch (reg_num) { - case 3: - if ((this->write_regs[3] ^ value) & 0x10) { - this->write_regs[3] |= 0x10; - this->read_regs[0] |= 0x10; // set SYNC_HUNT flag + case WR3: + if ((this->write_regs[WR3] ^ value) & WR3_ENTER_HUNT_MODE) { + this->write_regs[WR3] |= WR3_ENTER_HUNT_MODE; + this->read_regs[RR0] |= RR0_SYNC_HUNT; LOG_F(9, "%s: Hunt mode entered.", this->name.c_str()); } - if ((this->write_regs[3] ^ value) & 1) { - if (value & 1) { - this->write_regs[3] |= 0x1; + if ((this->write_regs[WR3] ^ value) & WR3_RX_ENABLE) { + if (value & WR3_RX_ENABLE) { + this->write_regs[WR3] |= WR3_RX_ENABLE; this->chario->rcv_enable(); LOG_F(9, "%s: receiver enabled.", this->name.c_str()); } else { - this->write_regs[3] ^= 0x1; + this->write_regs[WR3] ^= WR3_RX_ENABLE; this->chario->rcv_disable(); LOG_F(9, "%s: receiver disabled.", this->name.c_str()); - this->write_regs[3] |= 0x10; // enter HUNT mode - this->read_regs[0] |= 0x10; // set SYNC_HUNT flag + this->write_regs[WR3] |= WR3_ENTER_HUNT_MODE; + this->read_regs[RR0] |= RR0_SYNC_HUNT; } } - this->write_regs[3] = (this->write_regs[3] & 0x11) | (value & 0xEE); + this->write_regs[WR3] = (this->write_regs[WR3] & (WR3_RX_ENABLE | WR3_ENTER_HUNT_MODE)) | (value & ~(WR3_RX_ENABLE | WR3_ENTER_HUNT_MODE)); return; - case 7: - if (this->write_regs[15] & 1) { + case WR7: + if (this->write_regs[WR15] & WR15_SDLC_HDLC_ENHANCEMENT_ENABLE) { this->wr7_enh = value; return; } break; - case 14: - switch (value >> 5) { - case DPLL_NULL_CMD: + case WR14: + switch (value & WR14_DPLL_COMMAND_BITS) { + case WR14_DPLL_NULL_COMMAND: break; - case DPLL_ENTER_SRC_MODE: + case WR14_DPLL_ENTER_SEARCH_MODE: this->dpll_active = 1; - this->read_regs[10] &= 0x3F; + this->read_regs[RR10] &= ~(RR10_TWO_CLOCKS_MISSING | RR10_ONE_CLOCK_MISSING); break; - case DPLL_DISABLE: + case WR14_DPLL_RESET_MISSING_CLOCK: + this->read_regs[RR10] &= ~(RR10_TWO_CLOCKS_MISSING | RR10_ONE_CLOCK_MISSING); + break; + case WR14_DPLL_DISABLE_DPLL: this->dpll_active = 0; // fallthrough - case DPLL_RST_MISSING_CLK: - this->read_regs[10] &= 0x3F; - break; - case DPLL_SET_SRC_BGR: + case WR14_DPLL_SET_SOURCE_BR_GENERATOR: this->dpll_clock_src = 0; break; - case DPLL_SET_SRC_RTXC: + case WR14_DPLL_SET_SOURCE_RTXC: this->dpll_clock_src = 1; break; - case DPLL_SET_FM_MODE: + case WR14_DPLL_SET_FM_MODE: this->dpll_mode = DpllMode::FM; break; - case DPLL_SET_NRZI_MODE: + case WR14_DPLL_SET_NRZI_MODE: this->dpll_mode = DpllMode::NRZI; break; - default: - LOG_F(WARNING, "%s: unimplemented DPLL command %d", this->name.c_str(), value >> 5); } - if (value & 0x1C) { // Local Loopback, Auto Echo DTR/REQ bits set + if (value & (WR14_LOCAL_LOOPBACK | WR14_AUTO_ECHO | WR14_DTR_REQUEST_FUNCTION)) { LOG_F(WARNING, "%s: unexpected value in WR14 = 0x%X", this->name.c_str(), value); } - if (this->brg_active ^ (value & 1)) { - this->brg_active = value & 1; + if (this->brg_active ^ (value & WR14_BR_GENERATOR_ENABLE)) { + this->brg_active = value & WR14_BR_GENERATOR_ENABLE; LOG_F(9, "%s: BRG %s", this->name.c_str(), this->brg_active ? "enabled" : "disabled"); } return; @@ -310,9 +313,10 @@ void EsccChannel::write_reg(int reg_num, uint8_t value) uint8_t EsccChannel::read_reg(int reg_num) { - if (!reg_num) { + switch (reg_num) { + case RR0: if (this->chario->rcv_char_available()) { - this->read_regs[0] |= 1; + this->read_regs[RR0] |= RR0_RX_CHARACTER_AVAILABLE; } } return this->read_regs[reg_num]; @@ -336,7 +340,7 @@ uint8_t EsccChannel::receive_byte() } else { c = 0; } - this->read_regs[0] &= ~1; + this->read_regs[RR0] &= ~RR0_RX_CHARACTER_AVAILABLE; return c; } diff --git a/devices/serial/escc.h b/devices/serial/escc.h index f344e39..05fd21e 100644 --- a/devices/serial/escc.h +++ b/devices/serial/escc.h @@ -64,29 +64,6 @@ enum LocalTalkReg : uint8_t { Detect_AB = 0xB, }; -enum WR0Cmd : uint8_t { - Point_High = 1, -}; - -/** ESCC reset commands. */ -enum { - RESET_ESCC = 0xC0, - RESET_CH_A = 0x80, - RESET_CH_B = 0x40 -}; - -/** DPLL commands in WR14. */ -enum { - DPLL_NULL_CMD = 0, - DPLL_ENTER_SRC_MODE = 1, - DPLL_RST_MISSING_CLK = 2, - DPLL_DISABLE = 3, - DPLL_SET_SRC_BGR = 4, - DPLL_SET_SRC_RTXC = 5, - DPLL_SET_FM_MODE = 6, - DPLL_SET_NRZI_MODE = 7 -}; - enum DpllMode : uint8_t { NRZI = 0, FM = 1 @@ -161,7 +138,7 @@ private: uint8_t write_regs[16]; uint8_t wr7_enh; uint8_t dpll_active; - uint8_t dpll_mode; + DpllMode dpll_mode; uint8_t dpll_clock_src; uint8_t brg_active; uint8_t brg_clock_src; diff --git a/devices/serial/z85c30.h b/devices/serial/z85c30.h new file mode 100644 index 0000000..1b6623b --- /dev/null +++ b/devices/serial/z85c30.h @@ -0,0 +1,350 @@ +/* +DingusPPC - The Experimental PowerPC Macintosh emulator +Copyright (C) 2018-24 divingkatae and maximum + (theweirdo) spatium + +(Contact divingkatae#1017 or powermax#2286 on Discord for more info) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +/** Register definitions for Z85C30. */ + +#ifndef Z85C30_H +#define Z85C30_H + +enum +{ + WR0 = 0, + WR1, + WR2, + WR3, + WR4, + WR5, + WR6, + WR7, + WR8, + WR9, + WR10, + WR11, + WR12, + WR13, + WR14, + WR15, +}; + +enum +{ + RR0 = 0, + RR1, + RR2, + RR3, + RR4, + RR5, + RR6, + RR7, + RR8, + RR9, + RR10, + RR11, + RR12, + RR13, + RR14, + RR15, +}; + +enum +{ +// RR0 - Transmit/Receive Buffer Status and External Status + + RR0_RX_CHARACTER_AVAILABLE = 1 << 0, + RR0_ZERO_COUNT = 1 << 1, + RR0_TX_BUFFER_EMPTY = 1 << 2, + RR0_DCD = 1 << 3, + RR0_SYNC_HUNT = 1 << 4, + RR0_CTS = 1 << 5, + RR0_TX_UNDERRUN_EOM = 1 << 6, + RR0_BREAK_ABORT = 1 << 7, + +// RR1 - Special Receive Condition status, residue codes, error conditions + + RR1_ALL_SENT = 1 << 0, + RR1_RESIDUE_CODE_2 = 1 << 1, + RR1_RESIDUE_CODE_1 = 1 << 2, + RR1_RESIDUE_CODE_0 = 1 << 3, + RR1_PARITY_ERROR = 1 << 4, + RR1_RX_OVERRUN_ERROR = 1 << 5, + RR1_CRC_FRAMING_ERROR = 1 << 6, + RR1_END_OF_FRAME_SDLC = 1 << 7, + +// RR2 - Modified (Channel B only) interrupt vector and Unmodified interrupt vector (Channel A only) + + RR2_V0 = 1 << 0, + RR2_V1 = 1 << 1, + RR2_V2 = 1 << 2, + RR2_V3 = 1 << 3, + RR2_V4 = 1 << 4, + RR2_V5 = 1 << 5, + RR2_V6 = 1 << 6, + RR2_V7 = 1 << 7, + +// RR3 - Interrupt Pending bits (Channel A only) + + RR3_CHANNEL_B_EXT_STAT_IP = 1 << 0, + RR3_CHANNEL_B_TX_IP = 1 << 1, + RR3_CHANNEL_B_RX_IP = 1 << 2, + RR3_CHANNEL_A_EXT_STAT_IP = 1 << 3, + RR3_CHANNEL_A_TX_IP = 1 << 4, + RR3_CHANNEL_A_RX_IP = 1 << 5, + // 0 = 1 << 6, + // 0 = 1 << 7, + +// RR6 - 14-bit frame byte count (LSB) + +// RR7 - 14-bit frame byte count (MSB), frame status + + RR7_FIFO_OVERFLOW_STATUS = 1 << 7, + RR7_NORMAL = 0 << 7, + RR7_FIFO_OVERFLOWED_DURING_OPERATION = 1 << 7, + RR7_FIFO_DATA_AVAILABLE_STATUS = 1 << 6, + RR7_STATUS_READS_COME_FROM_SCC = 0 << 6, + RR7_STATUS_READS_COME_FROM_10_X_9_BIT_FIFO = 1 << 6, + RR7_FRAME_BYTE_COUNT_MSB = 0x3F, + +// RR8 - Receive Data // Receive buffer + +// RR10 - Miscellaneous XMTR, RCVR status parameters + + // 0 = 1 << 0, + RR10_ON_LOOP = 1 << 1, + // 0 = 1 << 2, + // 0 = 1 << 3, + RR10_LOOP_SENDING = 1 << 4, + // 0 = 1 << 5, + RR10_TWO_CLOCKS_MISSING = 1 << 6, + RR10_ONE_CLOCK_MISSING = 1 << 7, + +// RR12 - Lower byte of baud rate generator time constant + +// RR13 - Upper byte of baud rate generator time constant + +// RR15 - External/Status interrupt control information + + RR15_SDLC_HDLC_ENHANCEMENT_STATUS = 1 << 0, + RR15_ZERO_COUNT_IE = 1 << 1, + RR15_10_X_19_BIT_FRAME_STATUS_FIFO_ENABLE_STATUS = 1 << 2, + RR15_DCD_IE = 1 << 3, + RR15_SYNC_HUNT_IE = 1 << 4, + RR15_CTS_IE = 1 << 5, + RR15_TX_UNDERRUN_EOM_IE = 1 << 6, + RR15_BREAK_ABORT_IE = 1 << 7, + +// WR0 - Command Register // Command Register, (Register Pointers), CRC initialization, resets for various modes + + WR0_CRC_RESET_CODES = 3 << 6, + WR0_RESET_NULL_CODE = 0 << 6, + WR0_RESET_RX_CRC_CHECKER = 1 << 6, + WR0_RESET_TX_CRC_GENERATOR = 2 << 6, + WR0_RESET_TX_UNDERRUN_EOM_LATCH = 3 << 6, + WR0_COMMAND_CODES = 7 << 3, + WR0_COMMAND_NULL_CODE = 0 << 3, + WR0_COMMAND_POINT_HIGH = 1 << 3, // add 8 to Register Selection Code + WR0_COMMAND_RESET_EXT_STATUS_INTERRUPTS = 2 << 3, + WR0_COMMAND_SEND_ABORT_SDLC = 3 << 3, + WR0_COMMAND_ENABLE_INT_ON_NEXT_RX_CHARACTER = 4 << 3, + WR0_COMMAND_RESET_TXINT_PENDING = 5 << 3, + WR0_COMMAND_ERROR_RESET = 6 << 3, + WR0_COMMAND_RESET_HIGHEST_IUS = 7 << 3, + WR0_REGISTER_SELECTION_CODE = 7 << 0, + WR0_REGISTER_0 = 0 << 0, + WR0_REGISTER_1 = 1 << 0, + WR0_REGISTER_2 = 2 << 0, + WR0_REGISTER_3 = 3 << 0, + WR0_REGISTER_4 = 4 << 0, + WR0_REGISTER_5 = 5 << 0, + WR0_REGISTER_6 = 6 << 0, + WR0_REGISTER_7 = 7 << 0, + +// WR1 - Transmit/Receive Interrupt and Data Transfer Mode Definition // Interrupt conditions, Wait/DMA request control + + WR1_WAIT_DMA_REQUEST_ENABLE = 1 << 7, + WR1_WAIT_DMA_REQUEST_FUNCTION = 1 << 6, + WR1_WAIT_DMA_REQUEST_ON_RECEIVE_TRANSMIT = 1 << 5, + WR1_RECEIVE_INTERRUPT_MODES = 3 << 3, + WR1_RX_INT_DISABLE = 0 << 3, + WR1_RX_INT_ON_FIRST_CHARACTER_OR_SPECIAL_CONDITION = 1 << 3, + WR1_INT_ON_ALL_RX_CHARACTERS_OR_SPECIAL_CONDITION = 2 << 3, + WR1_RX_INT_ON_SPECIAL_CONDITION_ONLY = 3 << 3, + WR1_PARITY_IS_SPECIAL_CONDITION = 1 << 2, + WR1_TX_INT_ENABLE = 1 << 1, + WR1_EXT_INT_ENABLE = 1 << 0, + +// WR2 - Interrupt Vector // Interrupt vector (access through either channel) + + WR2_V0 = 1 << 0, + WR2_V1 = 1 << 1, + WR2_V2 = 1 << 2, + WR2_V3 = 1 << 3, + WR2_V4 = 1 << 4, + WR2_V5 = 1 << 5, + WR2_V6 = 1 << 6, + WR2_V7 = 1 << 7, + +// WR3 - Receive Parameters and Control // Receive/Control parameters, number of bits per character, Rx CRC enable + + WR3_RECEIVER_BITS_PER_CHARACTER = 3 << 6, + WR3_BITS_PER_CHARACTER_5 = 0 << 6, + WR3_BITS_PER_CHARACTER_7 = 1 << 6, + WR3_BITS_PER_CHARACTER_6 = 2 << 6, + WR3_BITS_PER_CHARACTER_8 = 3 << 6, + WR3_AUTO_ENABLES = 1 << 5, + WR3_ENTER_HUNT_MODE = 1 << 4, + WR3_RX_CRC_ENABLE = 1 << 3, + WR3_ADDRESS_SEARCH_MODE_SDLC = 1 << 2, + WR3_SYNC_CHARACTER_LOAD_INHIBIT = 1 << 1, + WR3_RX_ENABLE = 1 << 0, + +// WR4 - Transmit/Receiver Miscellaneous Parameters and Modes // Transmit/Receive miscellaneous parameters and codes, clock rate, number of sync characters, stop bits, parity + + WR4_CLOCK_RATE = 3 << 6, + WR4_X1_CLOCK_MODE = 0 << 6, + WR4_X16_CLOCK_MODE = 1 << 6, + WR4_X32_CLOCK_MODE = 2 << 6, + WR4_X64_CLOCK_MODE = 3 << 6, + WR4_SYNC_MODE = 3 << 4, + WR4_MONOSYNC = 0 << 4, + WR4_BISYNC = 1 << 4, + WR4_SDLC_MODE = 2 << 4, + WR4_EXTERNAL_SYNC_MODE = 3 << 4, + WR4_STOP_BITS = 3 << 2, + WR4_SYNC_MODES_ENABLE = 0 << 2, + WR4_STOP_BITS_PER_CHARACTER_1 = 1 << 2, + WR4_STOP_BITS_PER_CHARACTER_1_AND_HALF = 2 << 2, + WR4_STOP_BITS_PER_CHARACTER_2 = 3 << 2, + WR4_PARITY = 1 << 1, + WR4_PARITY_ODD = 0 << 1, + WR4_PARITY_EVEN = 1 << 1, + WR4_PARITY_ENABLE = 1 << 0, + +// WR5 - Transmit Parameter and Controls // Transmit parameters and control, number of Tx bits per character, Tx CRC enable + + WR5_DTR = 1 << 7, + WR5_TX_BITS_PER_CHARACTER = 3 << 5, + WR5_TX_5_BITS_OR_LESS_PER_CHARACTER = 0 << 5, + WR5_TX_7_BITS_PER_CHARACTER = 1 << 5, + WR5_TX_6_BITS_PER_CHARACTER = 2 << 5, + WR5_TX_8_BITS_PER_CHARACTER = 3 << 5, + WR5_SEND_BREAK = 1 << 4, + WR5_TX_ENABLE = 1 << 3, + WR5_SDLC_CRC16 = 1 << 2, + WR5_RTS = 1 << 1, + WR5_TX_CRC_ENABLE = 1 << 0, + +// WR6 - Sync Characters or SDLC Address Field // Sync character (1st byte) or SDLC address + +// WR7 - Sync Character or SDLCFlag/SDLC Option Register // SYNC character (2nd byte) or SDLC flag + +// WR8 - Transmit buffer + +// WR9 - Master Interrupt Control // Master interrupt control and reset (accessed through either channel), reset bits, control interrupt daisy chain + + WR9_RESET_COMMAND_BITS = 3 << 6, + WR9_NO_RESET = 0 << 6, + WR9_CHANNEL_RESET_B = 1 << 6, + WR9_CHANNEL_RESET_A = 2 << 6, + WR9_FORCE_HARDWARE_RESET = 3 << 6, + WR9_INTERRUPT_CONTROL_BITS = 0x3F, + WR9_INTERRUPT_MASKING_WITHOUT_INTACK = 1 << 5, + WR9_STATUS_HIGH_STATUS_LOW = 1 << 4, + WR9_MASTER_INTERRUPT_ENABLE = 1 << 3, + WR9_DISABLE_LOWER_CHAIN = 1 << 2, + WR9_NO_VECTOR = 1 << 1, + WR9_VECTOR_INCLUDES_STATUS = 1 << 0, + +// WR10 - Miscellaneous Transmitter/Receiver Control Bits // Miscellaneous transmitter/receiver control bits, NRZI, NRZ, FM encoding, CRC reset + + WR10_CRC_PRESET = 1 << 7, + WR10_DATA_ENCODING = 3 << 5, + WR10_NRZ = 0 << 5, + WR10_NRZI = 1 << 5, + WR10_FM1 = 2 << 5, + WR10_FM0 = 3 << 5, + WR10_GO_ACTIVE_ON_POLL = 1 << 4, + WR10_MARK_FLAG_IDLE = 1 << 3, + WR10_FLAG_IDLE = 0 << 3, + WR10_MARK_IDLE = 1 << 3, + WR10_ABORT_FLAG_ON_UNDERRUN = 1 << 2, + WR10_FLAG_ON_UNDERRUN = 0 << 2, + WR10_ABORT_ON_UNDERRUN = 1 << 2, + WR10_LOOP_MODE = 1 << 1, + WR10_SYNC_SIZE = 1 << 0, + WR10_SYNC_6_BIT = 0 << 0, + WR10_SYNC_8_BIT = 1 << 0, + +// WR11 - Clock Mode Control // Clock mode control, source of Rx and Tx clocks + + WR11_RTXC_XTAL_NO_XTAL = 1 << 7, + WR11_RTXC_NO_XTAL = 0 << 7, + WR11_RTXC_XTAL = 1 << 7, + WR11_RECEIVER_CLOCK = 3 << 5, + WR11_RECEIVE_CLOCK_RTXC_PIN = 0 << 5, + WR11_RECEIVE_CLOCK_TRXC_PIN = 1 << 5, + WR11_RECEIVE_CLOCK_BR_GENERATOR_OUTPUT = 2 << 5, + WR11_RECEIVE_CLOCK_DPLL_OUTPUT = 3 << 5, + WR11_TRANSMIT_CLOCK = 3 << 3, + WR11_TRANSMIT_CLOCK_RTXC_PIN = 0 << 3, + WR11_TRANSMIT_CLOCK_TRXC_PIN = 1 << 3, + WR11_TRANSMIT_CLOCK_BR_GENERATOR_OUTPUT = 2 << 3, + WR11_TRANSMIT_CLOCK_DPLL_OUTPUT = 3 << 3, + WR11_TRXC_O_I = 1 << 2, + WR11_TRXC_OUTPUT_SOURCE = 3 << 0, + WR11_TRXC_OUT_XTAL_OUTPUT = 0 << 0, + WR11_TRXC_OUT_TRANSMIT_CLOCK = 1 << 0, + WR11_TRXC_OUT_BR_GENERATOR_OUTPUT = 2 << 0, + WR11_TRXC_OUT_DPLL_OUTPUT = 3 << 0, + +// WR12 - Lower Byte of Baud Rate Generator Time Constant + +// WR13 - Upper Byte of Baud Rate Generator Time Constant + +// WR14 - Miscellaneous Control Bits // Miscellaneous control bits: baud rate generator, Phase-Locked Loop control, auto echo, local loopback + + WR14_DPLL_COMMAND_BITS = 7 << 5, + WR14_DPLL_NULL_COMMAND = 0 << 5, + WR14_DPLL_ENTER_SEARCH_MODE = 1 << 5, + WR14_DPLL_RESET_MISSING_CLOCK = 2 << 5, + WR14_DPLL_DISABLE_DPLL = 3 << 5, + WR14_DPLL_SET_SOURCE_BR_GENERATOR = 4 << 5, + WR14_DPLL_SET_SOURCE_RTXC = 5 << 5, + WR14_DPLL_SET_FM_MODE = 6 << 5, + WR14_DPLL_SET_NRZI_MODE = 7 << 5, + WR14_LOCAL_LOOPBACK = 1 << 4, + WR14_AUTO_ECHO = 1 << 3, + WR14_DTR_REQUEST_FUNCTION = 1 << 2, + WR14_BR_GENERATOR_SOURCE = 1 << 1, + WR14_BR_GENERATOR_ENABLE = 1 << 0, + +// WR15 - External/Status Interrupt Control // External/Status interrupt control information-control external conditions causing interrupts + + WR15_SDLC_HDLC_ENHANCEMENT_ENABLE = 1 << 0, + WR15_ZERO_COUNT_IE = 1 << 1, + WR15_10_X_19_BIT_FRAME_STATUS_FIFO_ENABLE = 1 << 2, + WR15_DCD_IE = 1 << 3, + WR15_SYNC_HUNT_IE = 1 << 4, + WR15_CTS_IE = 1 << 5, + WR15_TX_UNDERRUN_EOM_IE = 1 << 6, + WR15_BREAK_ABORT_IE = 1 << 7, +}; + +#endif // Z85C30_H