diff options
Diffstat (limited to 'src/mame/machine/concept.cpp')
-rw-r--r-- | src/mame/machine/concept.cpp | 401 |
1 files changed, 401 insertions, 0 deletions
diff --git a/src/mame/machine/concept.cpp b/src/mame/machine/concept.cpp new file mode 100644 index 00000000000..7beeb8fe1d7 --- /dev/null +++ b/src/mame/machine/concept.cpp @@ -0,0 +1,401 @@ +// license:GPL-2.0+ +// copyright-holders:Raphael Nabet, Brett Wyer +/* + Corvus Concept driver + + Raphael Nabet, Brett Wyer, 2003-2005 +*/ + +#include "emu.h" +#include "includes/concept.h" + + +#define VERBOSE 1 + +#define LOG(x) do { if (VERBOSE > 0) logerror x; } while (0) +#define VLOG(x) do { if (VERBOSE > 1) logerror x; } while (0) + + +/* interrupt priority encoder */ +enum +{ + IOCINT_level = 1, /* serial lines (CTS, DSR & DCD) and I/O ports */ + SR1INT_level, /* serial port 1 acia */ + OMINT_level, /* omninet */ + SR0INT_level, /* serial port 0 acia */ + TIMINT_level, /* via */ + KEYINT_level, /* keyboard acia */ + NMIINT_level /* reserved */ +}; + +/* Clock interface */ + +/* Omninet */ +/*static int ready;*/ /* ready line from monochip, role unknown */ + +/* Via */ + + +void concept_state::machine_start() +{ + /* initialize int state */ + m_pending_interrupts = 0; + + /* initialize clock interface */ + m_clock_enable = FALSE /*TRUE*/; + + save_item(NAME(m_pending_interrupts)); + save_item(NAME(m_clock_enable)); + save_item(NAME(m_clock_address)); +} + + +void concept_state::machine_reset() +{ + // OS will not boot if TDRE is clear on ACIA 0; this fixes that + m_acia0->write_cts(CLEAR_LINE); + m_acia1->write_cts(CLEAR_LINE); +} + +void concept_state::video_start() +{ +} + +UINT32 concept_state::screen_update_concept(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + /* resolution is 720*560 */ + UINT16 *videoram = m_videoram; + int x, y; + UINT16 *line; + + for (y = 0; y < 560; y++) + { + line = &bitmap.pix16(560-1-y); + for (x = 0; x < 720; x++) + line[720-1-x] = (videoram[(x+48+y*768)>>4] & (0x8000 >> ((x+48+y*768) & 0xf))) ? 1 : 0; + } + return 0; +} + +void concept_state::concept_set_interrupt(int level, int state) +{ + int interrupt_mask; + int final_level; + + if (state) + m_pending_interrupts |= 1 << level; + else + m_pending_interrupts &= ~ (1 << level); + + for (final_level = 7, interrupt_mask = m_pending_interrupts; (final_level > 0) && ! (interrupt_mask & 0x80); final_level--, interrupt_mask <<= 1) + ; + + if (final_level) + /* assert interrupt */ + m_maincpu->set_input_line_and_vector(M68K_IRQ_1 + final_level - 1, ASSERT_LINE, M68K_INT_ACK_AUTOVECTOR); + else + { + /* clear all interrupts */ + m_maincpu->set_input_line_and_vector(M68K_IRQ_1 + level - 1, CLEAR_LINE, M68K_INT_ACK_AUTOVECTOR); + } +} + +/* + VIA port A + + 0: omninet ready (I) + 1: CTS0 (I) + 2: CTS1 (I) + 3: DSR0 (I) + 4: DSR1 (I) + 5: DCD0 (I) + 6: DCD1 (I) + 7: IOX (O) +*/ +READ8_MEMBER(concept_state::via_in_a) +{ + LOG(("via_in_a: VIA port A (Omninet and COMM port status) read\n")); + return 1; /* omninet ready always 1 */ +} + +WRITE8_MEMBER(concept_state::via_out_a) +{ + LOG(("via_out_a: VIA port A status written: data=0x%2.2x\n", data)); + /*iox = (data & 0x80) != 0;*/ +} + +/* + VIA port B + + 0: video off (O) + 1: video address 17 (O) + 2: video address 18 (O) + 3: monitor orientation (I) + 4: CH rate select DC0 (serial port line) (O) + 5: CH rate select DC1 (serial port line) (O) + 6: boot switch 0 (I) + 7: boot switch 1 (I) +*/ +READ8_MEMBER(concept_state::via_in_b) +{ + UINT8 status; + + status = ((ioport("DSW0")->read() & 0x80) >> 1) | ((ioport("DSW0")->read() & 0x40) << 1); + LOG(("via_in_b: VIA port B (DIP switches, Video, Comm Rate) - status: 0x%2.2x\n", status)); + return status; +} + +WRITE8_MEMBER(concept_state::via_out_b) +{ + VLOG(("via_out_b: VIA port B (Video Control and COMM rate select) written: data=0x%2.2x\n", data)); +} + +/* + VIA CB2: used as sound output +*/ + +WRITE_LINE_MEMBER(concept_state::via_out_cb2) +{ +// LOG(("via_out_cb2: Sound control written: data=0x%2.2x\n", state)); + m_speaker->level_w(state); +} + +/* + VIA irq -> 68k level 5 +*/ +WRITE_LINE_MEMBER(concept_state::via_irq_func) +{ + concept_set_interrupt(TIMINT_level, state); +} + +READ16_MEMBER(concept_state::concept_io_r) +{ + if (! ACCESSING_BITS_0_7) + return 0; + + switch ((offset >> 8) & 7) + { + case 0: + /* I/O slot regs */ + switch ((offset >> 4) & 7) + { + case 1: // IO1 registers + case 2: // IO2 registers + case 3: // IO3 registers + case 4: // IO4 registers + { + int slot = ((offset >> 4) & 7); + device_a2bus_card_interface *card = m_a2bus->get_a2bus_card(slot); + + if (card) + { + return card->read_c0nx(space, offset & 0x0f); + } + + return 0xff; + } + break; + + default: // ??? + logerror("concept_io_r: Slot I/O memory accessed for unknown purpose at address 0x03%4.4x\n", offset << 1); + break; + } + break; + + case 1: // IO1 ROM + case 2: // IO2 ROM + case 3: // IO3 ROM + case 4: // IO4 ROM + { + int slot = (offset >> 8) & 7; + device_a2bus_card_interface *card = m_a2bus->get_a2bus_card(slot); + + if (card) + { + return card->read_cnxx(space, offset & 0xff); + } + } + break; + + case 5: + /* slot status */ + LOG(("concept_io_r: Slot status read at address 0x03%4.4x\n", offset << 1)); + break; + + case 6: + /* calendar R/W */ + VLOG(("concept_io_r: Calendar read at address 0x03%4.4x\n", offset << 1)); + if (!m_clock_enable) + return m_mm58274->read(space, m_clock_address); + break; + + case 7: + /* I/O ports */ + switch ((offset >> 4) & 7) + { + case 0: + /* NKBP keyboard */ + return m_kbdacia->read(space, (offset & 3)); + + case 1: + /* NSR0 data comm port 0 */ + return m_acia0->read(space, (offset & 3)); + + case 2: + /* NSR1 data comm port 1 */ + return m_acia1->read(space, (offset & 3)); + + case 3: + /* NVIA versatile system interface */ +// LOG(("concept_io_r: VIA read at address 0x03%4.4x\n", offset << 1)); + { + via6522_device *via_0 = machine().device<via6522_device>("via6522_0"); + return via_0->read(space, offset & 0xf); + } + + case 4: + /* NCALM clock calendar address and strobe register */ + /* write-only? */ + LOG(("concept_io_r: NCALM clock/calendar read at address 0x03%4.4x\n", offset << 1)); + break; + + case 5: + /* NOMNI omninet strobe */ + logerror("concept_io_r: NOMNI Omninet Transporter register read at address 0x03%4.4x\n", offset << 1); + break; + + case 6: + /* NOMOFF reset omninet interrupt flip-flop */ + logerror("concept_io_r: NOMOFF Omninet interrupt flip-flop read at address 0x03%4.4x\n", offset << 1); + break; + + case 7: + /* NIOSTRB external I/O ROM strobe (disables interface RAM) */ + logerror("concept_io_r: NIOSTRB External I/O ROM strobe read at address 0x03%4.4x\n", offset << 1); + break; + } + break; + } + + return 0; +} + +WRITE16_MEMBER(concept_state::concept_io_w) +{ + if (! ACCESSING_BITS_0_7) + return; + + data &= 0xff; + + switch ((offset >> 8) & 7) + { + case 0: + /* I/O slot regs */ + switch ((offset >> 4) & 7) + { + case 1: // IO1 registers + case 2: // IO2 registers + case 3: // IO3 registers + case 4: // IO4 registers + { + int slot = (offset >> 4) & 7; + device_a2bus_card_interface *card = m_a2bus->get_a2bus_card(slot); + + if (card) + { + return card->write_c0nx(space, offset & 0x0f, data); + } + } + break; + + default: // ??? + logerror("concept_io_w: Slot I/O memory written for unknown purpose at address 0x03%4.4x, data: 0x%4.4x\n", offset << 1, data); + break; + } + break; + + case 1: // IO1 ROM + case 2: // IO2 ROM + case 3: // IO3 ROM + case 4: // IO4 ROM + { + int slot = (offset >> 8) & 7; + device_a2bus_card_interface *card = m_a2bus->get_a2bus_card(slot); + + if (card) + { + return card->write_cnxx(space, offset & 0xff, data); + } + } + break; + + case 5: + /* slot status */ + logerror("concept_io_w: Slot status written at address 0x03%4.4x, data: 0x%4.4x\n", offset << 1, data); + break; + + case 6: + /* calendar R/W */ + LOG(("concept_io_w: Calendar written to at address 0x03%4.4x, data: 0x%4.4x\n", offset << 1, data)); + if (!m_clock_enable) + m_mm58274->write(space, m_clock_address, data & 0xf); + break; + + case 7: + /* I/O ports */ + switch ((offset >> 4) & 7) + { + case 0: + /* NKBP keyboard */ + m_kbdacia->write(space, (offset & 3), data); + break; + + case 1: + /* NSR0 data comm port 0 */ + m_acia0->write(space, (offset & 3), data); + break; + + case 2: + /* NSR1 data comm port 1 */ + m_acia1->write(space, (offset & 3), data); + break; + + case 3: + /* NVIA versatile system interface */ + { + via6522_device *via_0 = machine().device<via6522_device>("via6522_0"); + via_0->write(space, offset & 0xf, data); + } + break; + + case 4: + /* NCALM clock calendar address and strobe register */ + if (m_clock_enable != ((data & 0x10) != 0)) + { + m_clock_enable = ((data & 0x10) != 0); + if (! m_clock_enable) + /* latch address when enable goes low */ + m_clock_address = data & 0x0f; + } + /*volume_control = (data & 0x20) != 0;*/ + /*alt_map = (data & 0x40) != 0;*/ + break; + + case 5: + /* NOMNI omninet strobe */ + logerror("concept_io_w: NOMNI Omninet Transporter register written at address 0x03%4.4x, data: 0x%4.4x\n", offset << 1, data); + break; + + case 6: + /* NOMOFF reset omninet interrupt flip-flop */ + logerror("concept_io_w: NOMOFF Omninet flip-flop reset at address 0x03%4.4x, data: 0x%4.4x\n", offset << 1, data); + break; + + case 7: + /* NIOSTRB external I/O ROM strobe */ + logerror("concept_io_w: NIOSTRB External I/O ROM strobe written at address 0x03%4.4x, data: 0x%4.4x\n", offset << 1, data); + break; + } + break; + } +} |