diff options
-rw-r--r-- | scripts/target/mame/mess.lua | 3 | ||||
-rw-r--r-- | src/devices/cpu/m6805/m68705.cpp | 68 | ||||
-rw-r--r-- | src/devices/cpu/m6805/m68705.h | 33 | ||||
-rw-r--r-- | src/devices/machine/i8251.cpp | 221 | ||||
-rw-r--r-- | src/devices/machine/i8251.h | 28 | ||||
-rw-r--r-- | src/mame/drivers/gladiatr.cpp | 55 | ||||
-rw-r--r-- | src/mame/drivers/osborne1.cpp | 2 | ||||
-rw-r--r-- | src/mame/drivers/pitnrun.cpp | 28 | ||||
-rw-r--r-- | src/mame/drivers/zorba.cpp | 608 | ||||
-rw-r--r-- | src/mame/includes/gladiatr.h | 8 | ||||
-rw-r--r-- | src/mame/includes/osborne1.h | 2 | ||||
-rw-r--r-- | src/mame/includes/zorba.h | 113 | ||||
-rw-r--r-- | src/mame/machine/osborne1.cpp | 12 | ||||
-rw-r--r-- | src/mame/machine/taito68705interface.cpp | 1 | ||||
-rw-r--r-- | src/mame/machine/zorbakbd.cpp | 314 | ||||
-rw-r--r-- | src/mame/machine/zorbakbd.h | 43 |
16 files changed, 1112 insertions, 427 deletions
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 7487f4435e5..96cfc02d53c 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -3422,6 +3422,9 @@ files { MAME_DIR .. "src/mame/includes/xor100.h", MAME_DIR .. "src/mame/drivers/xavix.cpp", MAME_DIR .. "src/mame/drivers/zorba.cpp", + MAME_DIR .. "src/mame/includes/zorba.h", + MAME_DIR .. "src/mame/machine/zorbakbd.cpp", + MAME_DIR .. "src/mame/machine/zorbakbd.h", } end diff --git a/src/devices/cpu/m6805/m68705.cpp b/src/devices/cpu/m6805/m68705.cpp index b678954e386..fd7ff5be29c 100644 --- a/src/devices/cpu/m6805/m68705.cpp +++ b/src/devices/cpu/m6805/m68705.cpp @@ -569,6 +569,30 @@ void m68705_new_device::burn_cycles(unsigned count) } } +template <std::size_t N> void m68705_new_device::add_port_latch_state() +{ + state_add(M68705_LATCHA + N, util::string_format("LATCH%c", 'A' + N).c_str(), m_port_latch[N]).mask(~m_port_mask[N] & 0xff); +} + +template <std::size_t N> void m68705_new_device::add_port_ddr_state() +{ + state_add(M68705_DDRA + N, util::string_format("DDR%c", 'A' + N).c_str(), m_port_ddr[N]).mask(~m_port_mask[N] & 0xff); +} + +void m68705_new_device::add_timer_state() +{ + state_add(M68705_PS, "PS", m_prescaler).mask(0x7f); + state_add(M68705_TDR, "TDR", m_tdr).mask(0xff); + state_add(M68705_TCR, "TCR", m_tcr).mask(0xff); +} + +void m68705_new_device::add_eprom_state() +{ + state_add(M68705_PCR, "PCR", m_pcr).mask(0xff); + state_add(M68705_PLA, "PLA", m_pl_addr).mask(0xffff); + state_add(M68705_PLD, "PLD", m_pl_data).mask(0xff); +} + /**************************************************************************** * M68705Px family @@ -613,6 +637,21 @@ m68705p_device::m68705p_device( set_port_mask<3>(0xff); // Port D isn't present } +void m68705p_device::device_start() +{ + m68705_new_device::device_start(); + + add_port_latch_state<0>(); + add_port_latch_state<1>(); + add_port_latch_state<2>(); + add_port_ddr_state<0>(); + add_port_ddr_state<1>(); + add_port_ddr_state<2>(); + add_timer_state(); + add_eprom_state(); + state_add(M68705_MOR, "MOR", get_user_rom()[0x0784]).mask(0xff); +} + offs_t m68705p_device::disasm_disassemble( std::ostream &stream, offs_t pc, @@ -680,6 +719,24 @@ m68705u_device::m68705u_device( { } +void m68705u_device::device_start() +{ + m68705_new_device::device_start(); + + add_port_latch_state<0>(); + add_port_latch_state<1>(); + add_port_latch_state<2>(); + add_port_latch_state<3>(); + add_port_ddr_state<0>(); + add_port_ddr_state<1>(); + add_port_ddr_state<2>(); + add_timer_state(); + add_eprom_state(); + state_add(M68705_MOR, "MOR", get_user_rom()[0x0f38]).mask(0xff); + + // TODO: MISC register +} + offs_t m68705u_device::disasm_disassemble( std::ostream &stream, offs_t pc, @@ -734,6 +791,13 @@ m68705r_device::m68705r_device( { } +void m68705r_device::device_start() +{ + m68705u_device::device_start(); + + // TODO: ADC +} + offs_t m68705r_device::disasm_disassemble( std::ostream &stream, offs_t pc, @@ -801,7 +865,7 @@ tiny_rom_entry const *m68705r3_device::device_rom_region() const u8 m68705r3_device::get_mask_options() const { - return get_user_rom()[0x0784] & 0xf7; // no SNM bit + return get_user_rom()[0x0f38] & 0xf7; // no SNM bit } @@ -821,5 +885,5 @@ tiny_rom_entry const *m68705u3_device::device_rom_region() const u8 m68705u3_device::get_mask_options() const { - return get_user_rom()[0x0784] & 0xf7; // no SNM bit + return get_user_rom()[0x0f38] & 0xf7; // no SNM bit } diff --git a/src/devices/cpu/m6805/m68705.h b/src/devices/cpu/m6805/m68705.h index e89517e5735..cd839a6cc54 100644 --- a/src/devices/cpu/m6805/m68705.h +++ b/src/devices/cpu/m6805/m68705.h @@ -94,6 +94,28 @@ public: protected: enum { + M68705_LATCHA = 0x10, + M68705_LATCHB, + M68705_LATCHC, + M68705_LATCHD, + M68705_DDRA, + M68705_DDRB, + M68705_DDRC, + M68705_DDRD, + + M68705_PS, + M68705_TDR, + M68705_TCR, + + M68705_PCR, + M68705_PLD, + M68705_PLA, + + M68705_MOR + }; + + enum + { PORT_COUNT = 4 }; @@ -148,6 +170,11 @@ protected: u8 *const get_user_rom() const { return &m_user_rom[0]; } virtual u8 get_mask_options() const = 0; + template <std::size_t N> void add_port_latch_state(); + template <std::size_t N> void add_port_ddr_state(); + void add_timer_state(); + void add_eprom_state(); + private: bool tcr_tir() const { return BIT(m_tcr, 7); } bool tcr_tim() const { return BIT(m_tcr, 6); } @@ -206,6 +233,8 @@ protected: char const *shortname, char const *source); + virtual void device_start() override; + virtual offs_t disasm_disassemble( std::ostream &stream, offs_t pc, @@ -248,6 +277,8 @@ protected: char const *shortname, char const *source); + virtual void device_start() override; + virtual offs_t disasm_disassemble( std::ostream &stream, offs_t pc, @@ -277,6 +308,8 @@ protected: char const *shortname, char const *source); + virtual void device_start() override; + virtual offs_t disasm_disassemble( std::ostream &stream, offs_t pc, diff --git a/src/devices/machine/i8251.cpp b/src/devices/machine/i8251.cpp index 2fc9ef798b6..6eac8fd3c52 100644 --- a/src/devices/machine/i8251.cpp +++ b/src/devices/machine/i8251.cpp @@ -24,7 +24,7 @@ #define VERBOSE 0 -#define LOG(x) do { if (VERBOSE) logerror x; } while (0) +#define LOG(...) do { if (VERBOSE) logerror(__VA_ARGS__); } while (0) //************************************************************************** // DEVICE DEFINITIONS @@ -33,12 +33,26 @@ const device_type I8251 = &device_creator<i8251_device>; const device_type V53_SCU = &device_creator<v53_scu_device>; +template class device_finder<i8251_device, false>; +template class device_finder<i8251_device, true>; +template class device_finder<v53_scu_device, false>; +template class device_finder<v53_scu_device, true>; + + //------------------------------------------------- // i8251_device - constructor //------------------------------------------------- -i8251_device::i8251_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname) - : device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__), +i8251_device::i8251_device( + const machine_config &mconfig, + device_type type, + const char *name, + const char *tag, + device_t *owner, + uint32_t clock, + const char *shortname, + const char *source) + : device_t(mconfig, type, name, tag, owner, clock, shortname, source), device_serial_interface(mconfig, *this), m_txd_handler(*this), m_dtr_handler(*this), @@ -56,25 +70,12 @@ i8251_device::i8251_device(const machine_config &mconfig, device_type type, cons } i8251_device::i8251_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, I8251, "8251 USART", tag, owner, clock, "i8251", __FILE__), - device_serial_interface(mconfig, *this), - m_txd_handler(*this), - m_dtr_handler(*this), - m_rts_handler(*this), - m_rxrdy_handler(*this), - m_txrdy_handler(*this), - m_txempty_handler(*this), - m_syndet_handler(*this), - m_cts(1), - m_dsr(1), - m_rxd(0), - m_rxc(0), - m_txc(0) + : i8251_device(mconfig, I8251, "8251 USART", tag, owner, clock, "i8251", __FILE__) { } v53_scu_device::v53_scu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : i8251_device(mconfig, V53_SCU, "V53 SCU", tag, owner, clock, "v53_scu") + : i8251_device(mconfig, V53_SCU, "V53 SCU", tag, owner, clock, "v53_scu", __FILE__) { } @@ -121,15 +122,11 @@ void i8251_device::device_start() void i8251_device::update_rx_ready() { - int state; - - state = m_status & I8251_STATUS_RX_READY; + int state = m_status & I8251_STATUS_RX_READY; - /* masked? */ - if ((m_command & (1<<2))==0) - { + // masked? + if (!BIT(m_command, 2)) state = 0; - } m_rxrdy_handler(state != 0); } @@ -142,19 +139,22 @@ void i8251_device::update_rx_ready() void i8251_device::receive_clock() { - m_rxc_count++; - - if (m_rxc_count == m_br_factor) - m_rxc_count = 0; - else - return; - /* receive enable? */ - if (m_command & (1<<2)) + if (BIT(m_command, 2)) { + const bool sync = is_receive_register_synchronized(); + if (sync) + { + --m_rxc_count; + if (m_rxc_count) + return; + } + //logerror("I8251\n"); /* get bit received from other side and update receive register */ receive_register_update_bit(m_rxd); + if (is_receive_register_synchronized()) + m_rxc_count = sync ? m_br_factor : (3 * m_br_factor / 2); if (is_receive_register_full()) { @@ -167,25 +167,24 @@ void i8251_device::receive_clock() /*------------------------------------------------- is_tx_enabled -------------------------------------------------*/ -bool i8251_device::is_tx_enabled(void) const +bool i8251_device::is_tx_enabled() const { - return BIT(m_command , 0) != 0 && m_cts == 0; + return BIT(m_command , 0) && !m_cts; } /*------------------------------------------------- check_for_tx_start -------------------------------------------------*/ -void i8251_device::check_for_tx_start(void) +void i8251_device::check_for_tx_start() { - if (is_tx_enabled() && (m_status & (I8251_STATUS_TX_EMPTY | I8251_STATUS_TX_READY)) == I8251_STATUS_TX_EMPTY) { - start_tx(); - } + if (is_tx_enabled() && (m_status & (I8251_STATUS_TX_EMPTY | I8251_STATUS_TX_READY)) == I8251_STATUS_TX_EMPTY) + start_tx(); } /*------------------------------------------------- start_tx -------------------------------------------------*/ -void i8251_device::start_tx(void) +void i8251_device::start_tx() { transmit_register_setup(m_tx_data); m_status &= ~I8251_STATUS_TX_EMPTY; @@ -199,23 +198,25 @@ void i8251_device::start_tx(void) void i8251_device::transmit_clock() { m_txc_count++; - - if (m_txc_count == m_br_factor) - m_txc_count = 0; - else + if (m_txc_count != m_br_factor) return; - if (is_transmit_register_empty()) { - if ((m_status & I8251_STATUS_TX_READY) == 0 && (is_tx_enabled() || (m_flags & I8251_DELAYED_TX_EN) != 0)) { + m_txc_count = 0; + + if (is_transmit_register_empty()) + { + if ((m_status & I8251_STATUS_TX_READY) == 0 && (is_tx_enabled() || (m_flags & I8251_DELAYED_TX_EN) != 0)) start_tx(); - } else { + else m_status |= I8251_STATUS_TX_EMPTY; - } + update_tx_ready(); update_tx_empty(); } + /* if diserial has bits to send, make them so */ - if (!is_transmit_register_empty()) { + if (!is_transmit_register_empty()) + { uint8_t data = transmit_register_get_data_bit(); m_txd_handler(data); } @@ -223,7 +224,7 @@ void i8251_device::transmit_clock() #if 0 /* hunt mode? */ /* after each bit has been shifted in, it is compared against the current sync byte */ - if (m_command & (1<<7)) + if (BIT(m_command, 7)) { /* data matches sync byte? */ if (m_data == m_sync_bytes[m_sync_byte_offset]) @@ -236,7 +237,7 @@ void i8251_device::transmit_clock() if (m_sync_byte_offset == m_sync_byte_count) { /* ent hunt mode */ - m_command &=~(1<<7); + m_command &= ~(1<<7); } } else @@ -295,7 +296,7 @@ void i8251_device::update_tx_empty() void i8251_device::device_reset() { - LOG(("I8251: Reset\n")); + LOG("I8251: Reset\n"); /* what is the default setup when the 8251 has been reset??? */ @@ -342,52 +343,34 @@ void i8251_device::device_reset() WRITE8_MEMBER(i8251_device::command_w) { /* command */ - LOG(("I8251: Command byte\n")); + LOG("I8251: Command byte\n"); m_command = data; - LOG(("Command byte: %02x\n", data)); + LOG("Command byte: %02x\n", data); - if (data & (1<<7)) - { - LOG(("hunt mode\n")); - } + if (BIT(data, 7)) + LOG("hunt mode\n"); - if (data & (1<<5)) - { - LOG(("/rts set to 0\n")); - } + if (BIT(data, 5)) + LOG("/rts set to 0\n"); else - { - LOG(("/rts set to 1\n")); - } + LOG("/rts set to 1\n"); - if (data & (1<<2)) - { - LOG(("receive enable\n")); - } + if (BIT(data, 2)) + LOG("receive enable\n"); else - { - LOG(("receive disable\n")); - } + LOG("receive disable\n"); - if (data & (1<<1)) - { - LOG(("/dtr set to 0\n")); - } + if (BIT(data, 1)) + LOG("/dtr set to 0\n"); else - { - LOG(("/dtr set to 1\n")); - } + LOG("/dtr set to 1\n"); - if (data & (1<<0)) - { - LOG(("transmit enable\n")); - } + if (BIT(data, 0)) + LOG("transmit enable\n"); else - { - LOG(("transmit disable\n")); - } + LOG("transmit disable\n"); /* bit 7: @@ -419,12 +402,10 @@ WRITE8_MEMBER(i8251_device::command_w) m_rts_handler(!BIT(data, 5)); m_dtr_handler(!BIT(data, 1)); - if (data & (1<<4)) - { + if (BIT(data, 4)) m_status &= ~(I8251_STATUS_PARITY_ERROR | I8251_STATUS_OVERRUN_ERROR | I8251_STATUS_FRAMING_ERROR); - } - if (data & (1<<6)) + if (BIT(data, 6)) { // datasheet says "returns to mode format", not // completely resets the chip. behavior of DEC Rainbow @@ -432,15 +413,15 @@ WRITE8_MEMBER(i8251_device::command_w) m_flags |= I8251_EXPECTING_MODE; } - check_for_tx_start(); + check_for_tx_start(); update_rx_ready(); update_tx_ready(); - update_tx_empty(); + update_tx_empty(); } WRITE8_MEMBER(i8251_device::mode_w) { - LOG(("I8251: Mode byte\n")); + LOG("I8251: Mode byte = %X\n", data); m_mode_byte = data; @@ -472,60 +453,55 @@ WRITE8_MEMBER(i8251_device::mode_w) 3 = x64 */ - LOG(("I8251: Asynchronous operation\n")); + LOG("I8251: Asynchronous operation\n"); - LOG(("Character length: %d\n", (((data >> 2) & 0x03) + 5))); + const int data_bits_count = ((data >> 2) & 0x03) + 5; + LOG("Character length: %d\n", data_bits_count); parity_t parity; - - if (data & (1 << 4)) + if (BIT(data, 4)) { - LOG(("enable parity checking\n")); - - if (data & (1 << 5)) + if (BIT(data, 5)) { - LOG(("even parity\n")); + LOG("enable parity checking (even parity)\n"); parity = PARITY_EVEN; } else { - LOG(("odd parity\n")); + LOG("enable parity checking (odd parity)\n"); parity = PARITY_ODD; } } else { - LOG(("parity check disabled\n")); + LOG("parity check disabled\n"); parity = PARITY_NONE; } stop_bits_t stop_bits; - switch ((data >> 6) & 0x03) { case 0: - default: stop_bits = STOP_BITS_0; - LOG(("stop bit: inhibit\n")); + LOG("stop bit: inhibit\n"); break; case 1: stop_bits = STOP_BITS_1; - LOG(("stop bit: 1 bit\n")); + LOG("stop bit: 1 bit\n"); break; case 2: stop_bits = STOP_BITS_1_5; - LOG(("stop bit: 1.5 bits\n")); + LOG("stop bit: 1.5 bits\n"); break; case 3: stop_bits = STOP_BITS_2; - LOG(("stop bit: 2 bits\n")); + LOG("stop bit: 2 bits\n"); break; } - int data_bits_count = ((data >> 2) & 0x03) + 5; set_data_frame(1, data_bits_count, parity, stop_bits); receive_register_reset(); @@ -537,13 +513,13 @@ WRITE8_MEMBER(i8251_device::mode_w) case 3: m_br_factor = 64; break; } - m_rxc_count = m_txc_count = 0; + m_txc_count = 0; #if 0 /* data bits */ m_receive_char_length = (((data >> 2) & 0x03) + 5); - if (data & (1 << 4)) + if (BIT(data, 4)) { /* parity */ m_receive_char_length++; @@ -580,7 +556,7 @@ WRITE8_MEMBER(i8251_device::mode_w) 3 = 8 bits bit 1,0 = 0 */ - LOG(("I8251: Synchronous operation\n")); + LOG("I8251: Synchronous operation\n"); /* setup for sync byte(s) */ m_flags |= I8251_EXPECTING_SYNC_BYTE; @@ -603,9 +579,9 @@ WRITE8_MEMBER(i8251_device::control_w) { if (m_flags & I8251_EXPECTING_SYNC_BYTE) { - LOG(("I8251: Sync byte\n")); + LOG("I8251: Sync byte\n"); - LOG(("Sync byte: %02x\n", data)); + LOG("Sync byte: %02x\n", data); /* store sync byte written */ m_sync_bytes[m_sync_byte_offset] = data; m_sync_byte_offset++; @@ -639,7 +615,7 @@ READ8_MEMBER(i8251_device::status_r) { uint8_t status = (m_dsr << 7) | m_status; - LOG(("status: %02x\n", status)); + LOG("status: %02x\n", status); return status; } @@ -653,7 +629,7 @@ WRITE8_MEMBER(i8251_device::data_w) { m_tx_data = data; - LOG(("data_w %02x\n" , data)); + LOG("data_w %02x\n" , data); /* writing clears */ m_status &=~I8251_STATUS_TX_READY; @@ -687,9 +663,8 @@ void i8251_device::receive_character(uint8_t ch) /* char has not been read and another has arrived! */ if (m_status & I8251_STATUS_RX_READY) - { m_status |= I8251_STATUS_OVERRUN_ERROR; - } + m_status |= I8251_STATUS_RX_READY; update_rx_ready(); @@ -703,7 +678,7 @@ void i8251_device::receive_character(uint8_t ch) READ8_MEMBER(i8251_device::data_r) { - LOG(("read data: %02x, STATUS=%02x\n",m_rx_data,m_status)); + LOG("read data: %02x, STATUS=%02x\n",m_rx_data,m_status); /* reading clears */ m_status &= ~I8251_STATUS_RX_READY; @@ -728,9 +703,9 @@ WRITE_LINE_MEMBER(i8251_device::write_cts) { m_cts = state; - check_for_tx_start(); - update_tx_ready(); - update_tx_empty(); + check_for_tx_start(); + update_tx_ready(); + update_tx_empty(); } WRITE_LINE_MEMBER(i8251_device::write_dsr) diff --git a/src/devices/machine/i8251.h b/src/devices/machine/i8251.h index a556851beb7..82659caed11 100644 --- a/src/devices/machine/i8251.h +++ b/src/devices/machine/i8251.h @@ -8,8 +8,8 @@ *********************************************************************/ -#ifndef __I8251_H__ -#define __I8251_H__ +#ifndef MAME_DEVICES_MACHINE_I8251_H +#define MAME_DEVICES_MACHINE_I8251_H //************************************************************************** @@ -42,7 +42,6 @@ class i8251_device : public device_t, { public: // construction/destruction - i8251_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname); i8251_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // static configuration helpers @@ -82,6 +81,16 @@ public: }; protected: + i8251_device( + const machine_config &mconfig, + device_type type, + const char *name, + const char *tag, + device_t *owner, + uint32_t clock, + const char *shortname, + const char *source); + // device-level overrides virtual void device_start() override; virtual void device_reset() override; @@ -92,9 +101,9 @@ protected: void update_tx_empty(); void transmit_clock(); void receive_clock(); - bool is_tx_enabled(void) const; - void check_for_tx_start(void); - void start_tx(void); + bool is_tx_enabled() const; + void check_for_tx_start(); + void start_tx(); enum @@ -155,5 +164,10 @@ public: extern const device_type I8251; extern const device_type V53_SCU; +extern template class device_finder<i8251_device, false>; +extern template class device_finder<i8251_device, true>; +extern template class device_finder<v53_scu_device, false>; +extern template class device_finder<v53_scu_device, true>; + -#endif /* __I8251_H__ */ +#endif // MAME_DEVICES_MACHINE_I8251_H diff --git a/src/mame/drivers/gladiatr.cpp b/src/mame/drivers/gladiatr.cpp index 828fa447413..7b915a13739 100644 --- a/src/mame/drivers/gladiatr.cpp +++ b/src/mame/drivers/gladiatr.cpp @@ -270,22 +270,6 @@ WRITE8_MEMBER(gladiatr_state::gladiatr_irq_patch_w) WRITE_LINE_MEMBER(gladiatr_state::tclk_w) { m_tclk_val = state != 0; - - // these are actually edge-triggered, but MAME only supports polled inputs - - u8 const new_in0_val(m_in0->read()); - if (BIT(~new_in0_val & (new_in0_val ^ m_in0_val), 5)) - m_cctl_p1 = (m_cctl_p1 & 0xfc) | BIT(~new_in0_val, 5) | (BIT(~new_in0_val, 5) << 1); - else - m_cctl_p1 = (m_cctl_p1 & 0xfe) | BIT(~new_in0_val, 5); - m_in0_val = new_in0_val; - - u8 const new_in1_val(m_in0->read()); - if (BIT(~new_in1_val & (new_in1_val ^ m_in1_val), 5)) - m_cctl_p2 = (m_cctl_p2 & 0xfc) | BIT(~new_in1_val, 5) | (BIT(~new_in1_val, 5) << 1); - else - m_cctl_p2 = (m_cctl_p2 & 0xfe) | BIT(~new_in1_val, 5); - m_in1_val = new_in1_val; } READ8_MEMBER(gladiatr_state::cctl_p1_r) @@ -370,6 +354,33 @@ READ8_MEMBER(gladiatr_state::csnd_p2_r) } +INPUT_CHANGED_MEMBER(gladiatr_state::p1_s1) +{ + // P11 gets the value of 1P-S2 at the moment 1P-S1 was pressed + if (oldval && !newval) + m_cctl_p1 = (m_cctl_p1 & 0xfd) | (BIT(m_cctl_p1, 0) << 1); +} + +INPUT_CHANGED_MEMBER(gladiatr_state::p1_s2) +{ + // P10 is high when 1P-S2 is pressed + m_cctl_p1 = (m_cctl_p1 & 0xfe) | (newval ? 0x00 : 0x01); +} + +INPUT_CHANGED_MEMBER(gladiatr_state::p2_s1) +{ + // P21 gets the value of 2P-S2 at the moment 2P-S1 was pressed + if (oldval && !newval) + m_cctl_p2 = (m_cctl_p2 & 0xfd) | (BIT(m_cctl_p2, 0) << 1); +} + +INPUT_CHANGED_MEMBER(gladiatr_state::p2_s2) +{ + // P20 is high when 2P-S2 is pressed + m_cctl_p2 = (m_cctl_p2 & 0xfe) | (newval ? 0x00 : 0x01); +} + + READ8_MEMBER(ppking_state::ppking_f1_r) { @@ -622,8 +633,8 @@ static INPUT_PORTS_START( gladiatr ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_8WAY - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_8WAY + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, gladiatr_state, p1_s1, 0) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, gladiatr_state, p2_s2, 0) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 ) @@ -632,8 +643,8 @@ static INPUT_PORTS_START( gladiatr ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_COCKTAIL + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL PORT_CHANGED_MEMBER(DEVICE_SELF, gladiatr_state, p2_s1, 0) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_COCKTAIL PORT_CHANGED_MEMBER(DEVICE_SELF, gladiatr_state, p2_s2, 0) PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) // coin counter outputs PORT_START("IN2") // cctl p1 @@ -1143,16 +1154,12 @@ DRIVER_INIT_MEMBER(gladiatr_state,gladiatr) membank("bank2")->set_entry(0); m_tclk_val = false; - m_in0_val = 0xff; - m_in1_val = 0xff; m_cctl_p1 = 0xff; m_cctl_p2 = 0xff; m_ucpu_p1 = 0xff; m_csnd_p1 = 0xff; save_item(NAME(m_tclk_val)); - save_item(NAME(m_in0_val)); - save_item(NAME(m_in1_val)); save_item(NAME(m_cctl_p1)); save_item(NAME(m_cctl_p2)); save_item(NAME(m_ucpu_p1)); diff --git a/src/mame/drivers/osborne1.cpp b/src/mame/drivers/osborne1.cpp index f94df70c8b5..99b68229b14 100644 --- a/src/mame/drivers/osborne1.cpp +++ b/src/mame/drivers/osborne1.cpp @@ -180,7 +180,7 @@ static INPUT_PORTS_START( osborne1 ) PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) PORT_START("RESET") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RESET") PORT_CODE(KEYCODE_F12) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RESET") PORT_CODE(KEYCODE_F12) PORT_CHANGED_MEMBER(DEVICE_SELF, osborne1_state, reset_key, 0) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED) PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) diff --git a/src/mame/drivers/pitnrun.cpp b/src/mame/drivers/pitnrun.cpp index 0147a3716a2..80d20ddf5b9 100644 --- a/src/mame/drivers/pitnrun.cpp +++ b/src/mame/drivers/pitnrun.cpp @@ -66,22 +66,25 @@ K1000233A */ #include "emu.h" -#include "cpu/z80/z80.h" +#include "includes/pitnrun.h" + #include "cpu/m6805/m68705.h" +#include "cpu/z80/z80.h" + #include "machine/gen_latch.h" #include "machine/watchdog.h" + #include "sound/ay8910.h" -#include "includes/pitnrun.h" INTERRUPT_GEN_MEMBER(pitnrun_state::nmi_source) { - if(m_nmi) device.execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); + if (m_nmi) device.execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); } WRITE8_MEMBER(pitnrun_state::nmi_enable_w) { - m_nmi = data & 1; + m_nmi = data & 1; } WRITE8_MEMBER(pitnrun_state::hflip_w) @@ -136,15 +139,6 @@ static ADDRESS_MAP_START( pitnrun_sound_io_map, AS_IO, 8, pitnrun_state ) AM_RANGE(0x98, 0x98) AM_WRITENOP ADDRESS_MAP_END -static ADDRESS_MAP_START( pitnrun_mcu_map, AS_PROGRAM, 8, pitnrun_state ) - ADDRESS_MAP_GLOBAL_MASK(0x7ff) - AM_RANGE(0x0000, 0x0000) AM_READWRITE(m68705_portA_r,m68705_portA_w) - AM_RANGE(0x0001, 0x0001) AM_READWRITE(m68705_portB_r,m68705_portB_w) - AM_RANGE(0x0002, 0x0002) AM_READ(m68705_portC_r) - AM_RANGE(0x0003, 0x007f) AM_RAM - AM_RANGE(0x0080, 0x07ff) AM_ROM -ADDRESS_MAP_END - static INPUT_PORTS_START( pitnrun ) PORT_START("SYSTEM") @@ -231,8 +225,12 @@ static MACHINE_CONFIG_START( pitnrun, pitnrun_state ) MCFG_CPU_IO_MAP(pitnrun_sound_io_map) MCFG_CPU_VBLANK_INT_DRIVER("screen", pitnrun_state, irq0_line_hold) - MCFG_CPU_ADD("mcu", M68705,XTAL_18_432MHz/6) /* verified on pcb */ - MCFG_CPU_PROGRAM_MAP(pitnrun_mcu_map) + MCFG_CPU_ADD("mcu", M68705P5, XTAL_18_432MHz/6) /* verified on pcb */ + MCFG_M68705_PORTA_R_CB(READ8(pitnrun_state, m68705_portA_r)) + MCFG_M68705_PORTB_R_CB(READ8(pitnrun_state, m68705_portB_r)) + MCFG_M68705_PORTC_R_CB(READ8(pitnrun_state, m68705_portC_r)) + MCFG_M68705_PORTA_W_CB(WRITE8(pitnrun_state, m68705_portA_w)) + MCFG_M68705_PORTB_W_CB(WRITE8(pitnrun_state, m68705_portB_w)) MCFG_WATCHDOG_ADD("watchdog") diff --git a/src/mame/drivers/zorba.cpp b/src/mame/drivers/zorba.cpp index cc1faf0c449..2efeeed1112 100644 --- a/src/mame/drivers/zorba.cpp +++ b/src/mame/drivers/zorba.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Robbbert +// copyright-holders:Robbbert, Vas Crabb /************************************************************************************************************ Telcon Industries/Modular Micros/Gemini Electronics Zorba @@ -36,6 +36,10 @@ The startup screen varies across each company: - Modular Micros: "ZORBA" graphical logo with "MODULAR MICROS, INC." below in normal text - Gemini: "GEMINI ZORBA" graphical logo +Strangely, the Zorba configures its keyboard UART for 8N2 but the keyboard we're emulating sends 8N1. +If you type too fast or hold down a key until it repeats, characters will be dropped/corrupted. It's +possible we have a dump of a different CP/M-compatible keyboard, not the one supplied with the Zorba. + Status: - Boots up, and the keyboard works @@ -44,8 +48,6 @@ ToDo: - Add masking feature (only used for the UARTs) - Connect devices to the above hardware - Fix the display -- Connect the PIT to the UARTs -- Replace the ascii keyboard with the real one, if possible - Dump Telcon and Gemini BIOSes - Emulate the Co-Power-88 expansion (allows PC-DOS, CP/M-86, etc. to be used) - Probably lots of other things @@ -53,105 +55,44 @@ ToDo: *************************************************************************************************************/ - #include "emu.h" +#include "includes/zorba.h" + +#include "machine/zorbakbd.h" + +#include "bus/centronics/ctronics.h" +#include "bus/rs232/rs232.h" + #include "cpu/z80/z80.h" #include "cpu/m6805/m68705.h" -#include "machine/i8251.h" -#include "machine/6821pia.h" -#include "machine/z80dma.h" + +#include "machine/input_merger.h" +#include "machine/latch.h" #include "machine/pit8253.h" -#include "video/i8275.h" -#include "sound/beep.h" -#include "machine/keyboard.h" -#include "machine/wd_fdc.h" + #include "softlist.h" -class zorba_state : public driver_device -{ -public: - zorba_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_palette(*this, "palette") - , m_maincpu(*this, "maincpu") - , m_beep(*this, "beeper") - , m_dma(*this, "dma") - , m_u0(*this, "uart0") - , m_u1(*this, "uart1") - , m_u2(*this, "uart2") - , m_pia0(*this, "pia0") - , m_pia1(*this, "pia1") - , m_crtc(*this, "crtc") - , m_fdc (*this, "fdc") - , m_floppy0(*this, "fdc:0") - , m_floppy1(*this, "fdc:1") - {} - -public: - const uint8_t *m_p_chargen; - DECLARE_DRIVER_INIT(zorba); - DECLARE_MACHINE_RESET(zorba); - DECLARE_READ8_MEMBER(ram_r); - DECLARE_WRITE8_MEMBER(ram_w); - DECLARE_READ8_MEMBER(rom_r); - DECLARE_WRITE8_MEMBER(rom_w); - DECLARE_WRITE8_MEMBER(intmask_w); - DECLARE_WRITE_LINE_MEMBER(busreq_w); - DECLARE_READ8_MEMBER(memory_read_byte); - DECLARE_WRITE8_MEMBER(memory_write_byte); - DECLARE_READ8_MEMBER(io_read_byte); - DECLARE_WRITE8_MEMBER(io_write_byte); - DECLARE_WRITE8_MEMBER(pia0_porta_w); - DECLARE_WRITE8_MEMBER(kbd_put); - DECLARE_READ8_MEMBER(keyboard_r); - DECLARE_WRITE_LINE_MEMBER(irq0_w); - DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); - DECLARE_WRITE_LINE_MEMBER(fdc_intrq_w); - I8275_DRAW_CHARACTER_MEMBER(zorba_update_chr); - required_device<palette_device> m_palette; - -private: - uint8_t m_term_data; - uint8_t m_fdc_rq; - required_device<cpu_device> m_maincpu; - required_device<beep_device> m_beep; - required_device<z80dma_device> m_dma; - required_device<i8251_device> m_u0; - required_device<i8251_device> m_u1; - required_device<i8251_device> m_u2; - required_device<pia6821_device> m_pia0; - required_device<pia6821_device> m_pia1; - required_device<i8275_device> m_crtc; - required_device<fd1793_t> m_fdc; - required_device<floppy_connector> m_floppy0; - required_device<floppy_connector> m_floppy1; -}; +namespace { -static ADDRESS_MAP_START( zorba_mem, AS_PROGRAM, 8, zorba_state ) +ADDRESS_MAP_START( zorba_mem, AS_PROGRAM, 8, zorba_state ) AM_RANGE( 0x0000, 0x3fff ) AM_READ_BANK("bankr0") AM_WRITE_BANK("bankw0") AM_RANGE( 0x4000, 0xffff ) AM_RAM ADDRESS_MAP_END -static ADDRESS_MAP_START( zorba_kbdmem, AS_PROGRAM, 8, zorba_state ) - ADDRESS_MAP_GLOBAL_MASK(0x7ff) - AM_RANGE( 0x000, 0x07f ) AM_RAM // internal RAM - AM_RANGE( 0x080, 0x7ff ) AM_ROM // internal EPROM -ADDRESS_MAP_END -static ADDRESS_MAP_START( zorba_io, AS_IO, 8, zorba_state ) +ADDRESS_MAP_START( zorba_io, AS_IO, 8, zorba_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("pit", pit8254_device, read, write) - AM_RANGE(0x04, 0x04) AM_READWRITE(rom_r,rom_w) - AM_RANGE(0x05, 0x05) AM_READWRITE(ram_r,ram_w) + AM_RANGE(0x04, 0x04) AM_READWRITE(rom_r, rom_w) + AM_RANGE(0x05, 0x05) AM_READWRITE(ram_r, ram_w) AM_RANGE(0x10, 0x11) AM_DEVREADWRITE("crtc", i8275_device, read, write) AM_RANGE(0x20, 0x20) AM_DEVREADWRITE("uart0", i8251_device, data_r, data_w) AM_RANGE(0x21, 0x21) AM_DEVREADWRITE("uart0", i8251_device, status_r, control_w) AM_RANGE(0x22, 0x22) AM_DEVREADWRITE("uart1", i8251_device, data_r, data_w) AM_RANGE(0x23, 0x23) AM_DEVREADWRITE("uart1", i8251_device, status_r, control_w) - //AM_RANGE(0x24, 0x24) AM_DEVREADWRITE("uart2", i8251_device, data_r, data_w) - //AM_RANGE(0x25, 0x25) AM_DEVREADWRITE("uart2", i8251_device, status_r, control_w) - AM_RANGE(0x24, 0x25) AM_READ(keyboard_r) AM_WRITENOP + AM_RANGE(0x24, 0x24) AM_DEVREADWRITE("uart2", i8251_device, data_r, data_w) + AM_RANGE(0x25, 0x25) AM_DEVREADWRITE("uart2", i8251_device, status_r, control_w) AM_RANGE(0x26, 0x26) AM_WRITE(intmask_w) AM_RANGE(0x30, 0x30) AM_DEVREADWRITE("dma", z80dma_device, read, write) AM_RANGE(0x40, 0x43) AM_DEVREADWRITE("fdc", fd1793_t, read, write) @@ -159,83 +100,294 @@ static ADDRESS_MAP_START( zorba_io, AS_IO, 8, zorba_state ) AM_RANGE(0x60, 0x63) AM_DEVREADWRITE("pia1", pia6821_device, read, write) ADDRESS_MAP_END + +INPUT_PORTS_START( zorba ) + PORT_START("CNF") + PORT_CONFNAME(0x01, 0x00, "Parallel Printer") PORT_CHANGED_MEMBER(DEVICE_SELF, zorba_state, printer_type, 0) + PORT_CONFSETTING(0x00, "Centronics") + PORT_CONFSETTING(0x01, "Prowriter") +INPUT_PORTS_END + + +SLOT_INTERFACE_START( zorba_floppies ) + SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) +SLOT_INTERFACE_END + + +// F4 Character Displayer +const gfx_layout u5_charlayout = +{ + 8, 11, // 8 x 11 characters + 256, // 256 characters + 1, // 1 bits per pixel + { 0 }, // no bitplanes + /* x offsets */ + { 0, 1, 2, 3, 4, 5, 6, 7 }, + /* y offsets */ + { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8 }, + 8*16 // every char takes 16 bytes +}; + +GFXDECODE_START( zorba ) + GFXDECODE_ENTRY( "chargen", 0x0000, u5_charlayout, 0, 1 ) +GFXDECODE_END + + +MACHINE_CONFIG_START( zorba, zorba_state ) + // basic machine hardware + MCFG_CPU_ADD("maincpu", Z80, XTAL_24MHz / 6) + MCFG_CPU_PROGRAM_MAP(zorba_mem) + MCFG_CPU_IO_MAP(zorba_io) + MCFG_MACHINE_RESET_OVERRIDE(zorba_state, zorba) + + /* video hardware */ + MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green()) + MCFG_SCREEN_REFRESH_RATE(50) + MCFG_SCREEN_UPDATE_DEVICE("crtc", i8275_device, screen_update) + MCFG_GFXDECODE_ADD("gfxdecode", "palette", zorba) + MCFG_PALETTE_ADD_MONOCHROME_HIGHLIGHT("palette") + + /* sound hardware */ + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD("beeper", BEEP, 800) // should be horizontal frequency / 16, so depends on CRTC parameters + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) + + MCFG_INPUT_MERGER_ACTIVE_HIGH("irq0") + MCFG_INPUT_MERGER_OUTPUT_HANDLER(WRITELINE(zorba_state, irq_w<0>)) + MCFG_INPUT_MERGER_ACTIVE_HIGH("irq1") + MCFG_INPUT_MERGER_OUTPUT_HANDLER(WRITELINE(zorba_state, irq_w<1>)) + MCFG_INPUT_MERGER_ACTIVE_HIGH("irq2") + MCFG_INPUT_MERGER_OUTPUT_HANDLER(WRITELINE(zorba_state, irq_w<2>)) + + /* devices */ + MCFG_DEVICE_ADD("dma", Z80DMA, XTAL_24MHz/6) + // busack on cpu connects to bai pin + MCFG_Z80DMA_OUT_BUSREQ_CB(WRITELINE(zorba_state, busreq_w)) //connects to busreq on cpu + MCFG_Z80DMA_OUT_INT_CB(DEVWRITELINE("irq0", input_merger_active_high_device, in0_w)) + //ba0 - not connected + MCFG_Z80DMA_IN_MREQ_CB(READ8(zorba_state, memory_read_byte)) + MCFG_Z80DMA_OUT_MREQ_CB(WRITE8(zorba_state, memory_write_byte)) + MCFG_Z80DMA_IN_IORQ_CB(READ8(zorba_state, io_read_byte)) + MCFG_Z80DMA_OUT_IORQ_CB(WRITE8(zorba_state, io_write_byte)) + + MCFG_DEVICE_ADD("uart0", I8251, 0) // U32 COM port J2 + MCFG_I8251_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) // TODO: this line has a LED attached + MCFG_I8251_DTR_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + MCFG_I8251_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + MCFG_I8251_RXRDY_HANDLER(WRITELINE(zorba_state, tx_rx_rdy_w<1>)) + MCFG_I8251_TXRDY_HANDLER(WRITELINE(zorba_state, tx_rx_rdy_w<0>)) + + MCFG_DEVICE_ADD("uart1", I8251, 0) // U31 printer port J3 + MCFG_I8251_TXD_HANDLER(DEVWRITELINE("serprn", rs232_port_device, write_txd)) + MCFG_I8251_RTS_HANDLER(DEVWRITELINE("serprn", rs232_port_device, write_rts)) + MCFG_I8251_RXRDY_HANDLER(WRITELINE(zorba_state, tx_rx_rdy_w<3>)) + MCFG_I8251_TXRDY_HANDLER(WRITELINE(zorba_state, tx_rx_rdy_w<2>)) + + MCFG_DEVICE_ADD("uart2", I8251, 0) // U30 serial keyboard J6 + MCFG_I8251_TXD_HANDLER(DEVWRITELINE("keyboard", zorba_keyboard_device, txd_w)) + MCFG_I8251_RXRDY_HANDLER(WRITELINE(zorba_state, tx_rx_rdy_w<5>)) + MCFG_I8251_TXRDY_HANDLER(WRITELINE(zorba_state, tx_rx_rdy_w<4>)) + + // port A - disk select etc, beeper + // port B - parallel interface + MCFG_DEVICE_ADD("pia0", PIA6821, 0) + MCFG_PIA_WRITEPA_HANDLER(WRITE8(zorba_state, pia0_porta_w)) + MCFG_PIA_WRITEPB_HANDLER(DEVWRITE8("parprndata", output_latch_device, write)) + MCFG_PIA_CB2_HANDLER(DEVWRITELINE("parprn", centronics_device, write_strobe)) + + // IEEE488 interface + MCFG_DEVICE_ADD("pia1", PIA6821, 0) + MCFG_PIA_READPA_HANDLER(DEVREAD8(IEEE488_TAG, ieee488_device, dio_r)) // TODO: gated with PB1 + MCFG_PIA_WRITEPA_HANDLER(DEVWRITE8(IEEE488_TAG, ieee488_device, dio_w)) // TODO: gated with PB1 + MCFG_PIA_READPB_HANDLER(READ8(zorba_state, pia1_portb_r)) + MCFG_PIA_WRITEPB_HANDLER(WRITE8(zorba_state, pia1_portb_w)) + MCFG_PIA_CA2_HANDLER(DEVWRITELINE(IEEE488_TAG, ieee488_device, ifc_w)) + MCFG_PIA_CB2_HANDLER(DEVWRITELINE(IEEE488_TAG, ieee488_device, ren_w)) + MCFG_PIA_IRQA_HANDLER(DEVWRITELINE("irq1", input_merger_active_high_device, in0_w)) + MCFG_PIA_IRQB_HANDLER(DEVWRITELINE("irq1", input_merger_active_high_device, in1_w)) + + // PIT + MCFG_DEVICE_ADD("pit", PIT8254, 0) + MCFG_PIT8253_CLK0(XTAL_24MHz / 3) + MCFG_PIT8253_CLK1(XTAL_24MHz / 3) + MCFG_PIT8253_CLK2(XTAL_24MHz / 3) + MCFG_PIT8253_OUT0_HANDLER(WRITELINE(zorba_state, br1_w)) + MCFG_PIT8253_OUT1_HANDLER(DEVWRITELINE("uart1", i8251_device, write_txc)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart1", i8251_device, write_rxc)) + MCFG_PIT8253_OUT2_HANDLER(DEVWRITELINE("uart2", i8251_device, write_txc)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart2", i8251_device, write_rxc)) + + // CRTC + MCFG_DEVICE_ADD("crtc", I8275, XTAL_14_31818MHz/7) + MCFG_I8275_CHARACTER_WIDTH(8) + MCFG_I8275_DRAW_CHARACTER_CALLBACK_OWNER(zorba_state, zorba_update_chr) + MCFG_I8275_DRQ_CALLBACK(DEVWRITELINE("dma", z80dma_device, rdy_w)) + MCFG_I8275_IRQ_CALLBACK(DEVWRITELINE("irq0", input_merger_active_high_device, in1_w)) + + // Floppies + MCFG_FD1793_ADD("fdc", XTAL_24MHz / 24) + MCFG_WD_FDC_INTRQ_CALLBACK(DEVWRITELINE("irq2", input_merger_active_high_device, in0_w)) + MCFG_WD_FDC_DRQ_CALLBACK(DEVWRITELINE("irq2", input_merger_active_high_device, in1_w)) + MCFG_FLOPPY_DRIVE_ADD("fdc:0", zorba_floppies, "525dd", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_SOUND(true) + MCFG_FLOPPY_DRIVE_ADD("fdc:1", zorba_floppies, "525dd", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_SOUND(true) + + // J1 IEEE-488 + MCFG_IEEE488_BUS_ADD() + MCFG_IEEE488_SRQ_CALLBACK(DEVWRITELINE("pia1", pia6821_device, ca2_w)) // TODO: gated with PB1 from PIA + + // J2 EIA RS232/internal modem + // TODO: this has additional lines compared to a regular RS232 port (TxC in, RxC in, RxC out, speaker in, power) + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart0", i8251_device, write_rxd)) // TODO: this line has a LED attached + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("uart0", i8251_device, write_cts)) // TODO: this line has a LED attached + MCFG_RS232_DSR_HANDLER(DEVWRITELINE("uart0", i8251_device, write_dsr)) + + // J3 Parallel printer + MCFG_CENTRONICS_OUTPUT_LATCH_ADD("parprndata", "parprn") + MCFG_CENTRONICS_ADD("parprn", centronics_devices, "printer") + MCFG_CENTRONICS_BUSY_HANDLER(DEVWRITELINE("uart1", i8251_device, write_cts)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart1", i8251_device, write_dsr)) // TODO: shared with serial CTS + MCFG_CENTRONICS_FAULT_HANDLER(WRITELINE(zorba_state, printer_fault_w)) + MCFG_CENTRONICS_SELECT_HANDLER(WRITELINE(zorba_state, printer_select_w)) + + // J3 Serial printer + MCFG_RS232_PORT_ADD("serprn", default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart1", i8251_device, write_rxd)) // TODO: this line has a LED attached + + // J6 TTL-level serial keyboard + MCFG_DEVICE_ADD("keyboard", ZORBA_KEYBOARD, 0) + MCFG_ZORBA_KEYBOARD_RXD_CB(DEVWRITELINE("uart2", i8251_device, write_rxd)) + //MCFG_QUANTUM_PERFECT_CPU("keyboard:mcu") + + MCFG_SOFTWARE_LIST_ADD("flop_list", "zorba") +MACHINE_CONFIG_END + +} // anonymous namespace + + +//------------------------------------------------- +// Initialise/reset +//------------------------------------------------- + +DRIVER_INIT_MEMBER( zorba_state, zorba ) +{ + uint8_t *main = memregion("maincpu")->base(); + + membank("bankr0")->configure_entry(0, &main[0x0000]); + membank("bankr0")->configure_entry(1, &main[0x10000]); + membank("bankw0")->configure_entry(0, &main[0x0000]); + + save_item(NAME(m_intmask)); + save_item(NAME(m_tx_rx_rdy)); + save_item(NAME(m_irq)); + + save_item(NAME(m_printer_prowriter)); + save_item(NAME(m_printer_fault)); + save_item(NAME(m_printer_select)); + + save_item(NAME(m_term_data)); + + m_printer_prowriter = false; + m_printer_fault = 0; + m_printer_select = 0; +} + +MACHINE_RESET_MEMBER( zorba_state, zorba ) +{ + m_uart2->write_cts(0); // always asserted + + m_intmask = 0x00; + m_tx_rx_rdy = 0x00; + m_irq = 0x00; + + m_printer_prowriter = BIT(m_config_port->read(), 0); + m_pia0->cb1_w(m_printer_prowriter ? m_printer_select : m_printer_fault); + + m_read_bank->set_entry(1); // point at rom + membank("bankw0")->set_entry(0); // always write to ram + + m_maincpu->reset(); +} + + +//------------------------------------------------- +// Memory banking control +//------------------------------------------------- + READ8_MEMBER( zorba_state::ram_r ) { - membank("bankr0")->set_entry(0); + if (!space.debugger_access()) + m_read_bank->set_entry(0); return 0; } WRITE8_MEMBER( zorba_state::ram_w ) { - membank("bankr0")->set_entry(0); + m_read_bank->set_entry(0); } READ8_MEMBER( zorba_state::rom_r ) { - membank("bankr0")->set_entry(1); + if (!space.debugger_access()) + m_read_bank->set_entry(1); return 0; } WRITE8_MEMBER( zorba_state::rom_w ) { - membank("bankr0")->set_entry(1); + m_read_bank->set_entry(1); } -WRITE_LINE_MEMBER( zorba_state::irq0_w ) -{ - if (state) - { - m_maincpu->set_input_line_vector(0, 0x88); - m_maincpu->set_input_line(0, ASSERT_LINE); - } - else - m_maincpu->set_input_line(0, CLEAR_LINE); -} -WRITE_LINE_MEMBER( zorba_state::fdc_intrq_w ) -{ - m_fdc_rq = (m_fdc_rq & 2) | state; - if (m_fdc_rq == 1) - { - m_maincpu->set_input_line_vector(0, 0x80); - m_maincpu->set_input_line(0, ASSERT_LINE); - } - else - if (m_fdc_rq == 0) - m_maincpu->set_input_line(0, CLEAR_LINE); -} +//------------------------------------------------- +// Interrupt vectoring glue +//------------------------------------------------- -WRITE_LINE_MEMBER( zorba_state::fdc_drq_w ) +WRITE8_MEMBER( zorba_state::intmask_w ) { - m_fdc_rq = (m_fdc_rq & 1) | (state << 1); - if (m_fdc_rq == 2) - { - m_maincpu->set_input_line_vector(0, 0x80); - m_maincpu->set_input_line(0, ASSERT_LINE); - } - else - if (m_fdc_rq == 0) - m_maincpu->set_input_line(0, CLEAR_LINE); + m_intmask = data & 0x3f; // only six lines physically present + irq_w<3>(BIT(m_intmask & m_tx_rx_rdy, 0) | BIT(m_intmask & m_tx_rx_rdy, 1)); + irq_w<4>(BIT(m_intmask & m_tx_rx_rdy, 2) | BIT(m_intmask & m_tx_rx_rdy, 3)); + irq_w<5>(BIT(m_intmask & m_tx_rx_rdy, 4) | BIT(m_intmask & m_tx_rx_rdy, 5)); } -WRITE8_MEMBER( zorba_state::intmask_w ) +template <unsigned N> WRITE_LINE_MEMBER( zorba_state::tx_rx_rdy_w ) { + m_tx_rx_rdy = (m_tx_rx_rdy & ~(1 << N)) | ((state ? 1 : 0) << N); + irq_w<(N >> 1) + 3>(BIT(m_intmask & m_tx_rx_rdy, N & ~1) | BIT(m_intmask & m_tx_rx_rdy, N | 1)); } -static INPUT_PORTS_START( zorba ) -INPUT_PORTS_END - -DRIVER_INIT_MEMBER( zorba_state, zorba ) +template <unsigned N> WRITE_LINE_MEMBER( zorba_state::irq_w ) { - uint8_t *main = memregion("maincpu")->base(); - - membank("bankr0")->configure_entry(0, &main[0x0000]); - membank("bankr0")->configure_entry(1, &main[0x10000]); - membank("bankw0")->configure_entry(0, &main[0x0000]); + m_irq = (m_irq & ~(1 << N)) | ((state ? 1 : 0) << N); + + // TODO: get a good dump of the interrupt vector PROM and get rid of this hack + // There are six interrupt sources: + // * IRQ0: DMAC/CRTC shared + // * IRQ1: IEEE488 (PIA IRQA/IRQB shared) + // * IRQ2: FDC INTRQ/DRQ shared + // * IRQ3: RS232 TXRDY/RXRDY selectable + // * IRQ4: Serial printer TXRDY/RXRDY selectable + // * IRQ5: Keyboard TXRDY/RXRDY selectable + // Valid vectors are 0x80, 0x84, 0x88, 0x8c, 0x90 and 0x94 + // Floppy needs to be on 0x80, and RS232 is apparently on 0x88 + // Everything else, including priority, is a complete guess + u8 vector; + if (BIT(m_irq, 2)) vector = 0x80; + else if (BIT(m_irq, 3)) vector = 0x88; + else vector = 0x84; // very wrong, need test cases for other things + + m_maincpu->set_input_line_and_vector( + INPUT_LINE_IRQ0, + m_irq ? ASSERT_LINE : CLEAR_LINE, + vector); } + //------------------------------------------------- -// Z80DMA +// DMA controller handlers //------------------------------------------------- WRITE_LINE_MEMBER( zorba_state::busreq_w ) @@ -268,19 +420,28 @@ WRITE8_MEMBER(zorba_state::io_write_byte) address_space& prog_space = m_maincpu->space(AS_IO); if (offset == 0x10) - { m_crtc->dack_w(space, 0, data); - } else - { prog_space.write_byte(offset, data); - } } -static SLOT_INTERFACE_START( zorba_floppies ) - SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) -SLOT_INTERFACE_END +//------------------------------------------------- +// PIT handlers +//------------------------------------------------- + +WRITE_LINE_MEMBER( zorba_state::br1_w ) +{ + // TODO: these can be jumpered to inputs from J2 so a modem can generate Baud rates + // TODO: receive clock is exposed on J2 for external devices without Baud rate generators + m_uart0->write_txc(state); + m_uart0->write_rxc(state); +} + + +//------------------------------------------------- +// PIA handlers +//------------------------------------------------- WRITE8_MEMBER( zorba_state::pia0_porta_w ) { @@ -300,6 +461,50 @@ WRITE8_MEMBER( zorba_state::pia0_porta_w ) m_floppy1->get_device()->mon_w(BIT(data, 4)); } +READ8_MEMBER( zorba_state::pia1_portb_r ) +{ + // 0 (output only) + // 1 (output only) + // 2 (output only) + // 3 EOI gated with PB2 (active high) + // 4 (output only) + // 5 DAV gated with PB2 (active high) + // 6 NDAC gated with PB1 (active high) + // 7 NRFD gated with PB1 (active high) + + const uint8_t outputs(m_pia0->b_output()); + return + (m_ieee->eoi_r() << 3) | + (m_ieee->dav_r() << 5) | + (m_ieee->ndac_r() << 6) | + (m_ieee->nrfd_r() << 7) | + (BIT(outputs, 1) ? 0x00 : 0xc0) | + (BIT(outputs, 2) ? 0x00 : 0x28); +} + +WRITE8_MEMBER( zorba_state::pia1_portb_w ) +{ + // 0 DIO direction + // 1 NDAC/NRFD data direction, SRQ gate + // 2 EOI/DAV data direction + // 3 EOI gated with PB2 (active low) + // 4 ATN + // 5 DAV gated with PB2 (active low) + // 6 NDAC gated with PB1 (active low) + // 7 NRFD gated with PB1 (active low) + + m_ieee->eoi_w(BIT(data, 3) & BIT(~data, 2)); + m_ieee->atn_w(BIT(data, 4)); + m_ieee->dav_w(BIT(data, 5) & BIT(~data, 2)); + m_ieee->ndac_w(BIT(data, 6) & BIT(~data, 1)); + m_ieee->nrfd_w(BIT(data, 7) & BIT(~data, 1)); +} + + +//------------------------------------------------- +// Video +//------------------------------------------------- + I8275_DRAW_CHARACTER_MEMBER( zorba_state::zorba_update_chr ) { int i; @@ -321,138 +526,47 @@ I8275_DRAW_CHARACTER_MEMBER( zorba_state::zorba_update_chr ) } -/* F4 Character Displayer */ -static const gfx_layout u5_charlayout = -{ - 8, 11, /* 8 x 11 characters */ - 256, /* 256 characters */ - 1, /* 1 bits per pixel */ - { 0 }, /* no bitplanes */ - /* x offsets */ - { 0, 1, 2, 3, 4, 5, 6, 7 }, - /* y offsets */ - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8 }, - 8*16 /* every char takes 16 bytes */ -}; - -static GFXDECODE_START( zorba ) - GFXDECODE_ENTRY( "chargen", 0x0000, u5_charlayout, 0, 1 ) -GFXDECODE_END +//------------------------------------------------- +// Printer port glue +//------------------------------------------------- -MACHINE_RESET_MEMBER( zorba_state, zorba ) +WRITE_LINE_MEMBER( zorba_state::printer_fault_w ) { - m_fdc_rq = 0; - m_p_chargen = memregion("chargen")->base(); - membank("bankr0")->set_entry(1); // point at rom - membank("bankw0")->set_entry(0); // always write to ram - m_maincpu->reset(); + // connects to CB1 for Centronics + m_printer_fault = state; + if (!m_printer_prowriter) + m_pia0->cb1_w(state); } -READ8_MEMBER( zorba_state::keyboard_r ) +WRITE_LINE_MEMBER( zorba_state::printer_select_w ) { - if (offset) - return (m_term_data) ? 0x87 : 0x85; - - uint8_t data = m_term_data; - m_term_data = 0; - return data; + // connects to CB1 for Prowriter + m_printer_select = state; + if (m_printer_prowriter) + m_pia0->cb1_w(state); } -WRITE8_MEMBER( zorba_state::kbd_put ) +INPUT_CHANGED_MEMBER( zorba_state::printer_type ) { - m_term_data = data; + m_printer_prowriter = newval; + m_pia0->cb1_w(m_printer_prowriter ? m_printer_select : m_printer_fault); } -static MACHINE_CONFIG_START( zorba, zorba_state ) - // basic machine hardware - MCFG_CPU_ADD("maincpu", Z80, XTAL_24MHz / 6) - MCFG_CPU_PROGRAM_MAP(zorba_mem) - MCFG_CPU_IO_MAP(zorba_io) - MCFG_MACHINE_RESET_OVERRIDE(zorba_state, zorba) - - /* keyboard */ - MCFG_CPU_ADD("kbdcpu", M68705, XTAL_3_579545MHz) // MC68705P3S (0x80 bytes ram, 0x780 bytes of rom) - MCFG_CPU_PROGRAM_MAP(zorba_kbdmem) - - /* video hardware */ - MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green()) - MCFG_SCREEN_REFRESH_RATE(50) - MCFG_SCREEN_UPDATE_DEVICE("crtc", i8275_device, screen_update) - MCFG_GFXDECODE_ADD("gfxdecode", "palette", zorba) - MCFG_PALETTE_ADD_MONOCHROME_HIGHLIGHT("palette") - - /* sound hardware */ - MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_SOUND_ADD("beeper", BEEP, 800) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) - - /* devices */ - MCFG_DEVICE_ADD("dma", Z80DMA, XTAL_24MHz/6) - // busack on cpu connects to bai pin - MCFG_Z80DMA_OUT_BUSREQ_CB(WRITELINE(zorba_state, busreq_w)) //connects to busreq on cpu - MCFG_Z80DMA_OUT_INT_CB(WRITELINE(zorba_state, irq0_w)) // connects to IRQ0 on IM2 controller - //ba0 - not connected - MCFG_Z80DMA_IN_MREQ_CB(READ8(zorba_state, memory_read_byte)) - MCFG_Z80DMA_OUT_MREQ_CB(WRITE8(zorba_state, memory_write_byte)) - MCFG_Z80DMA_IN_IORQ_CB(READ8(zorba_state, io_read_byte)) - MCFG_Z80DMA_OUT_IORQ_CB(WRITE8(zorba_state, io_write_byte)) - - MCFG_DEVICE_ADD("uart0", I8251, 0) // U32 COM port J2 - - MCFG_DEVICE_ADD("uart1", I8251, 0) // U31 printer port J3 - - MCFG_DEVICE_ADD("uart2", I8251, 0) // U30 serial keyboard J6 - - // port A - disk select etc, beeper - // port B - parallel interface - MCFG_DEVICE_ADD("pia0", PIA6821, 0) - MCFG_PIA_WRITEPA_HANDLER(WRITE8(zorba_state, pia0_porta_w)) - - // IEEE488 interface - MCFG_DEVICE_ADD("pia1", PIA6821, 0) - - MCFG_DEVICE_ADD("pit", PIT8254, 0) - MCFG_PIT8253_CLK0(XTAL_24MHz / 3) /* Timer 0: clock to J2 comm port */ - MCFG_PIT8253_CLK1(XTAL_24MHz / 3) /* Timer 1: clock to U31 */ - MCFG_PIT8253_CLK2(XTAL_24MHz / 3) /* Timer 2: clock to U30 */ - - MCFG_DEVICE_ADD("crtc", I8275, XTAL_14_31818MHz/7) - MCFG_I8275_CHARACTER_WIDTH(8) - MCFG_I8275_DRAW_CHARACTER_CALLBACK_OWNER(zorba_state, zorba_update_chr) - MCFG_I8275_DRQ_CALLBACK(DEVWRITELINE("dma", z80dma_device, rdy_w)) - MCFG_I8275_IRQ_CALLBACK(WRITELINE(zorba_state, irq0_w)) - MCFG_FD1793_ADD("fdc", XTAL_24MHz / 24) - MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(zorba_state, fdc_intrq_w)) - MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(zorba_state, fdc_drq_w)) - MCFG_FLOPPY_DRIVE_ADD("fdc:0", zorba_floppies, "525dd", floppy_image_device::default_floppy_formats) - MCFG_FLOPPY_DRIVE_SOUND(true) - MCFG_FLOPPY_DRIVE_ADD("fdc:1", zorba_floppies, "525dd", floppy_image_device::default_floppy_formats) - MCFG_FLOPPY_DRIVE_SOUND(true) - - /* Keyboard */ - MCFG_DEVICE_ADD("keyboard", GENERIC_KEYBOARD, 0) - MCFG_GENERIC_KEYBOARD_CB(WRITE8(zorba_state, kbd_put)) - - MCFG_SOFTWARE_LIST_ADD("flop_list", "zorba") -MACHINE_CONFIG_END ROM_START( zorba ) ROM_REGION( 0x14000, "maincpu", ROMREGION_ERASEFF ) ROM_LOAD( "780000.u47", 0x10000, 0x1000, CRC(6d58f2c5) SHA1(7763f08c801cd36e5a761c6dc9f30a50b3bc482d) ) - ROM_REGION( 0x800, "kbdcpu", 0 ) - ROM_LOAD( "8999-1 3-28-83", 0x080, 0x780, CRC(79fe6c0d) SHA1(4b6fca9379d5199d1347ad1187cbfdebfc4c73e7) ) - ROM_REGION( 0x1000, "chargen", 0 ) ROM_LOAD( "773000.u5", 0x0000, 0x1000, CRC(d0a2f8fc) SHA1(29aee7ee657778c46e9800abd4955e6d4b33ef68) ) ROM_REGION( 0x60, "proms", 0 ) - ROM_LOAD( "74ls288.u37", 0x0000, 0x0020, CRC(0a67edd6) SHA1(c1ece8978a3a061e0130d43907fa63a71e75e75d) ) - ROM_LOAD( "74ls288.u38", 0x0020, 0x0020, CRC(5ec93ea7) SHA1(3a84c098474b05d5cbe1939a3e15f66d06470581) ) - ROM_LOAD( "74ls288.u77", 0x0040, 0x0020, CRC(946e03b0) SHA1(24240bdd7bdf507a5b51628fb36ad1266fc53a28) ) // suspected bad dump + ROM_LOAD( "74ls288.u37", 0x0000, 0x0020, CRC(0a67edd6) SHA1(c1ece8978a3a061e0130d43907fa63a71e75e75d) BAD_DUMP ) // looks like interrupt vector PROM dumped with scrambled lines + ROM_LOAD( "74ls288.u38", 0x0020, 0x0020, CRC(5ec93ea7) SHA1(3a84c098474b05d5cbe1939a3e15f66d06470581) BAD_DUMP ) // looks like bad dump of address decode PROM + ROM_LOAD( "74ls288.u77", 0x0040, 0x0020, CRC(946e03b0) SHA1(24240bdd7bdf507a5b51628fb36ad1266fc53a28) BAD_DUMP ) // looks like bad dump of address decode PROM ROM_END -COMP( 1984?, zorba, 0, 0, zorba, zorba, zorba_state, zorba, "Modular Micros", "Zorba (Modular Micros)", MACHINE_NOT_WORKING ) +COMP( 1984?, zorba, 0, 0, zorba, zorba, zorba_state, zorba, "Modular Micros", "Zorba (Modular Micros)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // Undumped versions (see startup screen notes at top of file) // COMP( 1983, zorbat, zorba, 0, zorba, zorba, zorba_state, zorba, "Telcon Industries", "Zorba (Telcon Industries)", MACHINE_NOT_WORKING ) diff --git a/src/mame/includes/gladiatr.h b/src/mame/includes/gladiatr.h index 60166ed4b99..39c99eb8391 100644 --- a/src/mame/includes/gladiatr.h +++ b/src/mame/includes/gladiatr.h @@ -83,8 +83,6 @@ public: , m_in2(*this, "IN2") , m_coins(*this, "COINS") , m_tclk_val(false) - , m_in0_val(0xff) - , m_in1_val(0xff) , m_cctl_p1(0xff) , m_cctl_p2(0xff) , m_ucpu_p1(0xff) @@ -123,6 +121,11 @@ public: DECLARE_WRITE8_MEMBER(csnd_p1_w); DECLARE_READ8_MEMBER(csnd_p2_r); + DECLARE_INPUT_CHANGED_MEMBER(p1_s1); + DECLARE_INPUT_CHANGED_MEMBER(p1_s2); + DECLARE_INPUT_CHANGED_MEMBER(p2_s1); + DECLARE_INPUT_CHANGED_MEMBER(p2_s2); + DECLARE_DRIVER_INIT(gladiatr); DECLARE_MACHINE_RESET(gladiator); @@ -137,7 +140,6 @@ private: required_ioport m_coins; bool m_tclk_val; - u8 m_in0_val, m_in1_val; u8 m_cctl_p1, m_cctl_p2; u8 m_ucpu_p1, m_csnd_p1; diff --git a/src/mame/includes/osborne1.h b/src/mame/includes/osborne1.h index bbe12f9efcb..56754a43e82 100644 --- a/src/mame/includes/osborne1.h +++ b/src/mame/includes/osborne1.h @@ -81,6 +81,8 @@ public: DECLARE_WRITE_LINE_MEMBER(serial_acia_irq_func); + DECLARE_INPUT_CHANGED_MEMBER(reset_key); + DECLARE_DRIVER_INIT(osborne1); virtual void machine_reset() override; virtual void video_start() override; diff --git a/src/mame/includes/zorba.h b/src/mame/includes/zorba.h new file mode 100644 index 00000000000..9eae677473f --- /dev/null +++ b/src/mame/includes/zorba.h @@ -0,0 +1,113 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert, Vas Crabb + +#include "sound/beep.h" + +#include "bus/ieee488/ieee488.h" + +#include "machine/6821pia.h" +#include "machine/i8251.h" +#include "machine/wd_fdc.h" +#include "machine/z80dma.h" + +#include "video/i8275.h" + + +class zorba_state : public driver_device +{ +public: + zorba_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_config_port(*this, "CNF") + , m_read_bank(*this, "bankr0") + , m_p_chargen(*this, "chargen") + , m_maincpu(*this, "maincpu") + , m_dma(*this, "dma") + , m_uart0(*this, "uart0") + , m_uart1(*this, "uart1") + , m_uart2(*this, "uart2") + , m_pia0(*this, "pia0") + , m_pia1(*this, "pia1") + , m_palette(*this, "palette") + , m_crtc(*this, "crtc") + , m_beep(*this, "beeper") + , m_fdc (*this, "fdc") + , m_floppy0(*this, "fdc:0") + , m_floppy1(*this, "fdc:1") + , m_ieee(*this, IEEE488_TAG) + { + } + +public: + DECLARE_DRIVER_INIT(zorba); + DECLARE_MACHINE_RESET(zorba); + + // Memory banking control + DECLARE_READ8_MEMBER(ram_r); + DECLARE_WRITE8_MEMBER(ram_w); + DECLARE_READ8_MEMBER(rom_r); + DECLARE_WRITE8_MEMBER(rom_w); + + // Interrupt vectoring glue + DECLARE_WRITE8_MEMBER(intmask_w); + template <unsigned N> DECLARE_WRITE_LINE_MEMBER(tx_rx_rdy_w); + template <unsigned N> DECLARE_WRITE_LINE_MEMBER(irq_w); + + // DMA controller handlers + DECLARE_WRITE_LINE_MEMBER(busreq_w); + DECLARE_READ8_MEMBER(memory_read_byte); + DECLARE_WRITE8_MEMBER(memory_write_byte); + DECLARE_READ8_MEMBER(io_read_byte); + DECLARE_WRITE8_MEMBER(io_write_byte); + + // PIT handlers + DECLARE_WRITE_LINE_MEMBER(br1_w); + + // PIA handlers + DECLARE_WRITE8_MEMBER(pia0_porta_w); + DECLARE_READ8_MEMBER(pia1_portb_r); + DECLARE_WRITE8_MEMBER(pia1_portb_w); + + // Video + I8275_DRAW_CHARACTER_MEMBER(zorba_update_chr); + + // Printer port glue + DECLARE_WRITE_LINE_MEMBER(printer_fault_w); + DECLARE_WRITE_LINE_MEMBER(printer_select_w); + DECLARE_INPUT_CHANGED_MEMBER(printer_type); + +private: + required_ioport m_config_port; + + required_memory_bank m_read_bank; + required_region_ptr<uint8_t> m_p_chargen; + + required_device<cpu_device> m_maincpu; + required_device<z80dma_device> m_dma; + required_device<i8251_device> m_uart0; + required_device<i8251_device> m_uart1; + required_device<i8251_device> m_uart2; + required_device<pia6821_device> m_pia0; + required_device<pia6821_device> m_pia1; + + required_device<palette_device> m_palette; + required_device<i8275_device> m_crtc; + + required_device<beep_device> m_beep; + + required_device<fd1793_t> m_fdc; + required_device<floppy_connector> m_floppy0; + required_device<floppy_connector> m_floppy1; + + required_device<ieee488_device> m_ieee; + + uint8_t m_intmask; + uint8_t m_tx_rx_rdy; + uint8_t m_irq; + + bool m_printer_prowriter; + int m_printer_fault; + int m_printer_select; + + uint8_t m_term_data; +}; diff --git a/src/mame/machine/osborne1.cpp b/src/mame/machine/osborne1.cpp index cd649cef91a..cb9f84f5bf3 100644 --- a/src/mame/machine/osborne1.cpp +++ b/src/mame/machine/osborne1.cpp @@ -252,6 +252,14 @@ WRITE_LINE_MEMBER( osborne1_state::serial_acia_irq_func ) } +INPUT_CHANGED_MEMBER( osborne1_state::reset_key ) +{ + // This key affects NMI + if (!m_ub6a_q) + m_maincpu->set_input_line(INPUT_LINE_NMI, newval ? CLEAR_LINE : ASSERT_LINE); +} + + DRIVER_INIT_MEMBER( osborne1_state, osborne1 ) { m_bank_0xxx->configure_entries(0, 1, m_ram->pointer(), 0); @@ -443,10 +451,6 @@ TIMER_CALLBACK_MEMBER(osborne1_state::video_callback) m_beep_state = (ra & 0x04) ? 1 : 0; m_speaker->level_w((BIT(port_b, 5) && m_beep_state) ? 1 : 0); - // Check reset key if necessary - it affects NMI - if (!m_ub6a_q) - m_maincpu->set_input_line(INPUT_LINE_NMI, (m_btn_reset->read() & 0x80) ? CLEAR_LINE : ASSERT_LINE); - m_video_timer->adjust(machine().first_screen()->time_until_pos(y + 1, 0)); } diff --git a/src/mame/machine/taito68705interface.cpp b/src/mame/machine/taito68705interface.cpp index 3af9611ef43..3cb18183b9a 100644 --- a/src/mame/machine/taito68705interface.cpp +++ b/src/mame/machine/taito68705interface.cpp @@ -38,7 +38,6 @@ bublbobl.cpp - bub68705 - this is a bootleg, not an official Taito hookup changela.cpp - changela - looks like an ancestor of arkanoid without automatic semaphores mexico86.cpp - knightb, mexico86 - bootleg 68705s - retofinv.cpp - the current MCU dump is a bootleg at least sqix.cpp - hotsmash - kaneko hookup, different from Taito ones. there are other drivers (and games in existing drivers) that could hookup here, but currently lack MCU dumps. diff --git a/src/mame/machine/zorbakbd.cpp b/src/mame/machine/zorbakbd.cpp new file mode 100644 index 00000000000..379a021a56b --- /dev/null +++ b/src/mame/machine/zorbakbd.cpp @@ -0,0 +1,314 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/* + * TTL-level serial matrix keyboard + * + * The keyboard MCU handles scanning the matrix and converting key down/ + * up events to high-level characters for the host computer. The DIP + * switches are only read on startup. + * + * TODO: the eight "holes" generate control codes, six of them are break, home and the arrows + * + * Strangely, the Zorba configures its keyboard UART for 8N2 but this + * keyboard sends 8N1. If you type too fast or hold down a key until it + * repeats, characters will be dropped/corrupted. It's possible this is + * a dump of a different CP/M-compatible keyboard, not the one supplied + * with the Zorba. + * + * The Zorba manual describes a keyboard PROM with enough space to map + * all eight modifier combinations independently, however this keyboard + * contains no PROMs (just the MCU and demultiplexer), and the internal + * MCU EPROM only contains three tables for normal, shift, and control + * (caps lock is computed off the normal table by checking for letter + * characters). + * + * 0 1 2 3 4 5 6 7 + * 0 F1 F13 3 # KP8 i I s S KP2 , < + * 1 F2 F14 4 $ KP9 o O d D KP3 . > + * 2 F3 F15 5 % p P f F / ? + * 3 F4 F16 6 ^ [ { g G KP0 + * 4 F5 F17 7 & tab ] } h H shift KP. + * 5 F6 F18 8 * q Q KP4 j J z Z + * 6 F7 F19 9 ( w W KP5 k K x X + * 7 F8 ~ 0 ) e E KP6 l L c C space + * 8 F9 \ | - _ r R s-lock ; : v V newline + * 9 F10 ESC = + t T ctrl ' " b B KP- + * 10 F11 1 ! del y Y c-lock return n N + * 11 F12 2 @ KP7 u U a A KP1 m M + */ +#include "emu.h" +#include "zorbakbd.h" + +#include "cpu/m6805/m68705.h" + + +namespace { + +INPUT_PORTS_START(zorba_keyboard) + PORT_START("ROW0") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F13") PORT_CODE(KEYCODE_F13) PORT_CHAR(UCHAR_MAMEKEY(F13)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 8") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 2") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + + PORT_START("ROW1") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F14") PORT_CODE(KEYCODE_F14) PORT_CHAR(UCHAR_MAMEKEY(F14)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 9") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 3") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + + PORT_START("ROW2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F15") PORT_CODE(KEYCODE_F15) PORT_CHAR(UCHAR_MAMEKEY(F15)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) // b9 + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) // b3 + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + + PORT_START("ROW3") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F3)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F16") PORT_CODE(KEYCODE_F16) PORT_CHAR(UCHAR_MAMEKEY(F16)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) // b7 + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) // b4 + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) + + PORT_START("ROW4") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F5") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F17") PORT_CODE(KEYCODE_F17) PORT_CHAR(UCHAR_MAMEKEY(F17)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP .") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) + + PORT_START("ROW5") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F6") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F18") PORT_CODE(KEYCODE_F18) PORT_CHAR(UCHAR_MAMEKEY(F18)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 4") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // b5 + + PORT_START("ROW6") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F7") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F19") PORT_CODE(KEYCODE_F19) PORT_CHAR(UCHAR_MAMEKEY(F19)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 5") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // b6 + + PORT_START("ROW7") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F8") PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("~ PRINT") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('~') PORT_CHAR(UCHAR_MAMEKEY(PRTSCR)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 6") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + + PORT_START("ROW8") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F9") PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT LOCK") PORT_CODE(KEYCODE_LALT) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("NEW LINE") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) + + PORT_START("ROW9") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F10") PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP -") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) + + PORT_START("ROW10") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F11") PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("BS DEL") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_CHAR(UCHAR_MAMEKEY(DEL)) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CAPS LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // e0 + + PORT_START("ROW11") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F12") PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 7") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("KP 1") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // e1 + + PORT_START("ROW12") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) // scanned but the tables are too small so it would post garbage + + PORT_START("ROW13") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) // scanned but the tables are too small so it would post garbage + + PORT_START("ROW14") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) // scanned but the tables are too small so it would post garbage + + PORT_START("ROW15") + PORT_DIPNAME( 0x07, 0x07, "Diagnostic Mode" ) + PORT_DIPSETTING( 0x07, "0 (Normal)" ) + PORT_DIPSETTING( 0x06, "1 (Dump Tables)" ) + PORT_DIPSETTING( 0x05, "2 (Report Revision)" ) + PORT_DIPSETTING( 0x04, "3 (Serial Test)" ) + PORT_DIPSETTING( 0x03, "4 (Serial Echo)" ) + PORT_DIPSETTING( 0x02, "5 (Output Test)" ) + PORT_DIPSETTING( 0x01, "6 (Normal)" ) + PORT_DIPSETTING( 0x00, "7 (Dump Tables)" ) + PORT_DIPNAME( 0x08, 0x08, "Key Repeat" ) + PORT_DIPSETTING( 0x08, DEF_STR(On) ) + PORT_DIPSETTING( 0x00, DEF_STR(Off) ) + PORT_DIPNAME( 0x10, 0x10, "Baud Rate" ) + PORT_DIPSETTING( 0x10, "1200" ) + PORT_DIPSETTING( 0x00, "300" ) + PORT_DIPNAME( 0x20, 0x20, "Key Click" ) + PORT_DIPSETTING( 0x20, DEF_STR(On) ) + PORT_DIPSETTING( 0x00, DEF_STR(Off) ) + PORT_DIPNAME( 0x40, 0x20, DEF_STR(Unknown) ) + PORT_DIPSETTING( 0x20, DEF_STR(Off) ) + PORT_DIPSETTING( 0x00, DEF_STR(On) ) + PORT_DIPNAME( 0x80, 0x20, DEF_STR(Unknown) ) + PORT_DIPSETTING( 0x20, DEF_STR(Off) ) + PORT_DIPSETTING( 0x00, DEF_STR(On) ) +INPUT_PORTS_END + + +MACHINE_CONFIG_FRAGMENT(zorba_keyboard) + MCFG_CPU_ADD("mcu", M68705P3, XTAL_3_579545MHz) // MC68705P3S + MCFG_M68705_PORTA_R_CB(READ8(zorba_keyboard_device, mcu_pa_r)); + MCFG_M68705_PORTB_R_CB(READ8(zorba_keyboard_device, mcu_pb_r)); + MCFG_M68705_PORTB_W_CB(WRITE8(zorba_keyboard_device, mcu_pb_w)); + MCFG_M68705_PORTC_W_CB(WRITE8(zorba_keyboard_device, mcu_pc_w)); + + // TODO: beeper frequency is unknown, using value from Sun keyboard for now + MCFG_SPEAKER_STANDARD_MONO("bell") + MCFG_SOUND_ADD("beeper", BEEP, ATTOSECONDS_TO_HZ(480 * ATTOSECONDS_PER_MICROSECOND)) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "bell", 1.0) +MACHINE_CONFIG_END + + +ROM_START(zorba_keyboard) + ROM_REGION(0x0800, "mcu", 0) + ROM_LOAD( "8999-1 3-28-83", 0x080, 0x780, CRC(79fe6c0d) SHA1(4b6fca9379d5199d1347ad1187cbfdebfc4c73e7) ) +ROM_END + +} // anonymous namespace + + +device_type const ZORBA_KEYBOARD = &device_creator<zorba_keyboard_device>; + + +zorba_keyboard_device::zorba_keyboard_device( + machine_config const &mconfig, + char const *tag, + device_t *owner, + uint32_t clock) + : device_t( + mconfig, + ZORBA_KEYBOARD, + "Zorba Keyboard", + tag, + owner, + clock, + "zorba_kbd", + __FILE__) + , m_rows(*this, "ROW%u", 0) + , m_beeper(*this, "beeper") + , m_rxd_cb(*this) + , m_txd_high(true) + , m_row_select(0) +{ +} + + +WRITE_LINE_MEMBER(zorba_keyboard_device::txd_w) +{ + m_txd_high = CLEAR_LINE != state; +} + + +READ8_MEMBER(zorba_keyboard_device::mcu_pa_r) +{ + return m_rows[m_row_select]->read(); +} + + +READ8_MEMBER(zorba_keyboard_device::mcu_pb_r) +{ + return m_txd_high ? 0x7f : 0xff; +} + + +WRITE8_MEMBER(zorba_keyboard_device::mcu_pb_w) +{ + // TODO: bits 2/3/4 do something; some photos show F17/F18/F19 with LED windows + m_rxd_cb(BIT(data, 6) ? 0 : 1); + m_beeper->set_state(BIT(data, 5) ? 0 : 1); + machine().output().set_value("led_key_caps_lock", BIT(data, 1) ? 0 : 1); + machine().output().set_value("led_key_shift_lock", BIT(data, 0) ? 0 : 1); +} + + +WRITE8_MEMBER(zorba_keyboard_device::mcu_pc_w) +{ + m_row_select = data & 0x0f; +} + + +void zorba_keyboard_device::device_start() +{ + m_rxd_cb.resolve_safe(); + + save_item(NAME(m_txd_high)); + save_item(NAME(m_row_select)); + + m_txd_high = true; + m_row_select = 0; +} + + +machine_config_constructor zorba_keyboard_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME(zorba_keyboard); +} + + +ioport_constructor zorba_keyboard_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(zorba_keyboard); +} + + +tiny_rom_entry const *zorba_keyboard_device::device_rom_region() const +{ + return ROM_NAME(zorba_keyboard); +} diff --git a/src/mame/machine/zorbakbd.h b/src/mame/machine/zorbakbd.h new file mode 100644 index 00000000000..196a4831c41 --- /dev/null +++ b/src/mame/machine/zorbakbd.h @@ -0,0 +1,43 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +#ifndef MAME_MACHINE_ZORBAKBD_H +#define MAME_MACHINE_ZORBAKBD_H + +#include "sound/beep.h" + + +extern device_type const ZORBA_KEYBOARD; + +#define MCFG_ZORBA_KEYBOARD_RXD_CB(cb) \ + zorba_keyboard_device::set_rxd_cb(*device, DEVCB_##cb); + +class zorba_keyboard_device : public device_t +{ +public: + template <typename Obj> static devcb_base &set_rxd_cb(device_t &device, Obj &&object) + { return downcast<zorba_keyboard_device &>(device).m_rxd_cb.set_callback(std::forward<Obj>(object)); } + + zorba_keyboard_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); + + DECLARE_WRITE_LINE_MEMBER(txd_w); + + DECLARE_READ8_MEMBER(mcu_pa_r); + DECLARE_READ8_MEMBER(mcu_pb_r); + DECLARE_WRITE8_MEMBER(mcu_pb_w); + DECLARE_WRITE8_MEMBER(mcu_pc_w); + +protected: + virtual void device_start() override; + virtual machine_config_constructor device_mconfig_additions() const override; + virtual ioport_constructor device_input_ports() const override; + virtual tiny_rom_entry const *device_rom_region() const override; + + required_ioport_array<16> m_rows; + required_device<beep_device> m_beeper; + devcb_write_line m_rxd_cb; + + bool m_txd_high; + u8 m_row_select; +}; + +#endif // MAME_MACHINE_ZORBAKBD_H
\ No newline at end of file |