mirror of
https://github.com/holub/mame
synced 2025-04-22 08:22:15 +03:00
intellec4: implement imm4-22 program/data storage module
This commit is contained in:
parent
3a751b164e
commit
7892bf71f9
@ -867,6 +867,8 @@ end
|
||||
|
||||
if (BUSES["INTELLEC4"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/bus/intellec4/insdatastor.cpp",
|
||||
MAME_DIR .. "src/devices/bus/intellec4/insdatastor.h",
|
||||
MAME_DIR .. "src/devices/bus/intellec4/intellec4.cpp",
|
||||
MAME_DIR .. "src/devices/bus/intellec4/intellec4.h",
|
||||
MAME_DIR .. "src/devices/bus/intellec4/prommemory.cpp",
|
||||
|
191
src/devices/bus/intellec4/insdatastor.cpp
Normal file
191
src/devices/bus/intellec4/insdatastor.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
|
||||
#include "emu.h"
|
||||
#include "insdatastor.h"
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE_NS(INTELLEC4_INST_DATA_STORAGE, bus::intellec4, imm4_22_device, "intlc4_imm4_22", "Intel imm4-22 Instruction/Data Storage Module")
|
||||
|
||||
|
||||
namespace bus { namespace intellec4 {
|
||||
|
||||
namespace {
|
||||
|
||||
INPUT_PORTS_START(imm4_22)
|
||||
PORT_START("JUMPERS")
|
||||
PORT_CONFNAME( 0x03, 0x01, "4002 RAM page" )
|
||||
PORT_CONFSETTING( 0x01, "1" )
|
||||
PORT_CONFSETTING( 0x02, "2" )
|
||||
PORT_CONFSETTING( 0x03, "3" )
|
||||
PORT_CONFNAME( 0x0c, 0x04, "PROM/GPIO page" )
|
||||
PORT_CONFSETTING( 0x04, "0x400-0x7FF" )
|
||||
PORT_CONFSETTING( 0x08, "0x800-0xBFF" )
|
||||
PORT_CONFSETTING( 0x0c, "0xC00-0xFFF" )
|
||||
PORT_CONFNAME( 0x10, 0x00, "PROM/GPIO mode" )
|
||||
PORT_CONFSETTING( 0x00, "All" )
|
||||
PORT_CONFSETTING( 0x10, "MON only" )
|
||||
INPUT_PORTS_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
imm4_22_device::imm4_22_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, INTELLEC4_INST_DATA_STORAGE, tag, owner, clock)
|
||||
, device_univ_card_interface(mconfig, *this)
|
||||
, device_image_interface(mconfig, *this)
|
||||
, m_jumpers(*this, "JUMPERS")
|
||||
, m_ram_io_mapped(false)
|
||||
, m_ram_page(0U), m_rom_page(0U), m_rom_mirror(false)
|
||||
, m_prom()
|
||||
{
|
||||
std::fill(std::begin(m_memory), std::end(m_memory), 0U);
|
||||
std::fill(std::begin(m_status), std::end(m_status), 0U);
|
||||
}
|
||||
|
||||
|
||||
image_init_result imm4_22_device::call_load()
|
||||
{
|
||||
if ((length() > 1024U) || (length() % 256U))
|
||||
return image_init_result::FAIL;
|
||||
|
||||
allocate();
|
||||
if (fread(m_prom.get(), length()) != length())
|
||||
return image_init_result::FAIL;
|
||||
|
||||
map_prom();
|
||||
|
||||
return image_init_result::PASS;
|
||||
}
|
||||
|
||||
void imm4_22_device::call_unload()
|
||||
{
|
||||
unmap_prom();
|
||||
}
|
||||
|
||||
|
||||
ioport_constructor imm4_22_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(imm4_22);
|
||||
}
|
||||
|
||||
void imm4_22_device::device_start()
|
||||
{
|
||||
m_ram_io_mapped = false;
|
||||
|
||||
allocate();
|
||||
|
||||
save_item(NAME(m_ram_page));
|
||||
save_item(NAME(m_rom_page));
|
||||
save_item(NAME(m_rom_mirror));
|
||||
save_item(NAME(m_memory));
|
||||
save_item(NAME(m_status));
|
||||
save_pointer(NAME(m_prom.get()), 1024U);
|
||||
}
|
||||
|
||||
void imm4_22_device::device_reset()
|
||||
{
|
||||
map_ram_io();
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(imm4_22_device::reset_4002_in)
|
||||
{
|
||||
// FIXME: this takes several cycles to actually erase everything, and prevents writes while asserted
|
||||
if (!state)
|
||||
{
|
||||
std::fill(std::begin(m_memory), std::end(m_memory), 0U);
|
||||
std::fill(std::begin(m_status), std::end(m_status), 0U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(imm4_22_device::ram_out)
|
||||
{
|
||||
// GPIO write - hooking this up would be a pain with MAME as it is
|
||||
logerror("4002 A%u out %X\n", 13U + (offset & 0x03U), data & 0x0fU);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(imm4_22_device::rom_out)
|
||||
{
|
||||
// GPIO write - hooking this up would be a pain with MAME as it is
|
||||
logerror("ROM %u out %X\n", (m_rom_page << 2) | ((offset >> 4) & 0x03U), data & 0x0fU);
|
||||
}
|
||||
|
||||
READ8_MEMBER(imm4_22_device::rom_in)
|
||||
{
|
||||
// GPIO read - hooking this up would be a pain with MAME as it is
|
||||
if (!machine().side_effect_disabled())
|
||||
logerror("ROM %u in\n", (m_rom_page << 2) | ((offset >> 4) & 0x03U));
|
||||
return 0x0fU;
|
||||
}
|
||||
|
||||
|
||||
void imm4_22_device::allocate()
|
||||
{
|
||||
if (!m_prom)
|
||||
{
|
||||
m_prom = std::make_unique<u8 []>(1024U);
|
||||
std::fill(m_prom.get(), m_prom.get() + 1024U, 0U);
|
||||
}
|
||||
}
|
||||
|
||||
void imm4_22_device::map_ram_io()
|
||||
{
|
||||
if (!m_ram_io_mapped)
|
||||
{
|
||||
static constexpr offs_t ram_start[3][4] = {
|
||||
{ 0x01U, 0x04U, 0x05U, 0x07U },
|
||||
{ 0x02U, 0x04U, 0x06U, 0x07U },
|
||||
{ 0x03U, 0x05U, 0x06U, 0x07U } };
|
||||
|
||||
m_ram_io_mapped = true;
|
||||
|
||||
ioport_value const jumpers(m_jumpers->read());
|
||||
m_ram_page = jumpers & 0x03U;
|
||||
m_rom_page = (jumpers >> 2) & 0x03U;
|
||||
m_rom_mirror = BIT(~jumpers, 4);
|
||||
|
||||
if ((1U > m_ram_page) || (3U < m_ram_page))
|
||||
throw emu_fatalerror("imm4_22_device: invalid RAM page %u", m_ram_page);
|
||||
if ((1U > m_rom_page) || (3U < m_rom_page))
|
||||
throw emu_fatalerror("imm4_22_device: invalid PROM/GPIO page %u", m_rom_page);
|
||||
|
||||
for (offs_t const start : ram_start[m_ram_page - 1U])
|
||||
{
|
||||
memory_space().install_ram(start << 8, (start << 8) | 0x00ffU, m_memory);
|
||||
status_space().install_ram(start << 6, (start << 6) | 0x003fU, m_status);
|
||||
ram_ports_space().install_write_handler(start << 2, (start << 2) | 0x03U, write8_delegate(FUNC(imm4_22_device::ram_out), this));
|
||||
}
|
||||
|
||||
offs_t const rom_ports_start(offs_t(m_rom_page) << 6);
|
||||
offs_t const rom_ports_end(rom_ports_start | 0x003fU);
|
||||
offs_t const rom_ports_mirror(m_rom_mirror ? 0x1f00U : 0x0700U);
|
||||
rom_ports_space().install_readwrite_handler(
|
||||
rom_ports_start, rom_ports_end, 0U, rom_ports_mirror, 0U,
|
||||
read8_delegate(FUNC(imm4_22_device::rom_in), this), write8_delegate(FUNC(imm4_22_device::rom_out), this));
|
||||
|
||||
if (is_loaded())
|
||||
map_prom();
|
||||
}
|
||||
}
|
||||
|
||||
void imm4_22_device::map_prom()
|
||||
{
|
||||
if (m_ram_io_mapped)
|
||||
{
|
||||
// FIXME: gimme a cookie!
|
||||
// FIXME: if mirror is on, this will fight console RAM for the bus in 0x2000 region and also appear in the "two switches" 0x3000 region
|
||||
rom_space().install_rom(
|
||||
offs_t(m_rom_page) << 10, offs_t((offs_t(m_rom_page) << 10) | length()), m_rom_mirror ? 0x1000U : 0x0000U,
|
||||
m_prom.get());
|
||||
}
|
||||
}
|
||||
|
||||
void imm4_22_device::unmap_prom()
|
||||
{
|
||||
// FIXME: where's my magic cookie?
|
||||
rom_space().unmap_read(offs_t(m_rom_page) << 10, (offs_t(m_rom_page) << 10) | 0x03ffU, m_rom_mirror ? 0x1000U : 0x0000U);
|
||||
}
|
||||
|
||||
} } // namespace bus::intellec4
|
199
src/devices/bus/intellec4/insdatastor.h
Normal file
199
src/devices/bus/intellec4/insdatastor.h
Normal file
@ -0,0 +1,199 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
/*
|
||||
imm4-22 Instruction/Data Storage Module
|
||||
|
||||
This card has four 4002 RAMs configured as a page, sockets for four
|
||||
1702A or similar 256×8 PROMs configured as a ROM page, buffers for four
|
||||
4-bit input ports, and latches for four 4-bit output ports.
|
||||
|
||||
The 4002 RAMs may be jumpered to be selected by CM-RAM1, CM-RAM2 or
|
||||
CM-RAM3. Note that the CM-RAM lines are not decoded, so the 4002 RAMs
|
||||
will be mirrored. (With two or more imm4-22 cards are installed, the
|
||||
4002 RAMs will fight for the bus if pages 4-7 are selected.)
|
||||
|
||||
The PROMs and I/O ports may be jumpered to be mapped at 0x04xx...0x07xx,
|
||||
0x08xx...0x0bff or 0x0cff...0x0fff. Additionally, the card may be
|
||||
jumpered to enable the PROMs and I/O ports only when /ENABLE MON PROM is
|
||||
asserted, or at all times.
|
||||
|
||||
This card may seem like a good way to expand three aspects of the system
|
||||
at once, but in practice the PROMs are of limited use:
|
||||
* If jumpered to enable the PROMs at all times, the PROMs will fight for
|
||||
the bus if console RAM card program storage is selected.
|
||||
* If jumpered to enable the PROMs only when /ENABLE MON PROM is
|
||||
asserted, the PROMs become effectively inaccessible as the boot vector
|
||||
is in the onboard monitor PROM region, and the onboard monitor PROM
|
||||
program provides no way to jump to or read from arbitrary locations.
|
||||
|
||||
This card was probably most useful as the cheapest way to double RAM and
|
||||
I/O ports. Without PROMs installed, mapping I/O at 0x0400...0x07ff only
|
||||
when /ENABLE MON PROM is asserted would be a convenient way to provide
|
||||
the necessary connections for an imm4-90 high-speed paper tape reader.
|
||||
|
||||
Image file for the PROMs must be an exact multiple of 256 bytes. PROMs
|
||||
are assumed to be filled in order from lowest to highest address.
|
||||
Jumper changes only take effect on hard reset.
|
||||
|
||||
|
||||
P1 Universal Slot edge connector
|
||||
|
||||
1 2
|
||||
GND 3 4 GND
|
||||
5 6
|
||||
7 8
|
||||
9 10
|
||||
MA0 11 12 MA1
|
||||
MA2 13 14 MA3
|
||||
MA4 15 16 MA5
|
||||
MA6 17 18 MA7
|
||||
C0 19 20 C1
|
||||
21 22
|
||||
/MDI0 23 24
|
||||
/MDI1 25 26
|
||||
/MDI3 27 28
|
||||
/MDI2 29 30
|
||||
/MDI5 31 32
|
||||
/MDI4 33 34
|
||||
/MDI7 35 36
|
||||
/MDI6 37 38
|
||||
39 40
|
||||
/OUT 41 42 /ENABLE MON PROM
|
||||
-10V 43 44 -10V
|
||||
45 46
|
||||
/CM-RAM2 47 48 /CM-RAM3
|
||||
49 50 /CM-RAM1
|
||||
I/O 1 51 52 I/O 0
|
||||
I/O 2 53 54 /IN
|
||||
55 56 I/O 3
|
||||
57 58
|
||||
59 60
|
||||
61 62
|
||||
63 64
|
||||
65 66
|
||||
67 68
|
||||
69 70
|
||||
71 72 /D3
|
||||
73 74
|
||||
75 76 /D2
|
||||
77 78
|
||||
/SYNC 79 80 /D1
|
||||
81 82
|
||||
/D0 83 84
|
||||
85 86
|
||||
87 88 /RESET-4002
|
||||
89 90
|
||||
91 92
|
||||
/CM-ROM 93 94 C3
|
||||
95 96 C2
|
||||
PHASE 2 97 98 PHASE 1
|
||||
+5V 99 100 +5V
|
||||
|
||||
|
||||
P1 inputs (40-pin IDC)
|
||||
|
||||
ROM 4/8/12 IN0 1 2 ROM 4/8/12 IN1
|
||||
ROM 4/8/12 IN2 3 4 ROM 4/8/12 IN3
|
||||
GND 5 6 ROM 5/9/13 IN0
|
||||
ROM 5/9/13 IN1 7 8 ROM 5/9/13 IN2
|
||||
ROM 5/9/13 IN3 9 10 GND
|
||||
ROM 6/10/14 IN0 11 12 ROM 6/10/14 IN1
|
||||
ROM 6/10/14 IN2 13 14 ROM 6/10/14 IN3
|
||||
GND 15 16 ROM 7/11/15 IN0
|
||||
ROM 7/11/15 IN1 17 18 ROM 7/11/15 IN2
|
||||
ROM 7/11/15 IN3 19 20 GND
|
||||
21 22
|
||||
23 24
|
||||
25 26
|
||||
27 28
|
||||
29 30
|
||||
31 32
|
||||
33 34
|
||||
35 36
|
||||
37 38
|
||||
39 40
|
||||
|
||||
|
||||
P2 outputs (40-pin IDC)
|
||||
|
||||
ROM 4/8/12 OUT0 1 2 ROM 4/8/12 OUT1
|
||||
ROM 4/8/12 OUT2 3 4 ROM 4/8/12 OUT3
|
||||
GND 5 6 ROM 5/9/13 OUT0
|
||||
ROM 5/9/13 OUT1 7 8 ROM 5/9/13 OUT2
|
||||
ROM 5/9/13 OUT3 9 10 GND
|
||||
ROM 6/10/14 OUT0 11 12 ROM 6/10/14 OUT1
|
||||
ROM 6/10/14 OUT2 13 14 ROM 6/10/14 OUT3
|
||||
GND 15 16 ROM 7/11/15 OUT0
|
||||
ROM 7/11/15 OUT1 17 18 ROM 7/11/15 OUT2
|
||||
ROM 7/11/15 OUT3 19 20 GND
|
||||
RAM 4/8/12 OUT0 21 22 RAM 4/8/12 OUT1
|
||||
RAM 4/8/12 OUT2 23 24 RAM 4/8/12 OUT3
|
||||
GND 25 26 RAM 5/9/13 OUT0
|
||||
RAM 5/9/13 OUT1 27 28 RAM 5/9/13 OUT2
|
||||
RAM 5/9/13 OUT3 29 30 GND
|
||||
RAM 6/10/14 OUT0 31 32 RAM 6/10/14 OUT1
|
||||
RAM 6/10/14 OUT2 33 34 RAM 6/10/14 OUT3
|
||||
GND 35 36 RAM 7/11/15 OUT0
|
||||
RAM 7/11/15 OUT1 37 38 RAM 7/11/15 OUT2
|
||||
RAM 7/11/15 OUT3 39 40 GND
|
||||
*/
|
||||
#ifndef MAME_BUS_INTELLEC4_INSDATASTOR_H
|
||||
#define MAME_BUS_INTELLEC4_INSDATASTOR_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "intellec4.h"
|
||||
|
||||
namespace bus { namespace intellec4 {
|
||||
|
||||
class imm4_22_device : public device_t, public device_univ_card_interface, public device_image_interface
|
||||
{
|
||||
public:
|
||||
imm4_22_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||
|
||||
virtual image_init_result call_load() override;
|
||||
virtual void call_unload() override;
|
||||
|
||||
virtual iodevice_t image_type() const override { return IO_ROM; }
|
||||
virtual bool is_readable() const override { return true; }
|
||||
virtual bool is_writeable() const override { return false; }
|
||||
virtual bool is_creatable() const override { return false; }
|
||||
virtual bool must_be_loaded() const override { return false; }
|
||||
virtual bool is_reset_on_load() const override { return false; }
|
||||
virtual char const *file_extensions() const override { return "rom,bin"; }
|
||||
virtual char const *custom_instance_name() const override { return "promimage"; }
|
||||
virtual char const *custom_brief_instance_name() const override { return "prom"; }
|
||||
|
||||
protected:
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
virtual DECLARE_WRITE_LINE_MEMBER(reset_4002_in) override;
|
||||
|
||||
private:
|
||||
DECLARE_WRITE8_MEMBER(ram_out);
|
||||
DECLARE_WRITE8_MEMBER(rom_out);
|
||||
DECLARE_READ8_MEMBER(rom_in);
|
||||
|
||||
void allocate();
|
||||
void map_ram_io();
|
||||
void map_prom();
|
||||
void unmap_prom();
|
||||
|
||||
required_ioport m_jumpers;
|
||||
|
||||
bool m_ram_io_mapped;
|
||||
|
||||
u8 m_ram_page, m_rom_page;
|
||||
bool m_rom_mirror;
|
||||
|
||||
u8 m_memory[256], m_status[64];
|
||||
std::unique_ptr<u8 []> m_prom;
|
||||
};
|
||||
|
||||
} } // namespace bus::intellec4
|
||||
|
||||
DECLARE_DEVICE_TYPE_NS(INTELLEC4_INST_DATA_STORAGE, bus::intellec4, imm4_22_device)
|
||||
|
||||
#endif // MAME_BUS_INTELLEC4_INSDATASTOR_H
|
@ -74,12 +74,12 @@ univ_bus_device::univ_bus_device(machine_config const &mconfig, char const *tag,
|
||||
, m_memory_space(-1)
|
||||
, m_status_space(-1)
|
||||
, m_ram_ports_space(-1)
|
||||
, m_stop_out_cb(*this)
|
||||
, m_test_out_cb(*this)
|
||||
, m_stop_out_cb(*this)
|
||||
, m_reset_4002_out_cb(*this)
|
||||
, m_user_reset_out_cb(*this)
|
||||
, m_stop(0U)
|
||||
, m_test(0U)
|
||||
, m_stop(0U)
|
||||
, m_reset_4002(0U)
|
||||
, m_user_reset(0U)
|
||||
{
|
||||
@ -133,44 +133,35 @@ void univ_bus_device::set_ram_ports_space(device_t &device, char const *tag, int
|
||||
|
||||
WRITE_LINE_MEMBER(univ_bus_device::sync_in)
|
||||
{
|
||||
// FIXME: distribute to cards
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(univ_bus_device::test_in)
|
||||
{
|
||||
if (state)
|
||||
m_test &= ~u16(1U);
|
||||
else
|
||||
m_test |= 1U;
|
||||
// FIXME: distribute to cards
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(univ_bus_device::stop_in)
|
||||
{
|
||||
if (state)
|
||||
m_stop &= ~u16(1U);
|
||||
else
|
||||
m_stop |= 1U;
|
||||
// FIXME: distribute to cards
|
||||
for (device_univ_card_interface *card : m_cards)
|
||||
{
|
||||
if (card)
|
||||
card->sync_in(state);
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(univ_bus_device::stop_acknowledge_in)
|
||||
{
|
||||
// FIXME: distribute to cards
|
||||
for (device_univ_card_interface *card : m_cards)
|
||||
{
|
||||
if (card)
|
||||
card->stop_acknowledge_in(state);
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(univ_bus_device::cpu_reset_in)
|
||||
{
|
||||
// FIXME: distribute to cards
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(univ_bus_device::reset_4002_in)
|
||||
{
|
||||
if (state)
|
||||
m_reset_4002 &= ~u16(1U);
|
||||
else
|
||||
m_reset_4002 |= 1U;
|
||||
// FIXME: distribute to cards
|
||||
for (device_univ_card_interface *card : m_cards)
|
||||
{
|
||||
if (card)
|
||||
card->cpu_reset_in(state);
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -194,10 +185,15 @@ void univ_bus_device::device_validity_check(validity_checker &valid) const
|
||||
|
||||
void univ_bus_device::device_start()
|
||||
{
|
||||
m_stop_out_cb.resolve_safe();
|
||||
m_test_out_cb.resolve_safe();
|
||||
m_stop_out_cb.resolve_safe();
|
||||
m_reset_4002_out_cb.resolve_safe();
|
||||
m_user_reset_out_cb.resolve_safe();
|
||||
|
||||
save_item(NAME(m_test));
|
||||
save_item(NAME(m_stop));
|
||||
save_item(NAME(m_reset_4002));
|
||||
save_item(NAME(m_user_reset));
|
||||
}
|
||||
|
||||
|
||||
@ -218,6 +214,98 @@ unsigned univ_bus_device::add_card(device_univ_card_interface &card)
|
||||
throw emu_fatalerror("univ_bus_device: maximum number of cards (%u) exceeded\n", unsigned(ARRAY_LENGTH(m_cards)));
|
||||
}
|
||||
|
||||
void univ_bus_device::set_test(unsigned index, int state)
|
||||
{
|
||||
assert(ARRAY_LENGTH(m_cards) >= index);
|
||||
bool const changed(bool(state) != !BIT(m_test, index));
|
||||
if (changed)
|
||||
{
|
||||
u16 const other(m_test & ~(u16(1U) << index));
|
||||
if (state)
|
||||
m_test = other;
|
||||
else
|
||||
m_test |= u16(1U) << index;
|
||||
|
||||
if ((ARRAY_LENGTH(m_cards) != index) && !(other & ~(u16(1U) << ARRAY_LENGTH(m_cards))))
|
||||
m_test_out_cb(state);
|
||||
|
||||
for (unsigned card = 0U; (ARRAY_LENGTH(m_cards) > card) && m_cards[card]; ++card)
|
||||
{
|
||||
if ((index != card) && !(other & ~(u16(1U) << index)))
|
||||
m_cards[card]->test_in(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void univ_bus_device::set_stop(unsigned index, int state)
|
||||
{
|
||||
assert(ARRAY_LENGTH(m_cards) >= index);
|
||||
bool const changed(bool(state) != !BIT(m_stop, index));
|
||||
if (changed)
|
||||
{
|
||||
u16 const other(m_stop & ~(u16(1U) << index));
|
||||
if (state)
|
||||
m_stop = other;
|
||||
else
|
||||
m_stop |= u16(1U) << index;
|
||||
|
||||
if ((ARRAY_LENGTH(m_cards) != index) && !(other & ~(u16(1U) << ARRAY_LENGTH(m_cards))))
|
||||
m_stop_out_cb(state);
|
||||
|
||||
for (unsigned card = 0U; (ARRAY_LENGTH(m_cards) > card) && m_cards[card]; ++card)
|
||||
{
|
||||
if ((index != card) && !(other & ~(u16(1U) << index)))
|
||||
m_cards[card]->stop_in(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void univ_bus_device::set_reset_4002(unsigned index, int state)
|
||||
{
|
||||
assert(ARRAY_LENGTH(m_cards) >= index);
|
||||
bool const changed(bool(state) != !BIT(m_reset_4002, index));
|
||||
if (changed)
|
||||
{
|
||||
u16 const other(m_reset_4002 & ~(u16(1U) << index));
|
||||
if (state)
|
||||
m_reset_4002 = other;
|
||||
else
|
||||
m_reset_4002 |= u16(1U) << index;
|
||||
|
||||
if ((ARRAY_LENGTH(m_cards) != index) && !(other & ~(u16(1U) << ARRAY_LENGTH(m_cards))))
|
||||
m_reset_4002_out_cb(state);
|
||||
|
||||
for (unsigned card = 0U; (ARRAY_LENGTH(m_cards) > card) && m_cards[card]; ++card)
|
||||
{
|
||||
if ((index != card) && !(other & ~(u16(1U) << index)))
|
||||
m_cards[card]->reset_4002_in(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void univ_bus_device::set_user_reset(unsigned index, int state)
|
||||
{
|
||||
assert(ARRAY_LENGTH(m_cards) > index);
|
||||
bool const changed(bool(state) != !BIT(m_user_reset, index));
|
||||
if (changed)
|
||||
{
|
||||
u16 const other(m_user_reset & ~(u16(1U) << index));
|
||||
if (state)
|
||||
m_user_reset = other;
|
||||
else
|
||||
m_user_reset |= u16(1U) << index;
|
||||
|
||||
if (!other)
|
||||
m_user_reset_out_cb(state);
|
||||
|
||||
for (unsigned card = 0U; (ARRAY_LENGTH(m_cards) > card) && m_cards[card]; ++card)
|
||||
{
|
||||
if ((index != card) && !(other & ~(u16(1U) << index)))
|
||||
m_cards[card]->user_reset_in(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
@ -248,10 +336,12 @@ void device_univ_card_interface::set_bus(univ_bus_device &bus)
|
||||
|
||||
|
||||
|
||||
#include "insdatastor.h"
|
||||
#include "prommemory.h"
|
||||
#include "tapereader.h"
|
||||
|
||||
SLOT_INTERFACE_START(intellec4_univ_cards)
|
||||
SLOT_INTERFACE("imm4_90", INTELLEC4_TAPE_READER)
|
||||
SLOT_INTERFACE("imm4_22", INTELLEC4_INST_DATA_STORAGE)
|
||||
SLOT_INTERFACE("imm6_26", INTELLEC4_PROM_MEMORY)
|
||||
SLOT_INTERFACE("imm4_90", INTELLEC4_TAPE_READER)
|
||||
SLOT_INTERFACE_END
|
||||
|
@ -138,12 +138,12 @@ to implement the card in both systems.
|
||||
#define MCFG_INTELLEC4_UNIV_BUS_RAM_PORTS_SPACE(tag, space) \
|
||||
bus::intellec4::univ_bus_device::set_ram_ports_space(*device, "^" tag, space);
|
||||
|
||||
#define MCFG_INTELLEC4_UNIV_BUS_STOP_CB(obj) \
|
||||
bus::intellec4::univ_bus_device::set_stop_out_cb(*device, DEVCB_##obj);
|
||||
|
||||
#define MCFG_INTELLEC4_UNIV_BUS_TEST_CB(obj) \
|
||||
bus::intellec4::univ_bus_device::set_test_out_cb(*device, DEVCB_##obj);
|
||||
|
||||
#define MCFG_INTELLEC4_UNIV_BUS_STOP_CB(obj) \
|
||||
bus::intellec4::univ_bus_device::set_stop_out_cb(*device, DEVCB_##obj);
|
||||
|
||||
#define MCFG_INTELLEC4_UNIV_BUS_RESET_4002_CB(obj) \
|
||||
bus::intellec4::univ_bus_device::set_reset_4002_out_cb(*device, DEVCB_##obj);
|
||||
|
||||
@ -202,15 +202,15 @@ public:
|
||||
|
||||
// input lines
|
||||
DECLARE_WRITE_LINE_MEMBER(sync_in);
|
||||
DECLARE_WRITE_LINE_MEMBER(test_in);
|
||||
DECLARE_WRITE_LINE_MEMBER(stop_in);
|
||||
DECLARE_WRITE_LINE_MEMBER(test_in) {set_test(ARRAY_LENGTH(m_cards), state); }
|
||||
DECLARE_WRITE_LINE_MEMBER(stop_in) {set_stop(ARRAY_LENGTH(m_cards), state); }
|
||||
DECLARE_WRITE_LINE_MEMBER(stop_acknowledge_in);
|
||||
DECLARE_WRITE_LINE_MEMBER(cpu_reset_in);
|
||||
DECLARE_WRITE_LINE_MEMBER(reset_4002_in);
|
||||
DECLARE_WRITE_LINE_MEMBER(reset_4002_in) { set_reset_4002(ARRAY_LENGTH(m_cards), state); }
|
||||
|
||||
// output lines
|
||||
DECLARE_READ_LINE_MEMBER(stop_out) const { return (m_stop & ~u16(1U)) ? 0 : 1; }
|
||||
DECLARE_READ_LINE_MEMBER(test_out) const { return (m_test & ~u16(1U)) ? 0 : 1; }
|
||||
DECLARE_READ_LINE_MEMBER(stop_out) const { return (m_stop & ~u16(1U)) ? 0 : 1; }
|
||||
DECLARE_READ_LINE_MEMBER(reset_4002_out) const { return (m_reset_4002 & ~u16(1U)) ? 0 : 1; }
|
||||
DECLARE_READ_LINE_MEMBER(user_reset_out) const { return (m_user_reset & ~u16(1U)) ? 0 : 1; }
|
||||
|
||||
@ -222,6 +222,10 @@ protected:
|
||||
private:
|
||||
// helpers for cards
|
||||
unsigned add_card(device_univ_card_interface &card);
|
||||
void set_test(unsigned index, int state);
|
||||
void set_stop(unsigned index, int state);
|
||||
void set_reset_4002(unsigned index, int state);
|
||||
void set_user_reset(unsigned index, int state);
|
||||
|
||||
// finding address spaces
|
||||
required_device<device_memory_interface> m_rom_device, m_rom_ports_device;
|
||||
@ -230,8 +234,8 @@ private:
|
||||
int m_memory_space, m_status_space, m_ram_ports_space;
|
||||
|
||||
// output line callbacks
|
||||
devcb_write_line m_stop_out_cb;
|
||||
devcb_write_line m_test_out_cb;
|
||||
devcb_write_line m_stop_out_cb;
|
||||
devcb_write_line m_reset_4002_out_cb;
|
||||
devcb_write_line m_user_reset_out_cb;
|
||||
|
||||
@ -239,7 +243,7 @@ private:
|
||||
device_univ_card_interface *m_cards[15];
|
||||
|
||||
// packed line states
|
||||
u16 m_stop, m_test, m_reset_4002, m_user_reset;
|
||||
u16 m_test, m_stop, m_reset_4002, m_user_reset;
|
||||
};
|
||||
|
||||
|
||||
@ -260,6 +264,19 @@ protected:
|
||||
address_space &status_space() { return m_bus->m_status_device->space(m_bus->m_status_space); }
|
||||
address_space &ram_ports_space() { return m_bus->m_ram_ports_device->space(m_bus->m_ram_ports_space); }
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(test_out) { m_bus->set_test(m_index, state); }
|
||||
DECLARE_WRITE_LINE_MEMBER(stop_out) { m_bus->set_stop(m_index, state); }
|
||||
DECLARE_WRITE_LINE_MEMBER(reset_4002_out) { m_bus->set_reset_4002(m_index, state); }
|
||||
DECLARE_WRITE_LINE_MEMBER(user_reset_out) { m_bus->set_user_reset(m_index, state); }
|
||||
|
||||
virtual DECLARE_WRITE_LINE_MEMBER(sync_in) { }
|
||||
virtual DECLARE_WRITE_LINE_MEMBER(test_in) { }
|
||||
virtual DECLARE_WRITE_LINE_MEMBER(stop_in) { }
|
||||
virtual DECLARE_WRITE_LINE_MEMBER(stop_acknowledge_in) { }
|
||||
virtual DECLARE_WRITE_LINE_MEMBER(cpu_reset_in) { }
|
||||
virtual DECLARE_WRITE_LINE_MEMBER(reset_4002_in) { }
|
||||
virtual DECLARE_WRITE_LINE_MEMBER(user_reset_in) { }
|
||||
|
||||
private:
|
||||
void set_bus(univ_bus_device &bus);
|
||||
|
||||
|
@ -8,8 +8,8 @@ device (use J command to select it), but it doesn't appear in any
|
||||
catalogues or manuals I've seen. Apparently it was announced in
|
||||
Computerworld.
|
||||
|
||||
In practice you needed a GPIO card (e.g. an imm4-60) to talk to the
|
||||
paper taper reader. To simplify configuration we emulate the I/O
|
||||
In practice you needed a GPIO card (e.g. an imm4-60 or imm4-22) to talk
|
||||
to the paper taper reader. To simplify configuration we emulate the I/O
|
||||
interface and paper tape reader as a single device.
|
||||
*/
|
||||
#ifndef MAME_BUS_INTELLEC4_TAPEREADER_H
|
||||
|
@ -95,7 +95,7 @@
|
||||
48 49 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 14 70 71 72
|
||||
5f 61 77 13 78 79 7a 43 0d 18 1b 1c 5e 32 5a
|
||||
|
||||
0f is a blank key
|
||||
0f has a blank keycap
|
||||
backspace immediately above return
|
||||
backslash and backtick/tilde at top right of main area
|
||||
control on home row, caps lock at bottom left corner of main area
|
||||
|
Loading…
Reference in New Issue
Block a user