diff options
| author | 2020-04-27 01:05:40 +0300 | |
|---|---|---|
| committer | 2020-04-26 18:05:40 -0400 | |
| commit | ee76fc03374ae894d78a21eaf790d9fa4d7bb5f0 (patch) | |
| tree | 63c089e5ad6b0dc1290380f5906415a930c18b13 | |
| parent | db0afba9afdeaa32a494af33bb9f78754141b557 (diff) | |
Heavily improved emulation of GRiD Compass 1101 (#6599)
Changes:
- added known dump checksums of 1101 BIOS
- high-level emulation of GPIB disk devices
- partial implementation of DMA (currently ignores ACCRQ so devices must have zero latency in order for it to work)
- serial is now properly memory-mapped
- modem stub in order to make system properly ignore modem device
- it now boots without any patches and debug scripts
- merged #6597 (needed in order to make disk devices work)
Still not implemented:
- RTC/MACHINE_ID
- modem
- has problems with multiple disk devices working simultaneously (possibly BIOS bug because this BIOS had some problems with that on real device)
| -rw-r--r-- | scripts/src/bus.lua | 2 | ||||
| -rw-r--r-- | src/devices/bus/ieee488/grid2102.cpp | 314 | ||||
| -rw-r--r-- | src/devices/bus/ieee488/grid2102.h | 114 | ||||
| -rw-r--r-- | src/devices/bus/ieee488/ieee488.cpp | 15 | ||||
| -rw-r--r-- | src/devices/bus/ieee488/ieee488.h | 1 | ||||
| -rw-r--r-- | src/devices/machine/i80130.cpp | 16 | ||||
| -rw-r--r-- | src/devices/machine/i80130.h | 2 | ||||
| -rw-r--r-- | src/devices/machine/tms9914.cpp | 3 | ||||
| -rw-r--r-- | src/mame/drivers/gridcomp.cpp | 120 | ||||
| -rw-r--r-- | src/mame/machine/gridkeyb.cpp | 8 |
10 files changed, 531 insertions, 64 deletions
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 751f9cca2ce..2c708f35b4d 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -1248,6 +1248,8 @@ if (BUSES["IEEE488"]~=null) then MAME_DIR .. "src/devices/bus/ieee488/hp9895.h", MAME_DIR .. "src/devices/bus/ieee488/remote488.cpp", MAME_DIR .. "src/devices/bus/ieee488/remote488.h", + MAME_DIR .. "src/devices/bus/ieee488/grid2102.cpp", + MAME_DIR .. "src/devices/bus/ieee488/grid2102.h", } dependency { diff --git a/src/devices/bus/ieee488/grid2102.cpp b/src/devices/bus/ieee488/grid2102.cpp new file mode 100644 index 00000000000..f8e4ac5a142 --- /dev/null +++ b/src/devices/bus/ieee488/grid2102.cpp @@ -0,0 +1,314 @@ +// license:BSD-3-Clause +// copyright-holders:usernameak +/********************************************************************** + + GRiD 2102 Portable Floppy emulation + + http://deltacxx.insomnia247.nl/gridcompass/disk_info.txt for some protocol info + http://deltacxx.insomnia247.nl/gridcompass/fdd_boards.jpg for floppy drive boards photo + +**********************************************************************/ + +#include "grid2102.h" + +// device type definition +DEFINE_DEVICE_TYPE(GRID2102, grid2102_device, "grid2102", "GRID2102") +DEFINE_DEVICE_TYPE(GRID2101_FLOPPY, grid2101_floppy_device, "grid2101_floppy", "GRID2101_FLOPPY") +DEFINE_DEVICE_TYPE(GRID2101_HDD, grid2101_hdd_device, "grid2101_hdd", "GRID2101_HDD") + +#define LOG_BYTES_MASK (LOG_GENERAL << 1) +#define LOG_BYTES(...) LOGMASKED(LOG_BYTES_MASK, __VA_ARGS__) +#define VERBOSE (LOG_GENERAL) +#include "logmacro.h" + +#define GRID2102_FETCH32(Array, Offset) ((uint32_t)(\ + (Array[Offset] << 0) |\ + (Array[Offset + 1] << 8) |\ + (Array[Offset + 2] << 16) |\ + (Array[Offset + 3] << 24)\ +)) + +#define GRID2102_FETCH16(Array, Offset) ((uint16_t)(\ + (Array[Offset] << 0) |\ + (Array[Offset + 1] << 8)\ +)) + +#define GRID2101_HARDDISK_DEV_ADDR 4 +#define GRID2102_DEV_ADDR 6 + +#define GRID210X_GPIB_STATE_IDLE 0 +#define GRID210X_GPIB_STATE_WAIT_DAV_FALSE 1 +#define GRID210X_GPIB_STATE_SEND_DATA_START 2 +#define GRID210X_GPIB_STATE_WAIT_NDAC_FALSE 3 + +#define GRID210X_STATE_IDLE 0 +#define GRID210X_STATE_READING_DATA 1 +#define GRID210X_STATE_WRITING_DATA 2 +#define GRID210X_STATE_WRITING_DATA_WAIT 3 + +uint8_t grid2102_device::identify_response[56] = {0x00, 0x02, 0xf8, 0x01, 0xD0, 0x02, 0x01, 0x20, 0x01, 0x21, 0x01, 0x01, 0x00, 0x00, + 0x34, 0x38, 0x20, 0x54, 0x50, 0x49, 0x20, 0x44, 0x53, 0x20, 0x44, 0x44, 0x20, 0x46, + 0x4c, 0x4f, 0x50, 0x50, 0x59, 0x20, 0x20, 0x20, 0x20, 0x33, 0x30, 0x32, 0x33, 0x37, + 0x2d, 0x30, 0x30, 0x00, 0x02, 0x09, 0x00}; + +uint8_t grid2101_floppy_device::identify_response[56] = {0x00, 0x02, 0xf8, 0x01, 0xD0, 0x02, 0x01, 0x20, 0x01, 0x21, 0x01, 0x01, 0x00, 0x00, + 0x34, 0x38, 0x20, 0x54, 0x50, 0x49, 0x20, 0x44, 0x53, 0x20, 0x44, 0x44, 0x20, 0x46, + 0x4c, 0x4f, 0x50, 0x50, 0x59, 0x20, 0x20, 0x20, 0x20, 0x33, 0x30, 0x32, 0x33, 0x37, + 0x2d, 0x30, 0x30, 0x00, 0x02, 0x09, 0x00}; + +uint8_t grid2101_hdd_device::identify_response[56] = { + 0x00, 0x02, 0xF8, 0x01, 0x8C, 0x51, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x4D, 0x41, + 0x4D, 0x45, 0x20, 0x48, 0x41, 0x52, 0x44, 0x44, 0x49, 0x53, 0x4B, 0x20, 0x44, 0x52, 0x49, 0x56, + 0x45, 0x20, 0x20, 0x20, 0x20, 0x20, 0x47, 0x52, 0x49, 0x44, 0x32, 0x31, 0x30, 0x31, 0x00, 0x02, + 0x11, 0x00, 0x33, 0x01, 0x00, 0x00, 0x04, 0x00 +}; + + +grid210x_device::grid210x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int bus_addr, uint8_t *identify_response, attotime read_delay) + : device_t(mconfig, type, tag, owner, clock), + device_ieee488_interface(mconfig, *this), + device_image_interface(mconfig, *this), + m_gpib_loop_state(GRID210X_GPIB_STATE_IDLE), + m_floppy_loop_state(GRID210X_STATE_IDLE), + listening(false), + talking(false), + serial_polling(false), + has_srq(false), + serial_poll_byte(0), + bus_addr(bus_addr), + identify_response_ptr(identify_response), + read_delay(read_delay) +{ + +} + +void grid210x_device::device_start() { + m_bus->ndac_w(this, 1); + m_bus->nrfd_w(this, 1); + m_delay_timer = timer_alloc(0); +} + +void grid210x_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { + if (m_floppy_loop_state == GRID210X_STATE_READING_DATA) { + uint8_t data[io_size]; + fseek(floppy_sector_number * 512, SEEK_SET); + fread(data, io_size); + for (int i = 0; i < io_size; i++) { + m_output_data_buffer.push(data[i]); + } + serial_poll_byte = 0x0F; + has_srq = true; + m_bus->srq_w(this, 0); + m_floppy_loop_state = GRID210X_STATE_IDLE; + } else if (m_floppy_loop_state == GRID210X_STATE_WRITING_DATA_WAIT) { + // send an srq as success flag + for (int i = 0; i < 7; i++) { // FIXME: + m_output_data_buffer.push(0); + } + serial_poll_byte = 0x0F; + has_srq = true; + m_bus->srq_w(this, 0); + m_floppy_loop_state = GRID210X_STATE_IDLE; + } +} + +void grid210x_device::ieee488_eoi(int state) { + // logerror("grid210x_device eoi state set to %d\n", state); +} + +void grid210x_device::accept_transfer() { + if (m_floppy_loop_state == GRID210X_STATE_IDLE) { + if (m_data_buffer.size() >= 0xA) { + uint8_t command = m_data_buffer[0]; + uint32_t sector_number = GRID2102_FETCH32(m_data_buffer, 3); + uint16_t data_size = GRID2102_FETCH16(m_data_buffer, 7); + LOG("grid210x_device command %u, data size %u, sector no %u\n", (unsigned)command, (unsigned)data_size, (unsigned)sector_number); + (void)(sector_number); + if (command == 0x1) { // ddGetStatus + for (int i = 0; i < 56 && i < data_size; i++) { + m_output_data_buffer.push(identify_response_ptr[i]); + } + } else if (command == 0x4) { // ddRead + floppy_sector_number = sector_number; + io_size = data_size; + m_floppy_loop_state = GRID210X_STATE_READING_DATA; + m_delay_timer->adjust(read_delay); + } else if (command == 0x5) { + floppy_sector_number = sector_number; + io_size = data_size; + m_floppy_loop_state = GRID210X_STATE_WRITING_DATA; + } + } // else something is wrong, ignore + } else if (m_floppy_loop_state == GRID210X_STATE_WRITING_DATA) { + // write + if (floppy_sector_number != 0xFFFFFFFF) { + fseek(floppy_sector_number * 512, SEEK_SET); + fwrite(m_data_buffer.data(), m_data_buffer.size()); + } else { + // TODO: set status + } + // logerror("grid210x_device write sector %d\n", floppy_sector_number); + // wait + m_floppy_loop_state = GRID210X_STATE_WRITING_DATA_WAIT; + m_delay_timer->adjust(read_delay); + } +} + +void grid210x_device::ieee488_dav(int state) { + if(state == 0 && m_gpib_loop_state == GRID210X_GPIB_STATE_IDLE) { + // read data and wait for transfer end + int atn = m_bus->atn_r() ^ 1; + m_bus->nrfd_w(this, 0); + uint8_t data = m_bus->read_dio() ^ 0xFF; + int eoi = m_bus->eoi_r() ^ 1; + LOG_BYTES("grid210x_device byte recv %02x atn %d eoi %d\n", data, atn, eoi); + m_last_recv_byte = data; + m_last_recv_atn = atn; + m_last_recv_eoi = eoi; + m_bus->ndac_w(this, 1); + m_gpib_loop_state = GRID210X_GPIB_STATE_WAIT_DAV_FALSE; + } else if (state == 1 && m_gpib_loop_state == GRID210X_GPIB_STATE_WAIT_DAV_FALSE) { + // restore initial state + // m_bus->ndac_w(this, 0); + m_bus->nrfd_w(this, 1); + m_gpib_loop_state = GRID210X_GPIB_STATE_IDLE; + update_ndac(m_bus->atn_r() ^ 1); + + if (m_last_recv_atn) { + if ((m_last_recv_byte & 0xE0) == 0x20) { + if ((m_last_recv_byte & 0x1F) == bus_addr) { + // dev-id = 5 + listening = true; + LOG("grid210x_device now listening\n"); + } else if((m_last_recv_byte & 0x1F) == 0x1F) { + // reset listen + listening = false; + LOG("grid210x_device now not listening\n"); + } + } else if ((m_last_recv_byte & 0xE0) == 0x40) { + if ((m_last_recv_byte & 0x1F) == bus_addr) { + // dev-id = 5 + talking = true; + LOG("grid210x_device now talking\n"); + } else { + // reset talk + talking = false; + LOG("grid210x_device now not talking\n"); + } + } else if (m_last_recv_byte == 0x18) { + // serial poll enable + serial_polling = true; + } else if (m_last_recv_byte == 0x19) { + // serial poll disable + serial_polling = false; + } + } else if (listening) { + m_data_buffer.push_back(m_last_recv_byte); + if (m_last_recv_eoi) { + accept_transfer(); + m_data_buffer.clear(); + } + } + + if (talking) { + if (serial_polling) { + bool had_srq = has_srq; + if (has_srq) { + has_srq = false; + m_bus->srq_w(this, 1); + } + m_byte_to_send = serial_poll_byte | (had_srq ? 0x40 : 0); + serial_poll_byte = 0; + m_send_eoi = 1; + m_gpib_loop_state = GRID210X_GPIB_STATE_SEND_DATA_START; + } else if (!m_output_data_buffer.empty()) { + m_byte_to_send = m_output_data_buffer.front(); + m_output_data_buffer.pop(); + m_send_eoi = m_output_data_buffer.empty() ? 1 : 0; + m_gpib_loop_state = GRID210X_GPIB_STATE_SEND_DATA_START; + } + } + } +} + +void grid210x_device::ieee488_nrfd(int state) { + if (state == 1 && m_gpib_loop_state == GRID210X_GPIB_STATE_SEND_DATA_START) { + // set dio and assert dav + m_bus->write_dio(m_byte_to_send ^ 0xFF); + m_bus->eoi_w(this, m_send_eoi ^ 1); + m_bus->dav_w(this, 0); + m_bus->ndac_w(this, 1); + m_gpib_loop_state = GRID210X_GPIB_STATE_WAIT_NDAC_FALSE; + LOG_BYTES("grid210x_device byte send %02x eoi %d\n", m_byte_to_send, m_send_eoi); + ieee488_ndac(m_bus->ndac_r()); + } + // logerror("grid210x_device nrfd state set to %d\n", state); +} + +void grid210x_device::ieee488_ndac(int state) { + if (state == 1 && m_gpib_loop_state == GRID210X_GPIB_STATE_WAIT_NDAC_FALSE) { + // restore initial state + // logerror("grid210x_device restore ndac nrfd dav eoi\n"); + m_bus->nrfd_w(this, 1); + m_bus->dav_w(this, 1); + m_bus->eoi_w(this, 1); + m_gpib_loop_state = GRID210X_GPIB_STATE_IDLE; + if (serial_polling) { + talking = false; + } + update_ndac(m_bus->atn_r() ^ 1); + + if (!serial_polling && talking && !m_output_data_buffer.empty()) { + m_byte_to_send = m_output_data_buffer.front(); + m_output_data_buffer.pop(); + m_send_eoi = m_output_data_buffer.empty() ? 1 : 0; + m_gpib_loop_state = GRID210X_GPIB_STATE_SEND_DATA_START; + } + } + // logerror("grid210x_device ndac state set to %d\n", state); +} + +void grid210x_device::ieee488_ifc(int state) { + // logerror("grid210x_device ifc state set to %d\n", state); +} + +void grid210x_device::ieee488_srq(int state) { + // logerror("grid210x_device srq state set to %d\n", state); +} + +void grid210x_device::ieee488_atn(int state) { + // logerror("grid210x_device atn state set to %d\n", state); + update_ndac(state ^ 1); +} + +void grid210x_device::update_ndac(int atn) { + if (m_gpib_loop_state == GRID210X_GPIB_STATE_IDLE) { + if (atn) { + // pull NDAC low + m_bus->ndac_w(this, 0); + } else { + // pull NDAC high if not listener and low if listener + m_bus->ndac_w(this, listening ? 0 : 1); + } + } +} + +void grid210x_device::ieee488_ren(int state) { + LOG("grid210x_device ren state set to %d\n", state); +} + +grid2101_hdd_device::grid2101_hdd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : grid210x_device(mconfig, GRID2101_HDD, tag, owner, clock, 4, identify_response, attotime::from_usec(150)) +{ + +} + +grid2101_floppy_device::grid2101_floppy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : grid210x_device(mconfig, GRID2101_FLOPPY, tag, owner, clock, 5, identify_response) +{ + +} + +grid2102_device::grid2102_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : grid210x_device(mconfig, GRID2102, tag, owner, clock, 6, identify_response) +{ + +} diff --git a/src/devices/bus/ieee488/grid2102.h b/src/devices/bus/ieee488/grid2102.h new file mode 100644 index 00000000000..1f461133bf6 --- /dev/null +++ b/src/devices/bus/ieee488/grid2102.h @@ -0,0 +1,114 @@ +// license:BSD-3-Clause +// copyright-holders:usernameak +/********************************************************************** + + GRiD 2102 Portable Floppy emulation + +**********************************************************************/ + +#ifndef MAME_BUS_IEEE488_GRID2102_H +#define MAME_BUS_IEEE488_GRID2102_H + +#pragma once + +#include "ieee488.h" + +#include <vector> +#include <queue> + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> grid210x_device +class grid210x_device : public device_t, + public device_ieee488_interface, + public device_image_interface +{ +public: + // construction/destruction + grid210x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int bus_addr, uint8_t *identify_response, attotime read_delay = attotime::from_msec(5)); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + + // device_ieee488_interface overrides + virtual void ieee488_eoi(int state) override; + virtual void ieee488_dav(int state) override; + virtual void ieee488_nrfd(int state) override; + virtual void ieee488_ndac(int state) override; + virtual void ieee488_ifc(int state) override; + virtual void ieee488_srq(int state) override; + virtual void ieee488_atn(int state) override; + virtual void ieee488_ren(int state) override; + + // image-level overrides + virtual iodevice_t image_type() const noexcept override { return IO_FLOPPY; } + + virtual bool is_readable() const noexcept override { return true; } + virtual bool is_writeable() const noexcept override { return true; } + virtual bool is_creatable() const noexcept override { return false; } + virtual bool must_be_loaded() const noexcept override { return false; } + virtual bool is_reset_on_load() const noexcept override { return false; } + virtual const char *file_extensions() const noexcept override { return "img"; } + + void accept_transfer(); + void update_ndac(int atn); +private: + int m_gpib_loop_state; + int m_floppy_loop_state; + uint8_t m_last_recv_byte; + int m_last_recv_eoi; + int m_last_recv_atn; + uint8_t m_byte_to_send; + int m_send_eoi; + bool listening, talking, serial_polling; + bool has_srq; + uint8_t serial_poll_byte; + uint32_t floppy_sector_number; + int bus_addr; + uint8_t *identify_response_ptr; + std::vector<uint8_t> m_data_buffer; + std::queue<uint8_t> m_output_data_buffer; + uint16_t io_size; + emu_timer *m_delay_timer; +protected: + attotime read_delay; +}; + +class grid2102_device : public grid210x_device { +public: + // construction/destruction + grid2102_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +private: + static uint8_t identify_response[]; +}; + +class grid2101_floppy_device : public grid210x_device { +public: + // construction/destruction + grid2101_floppy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +private: + static uint8_t identify_response[]; +}; + +class grid2101_hdd_device : public grid210x_device { +public: + // construction/destruction + grid2101_hdd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // image-level overrides + virtual iodevice_t image_type() const noexcept override { return IO_HARDDISK; } + +private: + static uint8_t identify_response[]; +}; + +// device type definition +DECLARE_DEVICE_TYPE(GRID2102, grid2102_device) +DECLARE_DEVICE_TYPE(GRID2101_FLOPPY, grid2101_floppy_device) +DECLARE_DEVICE_TYPE(GRID2101_HDD, grid2101_hdd_device) + +#endif // MAME_BUS_IEEE488_GRID2102_H diff --git a/src/devices/bus/ieee488/ieee488.cpp b/src/devices/bus/ieee488/ieee488.cpp index 77a5650333a..bcbe20e0573 100644 --- a/src/devices/bus/ieee488/ieee488.cpp +++ b/src/devices/bus/ieee488/ieee488.cpp @@ -450,3 +450,18 @@ void remote488_devices(device_slot_interface &device) { device.option_add("remote488", REMOTE488); } + + +//------------------------------------------------- +// SLOT_INTERFACE( grid_ieee488_devices ) +//------------------------------------------------- + +// slot devices +#include "grid2102.h" + +void grid_ieee488_devices(device_slot_interface &device) +{ + device.option_add("grid2102", GRID2102).clock(XTAL(4'000'000)); + device.option_add("grid2101_floppy", GRID2101_FLOPPY).clock(XTAL(4'000'000)); + device.option_add("grid2101_hdd", GRID2101_HDD).clock(XTAL(4'000'000)); +} diff --git a/src/devices/bus/ieee488/ieee488.h b/src/devices/bus/ieee488/ieee488.h index d960d17bacf..67c5ca6be07 100644 --- a/src/devices/bus/ieee488/ieee488.h +++ b/src/devices/bus/ieee488/ieee488.h @@ -15,6 +15,7 @@ void cbm_ieee488_devices(device_slot_interface &device); void hp_ieee488_devices(device_slot_interface &device); void remote488_devices(device_slot_interface &device); +void grid_ieee488_devices(device_slot_interface &device); DECLARE_DEVICE_TYPE(IEEE488, ieee488_device) DECLARE_DEVICE_TYPE(IEEE488_SLOT, ieee488_slot_device) diff --git a/src/devices/machine/i80130.cpp b/src/devices/machine/i80130.cpp index ac27c755020..524f1dca516 100644 --- a/src/devices/machine/i80130.cpp +++ b/src/devices/machine/i80130.cpp @@ -80,20 +80,20 @@ WRITE16_MEMBER( i80130_device::io_w ) // ROM( i80130 ) //------------------------------------------------- -ROM_START( i80130 ) - ROM_REGION16_LE( 0x4000, "rom", 0 ) - ROM_LOAD( "80130", 0x0000, 0x4000, NO_DUMP ) -ROM_END +//ROM_START( i80130 ) +// ROM_REGION16_LE( 0x4000, "rom", 0 ) +// ROM_LOAD( "80130", 0x0000, 0x4000, NO_DUMP ) +//ROM_END //------------------------------------------------- // rom_region - device-specific ROM region //------------------------------------------------- -const tiny_rom_entry *i80130_device::device_rom_region() const -{ - return ROM_NAME( i80130 ); -} +//const tiny_rom_entry *i80130_device::device_rom_region() const +//{ +// return ROM_NAME( i80130 ); +//} //------------------------------------------------- diff --git a/src/devices/machine/i80130.h b/src/devices/machine/i80130.h index 27f6e9c582d..0a0629b5a77 100644 --- a/src/devices/machine/i80130.h +++ b/src/devices/machine/i80130.h @@ -46,7 +46,7 @@ protected: virtual void device_start() override; virtual void device_reset() override; // optional information overrides - virtual const tiny_rom_entry *device_rom_region() const override; +// virtual const tiny_rom_entry *device_rom_region() const override; virtual void device_add_mconfig(machine_config &config) override; private: diff --git a/src/devices/machine/tms9914.cpp b/src/devices/machine/tms9914.cpp index 688f12b4762..fc6c7dbe9d5 100644 --- a/src/devices/machine/tms9914.cpp +++ b/src/devices/machine/tms9914.cpp @@ -1006,6 +1006,9 @@ void tms9914_device::update_fsm() switch (m_c_state) { case FSM_C_CIDS: // sic | rqc -> CADS + if (!controller_reset() && m_sic && m_c_state == FSM_C_CIDS) { + m_c_state = FSM_C_CADS; + } break; case FSM_C_CADS: diff --git a/src/mame/drivers/gridcomp.cpp b/src/mame/drivers/gridcomp.cpp index 5269eb99304..958d2a79b8f 100644 --- a/src/mame/drivers/gridcomp.cpp +++ b/src/mame/drivers/gridcomp.cpp @@ -20,7 +20,7 @@ - Intel 7220 Bubble Memory Controller - 7110 Magnetic Bubble Memory modules and support chips - (unknown) - EAROM for machine ID - - (unknown) - Real-Time Clock + - MM58174AN - Real-Time Clock - (custom DMA logic) - Intel 8741 - keyboard MCU - Intel 8274 - UART @@ -29,36 +29,37 @@ - MK5089N - DTMF generator - ... + high-resolution motherboard photo (enough to read chip numbers): http://deltacxx.insomnia247.nl/gridcompass/motherboard.jpg + + differences between models: + - Compass 110x do not have GRiDROM slots. + - Compass II (112x, 113x) have 4 of them. + - Compass II 113x have 512x256 screen size + - Compass 11x9 have 512K ram + - Compass II have DMA addresses different from Compass 110x + to do: - - confirm differences between models except screen size - - Compass 110x do not have GRiDROM slots. - - Compass II (112x, 113x) have 4 of them. - keyboard: decode and add the rest of keycodes + keycode table can be found here on page A-2: + http://deltacxx.insomnia247.nl/gridcompass/large_files/Yahoo%20group%20backup/RuGRiD-Laptop/files/6_GRiD-OS-Programming/3_GRiD-OS-Reference.pdf - EAROM, RTC - - serial port, modem (incl. DTMF generator) - - TMS9914 chip driver (incl. DMA) - - GPIB storage devices (floppy, hard disk) + - serial port (incomplete), modem (incl. DTMF generator) + - proper custom DMA logic timing + - implement units other than 1101 missing dumps: - - BIOS from models other than 1139 (CCOS and MS-DOS variants) + - BIOS from models other than 1139 and late 1101 revision (the latter one is detected as 1108 in VERIFYPROM utility) - GRiDROM's - keyboard MCU - external floppy and hard disk (2101, 2102) to boot CCOS 3.0.1: - - pad binary image (not .imd) to 384K - - attach it as -memcard - - use grid1129 with 'patched' ROM - - start with -debug and add breakpoints: - - # bubble memory driver - bp ff27a,1,{ax=ax*2;go} - # boot loader - bp 20618,1,{temp0=214A8;do w@(temp0+7)=120;do w@(temp0+9)=121;go} - # CCOS kernel - bp 0661a,1,{temp0=0f964;do w@(temp0+7)=120;do w@(temp0+9)=121;go} + - convert GRIDOS.IMD to IMG format + - create zero-filled 384K bubble memory image and attach it as -memcard + - attach floppy with `-ieee_grid grid2102 -flop GRIDOS.IMG` + - use grid1101 with 'ccos' ROM ***************************************************************************/ @@ -86,7 +87,7 @@ #define LOG_KEYBOARD (1U << 1) #define LOG_DEBUG (1U << 2) -//#define VERBOSE (LOG_DEBUG) +#define VERBOSE (LOG_GENERAL) //#define LOG_OUTPUT_FUNC printf #include "logmacro.h" @@ -107,6 +108,7 @@ public: , m_uart8274(*this, "uart8274") , m_speaker(*this, "speaker") , m_ram(*this, RAM_TAG) + , m_tms9914(*this, "hpib") { } void grid1129(machine_config &config); @@ -125,6 +127,7 @@ private: optional_device<i8274_device> m_uart8274; required_device<speaker_sound_device> m_speaker; required_device<ram_device> m_ram; + required_device<tms9914_device> m_tms9914; DECLARE_MACHINE_START(gridcomp); DECLARE_MACHINE_RESET(gridcomp); @@ -133,9 +136,12 @@ private: DECLARE_READ16_MEMBER(grid_9ff0_r); DECLARE_READ16_MEMBER(grid_keyb_r); - DECLARE_READ16_MEMBER(grid_gpib_r); + DECLARE_READ8_MEMBER(grid_modem_r); DECLARE_WRITE16_MEMBER(grid_keyb_w); - DECLARE_WRITE16_MEMBER(grid_gpib_w); + DECLARE_WRITE8_MEMBER(grid_modem_w); + + DECLARE_WRITE8_MEMBER(grid_dma_w); + DECLARE_READ8_MEMBER(grid_dma_r); uint32_t screen_update_110x(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); uint32_t screen_update_113x(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); @@ -207,39 +213,31 @@ void gridcomp_state::kbd_put(u16 data) // reject all commands -READ16_MEMBER(gridcomp_state::grid_gpib_r) +READ8_MEMBER(gridcomp_state::grid_modem_r) { - uint16_t data = 0; - - switch (offset) - { - case 0: - data = 0x10; // BO - break; - - case 1: - data = 0x40; // ERR - m_osp->ir5_w(CLEAR_LINE); - break; - } - - LOG("GPIB %02x == %02x\n", 0xdff80 + (offset << 1), data); + uint8_t data = 0; + LOG("MDM %02x == %02x\n", 0xdfec0 + (offset << 1), data); return data; } -WRITE16_MEMBER(gridcomp_state::grid_gpib_w) +WRITE8_MEMBER(gridcomp_state::grid_modem_w) { - switch (offset) - { - case 7: - m_osp->ir5_w(ASSERT_LINE); - break; - } + LOG("MDM %02x <- %02x\n", 0xdfec0 + (offset << 1), data); +} - LOG("GPIB %02x <- %02x\n", 0xdff80 + (offset << 1), data); +WRITE8_MEMBER(gridcomp_state::grid_dma_w) +{ + m_tms9914->write(7, data); + // LOG("DMA %02x <- %02x\n", offset, data); } +READ8_MEMBER(gridcomp_state::grid_dma_r) +{ + int ret = m_tms9914->read(7); + // LOG("DMA %02x == %02x\n", offset, ret); + return ret; +} uint32_t gridcomp_state::screen_update_generic(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int px) { @@ -307,10 +305,12 @@ void gridcomp_state::grid1101_map(address_map &map) map.unmap_value_high(); map(0xdfe80, 0xdfe83).rw("i7220", FUNC(i7220_device::read), FUNC(i7220_device::write)).umask16(0x00ff); map(0xdfea0, 0xdfeaf).unmaprw(); // ?? - map(0xdfec0, 0xdfecf).rw(m_modem, FUNC(i8255_device::read), FUNC(i8255_device::write)).umask16(0x00ff); // incl. DTMF generator + map(0xdfec0, 0xdfecf).rw(FUNC(gridcomp_state::grid_modem_r), FUNC(gridcomp_state::grid_modem_w)).umask16(0x00ff); // incl. DTMF generator + map(0xdff00, 0xdff1f).rw("uart8274", FUNC(i8274_device::ba_cd_r), FUNC(i8274_device::ba_cd_w)).umask16(0x00ff); map(0xdff40, 0xdff5f).noprw(); // ?? machine ID EAROM, RTC map(0xdff80, 0xdff8f).rw("hpib", FUNC(tms9914_device::read), FUNC(tms9914_device::write)).umask16(0x00ff); map(0xdffc0, 0xdffcf).rw(FUNC(gridcomp_state::grid_keyb_r), FUNC(gridcomp_state::grid_keyb_w)); // Intel 8741 MCU + map(0xe0000, 0xeffff).rw(FUNC(gridcomp_state::grid_dma_r), FUNC(gridcomp_state::grid_dma_w)); // DMA map(0xfc000, 0xfffff).rom().region("user1", 0); } @@ -320,11 +320,12 @@ void gridcomp_state::grid1121_map(address_map &map) map(0x90000, 0x97fff).unmaprw(); // ?? ROM slot map(0x9ff00, 0x9ff0f).unmaprw(); // .r(FUNC(gridcomp_state::grid_9ff0_r)); // ?? ROM? map(0xc0000, 0xcffff).unmaprw(); // ?? ROM slot -- signature expected: 0x4554, 0x5048 + map(0xdfa00, 0xdfdff).rw(FUNC(gridcomp_state::grid_dma_r), FUNC(gridcomp_state::grid_dma_w)); // DMA map(0xdfe00, 0xdfe1f).unmaprw(); // .rw("uart8274", FUNC(i8274_device::ba_cd_r), FUNC(i8274_device::ba_cd_w)).umask16(0x00ff); map(0xdfe40, 0xdfe4f).unmaprw(); // ?? diagnostic 8274 map(0xdfe80, 0xdfe83).rw("i7220", FUNC(i7220_device::read), FUNC(i7220_device::write)).umask16(0x00ff); map(0xdfea0, 0xdfeaf).unmaprw(); // ?? - map(0xdfec0, 0xdfecf).rw(m_modem, FUNC(i8255_device::read), FUNC(i8255_device::write)).umask16(0x00ff); // incl. DTMF generator + map(0xdfec0, 0xdfecf).rw(FUNC(gridcomp_state::grid_modem_r), FUNC(gridcomp_state::grid_modem_w)).umask16(0x00ff); // incl. DTMF generator map(0xdff40, 0xdff5f).noprw(); // ?? machine ID EAROM, RTC map(0xdff80, 0xdff8f).rw("hpib", FUNC(tms9914_device::read), FUNC(tms9914_device::write)).umask16(0x00ff); map(0xdffc0, 0xdffcf).rw(FUNC(gridcomp_state::grid_keyb_r), FUNC(gridcomp_state::grid_keyb_w)); // Intel 8741 MCU @@ -382,7 +383,7 @@ void gridcomp_state::grid1101(machine_config &config) i7220.irq_callback().set(I80130_TAG, FUNC(i80130_device::ir1_w)); i7220.drq_callback().set(I80130_TAG, FUNC(i80130_device::ir1_w)); - tms9914_device &hpib(TMS9914(config, "hpib", XTAL(4'000'000))); + tms9914_device &hpib(TMS9914(config, m_tms9914, XTAL(4'000'000))); hpib.int_write_cb().set(I80130_TAG, FUNC(i80130_device::ir5_w)); hpib.dio_read_cb().set(IEEE488_TAG, FUNC(ieee488_device::dio_r)); hpib.dio_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_dio_w)); @@ -404,9 +405,21 @@ void gridcomp_state::grid1101(machine_config &config) ieee.srq_callback().set("hpib", FUNC(tms9914_device::srq_w)); ieee.atn_callback().set("hpib", FUNC(tms9914_device::atn_w)); ieee.ren_callback().set("hpib", FUNC(tms9914_device::ren_w)); + IEEE488_SLOT(config, "ieee_grid", 0, grid_ieee488_devices, nullptr); + IEEE488_SLOT(config, "ieee_grid2", 0, grid_ieee488_devices, nullptr); + IEEE488_SLOT(config, "ieee_grid3", 0, grid_ieee488_devices, nullptr); + IEEE488_SLOT(config, "ieee_grid4", 0, grid_ieee488_devices, nullptr); IEEE488_SLOT(config, "ieee_rem", 0, remote488_devices, nullptr); I8274(config, m_uart8274, XTAL(4'032'000)); + m_uart8274->out_txda_callback().set("rs232_port", FUNC(rs232_port_device::write_txd)); + m_uart8274->out_dtra_callback().set("rs232_port", FUNC(rs232_port_device::write_dtr)); + m_uart8274->out_rtsa_callback().set("rs232_port", FUNC(rs232_port_device::write_rts)); + + rs232_port_device &rs232_port(RS232_PORT(config, "rs232_port", default_rs232_devices, nullptr)); + rs232_port.rxd_handler().set("uart8274", FUNC(i8274_device::rxa_w)); + rs232_port.dcd_handler().set("uart8274", FUNC(i8274_device::dcda_w)); + rs232_port.cts_handler().set("uart8274", FUNC(i8274_device::ctsa_w)); I8255(config, "modem", 0); @@ -422,7 +435,7 @@ void gridcomp_state::grid1109(machine_config &config) void gridcomp_state::grid1121(machine_config &config) { grid1101(config); - m_maincpu->set_clock(XTAL(24'000'000) / 3); // XXX + // m_maincpu->set_clock(XTAL(24'000'000) / 3); // XXX m_maincpu->set_addrmap(AS_PROGRAM, &gridcomp_state::grid1121_map); } @@ -450,8 +463,7 @@ ROM_START( grid1101 ) ROM_REGION16_LE(0x10000, "user1", 0) ROM_SYSTEM_BIOS(0, "ccos", "ccos bios") - ROMX_LOAD("1101even.bin", 0x0000, 0x2000, NO_DUMP, ROM_SKIP(1) | ROM_BIOS(0)) - ROMX_LOAD("1101odd.bin", 0x0001, 0x2000, NO_DUMP, ROM_SKIP(1) | ROM_BIOS(0)) + ROMX_LOAD("bios1101_0_25.bin", 0x0000, 0x4000, CRC(625388cb) SHA1(4c52c62fa9bc2f9a9a0a1e7f3beddef6809b9eed), ROM_BIOS(0)) ROM_END ROM_START( grid1109 ) @@ -472,7 +484,7 @@ ROM_END ROM_START( grid1129 ) ROM_REGION16_LE(0x10000, "user1", 0) - ROM_DEFAULT_BIOS("patched") + ROM_DEFAULT_BIOS("ccos") ROM_SYSTEM_BIOS(0, "ccos", "ccos bios") ROMX_LOAD("1129even.bin", 0x0000, 0x2000, NO_DUMP, ROM_SKIP(1) | ROM_BIOS(0)) @@ -603,7 +615,7 @@ ROM_END ***************************************************************************/ // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1982, grid1101, 0, 0, grid1101, gridcomp, gridcomp_state, empty_init, "GRiD Computers", "Compass 1101", MACHINE_IS_SKELETON ) +COMP( 1982, grid1101, 0, 0, grid1101, gridcomp, gridcomp_state, empty_init, "GRiD Computers", "Compass 1101", MACHINE_TYPE_COMPUTER | MACHINE_NO_SOUND_HW | MACHINE_IMPERFECT_CONTROLS | MACHINE_NODEVICE_PRINTER | MACHINE_NODEVICE_LAN ) COMP( 1982, grid1109, grid1101, 0, grid1109, gridcomp, gridcomp_state, empty_init, "GRiD Computers", "Compass 1109", MACHINE_IS_SKELETON ) COMP( 1984, grid1121, 0, 0, grid1121, gridcomp, gridcomp_state, empty_init, "GRiD Computers", "Compass II 1121", MACHINE_IS_SKELETON ) COMP( 1984, grid1129, grid1121, 0, grid1129, gridcomp, gridcomp_state, empty_init, "GRiD Computers", "Compass II 1129", MACHINE_IS_SKELETON ) diff --git a/src/mame/machine/gridkeyb.cpp b/src/mame/machine/gridkeyb.cpp index bace5c09696..0d00db9d4cb 100644 --- a/src/mame/machine/gridkeyb.cpp +++ b/src/mame/machine/gridkeyb.cpp @@ -43,6 +43,12 @@ u16 const TRANSLATION_TABLE[][4][16] = { { 0xffU, 0x01U, 0x13U, 0x04U, 0x06U, 0x07U, 0x08U, 0x0aU, 0x0bU, 0x0cU, ';', '\'', 0x8dU, 0xffU, 0xffU, 0x0aU }, { 0xffU, 0x1cU, 0x1aU, 0x18U, 0x03U, 0x16U, 0x02U, 0x0eU, 0x0dU, ',', '.', 0xbfU, 0xffU, 0xffU, 0xffU, 0x00U } }, + { // CODE-CTRL + { 0x00U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, 0x98U, 0x99U, 0x90U, 0xBDU, 0x9DU, 0x88U, 0x7fU, 0x9bU }, + { 0x89U, 0x91U, 0x97U, 0x85U, 0x92U, 0x94U, 0x99U, 0x95U, 0x89U, 0x8fU, 0x90U, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU }, + { 0xffU, 0x81U, 0x93U, 0x84U, 0x86U, 0x87U, 0x88U, 0x8aU, 0x8bU, 0x8cU, 0x1EU, 0x00U, 0x8dU, 0xffU, 0xffU, 0x0aU }, + { 0xffU, 0x9cU, 0x9aU, 0x98U, 0x83U, 0x96U, 0x82U, 0x8eU, 0x8dU, 0x1bU, 0x1DU, 0xbfU, 0xffU, 0xffU, 0xffU, 0x00U } + }, }; @@ -270,7 +276,7 @@ bool grid_keyboard_device::translate(u8 code, u16 &translated) const bool const ctrl(modifiers & 0x01U); bool const meta(modifiers & 0x08U); - unsigned const map(ctrl ? 3U : meta ? 2U : shift ? 1U : 0U); + unsigned const map(ctrl ? (meta ? 4U : 3U) : meta ? 2U : shift ? 1U : 0U); u16 const result(TRANSLATION_TABLE[map][row][col]); if (result == u8(~0U)) { |
