diff options
Diffstat (limited to 'src/mame/concept')
-rw-r--r-- | src/mame/concept/concept.cpp | 233 | ||||
-rw-r--r-- | src/mame/concept/concept.h | 75 | ||||
-rw-r--r-- | src/mame/concept/concept_kbd.cpp | 227 | ||||
-rw-r--r-- | src/mame/concept/concept_kbd.h | 62 | ||||
-rw-r--r-- | src/mame/concept/concept_m.cpp | 362 |
5 files changed, 959 insertions, 0 deletions
diff --git a/src/mame/concept/concept.cpp b/src/mame/concept/concept.cpp new file mode 100644 index 00000000000..99e0a8a6e11 --- /dev/null +++ b/src/mame/concept/concept.cpp @@ -0,0 +1,233 @@ +// license:GPL-2.0+ +// copyright-holders:Raphael Nabet, Brett Wyer +/* + Corvus Concept driver + + Relatively simple 68k-based system + + * 256 or 512 kbytes of DRAM + * 4kbytes of SRAM + * 8kbyte boot ROM + * optional MacsBugs ROM + * two serial ports, keyboard, bitmapped display, simple sound, omninet + LAN port (seems more or less similar to AppleTalk) + * 4 expansion ports enable to add expansion cards, namely floppy disk + and hard disk controllers (the expansion ports are partially compatible + with Apple 2 expansion ports; DMA is not supported) + + Video: monochrome bitmapped display, 720*560 visible area (bitmaps are 768 + pixels wide in memory). One interesting feature is the fact that the + monitor can be rotated to give a 560*720 vertical display (you need to + throw a switch and reset the machine for the display rotation to be taken + into account, though). One oddity is that the video hardware scans the + display from the lower-left corner to the upper-left corner (or from the + upper-right corner to the lower-left if the screen is flipped). + Sound: simpler buzzer connected to the via shift register + Keyboard: intelligent controller, connected through an ACIA. See CCOS + manual pp. 76 through 78. and User Guide p. 2-1 through 2-9. + Clock: mm58174 RTC + + Raphael Nabet, Brett Wyer, 2003-2005 + Major reworking by R. Belmont 2012-2013 resulting in bootable floppies + + ACIA baud rates are 1.36% slower than normal by design. The clock division + used as the BRG input for all three is about 1.818 MHz, not the standard + 1.8432 MHz. The schematics indicate a PCB option to leave the 74LS161 at + U212 unpopulated and use a secondary XTAL as the baud rate clock. This + XTAL is also specified as 1.818 MHz. +*/ + +#include "emu.h" +#include "concept.h" +#include "concept_kbd.h" + +#include "cpu/m68000/m68000.h" +#include "cpu/m6800/m6801.h" +#include "bus/a2bus/a2corvus.h" +#include "bus/a2bus/corvfdc01.h" +#include "bus/a2bus/corvfdc02.h" +#include "bus/rs232/rs232.h" +#include "machine/input_merger.h" +#include "emupal.h" +#include "screen.h" +#include "speaker.h" + +void concept_state::concept_memmap(address_map &map) +{ + map(0x000000, 0x000007).rom().region("maincpu", 0x010000); /* boot ROM mirror */ + map(0x000008, 0x000fff).ram(); /* static RAM */ + map(0x010000, 0x011fff).rom().region("maincpu", 0x010000); /* boot ROM */ + map(0x020000, 0x021fff).rom().region("macsbug", 0x0); /* macsbugs ROM (optional) */ + map(0x030000, 0x03ffff).rw(FUNC(concept_state::io_r), FUNC(concept_state::io_w)).umask16(0x00ff); /* I/O space */ + + map(0x080000, 0x0fffff).ram().share("videoram"); /* .bankrw(2); */ /* DRAM */ +} + + +static INPUT_PORTS_START( corvus_concept ) + PORT_START("DSW0") /* port 6: on-board DIP switches */ + PORT_DIPNAME(0x01, 0x00, "Omninet Address bit 0") + PORT_DIPSETTING(0x00, DEF_STR( Off )) + PORT_DIPSETTING(0x01, DEF_STR( On )) + PORT_DIPNAME(0x02, 0x02, "Omninet Address bit 1") + PORT_DIPSETTING(0x00, DEF_STR( Off )) + PORT_DIPSETTING(0x02, DEF_STR( On )) + PORT_DIPNAME(0x04, 0x00, "Omninet Address bit 2") + PORT_DIPSETTING(0x00, DEF_STR( Off )) + PORT_DIPSETTING(0x04, DEF_STR( On )) + PORT_DIPNAME(0x08, 0x00, "Omninet Address bit 3") + PORT_DIPSETTING(0x00, DEF_STR( Off )) + PORT_DIPSETTING(0x08, DEF_STR( On )) + PORT_DIPNAME(0x10, 0x00, "Omninet Address bit 4") + PORT_DIPSETTING(0x00, DEF_STR( Off )) + PORT_DIPSETTING(0x10, DEF_STR( On )) + PORT_DIPNAME(0x20, 0x00, "Omninet Address bit 5") + PORT_DIPSETTING(0x00, DEF_STR( Off )) + PORT_DIPSETTING(0x20, DEF_STR( On )) + PORT_DIPNAME(0xc0, 0x00, "Type of Boot") + PORT_DIPSETTING(0x00, "Prompt for type of Boot") // Documentation has 0x00 and 0xc0 reversed per boot PROM + PORT_DIPSETTING(0x40, "Boot from Omninet") + PORT_DIPSETTING(0x80, "Boot from Local Disk") + PORT_DIPSETTING(0xc0, "Boot from Diskette") + +#if 0 + PORT_START("DISPLAY") /* port 7: Display orientation */ + PORT_DIPNAME(0x01, 0x00, "Screen Orientation") + PORT_DIPSETTING(0x00, "Horizontal") + PORT_DIPSETTING(0x01, "Vertical") +#endif + +INPUT_PORTS_END + + +void concept_a2_cards(device_slot_interface &device) +{ + device.option_add("fchdd", A2BUS_CORVUS); // Corvus flat-cable HDD interface (see notes in a2corvus.c) + device.option_add("fdc01", A2BUS_CORVFDC01); // Corvus WD1793 floppy controller + device.option_add("fdc02", A2BUS_CORVFDC02); // Corvus NEC765 buffered floppy controller +} + + +void concept_state::corvus_concept(machine_config &config) +{ + /* basic machine hardware */ + M68000(config, m_maincpu, 16.364_MHz_XTAL / 2); + m_maincpu->set_addrmap(AS_PROGRAM, &concept_state::concept_memmap); + + M6801(config, "omni", 10_MHz_XTAL / 2).set_disable(); + + config.set_maximum_quantum(attotime::from_hz(60)); + + /* video hardware */ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_video_attributes(VIDEO_UPDATE_BEFORE_VBLANK); + screen.set_raw(16.364_MHz_XTAL * 2, 944, 0, 720, 578, 0, 560); + // Horizontal sync is 34.669 kHz; refresh rate is ~50 or ~60 Hz, jumper-selectable + screen.set_screen_update(FUNC(concept_state::screen_update)); + screen.set_palette("palette"); + + /* Is the palette black on white or white on black??? */ + PALETTE(config, "palette", palette_device::MONOCHROME); + + /* sound */ + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 1.00); + + /* rtc */ + MM58174(config, m_mm58174, 32.768_kHz_XTAL); + + /* via */ + MOS6522(config, m_via0, 16.364_MHz_XTAL / 16); + m_via0->readpa_handler().set(FUNC(concept_state::via_in_a)); + m_via0->readpb_handler().set(FUNC(concept_state::via_in_b)); + m_via0->writepa_handler().set(FUNC(concept_state::via_out_a)); + m_via0->writepb_handler().set(FUNC(concept_state::via_out_b)); + m_via0->cb2_handler().set(FUNC(concept_state::via_out_cb2)); + m_via0->irq_handler().set_inputline(m_maincpu, M68K_IRQ_5); + + /* ACIAs */ + MOS6551(config, m_acia0, 16.364_MHz_XTAL / 16); + m_acia0->set_xtal(16.364_MHz_XTAL / 9); + m_acia0->txd_handler().set("rs232a", FUNC(rs232_port_device::write_txd)); + m_acia0->irq_handler().set_inputline(m_maincpu, M68K_IRQ_4); + + MOS6551(config, m_acia1, 16.364_MHz_XTAL / 16); + m_acia1->set_xtal(16.364_MHz_XTAL / 9); + m_acia1->txd_handler().set("rs232b", FUNC(rs232_port_device::write_txd)); + m_acia1->irq_handler().set_inputline(m_maincpu, M68K_IRQ_2); + + MOS6551(config, m_kbdacia, 16.364_MHz_XTAL / 16); + m_kbdacia->set_xtal(16.364_MHz_XTAL / 9); + m_kbdacia->txd_handler().set("keyboard", FUNC(concept_keyboard_device::write_rxd)); + m_kbdacia->dtr_handler().set("keyrxd", FUNC(input_merger_device::in_w<0>)).invert(); // open collector + m_kbdacia->irq_handler().set_inputline(m_maincpu, M68K_IRQ_6); + + CONCEPT_KEYBOARD(config, "keyboard").txd_callback().set("keyrxd", FUNC(input_merger_device::in_w<1>)); + + INPUT_MERGER_ALL_HIGH(config, "keyrxd").output_handler().set(m_kbdacia, FUNC(mos6551_device::write_rxd)); + + /* Apple II bus */ + A2BUS(config, m_a2bus, 0).set_space(m_maincpu, AS_PROGRAM); + m_a2bus->nmi_w().set("iocint", FUNC(input_merger_device::in_w<0>)); + m_a2bus->irq_w().set("iocint", FUNC(input_merger_device::in_w<1>)); + A2BUS_SLOT(config, "sl1", 16.364_MHz_XTAL / 2, m_a2bus, concept_a2_cards, nullptr); + A2BUS_SLOT(config, "sl2", 16.364_MHz_XTAL / 2, m_a2bus, concept_a2_cards, nullptr); + A2BUS_SLOT(config, "sl3", 16.364_MHz_XTAL / 2, m_a2bus, concept_a2_cards, nullptr); + A2BUS_SLOT(config, "sl4", 16.364_MHz_XTAL / 2, m_a2bus, concept_a2_cards, "fdc01"); + + INPUT_MERGER_ANY_HIGH(config, "iocint").output_handler().set_inputline(m_maincpu, M68K_IRQ_1); + + /* 2x RS232 ports */ + rs232_port_device &rs232a(RS232_PORT(config, "rs232a", default_rs232_devices, nullptr)); + rs232a.rxd_handler().set(m_acia0, FUNC(mos6551_device::write_rxd)); + //rs232a.dcd_handler().set("iocint", FUNC(input_merger_device::in_w<2>)).invert(); + //rs232a.dsr_handler().set("iocint", FUNC(input_merger_device::in_w<3>)).invert(); + //rs232a.cts_handler().set("iocint", FUNC(input_merger_device::in_w<4>)).invert(); + + rs232_port_device &rs232b(RS232_PORT(config, "rs232b", default_rs232_devices, nullptr)); + rs232b.rxd_handler().set(m_acia1, FUNC(mos6551_device::write_rxd)); + //rs232b.dcd_handler().set("iocint", FUNC(input_merger_device::in_w<5>)).invert(); + //rs232b.dsr_handler().set("iocint", FUNC(input_merger_device::in_w<6>)).invert(); + //rs232b.cts_handler().set("iocint", FUNC(input_merger_device::in_w<7>)).invert(); +} + + +ROM_START( concept ) + ROM_REGION16_BE(0x100000,"maincpu",0) /* 68k rom and ram */ + + // concept boot ROM + ROM_SYSTEM_BIOS(0, "lvl8", "Level 8" ) // v0? + ROMX_LOAD("bootl08h", 0x010000, 0x1000, CRC(ee479f51) SHA1(b20ba18564672196076e46507020c6d69a640a2f), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("bootl08l", 0x010001, 0x1000, CRC(acaefd07) SHA1(de0c7eaacaf4c0652aa45e523cebce2b2993c437), ROM_BIOS(0) | ROM_SKIP(1)) + + ROM_SYSTEM_BIOS(1, "lvl7", "Level 7" ) // v0? v1? + ROMX_LOAD("cc07h", 0x010000, 0x1000, CRC(455abac8) SHA1(b12e1580220242d34eafed1b486cebd89e823c8b), ROM_BIOS(1) | ROM_SKIP(1)) + ROMX_LOAD("cc07l", 0x010001, 0x1000, CRC(107a3830) SHA1(0ea12ef13b0d11fcd83b306b3a1bb8014ba910c0), ROM_BIOS(1) | ROM_SKIP(1)) + + ROM_SYSTEM_BIOS(2, "lvl6", "Level 6" ) // v0? + ROMX_LOAD("cc06h", 0x010000, 0x1000, CRC(66b6b259) SHA1(1199a38ef3e94f695e8da6a7c80c6432da3cb80c), ROM_BIOS(2) | ROM_SKIP(1)) + ROMX_LOAD("cc06l", 0x010001, 0x1000, CRC(600940d3) SHA1(c3278bf23b3b1c35ea1e3da48a05e877862a8345), ROM_BIOS(2) | ROM_SKIP(1)) + +#if 0 + // version 1 lvl 7 release + ROM_LOAD16_BYTE("bootl17h", 0x010000, 0x1000, CRC(6dd9718f)) // where does this come from? + ROM_LOAD16_BYTE("bootl17l", 0x010001, 0x1000, CRC(107a3830) SHA1(0ea12ef13b0d11fcd83b306b3a1bb8014ba910c0)) +#elif 0 + // version $F lvl 8 (development version found on a floppy disk along with + // the source code) + ROM_LOAD16_WORD("cc.prm", 0x010000, 0x2000, CRC(b5a87dab) SHA1(0da59af6cfeeb38672f71731527beac323d9c3d6)) +#endif + + ROM_REGION(0x1000, "omni", 0) + ROM_LOAD("sc85180l_3265-02762.u302", 0x0000, 0x1000, NO_DUMP) + + ROM_REGION(0x400, "proms", 0) + ROM_LOAD("map04a.bin", 0x000, 0x400, CRC(1ae0db9b) SHA1(cdb6f63bb08072b454b4704e62de51c483ede734) ) + + ROM_REGION16_BE(0x2000, "macsbug", 0) + ROM_LOAD16_BYTE( "mb20h.bin", 0x000000, 0x001000, CRC(aa357112) SHA1(88211e5f59887928c557c27cdea674f48bf8eaf7) ) + ROM_LOAD16_BYTE( "mb20l.bin", 0x000001, 0x001000, CRC(b4b59de9) SHA1(3e8b8b5950b5359203c054f94af1fc5b8f0495b9) ) +ROM_END + +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME */ +COMP( 1982, concept, 0, 0, corvus_concept, corvus_concept, concept_state, empty_init, "Corvus Systems", "Concept" , 0 ) diff --git a/src/mame/concept/concept.h b/src/mame/concept/concept.h new file mode 100644 index 00000000000..6ea4ba70aa9 --- /dev/null +++ b/src/mame/concept/concept.h @@ -0,0 +1,75 @@ +// license:GPL-2.0+ +// copyright-holders:Raphael Nabet, Brett Wyer +/***************************************************************************** + * + * includes/concept.h + * + * Corvus Concept driver + * + * Raphael Nabet, 2003 + * + ****************************************************************************/ + +#ifndef MAME_CONCEPT_CONCEPT_H +#define MAME_CONCEPT_CONCEPT_H + +#include "cpu/m68000/m68000.h" +#include "machine/6522via.h" +#include "machine/mos6551.h" +#include "machine/mm58174.h" +#include "sound/spkrdev.h" +#include "bus/a2bus/a2bus.h" + +#define ACIA_0_TAG "acia0" +#define ACIA_1_TAG "acia1" +#define VIA_0_TAG "via6522_0" +#define KBD_ACIA_TAG "kbacia" + +class concept_state : public driver_device +{ +public: + concept_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_acia0(*this, ACIA_0_TAG), + m_acia1(*this, ACIA_1_TAG), + m_via0(*this, VIA_0_TAG), + m_kbdacia(*this, KBD_ACIA_TAG), + m_speaker(*this, "spkr"), + m_mm58174(*this, "mm58174"), + m_a2bus(*this, "a2bus"), + m_videoram(*this,"videoram") + { } + + void corvus_concept(machine_config &config); + +private: + required_device<cpu_device> m_maincpu; + required_device<mos6551_device> m_acia0; + required_device<mos6551_device> m_acia1; + required_device<via6522_device> m_via0; + required_device<mos6551_device> m_kbdacia; + required_device<speaker_sound_device> m_speaker; + required_device<mm58174_device> m_mm58174; + required_device<a2bus_device> m_a2bus; + required_shared_ptr<uint16_t> m_videoram; + + bool m_clock_enable = false; + uint8_t m_clock_address = 0U; + uint8_t io_r(offs_t offset); + void io_w(offs_t offset, uint8_t data); + virtual void machine_start() override ATTR_COLD; + virtual void machine_reset() override ATTR_COLD; + virtual void video_start() override ATTR_COLD; + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + uint8_t via_in_a(); + void via_out_a(uint8_t data); + uint8_t via_in_b(); + void via_out_b(uint8_t data); + void via_out_cb2(int state); + + void concept_memmap(address_map &map) ATTR_COLD; +}; + +#endif // MAME_CONCEPT_CONCEPT_H diff --git a/src/mame/concept/concept_kbd.cpp b/src/mame/concept/concept_kbd.cpp new file mode 100644 index 00000000000..e9a5570be20 --- /dev/null +++ b/src/mame/concept/concept_kbd.cpp @@ -0,0 +1,227 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + Corvus Concept 91-key keyboard + + This is a rather generic Key Tronic Corp. product using their + 22-950-3B and 22-908-03 custom ICs. + + The program outputs raw make and break scan codes in TTL-level + asynchronous serial at a rate somewhat less than 600 bits per + second (the host ACIA also happens to runs slow). It occupies + very little of the external ROM. + + Corvus seems to have swapped the positions of the backspace and + backslash keys at least once. + + The serial input from the host ACIA appears to have the sole + function of driving the LED on the Break key. The program reads + inputs only from the key matrix. + +**********************************************************************/ + +#include "emu.h" +#include "concept_kbd.h" + + +// device type definition +DEFINE_DEVICE_TYPE(CONCEPT_KEYBOARD, concept_keyboard_device, "concept_kbd", "Corvus Concept Keyboard") + +concept_keyboard_device::concept_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, CONCEPT_KEYBOARD, tag, owner, clock) + , m_mcu(*this, "mcu") + , m_keys(*this, "KEYS%X", 0U) + , m_led(*this, "led") + , m_txd_callback(*this) + , m_p2_output(0xff) + , m_key_input(0xff) +{ +} + +void concept_keyboard_device::device_resolve_objects() +{ + m_led.resolve(); +} + +void concept_keyboard_device::device_start() +{ + save_item(NAME(m_p2_output)); + save_item(NAME(m_key_input)); +} + +void concept_keyboard_device::write_rxd(int state) +{ + m_led = !state; +} + + +u8 concept_keyboard_device::p1_r() +{ + return m_key_input; +} + +void concept_keyboard_device::p2_w(u8 data) +{ + m_txd_callback(BIT(data, 4)); + + if (!BIT(data, 7)) + m_key_input = 0xff; + else if (!BIT(m_p2_output, 7)) + { + u8 row = m_mcu->p1_r() & 0x0f; + m_key_input = row >= 0x0c ? 0xff : m_keys[row]->read(); + } + + m_p2_output = data; +} + +void concept_keyboard_device::prog_map(address_map &map) +{ + map(0x000, 0x3ff).rom().region("program", 0); +} + + +static INPUT_PORTS_START(concept_keyboard) + PORT_START("KEYS0") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME)) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(COMMA_PAD)) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) + + PORT_START("KEYS1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) + + PORT_START("KEYS2") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("Back Space") PORT_CHAR(0x08) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_NAME("Return") PORT_CHAR(0x0d) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("] }") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') PORT_CHAR(0x1d) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\ |") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') PORT_CHAR(0x1c) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("KEYS3") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_NAME("P") PORT_CHAR('p') PORT_CHAR('P') PORT_CHAR(0x10) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) PORT_NAME("Right Shift") + + PORT_START("KEYS4") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) + PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("KEYS5") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_NAME("R") PORT_CHAR('r') PORT_CHAR('R') PORT_CHAR(0x12) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_NAME("T") PORT_CHAR('t') PORT_CHAR('T') PORT_CHAR(0x14) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_NAME("F") PORT_CHAR('f') PORT_CHAR('F') PORT_CHAR(0x06) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_NAME("G") PORT_CHAR('g') PORT_CHAR('G') PORT_CHAR(0x07) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_NAME("V") PORT_CHAR('v') PORT_CHAR('V') PORT_CHAR(0x16) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_NAME("B") PORT_CHAR('b') PORT_CHAR('B') PORT_CHAR(0x02) + + PORT_START("KEYS6") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_NAME("W") PORT_CHAR('w') PORT_CHAR('W') PORT_CHAR(0x17) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_NAME("E") PORT_CHAR('e') PORT_CHAR('E') PORT_CHAR(0x05) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_NAME("S") PORT_CHAR('s') PORT_CHAR('S') PORT_CHAR(0x13) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_NAME("D") PORT_CHAR('d') PORT_CHAR('D') PORT_CHAR(0x04) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_NAME("X") PORT_CHAR('x') PORT_CHAR('X') PORT_CHAR(0x18) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_NAME("C") PORT_CHAR('c') PORT_CHAR('C') PORT_CHAR(0x03) + + PORT_START("KEYS7") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_NAME("Esc") PORT_CHAR(0x1b) + 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_CODE(KEYCODE_TAB) PORT_NAME("Tab") // not normally translated to 0x09 here + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_NAME("Q") PORT_CHAR('q') PORT_CHAR('Q') PORT_CHAR(0x11) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_NAME("Caps Lock") PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_NAME("A") PORT_CHAR('a') PORT_CHAR('A') PORT_CHAR(0x01) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_NAME("Left Shift") PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_NAME("Z") PORT_CHAR('z') PORT_CHAR('Z') PORT_CHAR(0x1a) + + PORT_START("KEYS8") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_NAME("Y") PORT_CHAR('y') PORT_CHAR('Y') PORT_CHAR(0x19) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_NAME("U") PORT_CHAR('u') PORT_CHAR('U') PORT_CHAR(0x14) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_NAME("H") PORT_CHAR('h') PORT_CHAR('H') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_NAME("J") PORT_CHAR('j') PORT_CHAR('J') PORT_CHAR(0x0a) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_NAME("N") PORT_CHAR('n') PORT_CHAR('N') PORT_CHAR(0x0e) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_NAME("M") PORT_CHAR('m') PORT_CHAR('M') + + PORT_START("KEYS9") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_NAME("Ctrl") PORT_CHAR(UCHAR_SHIFT_2) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RCONTROL) PORT_NAME("Fast") // actually between Ctrl and Command + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LALT) PORT_NAME("Command") PORT_CHAR(UCHAR_MAMEKEY(LALT)) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_NAME("Space") PORT_CHAR(' ') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RALT) PORT_NAME("Alt") PORT_CHAR(UCHAR_MAMEKEY(RALT)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_00_PAD) PORT_CHAR(UCHAR_MAMEKEY(00_PAD)) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) + + PORT_START("KEYSA") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_NAME("I") PORT_CHAR('i') PORT_CHAR('I') PORT_CHAR(0x09) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_NAME("O") PORT_CHAR('o') PORT_CHAR('O') PORT_CHAR(0x0f) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_NAME("K") PORT_CHAR('k') PORT_CHAR('K') PORT_CHAR(0x0b) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_NAME("L") PORT_CHAR('l') PORT_CHAR('L') PORT_CHAR(0x0c) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + + PORT_START("KEYSB") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F11) PORT_NAME("Blank key") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F12) PORT_NAME("Break") +INPUT_PORTS_END + +ioport_constructor concept_keyboard_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(concept_keyboard); +} + +void concept_keyboard_device::device_add_mconfig(machine_config &config) +{ + I8035(config, m_mcu, 4.608_MHz_XTAL); // Intel P8048 in EA mode (XTAL marked "48-300-007") + m_mcu->set_addrmap(AS_PROGRAM, &concept_keyboard_device::prog_map); + m_mcu->p1_in_cb().set(FUNC(concept_keyboard_device::p1_r)); + m_mcu->p2_out_cb().set(FUNC(concept_keyboard_device::p2_w)); +} + + +ROM_START(concept_kbd) + ROM_REGION(0x400, "program", 0) + ROM_LOAD("112.z1", 0x000, 0x400, CRC(b3d37000) SHA1(fc58d77919739b66b85eb52b084af9716cd7f260)) // Intel D2758 +ROM_END + +const tiny_rom_entry *concept_keyboard_device::device_rom_region() const +{ + return ROM_NAME(concept_kbd); +} diff --git a/src/mame/concept/concept_kbd.h b/src/mame/concept/concept_kbd.h new file mode 100644 index 00000000000..8b5c2657af4 --- /dev/null +++ b/src/mame/concept/concept_kbd.h @@ -0,0 +1,62 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_CONCEPT_CONCEPT_KBD_H +#define MAME_CONCEPT_CONCEPT_KBD_H + +#pragma once + +#include "cpu/mcs48/mcs48.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> concept_keyboard_device + +class concept_keyboard_device : public device_t +{ +public: + // device type constructor + concept_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + // callback configuration + auto txd_callback() { return m_txd_callback.bind(); } + + // serial line input + void write_rxd(int state); + +protected: + // device-level overrides + virtual void device_resolve_objects() override ATTR_COLD; + virtual void device_start() override ATTR_COLD; + virtual ioport_constructor device_input_ports() const override ATTR_COLD; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD; + +private: + // MCU handlers + u8 p1_r(); + void p2_w(u8 data); + + // address maps + void prog_map(address_map &map) ATTR_COLD; + + // object finders + required_device<mcs48_cpu_device> m_mcu; + required_ioport_array<12> m_keys; + output_finder<> m_led; + + // output callback + devcb_write_line m_txd_callback; + + // internal state + u8 m_p2_output; + u8 m_key_input; +}; + +// device type declaration +DECLARE_DEVICE_TYPE(CONCEPT_KEYBOARD, concept_keyboard_device) + +#endif // MAME_CONCEPT_CONCEPT_KBD_H diff --git a/src/mame/concept/concept_m.cpp b/src/mame/concept/concept_m.cpp new file mode 100644 index 00000000000..c410ca38c65 --- /dev/null +++ b/src/mame/concept/concept_m.cpp @@ -0,0 +1,362 @@ +// license:GPL-2.0+ +// copyright-holders:Raphael Nabet, Brett Wyer +/* + Corvus Concept driver + + Raphael Nabet, Brett Wyer, 2003-2005 +*/ + +#include "emu.h" +#include "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) + + +#if 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 */ +}; +#endif + +/* Clock interface */ + +/* Omninet */ +/*static int ready;*/ /* ready line from monochip, role unknown */ + +/* Via */ + + +void concept_state::machine_start() +{ + // OS will not boot if TDRE is clear on ACIA 0; this fixes that + m_acia0->write_cts(0); + m_acia0->write_dcd(0); + m_acia0->write_dsr(0); + m_acia1->write_cts(0); + m_acia1->write_dcd(0); + m_acia1->write_dsr(0); + m_kbdacia->write_cts(0); + m_kbdacia->write_dcd(0); + m_kbdacia->write_dsr(0); + + /* initialize clock interface */ + m_clock_enable = false /*true*/; + + save_item(NAME(m_clock_enable)); + save_item(NAME(m_clock_address)); +} + + +void concept_state::machine_reset() +{ +} + +void concept_state::video_start() +{ +} + +uint32_t concept_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + /* resolution is 720*560 */ + for (int y = 0; y < 560; y++) + { + uint16_t *const line = &bitmap.pix(560-1-y); + for (int x = 0; x < 720; x++) + line[720-1-x] = (m_videoram[(x+48+y*768)>>4] & (0x8000 >> ((x+48+y*768) & 0xf))) ? 1 : 0; + } + return 0; +} + +/* + 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) +*/ +uint8_t 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 */ +} + +void concept_state::via_out_a(uint8_t data) +{ + 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) +*/ +uint8_t concept_state::via_in_b() +{ + uint8_t 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; +} + +void concept_state::via_out_b(uint8_t data) +{ + 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 +*/ + +void concept_state::via_out_cb2(int state) +{ +// LOG(("via_out_cb2: Sound control written: data=0x%2.2x\n", state)); + m_speaker->level_w(state); +} + +uint8_t concept_state::io_r(offs_t offset) +{ + 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(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(offset & 0xff); + } + } + break; + + case 5: + /* slot status */ + LOG(("concept_io_r: Slot status read at address 0x03%4.4x\n", offset << 1)); + return (~m_a2bus->get_a2bus_nmi_mask() & 0x0f) | (~m_a2bus->get_a2bus_irq_mask() & 0x0f) << 4; + + 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_mm58174->read(m_clock_address); + break; + + case 7: + /* I/O ports */ + switch ((offset >> 4) & 7) + { + case 0: + /* NKBP keyboard */ + return m_kbdacia->read(offset & 3); + + case 1: + /* NSR0 data comm port 0 */ + return m_acia0->read(offset & 3); + + case 2: + /* NSR1 data comm port 1 */ + return m_acia1->read(offset & 3); + + case 3: + /* NVIA versatile system interface */ +// LOG(("concept_io_r: VIA read at address 0x03%4.4x\n", offset << 1)); + { + return m_via0->read(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; +} + +void concept_state::io_w(offs_t offset, uint8_t data) +{ + 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(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(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_mm58174->write(m_clock_address, data & 0xf); + break; + + case 7: + /* I/O ports */ + switch ((offset >> 4) & 7) + { + case 0: + /* NKBP keyboard */ + m_kbdacia->write(offset & 3, data); + break; + + case 1: + /* NSR0 data comm port 0 */ + m_acia0->write(offset & 3, data); + break; + + case 2: + /* NSR1 data comm port 1 */ + m_acia1->write(offset & 3, data); + break; + + case 3: + /* NVIA versatile system interface */ + { + m_via0->write(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; + } +} |