mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
INTELLEC 4: implement front-panel PROM programmer
This commit is contained in:
parent
4b6e1f2a0c
commit
95906048ab
@ -2130,6 +2130,8 @@ files {
|
||||
MAME_DIR .. "src/mame/drivers/isbc.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/isbc8010.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/isbc8030.cpp",
|
||||
MAME_DIR .. "src/mame/machine/imm6_76.cpp",
|
||||
MAME_DIR .. "src/mame/machine/imm6_76.h",
|
||||
MAME_DIR .. "src/mame/machine/isbc_215g.cpp",
|
||||
MAME_DIR .. "src/mame/machine/isbc_215g.h",
|
||||
MAME_DIR .. "src/mame/machine/isbc_208.cpp",
|
||||
|
@ -254,6 +254,12 @@ protected:
|
||||
// device_interface implementation
|
||||
void interface_pre_start() override;
|
||||
|
||||
address_space &rom_space() { return m_bus->m_rom_device->space(m_bus->m_rom_space); }
|
||||
address_space &rom_ports_space() { return m_bus->m_rom_ports_device->space(m_bus->m_rom_ports_space); }
|
||||
address_space &memory_space() { return m_bus->m_memory_device->space(m_bus->m_memory_space); }
|
||||
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); }
|
||||
|
||||
private:
|
||||
void set_bus(univ_bus_device &bus);
|
||||
|
||||
|
@ -23,19 +23,29 @@
|
||||
MOD 40 jumpered to provide TEST line control rather than 4040 STOP
|
||||
and SINGLE STEP features.
|
||||
|
||||
The MOD 40 repurposes the pins originally used for ROM 1 input port
|
||||
lines to expose stop/interrupt request/acknowledge. It's pretty
|
||||
obvious that the MOD 40 was designed as a minimal modification. A
|
||||
set of X1 display LEDs would have been fantastic, as it would show the
|
||||
contents of the accumulator with the 4040 CPU, while the X3 LEDs really
|
||||
aren't very useful. However, since the 4004 just echoes M2 during X1,
|
||||
the control board has no provision for latching data during this cycle
|
||||
and would have required significant layout changes to cater for this.
|
||||
|
||||
Set the terminal for 110 1/8/N/2 to talk to the monitor.
|
||||
It only accepts uppercase letters, digits, comma, and carriage return.
|
||||
Paper tape reader run/stop is sent to RTS on the serial port.
|
||||
|
||||
TODO:
|
||||
* Default terminal serial settings
|
||||
* 4702A programmer
|
||||
* Universal slot cards
|
||||
* Image device for paper tape reader?
|
||||
* Expose general-purpose I/O?
|
||||
*/
|
||||
#include "emu.h"
|
||||
|
||||
#include "machine/imm6_76.h"
|
||||
|
||||
#include "bus/intellec4/intellec4.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/mcs40/mcs40.h"
|
||||
@ -60,9 +70,15 @@ public:
|
||||
DECLARE_WRITE8_MEMBER(pm_write);
|
||||
|
||||
DECLARE_READ8_MEMBER(rom0_in);
|
||||
DECLARE_READ8_MEMBER(rom2_in);
|
||||
DECLARE_READ8_MEMBER(rom3_in);
|
||||
DECLARE_READ8_MEMBER(rome_in);
|
||||
DECLARE_READ8_MEMBER(romf_in);
|
||||
|
||||
DECLARE_WRITE8_MEMBER(rom0_out);
|
||||
DECLARE_WRITE8_MEMBER(rom1_out);
|
||||
DECLARE_WRITE8_MEMBER(rom2_out);
|
||||
DECLARE_WRITE8_MEMBER(rom3_out);
|
||||
DECLARE_WRITE8_MEMBER(rome_out);
|
||||
DECLARE_WRITE8_MEMBER(romf_out);
|
||||
|
||||
@ -84,6 +100,8 @@ public:
|
||||
DECLARE_INPUT_CHANGED_MEMBER(sw_load);
|
||||
DECLARE_INPUT_CHANGED_MEMBER(sw_cma_enable);
|
||||
DECLARE_INPUT_CHANGED_MEMBER(sw_cma_write);
|
||||
DECLARE_INPUT_CHANGED_MEMBER(sw_prgm_pwr);
|
||||
DECLARE_INPUT_CHANGED_MEMBER(sw_do_enable);
|
||||
|
||||
protected:
|
||||
intellec4_state(machine_config const &mconfig, device_type type, char const *tag)
|
||||
@ -94,11 +112,13 @@ protected:
|
||||
, m_sw_mode(*this, "MODE")
|
||||
, m_program_banks(*this, "prgbank")
|
||||
, m_rom_port_banks(*this, "rpbank")
|
||||
, m_prom_programmer(*this, "promprg")
|
||||
, m_tty(*this, "tty")
|
||||
, m_memory(*this, "memory"), m_status(*this, "status")
|
||||
, m_sw_control(*this, "CONTROL")
|
||||
, m_sw_addr_data(*this, "ADDRDAT")
|
||||
, m_sw_passes(*this, "PASSES")
|
||||
, m_sw_prom_prgm(*this, "PROM")
|
||||
{
|
||||
}
|
||||
|
||||
@ -134,7 +154,10 @@ private:
|
||||
BIT_SW_INCR,
|
||||
BIT_SW_LOAD,
|
||||
BIT_SW_CMA_ENABLE,
|
||||
BIT_SW_CMA_WRITE
|
||||
BIT_SW_CMA_WRITE,
|
||||
|
||||
BIT_SW_PRGM_PWR = 0,
|
||||
BIT_SW_DATA_OUT_ENABLE
|
||||
};
|
||||
|
||||
TIMER_CALLBACK_MEMBER(reset_expired);
|
||||
@ -151,10 +174,12 @@ private:
|
||||
void reset_panel();
|
||||
|
||||
required_device<address_map_bank_device> m_program_banks, m_rom_port_banks;
|
||||
required_device<intel_imm6_76_device> m_prom_programmer;
|
||||
required_device<rs232_port_device> m_tty;
|
||||
|
||||
required_shared_ptr<u8> m_memory, m_status;
|
||||
required_ioport m_sw_control, m_sw_addr_data, m_sw_passes;
|
||||
required_ioport m_sw_prom_prgm;
|
||||
|
||||
emu_timer *m_reset_timer = nullptr;
|
||||
|
||||
@ -162,6 +187,9 @@ private:
|
||||
u8 m_ram_page = 0U, m_ram_data = 0U;
|
||||
bool m_ram_write = false;
|
||||
|
||||
// PROM programmer
|
||||
u8 m_prom_addr = 0U, m_prom_data = 0U;
|
||||
|
||||
// control board state
|
||||
bool m_cpu_reset = false;
|
||||
bool m_ff_prg_mode[3] = { false, false, false };
|
||||
@ -207,7 +235,10 @@ ADDRESS_MAP_START(intellec4_rom_port_banks, mcs40_cpu_device_base::AS_ROM_PORTS,
|
||||
ADDRESS_MAP_UNMAP_LOW
|
||||
|
||||
// 0x0000...0x07ff MON
|
||||
AM_RANGE(0x0000, 0x000f) AM_MIRROR(0x1f00) AM_READ(rom0_in)
|
||||
AM_RANGE(0x0000, 0x000f) AM_MIRROR(0x1f00) AM_READWRITE(rom0_in, rom0_out)
|
||||
AM_RANGE(0x0010, 0x001f) AM_MIRROR(0x1f00) AM_WRITE(rom1_out)
|
||||
AM_RANGE(0x0020, 0x002f) AM_MIRROR(0x1f00) AM_READWRITE(rom2_in, rom2_out)
|
||||
AM_RANGE(0x0030, 0x003f) AM_MIRROR(0x1f00) AM_READWRITE(rom3_in, rom3_out)
|
||||
AM_RANGE(0x00e0, 0x00ef) AM_MIRROR(0x1f00) AM_READWRITE(rome_in, rome_out)
|
||||
AM_RANGE(0x00f0, 0x00ff) AM_MIRROR(0x1f00) AM_READWRITE(romf_in, romf_out)
|
||||
|
||||
@ -273,6 +304,8 @@ MACHINE_CONFIG_START(intellec4)
|
||||
MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(14)
|
||||
MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000)
|
||||
|
||||
MCFG_DEVICE_ADD("promprg", INTEL_IMM6_76, 0)
|
||||
|
||||
MCFG_RS232_PORT_ADD("tty", default_rs232_devices, "terminal")
|
||||
|
||||
MCFG_DEVICE_ADD("bus", INTELLEC4_UNIV_BUS, 518000. / 7)
|
||||
@ -339,6 +372,12 @@ INPUT_PORTS_START(intellec4)
|
||||
PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("PASSES 1")
|
||||
PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("PASSES 2")
|
||||
PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("PASSES 3")
|
||||
|
||||
PORT_START("PROM")
|
||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("PRGM PROM PWR") PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_state, sw_prgm_pwr, nullptr)
|
||||
PORT_CONFNAME( 0x0002, 0x0002, "PROM PROGRAMMER DATA OUT ENABLE" ) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_state, sw_do_enable, nullptr)
|
||||
PORT_CONFSETTING( 0x0000, DEF_STR(Off) )
|
||||
PORT_CONFSETTING( 0x0002, DEF_STR(On) )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
@ -464,6 +503,18 @@ READ8_MEMBER(intellec4_state::rom0_in)
|
||||
return m_tty->rxd_r() ? 0x00U : 0x01U;
|
||||
}
|
||||
|
||||
READ8_MEMBER(intellec4_state::rom2_in)
|
||||
{
|
||||
// lower nybble of PROM programmer data
|
||||
return m_prom_programmer->do_r() & 0x0fU;
|
||||
}
|
||||
|
||||
READ8_MEMBER(intellec4_state::rom3_in)
|
||||
{
|
||||
// upper nybble of PROM programmer data
|
||||
return (m_prom_programmer->do_r() >> 4) & 0x0fU;
|
||||
}
|
||||
|
||||
READ8_MEMBER(intellec4_state::rome_in)
|
||||
{
|
||||
// upper nybble of RAM data latch
|
||||
@ -476,6 +527,34 @@ READ8_MEMBER(intellec4_state::romf_in)
|
||||
return m_ram_data & 0x0fU;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(intellec4_state::rom0_out)
|
||||
{
|
||||
// lower nybble of PROM programmer address
|
||||
m_prom_addr = (m_prom_addr & 0xf0U) | (data & 0x0fU);
|
||||
m_prom_programmer->a_w(m_prom_addr);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(intellec4_state::rom1_out)
|
||||
{
|
||||
// upper nybble of PROM programmer address
|
||||
m_prom_addr = (m_prom_addr & 0x0fU) | ((data << 4) & 0xf0U);
|
||||
m_prom_programmer->a_w(m_prom_addr);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(intellec4_state::rom2_out)
|
||||
{
|
||||
// lower nybble of PROM programmer data
|
||||
m_prom_data = (m_prom_data & 0xf0U) | (data & 0x0fU);
|
||||
m_prom_programmer->di_w(m_prom_data);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(intellec4_state::rom3_out)
|
||||
{
|
||||
// upper nybble of PROM programmer data
|
||||
m_prom_data = (m_prom_data & 0x0fU) | ((data << 4) & 0xf0U);
|
||||
m_prom_programmer->di_w(m_prom_data);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(intellec4_state::rome_out)
|
||||
{
|
||||
// bit 0 of this port enables program memory write
|
||||
@ -498,6 +577,10 @@ WRITE8_MEMBER(intellec4_state::ram1_out)
|
||||
{
|
||||
// bit 0 of this port controls the paper tape motor (0 = stop, 1 = run)
|
||||
m_tty->write_rts(BIT(~data, 0));
|
||||
|
||||
// bits 1 and 2 of this port enable PROM write
|
||||
m_prom_programmer->r_w_a(BIT(~data, 1));
|
||||
m_prom_programmer->r_w(BIT(~data, 2));
|
||||
}
|
||||
|
||||
|
||||
@ -628,6 +711,16 @@ INPUT_CHANGED_MEMBER(intellec4_state::sw_cma_write)
|
||||
m_cma_write = m_cma_enable;
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER(intellec4_state::sw_prgm_pwr)
|
||||
{
|
||||
m_prom_programmer->prgm_prom_pwr(newval);
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER(intellec4_state::sw_do_enable)
|
||||
{
|
||||
m_prom_programmer->data_out_enable(newval);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------
|
||||
driver_device implementation
|
||||
@ -641,6 +734,9 @@ void intellec4_state::driver_start()
|
||||
save_item(NAME(m_ram_data));
|
||||
save_item(NAME(m_ram_write));
|
||||
|
||||
save_item(NAME(m_prom_addr));
|
||||
save_item(NAME(m_prom_data));
|
||||
|
||||
save_item(NAME(m_cpu_reset));
|
||||
save_item(NAME(m_ff_prg_mode));
|
||||
|
||||
@ -705,6 +801,13 @@ void intellec4_state::driver_reset()
|
||||
m_bus->cpu_reset_in(m_cpu_reset ? 0 : 1);
|
||||
m_bus->reset_4002_in((m_cpu_reset && m_sw_reset_mode) ? 0 : 1);
|
||||
|
||||
// set up the PROM programmer
|
||||
ioport_value const sw_prom_prgm(m_sw_prom_prgm->read());
|
||||
m_prom_programmer->data_out_enable(BIT(sw_prom_prgm, BIT_SW_DATA_OUT_ENABLE));
|
||||
m_prom_programmer->data_in_positive(1); // not jumpered in, onboard pullup
|
||||
m_prom_programmer->data_out_positive(0); // jumpered to ground
|
||||
m_prom_programmer->prgm_prom_pwr(BIT(sw_prom_prgm, BIT_SW_PRGM_PWR));
|
||||
|
||||
// set front panel LEDs
|
||||
machine().output().set_value("led_status_ptr_valid", m_pointer_valid);
|
||||
machine().output().set_value("led_status_search", m_search_complete);
|
||||
|
@ -74,6 +74,9 @@ Intel INTELLEC® 4/MOD 40 layout
|
||||
<element name="label_ram"><text string="RAM"><color red="1.0" green="1.0" blue="1.0" /></text></element>
|
||||
<element name="label_prom"><text string="PROM"><color red="1.0" green="1.0" blue="1.0" /></text></element>
|
||||
|
||||
<element name="label_prgm"><text string="PRGM"><color red="1.0" green="1.0" blue="1.0" /></text></element>
|
||||
<element name="label_pwr"><text string="PWR"><color red="1.0" green="1.0" blue="1.0" /></text></element>
|
||||
|
||||
<element name="label_passes"><text string="PASSES"><color red="1.0" green="1.0" blue="1.0" /></text></element>
|
||||
|
||||
<element name="label_run"><text string="RUN"><color red="1.0" green="1.0" blue="1.0" /></text></element>
|
||||
@ -114,6 +117,13 @@ Intel INTELLEC® 4/MOD 40 layout
|
||||
<text string="LAST RAM/ROM POINTER" align="1"><color red="1.0" green="1.0" blue="1.0" /></text>
|
||||
</element>
|
||||
|
||||
<element name="label_on">
|
||||
<text string="ON" align="1"><color red="1.0" green="1.0" blue="1.0" /></text>
|
||||
</element>
|
||||
<element name="label_off">
|
||||
<text string="OFF" align="1"><color red="1.0" green="1.0" blue="1.0" /></text>
|
||||
</element>
|
||||
|
||||
<element name="label_enable">
|
||||
<text string="ENABLE" align="2"><color red="1.0" green="1.0" blue="1.0" /></text>
|
||||
</element>
|
||||
@ -244,6 +254,12 @@ Intel INTELLEC® 4/MOD 40 layout
|
||||
<cpanel element="label_ram"><bounds left="604" top="230" right="629" bottom="237" /></cpanel>
|
||||
<cpanel element="label_prom"><bounds left="635" top="230" right="660" bottom="237" /></cpanel>
|
||||
|
||||
<cpanel element="label_prgm"><bounds left="728" top="214" right="753" bottom="221" /></cpanel>
|
||||
<cpanel element="label_prom"><bounds left="728" top="222" right="753" bottom="229" /></cpanel>
|
||||
<cpanel element="label_pwr"><bounds left="728" top="230" right="753" bottom="237" /></cpanel>
|
||||
<cpanel element="label_on"><bounds left="758" top="239" right="814" bottom="246" /></cpanel>
|
||||
<cpanel element="label_off"><bounds left="758" top="279" right="814" bottom="287" /></cpanel>
|
||||
|
||||
<cpanel element="label_pass_counter"><bounds left="72" top="296" right="194" bottom="304" /></cpanel>
|
||||
<cpanel element="label_passes"><bounds left="74" top="304" right="192" bottom="311" /></cpanel>
|
||||
<cpanel element="label_3"><bounds left="74" top="312" right="99" bottom="319" /></cpanel>
|
||||
@ -467,6 +483,10 @@ Intel INTELLEC® 4/MOD 40 layout
|
||||
<bounds left="635" top="240" right="660" bottom="286" />
|
||||
</cpanel>
|
||||
|
||||
<cpanel element="switch" inputtag="PROM" inputmask="0x0001">
|
||||
<bounds left="728" top="240" right="753" bottom="286" />
|
||||
</cpanel>
|
||||
|
||||
<cpanel element="switch" inputtag="PASSES" inputmask="0x08">
|
||||
<bounds left="74" top="322" right="99" bottom="368" />
|
||||
</cpanel>
|
||||
@ -614,6 +634,12 @@ Intel INTELLEC® 4/MOD 40 layout
|
||||
<cpanel element="label_ram"><bounds left="604" top="230" right="629" bottom="237" /></cpanel>
|
||||
<cpanel element="label_prom"><bounds left="635" top="230" right="660" bottom="237" /></cpanel>
|
||||
|
||||
<cpanel element="label_prgm"><bounds left="728" top="214" right="753" bottom="221" /></cpanel>
|
||||
<cpanel element="label_prom"><bounds left="728" top="222" right="753" bottom="229" /></cpanel>
|
||||
<cpanel element="label_pwr"><bounds left="728" top="230" right="753" bottom="237" /></cpanel>
|
||||
<cpanel element="label_on"><bounds left="758" top="239" right="814" bottom="246" /></cpanel>
|
||||
<cpanel element="label_off"><bounds left="758" top="279" right="814" bottom="287" /></cpanel>
|
||||
|
||||
<cpanel element="label_pass_counter"><bounds left="72" top="296" right="194" bottom="304" /></cpanel>
|
||||
<cpanel element="label_passes"><bounds left="74" top="304" right="192" bottom="311" /></cpanel>
|
||||
<cpanel element="label_3"><bounds left="74" top="312" right="99" bottom="319" /></cpanel>
|
||||
@ -837,6 +863,10 @@ Intel INTELLEC® 4/MOD 40 layout
|
||||
<bounds left="635" top="240" right="660" bottom="286" />
|
||||
</cpanel>
|
||||
|
||||
<cpanel element="switch" inputtag="PROM" inputmask="0x0001">
|
||||
<bounds left="728" top="240" right="753" bottom="286" />
|
||||
</cpanel>
|
||||
|
||||
<cpanel element="switch" inputtag="PASSES" inputmask="0x08">
|
||||
<bounds left="74" top="322" right="99" bottom="368" />
|
||||
</cpanel>
|
||||
|
@ -73,6 +73,9 @@ Intel INTELLEC® 4/MOD 40 layout
|
||||
<element name="label_ram"><text string="RAM"><color red="1.0" green="1.0" blue="1.0" /></text></element>
|
||||
<element name="label_prom"><text string="PROM"><color red="1.0" green="1.0" blue="1.0" /></text></element>
|
||||
|
||||
<element name="label_prgm"><text string="PRGM"><color red="1.0" green="1.0" blue="1.0" /></text></element>
|
||||
<element name="label_pwr"><text string="PWR"><color red="1.0" green="1.0" blue="1.0" /></text></element>
|
||||
|
||||
<element name="label_passes"><text string="PASSES"><color red="1.0" green="1.0" blue="1.0" /></text></element>
|
||||
|
||||
<element name="label_run"><text string="RUN"><color red="1.0" green="1.0" blue="1.0" /></text></element>
|
||||
@ -113,6 +116,13 @@ Intel INTELLEC® 4/MOD 40 layout
|
||||
<text string="LAST RAM/ROM POINTER" align="1"><color red="1.0" green="1.0" blue="1.0" /></text>
|
||||
</element>
|
||||
|
||||
<element name="label_on">
|
||||
<text string="ON" align="1"><color red="1.0" green="1.0" blue="1.0" /></text>
|
||||
</element>
|
||||
<element name="label_off">
|
||||
<text string="OFF" align="1"><color red="1.0" green="1.0" blue="1.0" /></text>
|
||||
</element>
|
||||
|
||||
<element name="label_enable">
|
||||
<text string="ENABLE" align="2"><color red="1.0" green="1.0" blue="1.0" /></text>
|
||||
</element>
|
||||
@ -240,6 +250,12 @@ Intel INTELLEC® 4/MOD 40 layout
|
||||
<cpanel element="label_ram"><bounds left="604" top="230" right="629" bottom="237" /></cpanel>
|
||||
<cpanel element="label_prom"><bounds left="635" top="230" right="660" bottom="237" /></cpanel>
|
||||
|
||||
<cpanel element="label_prgm"><bounds left="728" top="214" right="753" bottom="221" /></cpanel>
|
||||
<cpanel element="label_prom"><bounds left="728" top="222" right="753" bottom="229" /></cpanel>
|
||||
<cpanel element="label_pwr"><bounds left="728" top="230" right="753" bottom="237" /></cpanel>
|
||||
<cpanel element="label_on"><bounds left="758" top="239" right="814" bottom="246" /></cpanel>
|
||||
<cpanel element="label_off"><bounds left="758" top="279" right="814" bottom="287" /></cpanel>
|
||||
|
||||
<cpanel element="label_pass_counter"><bounds left="72" top="296" right="194" bottom="304" /></cpanel>
|
||||
<cpanel element="label_passes"><bounds left="74" top="304" right="192" bottom="311" /></cpanel>
|
||||
<cpanel element="label_3"><bounds left="74" top="312" right="99" bottom="319" /></cpanel>
|
||||
@ -462,6 +478,10 @@ Intel INTELLEC® 4/MOD 40 layout
|
||||
<bounds left="635" top="240" right="660" bottom="286" />
|
||||
</cpanel>
|
||||
|
||||
<cpanel element="switch" inputtag="PROM" inputmask="0x0001">
|
||||
<bounds left="728" top="240" right="753" bottom="286" />
|
||||
</cpanel>
|
||||
|
||||
<cpanel element="switch" inputtag="PASSES" inputmask="0x08">
|
||||
<bounds left="74" top="322" right="99" bottom="368" />
|
||||
</cpanel>
|
||||
@ -609,6 +629,12 @@ Intel INTELLEC® 4/MOD 40 layout
|
||||
<cpanel element="label_ram"><bounds left="604" top="230" right="629" bottom="237" /></cpanel>
|
||||
<cpanel element="label_prom"><bounds left="635" top="230" right="660" bottom="237" /></cpanel>
|
||||
|
||||
<cpanel element="label_prgm"><bounds left="728" top="214" right="753" bottom="221" /></cpanel>
|
||||
<cpanel element="label_prom"><bounds left="728" top="222" right="753" bottom="229" /></cpanel>
|
||||
<cpanel element="label_pwr"><bounds left="728" top="230" right="753" bottom="237" /></cpanel>
|
||||
<cpanel element="label_on"><bounds left="758" top="239" right="814" bottom="246" /></cpanel>
|
||||
<cpanel element="label_off"><bounds left="758" top="279" right="814" bottom="287" /></cpanel>
|
||||
|
||||
<cpanel element="label_pass_counter"><bounds left="72" top="296" right="194" bottom="304" /></cpanel>
|
||||
<cpanel element="label_passes"><bounds left="74" top="304" right="192" bottom="311" /></cpanel>
|
||||
<cpanel element="label_3"><bounds left="74" top="312" right="99" bottom="319" /></cpanel>
|
||||
@ -831,6 +857,10 @@ Intel INTELLEC® 4/MOD 40 layout
|
||||
<bounds left="635" top="240" right="660" bottom="286" />
|
||||
</cpanel>
|
||||
|
||||
<cpanel element="switch" inputtag="PROM" inputmask="0x0001">
|
||||
<bounds left="728" top="240" right="753" bottom="286" />
|
||||
</cpanel>
|
||||
|
||||
<cpanel element="switch" inputtag="PASSES" inputmask="0x08">
|
||||
<bounds left="74" top="322" right="99" bottom="368" />
|
||||
</cpanel>
|
||||
|
204
src/mame/machine/imm6_76.cpp
Normal file
204
src/mame/machine/imm6_76.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
#include "emu.h"
|
||||
#include "imm6_76.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE(INTEL_IMM6_76, intel_imm6_76_device, "imm6_76", "Intel imm6-76 PROM programmer")
|
||||
|
||||
|
||||
intel_imm6_76_device::intel_imm6_76_device(
|
||||
machine_config const &mconfig,
|
||||
char const *tag,
|
||||
device_t *owner,
|
||||
uint32_t clock)
|
||||
: device_t(mconfig, INTEL_IMM6_76, tag, owner, clock)
|
||||
, device_image_interface(mconfig, *this)
|
||||
, m_cycle_tmr(nullptr), m_cycle_a_tmr(nullptr), m_prg_tmr(nullptr)
|
||||
, m_di(0U), m_a(0U)
|
||||
, m_do_enable(true), m_di_pos(true), m_do_pos(true)
|
||||
, m_r_w(false), m_r_w_a(false)
|
||||
, m_prgm_pwr(false)
|
||||
, m_cycle(false), m_cycle_a(false), m_prg(false)
|
||||
{
|
||||
std::fill(std::begin(m_data), std::end(m_data), 0U);
|
||||
}
|
||||
|
||||
|
||||
void intel_imm6_76_device::device_start()
|
||||
{
|
||||
m_cycle_tmr = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(intel_imm6_76_device::cycle_expired), this));
|
||||
m_cycle_a_tmr = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(intel_imm6_76_device::cycle_a_expired), this));
|
||||
m_prg_tmr = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(intel_imm6_76_device::prg_expired), this));
|
||||
|
||||
save_item(NAME(m_data));
|
||||
save_item(NAME(m_di));
|
||||
save_item(NAME(m_a));
|
||||
save_item(NAME(m_do_enable));
|
||||
save_item(NAME(m_di_pos));
|
||||
save_item(NAME(m_do_pos));
|
||||
save_item(NAME(m_r_w));
|
||||
save_item(NAME(m_r_w_a));
|
||||
save_item(NAME(m_prgm_pwr));
|
||||
save_item(NAME(m_cycle));
|
||||
save_item(NAME(m_cycle_a));
|
||||
save_item(NAME(m_prg));
|
||||
}
|
||||
|
||||
|
||||
image_init_result intel_imm6_76_device::call_load()
|
||||
{
|
||||
if (length() != ARRAY_LENGTH(m_data))
|
||||
return image_init_result::FAIL;
|
||||
else if (fread(m_data, ARRAY_LENGTH(m_data)) != ARRAY_LENGTH(m_data))
|
||||
return image_init_result::FAIL;
|
||||
else
|
||||
return image_init_result::PASS;
|
||||
}
|
||||
|
||||
image_init_result intel_imm6_76_device::call_create(int format_type, util::option_resolution *format_options)
|
||||
{
|
||||
std::fill(std::begin(m_data), std::end(m_data), 0U);
|
||||
if (fwrite(m_data, ARRAY_LENGTH(m_data)) != ARRAY_LENGTH(m_data))
|
||||
return image_init_result::FAIL;
|
||||
else
|
||||
return image_init_result::PASS;
|
||||
}
|
||||
|
||||
void intel_imm6_76_device::call_unload()
|
||||
{
|
||||
if (!is_readonly())
|
||||
{
|
||||
fseek(0, SEEK_SET);
|
||||
fwrite(m_data, ARRAY_LENGTH(m_data));
|
||||
}
|
||||
std::fill(std::begin(m_data), std::end(m_data), 0U);
|
||||
}
|
||||
|
||||
|
||||
void intel_imm6_76_device::di_w(u8 data)
|
||||
{
|
||||
if (data != m_di)
|
||||
{
|
||||
if (m_prg)
|
||||
logerror("data inputs changed during write - PROM damage likely (%02X -> %02X)\n", m_di, data);
|
||||
m_di = data;
|
||||
}
|
||||
}
|
||||
|
||||
void intel_imm6_76_device::a_w(u8 data)
|
||||
{
|
||||
if (data != m_a)
|
||||
{
|
||||
if (m_prg)
|
||||
logerror("address changed during write - PROM damage likely (%02X -> %02X)\n", m_a, data);
|
||||
m_a = data;
|
||||
}
|
||||
}
|
||||
|
||||
u8 intel_imm6_76_device::do_r() const
|
||||
{
|
||||
if (!m_do_enable)
|
||||
{
|
||||
return 0xffU;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8 const data(!m_prg ? m_data[m_a] : m_di_pos ? ~m_di : m_di);
|
||||
return m_do_pos ? ~data : data;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(intel_imm6_76_device::data_out_enable)
|
||||
{
|
||||
m_do_enable = bool(state);
|
||||
}
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(intel_imm6_76_device::data_in_positive)
|
||||
{
|
||||
if (bool(state) != m_di_pos)
|
||||
{
|
||||
if (m_prg)
|
||||
logerror("input polarity changed during write - PROM damage likely (%c -> %c)\n", m_di_pos ? '+' : '-', bool(state) ? '+' : '-');
|
||||
m_di_pos = bool(state);
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(intel_imm6_76_device::data_out_positive)
|
||||
{
|
||||
m_do_pos = !bool(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(intel_imm6_76_device::r_w)
|
||||
{
|
||||
if (!m_r_w && !bool(state) && !m_cycle)
|
||||
{
|
||||
// half 9602 with Rx = 20kΩ, Cx = 22µF, 1N914 across capacitor
|
||||
// wired to prevent re-triggering
|
||||
m_cycle_tmr->adjust(attotime::from_msec(150));
|
||||
trigger_prg();
|
||||
m_cycle = true;
|
||||
}
|
||||
m_r_w = !bool(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(intel_imm6_76_device::r_w_a)
|
||||
{
|
||||
if (!m_r_w_a && !bool(state) && !m_cycle_a)
|
||||
{
|
||||
// half 9602 with Rx = 20kΩ, Cx = 2.2µF, 1N914 across capacitor
|
||||
// wired to prevent re-triggering
|
||||
m_cycle_a_tmr->adjust(attotime::from_msec(15));
|
||||
trigger_prg();
|
||||
m_cycle_a = true;
|
||||
}
|
||||
m_r_w_a = !bool(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(intel_imm6_76_device::prgm_prom_pwr)
|
||||
{
|
||||
if (!bool(state) != m_prgm_pwr)
|
||||
{
|
||||
if (m_prg)
|
||||
logerror("programming power %s during write - PROM damage likely\n", bool(state) ? "disabled" : "enabled");
|
||||
m_prgm_pwr = !bool(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TIMER_CALLBACK_MEMBER(intel_imm6_76_device::cycle_expired)
|
||||
{
|
||||
m_cycle = false;
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(intel_imm6_76_device::cycle_a_expired)
|
||||
{
|
||||
m_cycle_a = false;
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(intel_imm6_76_device::prg_expired)
|
||||
{
|
||||
m_prg = false;
|
||||
}
|
||||
|
||||
|
||||
void intel_imm6_76_device::trigger_prg()
|
||||
{
|
||||
if (!m_cycle && !m_cycle_a)
|
||||
{
|
||||
// half 9602 with Rx = 4.7kΩ + 20kΩ trimpot, Cx = 1.0µF
|
||||
m_prg_tmr->adjust(attotime::from_usec(3250));
|
||||
if (!m_prg)
|
||||
{
|
||||
if (m_prgm_pwr && is_loaded())
|
||||
m_data[m_a] |= m_di_pos ? ~m_di : m_di; // PROM can't be erased electronically
|
||||
m_prg = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("write re-triggered - PROM damage likely\n");
|
||||
}
|
||||
}
|
||||
}
|
203
src/mame/machine/imm6_76.h
Normal file
203
src/mame/machine/imm6_76.h
Normal file
@ -0,0 +1,203 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
/*
|
||||
Intel imm6-76 PROM programmer
|
||||
|
||||
Simple programmer for 1602/1702 and 1602A/1702A 256x8 static PMOS
|
||||
UVEPROMs (1602/1602A have a metal lid preventing erasure but are
|
||||
otherwise identical to 1702/1702A). Used in the INTELLEC® 4 and
|
||||
INTELLEC® 8 development systems.
|
||||
|
||||
P1 universal edge connector (only used for power)
|
||||
|
||||
1 2
|
||||
GND 3 4 GND
|
||||
5 6
|
||||
7 8
|
||||
9 10
|
||||
11 12
|
||||
13 14
|
||||
15 16
|
||||
17 18
|
||||
19 20
|
||||
21 22
|
||||
23 24
|
||||
25 26
|
||||
27 28
|
||||
29 30
|
||||
31 32
|
||||
33 34
|
||||
35 36
|
||||
37 38
|
||||
39 40
|
||||
41 42
|
||||
-10V 43 44 -10V
|
||||
45 46
|
||||
47 48
|
||||
49 50
|
||||
51 52
|
||||
53 54
|
||||
55 56
|
||||
57 58
|
||||
59 60
|
||||
61 62
|
||||
63 64
|
||||
65 66
|
||||
67 68
|
||||
69 70
|
||||
71 72
|
||||
73 74
|
||||
75 76
|
||||
77 78
|
||||
79 80
|
||||
81 82
|
||||
83 84
|
||||
85 86
|
||||
87 88
|
||||
89 90
|
||||
91 92
|
||||
93 94
|
||||
95 96
|
||||
97 98
|
||||
+5V 99 100 +5V
|
||||
|
||||
|
||||
J1 40-pin IDC connector (data/control)
|
||||
|
||||
DI1 1 2 A0
|
||||
DI2 3 4 A1
|
||||
DI3 5 6 A2
|
||||
DI4 7 8 A3
|
||||
DI5 9 10 A4
|
||||
DI6 11 12 A5
|
||||
DI7 13 14 A6
|
||||
DI8 15 16 A7
|
||||
DO1 17 18
|
||||
DO2 19 20
|
||||
DO3 21 22
|
||||
DO4 23 24 DATA OUT ENABLE
|
||||
DO5 25 26 DATA IN + TRUE
|
||||
DO6 27 28 /DATA OUT + TRUE
|
||||
DO7 29 30 R/W (1702)
|
||||
DO8 31 32 R/W A (1702A)
|
||||
GND 33 34 GND
|
||||
GND 35 36 GND
|
||||
GND 37 38 GND
|
||||
GND 39 40 GND
|
||||
|
||||
|
||||
J2 40-pin IDC connector (to PROM socket)
|
||||
|
||||
D1 1 2 A0
|
||||
D2 3 4 A1
|
||||
D3 5 6 A2
|
||||
D4 7 8 A3
|
||||
D5 9 10 A4
|
||||
D6 11 11 A5
|
||||
D7 13 12 A6
|
||||
D8 15 16 A7
|
||||
GND 17 18 GND
|
||||
Vccs 19 20 Vccs
|
||||
Vdd 21 22 Vdd
|
||||
Vgg 23 24 /CS
|
||||
Vbb 25 26 PRGM
|
||||
27 28
|
||||
29 30
|
||||
31 32
|
||||
GND 33 34 GND
|
||||
35 36
|
||||
37 38
|
||||
39 40
|
||||
|
||||
|
||||
J3 Six-pin connector on flying leads
|
||||
|
||||
50V AC 1 2
|
||||
50V AC 3 4 +80V DC
|
||||
/PRGM PROM PWR 5 6 GND
|
||||
|
||||
|
||||
DO are open-collector TTL outputs with 5.6kΩ pullups.
|
||||
|
||||
DATA OUT ENABLE has an onboard 5.6kΩ pullup. Driving it low disables DO
|
||||
outputs.
|
||||
|
||||
DATA IN + TRUE (if jumpered in) has a 5.6kΩ pullup and is XORed with the
|
||||
DI inputs. It should be pulled low in systems that use negative logic.
|
||||
It is not jumpered in when used with INTELLEC 4 or INTELLEC 8 systems.
|
||||
|
||||
/DATA OUT + TRUE (if jumpered in) has a 5.6kΩ and is XORed with the PROM
|
||||
data outputs. It should be pulled low in systems that use positive
|
||||
logic. It is not jumpered in when used with INTELLEC 4 or INTELLEC 8
|
||||
systems, the line is tied low with an onboard jumper.
|
||||
|
||||
/PRGM PROM PWR has a 27kΩ pullup to +80V DC and must be pulled low (to
|
||||
GND) for programming voltage to be applied to the PROM.
|
||||
|
||||
When pulled low, R/W initiates a 2% programming duty cycle for writing
|
||||
to a 1602 or 1702 PROM (150 millisecond cycle time).
|
||||
|
||||
When pulled low, RW A initiates a 20% programming duty cycle for writing
|
||||
to a 1602A or 1702A PROM (15 millisecond cycle time).
|
||||
*/
|
||||
#ifndef MAME_MACHINE_IMM6_76_H
|
||||
#define MAME_MACHINE_IMM6_76_H
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
class intel_imm6_76_device : public device_t, public device_image_interface
|
||||
{
|
||||
public:
|
||||
intel_imm6_76_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// device_image_interface implementation
|
||||
virtual image_init_result call_load() override;
|
||||
virtual image_init_result call_create(int format_type, util::option_resolution *format_options) override;
|
||||
virtual void call_unload() override;
|
||||
|
||||
// device_image_interface static info
|
||||
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 true; }
|
||||
virtual bool is_creatable() const override { return true; }
|
||||
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"; }
|
||||
|
||||
void di_w(u8 data);
|
||||
void a_w(u8 data);
|
||||
u8 do_r() const;
|
||||
DECLARE_WRITE_LINE_MEMBER(data_out_enable); // 1 = asserted
|
||||
DECLARE_WRITE_LINE_MEMBER(data_in_positive); // 1 = asserted
|
||||
DECLARE_WRITE_LINE_MEMBER(data_out_positive); // 0 = asserted
|
||||
DECLARE_WRITE_LINE_MEMBER(r_w); // 1 = read, 0 = write
|
||||
DECLARE_WRITE_LINE_MEMBER(r_w_a); // 1 = read, 0 = write
|
||||
DECLARE_WRITE_LINE_MEMBER(prgm_prom_pwr); // 0 = asserted
|
||||
|
||||
protected:
|
||||
// device_t implementation
|
||||
virtual void device_start() override;
|
||||
|
||||
private:
|
||||
TIMER_CALLBACK_MEMBER(cycle_expired);
|
||||
TIMER_CALLBACK_MEMBER(cycle_a_expired);
|
||||
TIMER_CALLBACK_MEMBER(prg_expired);
|
||||
|
||||
void trigger_prg();
|
||||
|
||||
emu_timer *m_cycle_tmr, *m_cycle_a_tmr, *m_prg_tmr;
|
||||
|
||||
u8 m_data[256];
|
||||
u8 m_di, m_a;
|
||||
bool m_do_enable, m_di_pos, m_do_pos;
|
||||
bool m_r_w, m_r_w_a;
|
||||
bool m_prgm_pwr;
|
||||
bool m_cycle, m_cycle_a, m_prg;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(INTEL_IMM6_76, intel_imm6_76_device)
|
||||
|
||||
#endif // MAME_MACHINE_IMM6_76_H
|
Loading…
Reference in New Issue
Block a user