1 // license:BSD-3-Clause
2 // copyright-holders:Vas Crabb
3 /*
4 Intel INTELLEC® 4
5
6 The MOD 4 system has a 4004/4008/4009 chipset. It has front panel
7 switches for holding or pulsing the CPU's TEST line, and a CPU LED
8 driven by clock phase 2.
9
10 The MOD 40 system has a 4040/4289 chipset. It replaces the TEST
11 switches with STOP and SINGLE STEP switches, and replaces the CPU LED
12 with a RUN LED that's lit when the CPU isn't acknowledging a STOP or
13 HALT condition.
14
15 The MOD 4 and MOD 40 systems use the same monitor PROM. The monitor
16 program doesn't use any 4040-specific features, and the console RAM
17 readback feature avoids the need for the RPM instruction by latching
18 the data and reading it through the ROM port space.
19
20 Strictly speaking, the INTELLEC® 4 and INTELLEC® 4/MOD 4 are different
21 machines. The former uses an earlier control board without support
22 for MOD 40 features; the latter uses the same control board as the
23 MOD 40 jumpered to provide TEST line control rather than 4040 STOP
24 and SINGLE STEP features.
25
26 The MOD 40 repurposes the pins originally used for ROM 1 input port
27 lines to expose stop/interrupt request/acknowledge. It's pretty
28 obvious that the MOD 40 was designed as a minimal modification. A
29 set of X1 display LEDs would have been fantastic, as it would show the
30 contents of the accumulator with the 4040 CPU, while the X3 LEDs really
31 aren't very useful. However, since the 4004 just echoes M2 during X1,
32 the control board has no provision for latching data during this cycle
33 and would have required significant layout changes to cater for this.
34
35 Set the terminal for 110 1/8/N/2 to talk to the monitor.
36 It only accepts uppercase letters, digits, comma, and carriage return.
37 Paper tape reader run/stop is sent to RTS on the serial port.
38
39 TODO:
40 * Expose general-purpose I/O?
41 */
42 #include "emu.h"
43
44 #include "machine/imm6_76.h"
45
46 #include "bus/intellec4/intellec4.h"
47 #include "bus/rs232/rs232.h"
48 #include "cpu/mcs40/mcs40.h"
49 #include "machine/bankdev.h"
50
51 #include "intlc44.lh"
52 #include "intlc440.lh"
53
54
55 namespace {
56
57 /***********************************************************************
58 INTELLEC® 4 base driver
59 ***********************************************************************/
60
61 class intellec4_state : public driver_device
62 {
63 public:
64 void bus_cycle(mcs40_cpu_device_base::phase step, u8 sync, u8 data);
65
66 u8 pm_read(offs_t offset);
67 void pm_write(offs_t offset, u8 data);
68
69 u8 rom0_in();
70 u8 rom2_in();
71 u8 rom3_in();
72 u8 rome_in();
73 u8 romf_in();
74
75 void rom0_out(u8 data);
76 void rom1_out(u8 data);
77 void rom2_out(u8 data);
78 void rom3_out(u8 data);
79 void rome_out(u8 data);
80 void romf_out(u8 data);
81
82 void ram0_out(u8 data);
83 void ram1_out(u8 data);
84
85 // universal slot outputs
86 DECLARE_WRITE_LINE_MEMBER(bus_reset_4002);
87 DECLARE_WRITE_LINE_MEMBER(bus_user_reset);
88
89 // front panel switches
90 DECLARE_INPUT_CHANGED_MEMBER(sw_reset);
91 DECLARE_INPUT_CHANGED_MEMBER(sw_reset_mode);
92 template <unsigned N> DECLARE_INPUT_CHANGED_MEMBER(sw_prg_mode);
93 DECLARE_INPUT_CHANGED_MEMBER(sw_run);
94 DECLARE_INPUT_CHANGED_MEMBER(sw_next_inst);
95 DECLARE_INPUT_CHANGED_MEMBER(sw_decr);
96 DECLARE_INPUT_CHANGED_MEMBER(sw_incr);
97 DECLARE_INPUT_CHANGED_MEMBER(sw_load);
98 DECLARE_INPUT_CHANGED_MEMBER(sw_cma_enable);
99 DECLARE_INPUT_CHANGED_MEMBER(sw_cma_write);
100 DECLARE_INPUT_CHANGED_MEMBER(sw_prgm_pwr);
101 DECLARE_INPUT_CHANGED_MEMBER(sw_do_enable);
102
103 protected:
intellec4_state(machine_config const & mconfig,device_type type,char const * tag)104 intellec4_state(machine_config const &mconfig, device_type type, char const *tag)
105 : driver_device(mconfig, type, tag)
106 , m_cpu(*this, "maincpu")
107 , m_bus(*this, "bus")
108 , m_prg_ram(*this, "ram")
109 , m_sw_mode(*this, "MODE")
110 , m_program_banks(*this, "prgbank")
111 , m_rom_port_banks(*this, "rpbank")
112 , m_prom_programmer(*this, "promprg")
113 , m_tty(*this, "tty")
114 , m_memory(*this, "memory"), m_status(*this, "status")
115 , m_sw_control(*this, "CONTROL")
116 , m_sw_addr_data(*this, "ADDRDAT")
117 , m_sw_passes(*this, "PASSES")
118 , m_sw_prom_prgm(*this, "PROM")
119 , m_led_address(*this, "led_address_a%u_%u", 1U, 0U)
120 , m_led_instruction(*this, "led_instruction_m%u_%u", 1U, 0U)
121 , m_led_active_bank(*this, "led_active_bank_%u", 0U)
122 , m_led_execution(*this, "led_execution_x%u_%u", 2U, 0U)
123 , m_led_last_ptr(*this, "led_last_ptr_x%u_%u", 2U, 0U)
124 , m_led_status_ptr_valid(*this, "led_status_ptr_valid")
125 , m_led_status_search(*this, "led_status_search")
126 , m_led_mode_mon(*this, "led_mode_mon")
127 , m_led_mode_ram(*this, "led_mode_ram")
128 , m_led_mode_prom(*this, "led_mode_prom")
129 {
130 }
131
132 virtual void driver_start() override;
133 virtual void driver_reset() override;
134
135 void intellec4_program_banks(address_map &map);
136 void intellec4_rom_port_banks(address_map &map);
137
138 void intellec4_rom(address_map &map);
139 void intellec4_ram_memory(address_map &map);
140 void intellec4_rom_ports(address_map &map);
141 void intellec4_ram_status(address_map &map);
142 void intellec4_ram_ports(address_map &map);
143 void intellec4_program_memory(address_map &map);
144
145 void intellec4(machine_config &config);
146
147 required_device<mcs40_cpu_device_base> m_cpu;
148 required_device<bus::intellec4::univ_bus_device> m_bus;
149 required_shared_ptr<u8> m_prg_ram;
150 required_ioport m_sw_mode;
151
152 private:
153 enum
154 {
155 BANK_PRG_MON = 0,
156 BANK_PRG_PROM,
157 BANK_PRG_RAM,
158 BANK_PRG_NONE,
159
160 BANK_IO_MON = 0,
161 BANK_IO_PROM,
162 BANK_IO_NEITHER,
163
164 BIT_SW_RESET = 2,
165 BIT_SW_RESET_MODE,
166 BIT_SW_MON,
167 BIT_SW_RAM,
168 BIT_SW_PROM,
169
170 BIT_SW_RUN = 0,
171 BIT_SW_NEXT_INST,
172 BIT_SW_DECR,
173 BIT_SW_INCR,
174 BIT_SW_LOAD,
175 BIT_SW_CMA_ENABLE,
176 BIT_SW_CMA_WRITE,
177
178 BIT_SW_PRGM_PWR = 0,
179 BIT_SW_DATA_OUT_ENABLE
180 };
181
182 TIMER_CALLBACK_MEMBER(reset_expired);
183
184 // LED update helpers
185 void display_address(u16 value, u16 mask);
186 void display_instruction(u8 value, u8 mask);
187 void display_active_bank(u8 value);
188 void display_execution(u8 value, u8 mask);
189 void display_pointer(u8 value, u8 mask);
190
191 void trigger_reset();
192 void check_4002_reset();
193 void reset_panel();
194
195 required_device<address_map_bank_device> m_program_banks, m_rom_port_banks;
196 required_device<intel_imm6_76_device> m_prom_programmer;
197 required_device<rs232_port_device> m_tty;
198
199 required_shared_ptr<u8> m_memory, m_status;
200 required_ioport m_sw_control, m_sw_addr_data, m_sw_passes;
201 required_ioport m_sw_prom_prgm;
202 output_finder<3, 4> m_led_address;
203 output_finder<2, 4> m_led_instruction;
204 output_finder<4> m_led_active_bank;
205 output_finder<2, 4> m_led_execution;
206 output_finder<2, 4> m_led_last_ptr;
207 output_finder<> m_led_status_ptr_valid;
208 output_finder<> m_led_status_search;
209 output_finder<> m_led_mode_mon;
210 output_finder<> m_led_mode_ram;
211 output_finder<> m_led_mode_prom;
212
213 emu_timer *m_reset_timer = nullptr;
214
215 // program memory access
216 u8 m_ram_page = 0U, m_ram_data = 0U;
217 bool m_ram_write = false;
218
219 // PROM programmer
220 u8 m_prom_addr = 0U, m_prom_data = 0U;
221
222 // control board state
223 bool m_cpu_reset = false;
224 bool m_ff_prg_mode[3] = { false, false, false };
225
226 // current state of signals from bus
227 bool m_bus_reset_4002 = false, m_bus_user_reset = false;
228
229 // front panel state
230 u16 m_latched_addr = 0U, m_display_addr = 0U;
231 u8 m_display_instr = 0U, m_display_exec = 0U, m_display_ptr = 0U;
232 u8 m_pass_counter = 0U;
233 bool m_panel_reset = false;
234 bool m_next_inst = false, m_adr_cmp_latch = false, m_search_complete = false;
235 bool m_src = false, m_pointer_valid = false;
236 bool m_cma_enable = false, m_cma_write = false;
237
238 // current state of front panel switches
239 bool m_sw_reset = false, m_sw_reset_mode = false;
240 bool m_sw_prg_mode[3] = { false, false, false };
241 bool m_sw_run = false;
242 };
243
244
245 /*----------------------------------
246 Common front panel switches
247 ----------------------------------*/
248
249 INPUT_PORTS_START(intellec4)
250 PORT_START("MODE")
251 PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("RESET") PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_state, sw_reset, 0)
252 PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("RESET MODE") PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_state, sw_reset_mode, 0)
PORT_CODE(KEYCODE_1_PAD)253 PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("MON") PORT_CODE(KEYCODE_1_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_state, sw_prg_mode<0>, 0)
254 PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("RAM") PORT_CODE(KEYCODE_2_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_state, sw_prg_mode<1>, 0)
255 PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("PROM") PORT_CODE(KEYCODE_3_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_state, sw_prg_mode<2>, 0)
256
257 PORT_START("CONTROL")
258 PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("RUN") PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_state, sw_run, 0)
259 PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("NEXT INST") PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_state, sw_next_inst, 0)
260 PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("DECR") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_state, sw_decr, 0)
261 PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("INCR") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_state, sw_incr, 0)
262 PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("LOAD") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_state, sw_load, 0)
263 PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("CMA ENABLE") PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_state, sw_cma_enable, 0)
264 PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("CMA WRITE") PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_state, sw_cma_write, 0)
265
266 PORT_START("ADDRDAT")
267 PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 0")
268 PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 1")
269 PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 2")
270 PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 3")
271 PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 4")
272 PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 5")
273 PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 6")
274 PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 7")
275 PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 8")
276 PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 9")
277 PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 10")
278 PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 11")
279
280 PORT_START("PASSES")
281 PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("PASSES 0")
282 PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("PASSES 1")
283 PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("PASSES 2")
284 PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("PASSES 3")
285
286 PORT_START("PROM")
287 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, 0)
288 PORT_CONFNAME( 0x0002, 0x0002, "PROM PROGRAMMER DATA OUT ENABLE" ) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_state, sw_do_enable, 0)
289 PORT_CONFSETTING( 0x0000, DEF_STR(Off) )
290 PORT_CONFSETTING( 0x0002, DEF_STR(On) )
291 INPUT_PORTS_END
292
293
294 /*----------------------------------
295 System bus cycle handler
296 ----------------------------------*/
297
298 void intellec4_state::bus_cycle(mcs40_cpu_device_base::phase step, u8 sync, u8 data)
299 {
300 switch (step)
301 {
302 case mcs40_cpu_device_base::phase::A1:
303 if (m_cma_enable)
304 {
305 display_address(m_latched_addr, 0x0fffU);
306 display_instruction(m_prg_ram[m_latched_addr], 0xffU);
307 }
308 else if (!m_search_complete)
309 {
310 display_address(u16(data), 0x000fU);
311 m_src = false;
312 }
313 if (m_cma_write)
314 {
315 m_prg_ram[m_latched_addr] = u8(~m_sw_addr_data->read() & 0x00ffU);
316 m_cma_write = false;
317 }
318 break;
319 case mcs40_cpu_device_base::phase::A2:
320 if (!m_search_complete && !m_cma_enable)
321 display_address(u16(data) << 4, 0x00f0U);
322 break;
323 case mcs40_cpu_device_base::phase::A3:
324 if (!m_search_complete && !m_cma_enable)
325 {
326 display_address(u16(data) << 8, 0x0f00U);
327 display_active_bank(~m_cpu->get_cm_ram());
328 }
329 break;
330 case mcs40_cpu_device_base::phase::M1:
331 if (!m_search_complete && !m_cma_enable)
332 display_instruction(data << 4, 0xf0U);
333 break;
334 case mcs40_cpu_device_base::phase::M2:
335 if (!m_search_complete && !m_cma_enable)
336 display_instruction(data, 0x0fU);
337 break;
338 case mcs40_cpu_device_base::phase::X1:
339 // not connected to anything
340 break;
341 case mcs40_cpu_device_base::phase::X2:
342 if (!m_search_complete && !m_cma_enable)
343 {
344 display_execution(data << 4, 0xf0U);
345 m_src = BIT(~m_cpu->get_cm_rom(), 0);
346 if (m_src)
347 display_pointer(data << 4, 0xf0U);
348 }
349 break;
350 case mcs40_cpu_device_base::phase::X3:
351 if (m_search_complete != m_adr_cmp_latch)
352 m_led_status_search = m_search_complete = m_adr_cmp_latch;
353 if (!m_search_complete && !m_cma_enable)
354 {
355 display_execution(data, 0x0fU);
356 if (m_src)
357 {
358 display_pointer(data, 0x0fU);
359 if (!m_panel_reset && !m_pointer_valid)
360 m_led_status_ptr_valid = m_pointer_valid = true;
361 }
362 }
363 if (!m_panel_reset && !m_adr_cmp_latch)
364 m_adr_cmp_latch = (m_latched_addr == m_display_addr) && !((m_pass_counter ^ m_sw_passes->read()) & 0x0fU);
365 if (!m_search_complete && !m_panel_reset && !m_cma_enable && !m_sw_run && (m_latched_addr == m_display_addr))
366 m_pass_counter = (m_pass_counter + 1U) & 0x0fU;
367 if (m_adr_cmp_latch && !m_next_inst && !m_search_complete)
368 m_led_status_search = m_search_complete = true;
369 if (!m_cpu_reset && !m_cma_enable && !m_sw_run)
370 m_panel_reset = false;
371 break;
372 }
373 }
374
375
376 /*----------------------------------
377 Program memory access handlers
378 ----------------------------------*/
379
pm_read(offs_t offset)380 u8 intellec4_state::pm_read(offs_t offset)
381 {
382 if (!machine().side_effects_disabled())
383 {
384 // always causes data to be latched
385 u16 const addr((u16(m_ram_page) << 8) | ((offset >> 1) & 0x00ffU));
386 m_ram_data = m_prg_ram[addr];
387 }
388
389 // the C outputs of the 4289 are always high for RPM/WPM so it's equivalent to romf_in
390 return m_ram_data & 0x0fU;
391 }
392
pm_write(offs_t offset,u8 data)393 void intellec4_state::pm_write(offs_t offset, u8 data)
394 {
395 // always causes data to be latched
396 u16 const addr((u16(m_ram_page) << 8) | ((offset >> 1) & 0x00ffU));
397 m_ram_data = m_prg_ram[addr];
398 if (m_ram_write)
399 {
400 bool const first(BIT(offset, 0));
401 m_prg_ram[addr] = (m_ram_data & (first ? 0x0fU : 0xf0U)) | ((data & 0x0fU) << (first ? 4 : 0));
402 }
403 }
404
405
406 /*----------------------------------
407 I/O port handlers
408 ----------------------------------*/
409
rom0_in()410 u8 intellec4_state::rom0_in()
411 {
412 // bit 0 of this port is ANDed with the TTY input
413 return m_tty->rxd_r() ? 0x0eU : 0x0fU;
414 }
415
rom2_in()416 u8 intellec4_state::rom2_in()
417 {
418 // lower nybble of PROM programmer data
419 return m_prom_programmer->do_r() & 0x0fU;
420 }
421
rom3_in()422 u8 intellec4_state::rom3_in()
423 {
424 // upper nybble of PROM programmer data
425 return (m_prom_programmer->do_r() >> 4) & 0x0fU;
426 }
427
rome_in()428 u8 intellec4_state::rome_in()
429 {
430 // upper nybble of RAM data latch
431 return (m_ram_data >> 4) & 0x0fU;
432 }
433
romf_in()434 u8 intellec4_state::romf_in()
435 {
436 // lower nybble of RAM data latch
437 return m_ram_data & 0x0fU;
438 }
439
rom0_out(u8 data)440 void intellec4_state::rom0_out(u8 data)
441 {
442 // lower nybble of PROM programmer address
443 m_prom_addr = (m_prom_addr & 0xf0U) | (data & 0x0fU);
444 m_prom_programmer->a_w(m_prom_addr);
445 }
446
rom1_out(u8 data)447 void intellec4_state::rom1_out(u8 data)
448 {
449 // upper nybble of PROM programmer address
450 m_prom_addr = (m_prom_addr & 0x0fU) | ((data << 4) & 0xf0U);
451 m_prom_programmer->a_w(m_prom_addr);
452 }
453
rom2_out(u8 data)454 void intellec4_state::rom2_out(u8 data)
455 {
456 // lower nybble of PROM programmer data
457 m_prom_data = (m_prom_data & 0xf0U) | (data & 0x0fU);
458 m_prom_programmer->di_w(m_prom_data);
459 }
460
rom3_out(u8 data)461 void intellec4_state::rom3_out(u8 data)
462 {
463 // upper nybble of PROM programmer data
464 m_prom_data = (m_prom_data & 0x0fU) | ((data << 4) & 0xf0U);
465 m_prom_programmer->di_w(m_prom_data);
466 }
467
rome_out(u8 data)468 void intellec4_state::rome_out(u8 data)
469 {
470 // bit 0 of this port enables program memory write
471 m_ram_write = BIT(data, 0);
472 }
473
romf_out(u8 data)474 void intellec4_state::romf_out(u8 data)
475 {
476 // sets the program memory page for read/write operations
477 m_ram_page = data & 0x0fU;
478 }
479
ram0_out(u8 data)480 void intellec4_state::ram0_out(u8 data)
481 {
482 // bit 0 of this port controls the TTY current loop
483 m_tty->write_txd(BIT(data, 0));
484 }
485
ram1_out(u8 data)486 void intellec4_state::ram1_out(u8 data)
487 {
488 // bit 0 of this port controls the paper tape motor (0 = stop, 1 = run)
489 m_tty->write_rts(BIT(~data, 0));
490
491 // bits 1 and 2 of this port enable PROM write
492 m_prom_programmer->r_w_a(BIT(~data, 1));
493 m_prom_programmer->r_w(BIT(~data, 2));
494 }
495
496
497 /*----------------------------------
498 Bus signal handlers
499 ----------------------------------*/
500
WRITE_LINE_MEMBER(intellec4_state::bus_reset_4002)501 WRITE_LINE_MEMBER(intellec4_state::bus_reset_4002)
502 {
503 m_bus_reset_4002 = 0 == state;
504 check_4002_reset();
505 }
506
WRITE_LINE_MEMBER(intellec4_state::bus_user_reset)507 WRITE_LINE_MEMBER(intellec4_state::bus_user_reset)
508 {
509 if (!state)
510 trigger_reset();
511 m_bus_user_reset = 0 == state;
512 }
513
514
515 /*----------------------------------
516 Front panel switch handlers
517 ----------------------------------*/
518
INPUT_CHANGED_MEMBER(intellec4_state::sw_reset)519 INPUT_CHANGED_MEMBER(intellec4_state::sw_reset)
520 {
521 if (!newval && oldval)
522 trigger_reset();
523 m_sw_reset = !bool(newval);
524 }
525
INPUT_CHANGED_MEMBER(intellec4_state::sw_reset_mode)526 INPUT_CHANGED_MEMBER(intellec4_state::sw_reset_mode)
527 {
528 m_sw_reset_mode = bool(newval);
529 if (m_cpu_reset)
530 {
531 m_bus->reset_4002_in(m_sw_reset_mode ? 0 : 1);
532 check_4002_reset();
533 }
534 }
535
INPUT_CHANGED_MEMBER(intellec4_state::sw_prg_mode)536 template <unsigned N> INPUT_CHANGED_MEMBER(intellec4_state::sw_prg_mode)
537 {
538 static constexpr int prg_banks[3] = { BANK_PRG_MON, BANK_PRG_RAM, BANK_PRG_PROM };
539 static constexpr int io_banks[3] = { BANK_IO_MON, BANK_IO_NEITHER, BANK_IO_PROM };
540
541 std::tuple<output_finder<> &, output_finder<> &, output_finder<> &> mode_leds(m_led_mode_mon, m_led_mode_ram, m_led_mode_prom);
542
543 if (oldval && !newval)
544 {
545 if (((0U == N) || !m_sw_prg_mode[0]) && ((1U == N) || !m_sw_prg_mode[1]) && ((2U == N) || !m_sw_prg_mode[2]))
546 {
547 if (!m_ff_prg_mode[N])
548 {
549 m_program_banks->set_bank(prg_banks[N]);
550 m_rom_port_banks->set_bank(io_banks[N]);
551 std::get<N>(mode_leds) = m_ff_prg_mode[N] = true;
552 }
553 trigger_reset();
554 }
555 else
556 {
557 m_program_banks->set_bank(BANK_PRG_NONE);
558 m_rom_port_banks->set_bank(BANK_IO_NEITHER);
559 }
560 if ((0U != N) && m_ff_prg_mode[0])
561 std::get<0>(mode_leds) = m_ff_prg_mode[0] = false;
562 if ((1U != N) && m_ff_prg_mode[1])
563 std::get<1>(mode_leds) = m_ff_prg_mode[1] = false;
564 if ((2U != N) && m_ff_prg_mode[2])
565 std::get<2>(mode_leds) = m_ff_prg_mode[2] = false;
566 }
567 m_sw_prg_mode[N] = !bool(newval);
568 }
569
INPUT_CHANGED_MEMBER(intellec4_state::sw_run)570 INPUT_CHANGED_MEMBER(intellec4_state::sw_run)
571 {
572 m_sw_run = !bool(newval);
573 if (m_sw_run)
574 reset_panel();
575 }
576
INPUT_CHANGED_MEMBER(intellec4_state::sw_next_inst)577 INPUT_CHANGED_MEMBER(intellec4_state::sw_next_inst)
578 {
579 m_next_inst = !bool(newval);
580 }
581
INPUT_CHANGED_MEMBER(intellec4_state::sw_decr)582 INPUT_CHANGED_MEMBER(intellec4_state::sw_decr)
583 {
584 // connected to a pulse generator circuit
585 if (newval && !oldval)
586 {
587 m_latched_addr = (m_latched_addr - 1U) & 0x0fffU;
588 reset_panel();
589 }
590 }
591
INPUT_CHANGED_MEMBER(intellec4_state::sw_incr)592 INPUT_CHANGED_MEMBER(intellec4_state::sw_incr)
593 {
594 // connected to a pulse generator circuit
595 if (newval && !oldval)
596 {
597 m_latched_addr = (m_latched_addr + 1U) & 0x0fffU;
598 reset_panel();
599 }
600 }
601
INPUT_CHANGED_MEMBER(intellec4_state::sw_load)602 INPUT_CHANGED_MEMBER(intellec4_state::sw_load)
603 {
604 // connected to a pulse generator circuit
605 if (newval && !oldval)
606 {
607 m_latched_addr = ~m_sw_addr_data->read() & 0x0fffU;
608 reset_panel();
609 }
610 }
611
INPUT_CHANGED_MEMBER(intellec4_state::sw_cma_enable)612 INPUT_CHANGED_MEMBER(intellec4_state::sw_cma_enable)
613 {
614 m_cma_enable = bool(newval);
615 if (m_cma_enable)
616 reset_panel();
617 }
618
INPUT_CHANGED_MEMBER(intellec4_state::sw_cma_write)619 INPUT_CHANGED_MEMBER(intellec4_state::sw_cma_write)
620 {
621 if (newval && !oldval)
622 m_cma_write = m_cma_enable;
623 }
624
INPUT_CHANGED_MEMBER(intellec4_state::sw_prgm_pwr)625 INPUT_CHANGED_MEMBER(intellec4_state::sw_prgm_pwr)
626 {
627 m_prom_programmer->prgm_prom_pwr(newval);
628 }
629
INPUT_CHANGED_MEMBER(intellec4_state::sw_do_enable)630 INPUT_CHANGED_MEMBER(intellec4_state::sw_do_enable)
631 {
632 m_prom_programmer->data_out_enable(newval);
633 }
634
635
636 /*----------------------------------
637 driver_device implementation
638 ----------------------------------*/
639
driver_start()640 void intellec4_state::driver_start()
641 {
642 m_reset_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(intellec4_state::reset_expired), this));
643
644 m_led_address.resolve();
645 m_led_instruction.resolve();
646 m_led_active_bank.resolve();
647 m_led_execution.resolve();
648 m_led_last_ptr.resolve();
649 m_led_status_ptr_valid.resolve();
650 m_led_status_search.resolve();
651 m_led_mode_mon.resolve();
652 m_led_mode_ram.resolve();
653 m_led_mode_prom.resolve();
654
655 save_item(NAME(m_ram_page));
656 save_item(NAME(m_ram_data));
657 save_item(NAME(m_ram_write));
658
659 save_item(NAME(m_prom_addr));
660 save_item(NAME(m_prom_data));
661
662 save_item(NAME(m_cpu_reset));
663 save_item(NAME(m_ff_prg_mode));
664
665 save_item(NAME(m_bus_reset_4002));
666 save_item(NAME(m_bus_user_reset));
667
668 save_item(NAME(m_latched_addr));
669 save_item(NAME(m_display_addr));
670 save_item(NAME(m_display_instr));
671 save_item(NAME(m_display_exec));
672 save_item(NAME(m_display_ptr));
673 save_item(NAME(m_pass_counter));
674 save_item(NAME(m_panel_reset));
675 save_item(NAME(m_next_inst));
676 save_item(NAME(m_adr_cmp_latch));
677 save_item(NAME(m_search_complete));
678 save_item(NAME(m_src));
679 save_item(NAME(m_pointer_valid));
680 save_item(NAME(m_cma_enable));
681 save_item(NAME(m_cma_write));
682
683 save_item(NAME(m_sw_reset));
684 save_item(NAME(m_sw_reset_mode));
685 save_item(NAME(m_sw_prg_mode));
686 save_item(NAME(m_sw_run));
687
688 m_ff_prg_mode[0] = true;
689 m_ff_prg_mode[1] = m_ff_prg_mode[2] = false;
690 };
691
driver_reset()692 void intellec4_state::driver_reset()
693 {
694 // set stuff according to initial state of front panel
695 ioport_value const sw_mode(m_sw_mode->read()), sw_control(m_sw_control->read());
696 m_sw_reset = BIT(~sw_mode, BIT_SW_RESET);
697 m_sw_reset_mode = BIT( sw_mode, BIT_SW_RESET_MODE);
698 m_sw_prg_mode[0] = BIT(~sw_mode, BIT_SW_MON);
699 m_sw_prg_mode[1] = BIT(~sw_mode, BIT_SW_RAM);
700 m_sw_prg_mode[2] = BIT(~sw_mode, BIT_SW_PROM);
701 m_sw_run = BIT(~sw_control, BIT_SW_RUN);
702 m_next_inst = BIT(~sw_control, BIT_SW_NEXT_INST);
703 m_cma_enable = BIT( sw_control, BIT_SW_CMA_ENABLE);
704 m_ff_prg_mode[0] = m_ff_prg_mode[0] && !m_sw_prg_mode[1] && !m_sw_prg_mode[2];
705 m_ff_prg_mode[1] = m_ff_prg_mode[1] && !m_sw_prg_mode[0] && !m_sw_prg_mode[2];
706 m_ff_prg_mode[2] = m_ff_prg_mode[2] && !m_sw_prg_mode[0] && !m_sw_prg_mode[1];
707 m_panel_reset = m_panel_reset || m_cma_enable || m_sw_run;
708 if (m_panel_reset)
709 {
710 m_pass_counter = 0U;
711 m_adr_cmp_latch = false;
712 m_search_complete = m_search_complete && m_next_inst;
713 m_pointer_valid = false;
714 }
715
716 // ensure we're consistent with the state of the bus
717 m_bus_reset_4002 = 0 == m_bus->reset_4002_out();
718 m_bus_user_reset = 0 == m_bus->user_reset_out();
719
720 // ensure device inputs are all in the correct state
721 m_cpu->set_input_line(INPUT_LINE_RESET, m_cpu_reset ? ASSERT_LINE : CLEAR_LINE);
722 m_bus->cpu_reset_in(m_cpu_reset ? 0 : 1);
723 m_bus->reset_4002_in((m_cpu_reset && m_sw_reset_mode) ? 0 : 1);
724
725 // set up the PROM programmer
726 ioport_value const sw_prom_prgm(m_sw_prom_prgm->read());
727 m_prom_programmer->data_out_enable(BIT(sw_prom_prgm, BIT_SW_DATA_OUT_ENABLE));
728 m_prom_programmer->data_in_positive(1); // not jumpered in, onboard pullup
729 m_prom_programmer->data_out_positive(0); // jumpered to ground
730 m_prom_programmer->prgm_prom_pwr(BIT(sw_prom_prgm, BIT_SW_PRGM_PWR));
731
732 // set front panel LEDs
733 m_led_status_ptr_valid = m_pointer_valid;
734 m_led_status_search = m_search_complete;
735 m_led_mode_mon = m_ff_prg_mode[0];
736 m_led_mode_ram = m_ff_prg_mode[1];
737 m_led_mode_prom = m_ff_prg_mode[2];
738 }
739
740
741 /*----------------------------------
742 System address spaces
743 ----------------------------------*/
744
intellec4_program_banks(address_map & map)745 void intellec4_state::intellec4_program_banks(address_map &map)
746 {
747 map.unmap_value_low();
748
749 // 0x0000...0x0fff MON
750 map(0x0000, 0x03ff).rom().region("monitor", 0x0000);
751
752 // 0x1000...0x1fff PROM
753
754 // 0x1000...0x1fff RAM
755 map(0x2000, 0x2fff).readonly().share("ram");
756
757 // 0x3000...0x3fff unmapped in case someone presses two mode switches at once
758 }
759
intellec4_rom_port_banks(address_map & map)760 void intellec4_state::intellec4_rom_port_banks(address_map &map)
761 {
762 map.unmap_value_high();
763
764 // 0x0000...0x07ff MON
765 map(0x0000, 0x000f).mirror(0x1f00).rw(FUNC(intellec4_state::rom0_in), FUNC(intellec4_state::rom0_out));
766 map(0x0010, 0x001f).mirror(0x1f00).w(FUNC(intellec4_state::rom1_out));
767 map(0x0020, 0x002f).mirror(0x1f00).rw(FUNC(intellec4_state::rom2_in), FUNC(intellec4_state::rom2_out));
768 map(0x0030, 0x003f).mirror(0x1f00).rw(FUNC(intellec4_state::rom3_in), FUNC(intellec4_state::rom3_out));
769 map(0x00e0, 0x00ef).mirror(0x1f00).rw(FUNC(intellec4_state::rome_in), FUNC(intellec4_state::rome_out));
770 map(0x00f0, 0x00ff).mirror(0x1f00).rw(FUNC(intellec4_state::romf_in), FUNC(intellec4_state::romf_out));
771
772 // 0x0800...0x0fff PROM
773
774 // 0x1000...0x17ff neither
775
776 // 0x1800...0x1fff unused
777 }
778
779
780 /*---------------------------------
781 CPU views of address spaces
782 ---------------------------------*/
783
intellec4_rom(address_map & map)784 void intellec4_state::intellec4_rom(address_map &map)
785 {
786 map.unmap_value_low();
787 map(0x0000, 0x0fff).m(m_program_banks, FUNC(address_map_bank_device::amap8));
788 }
789
intellec4_ram_memory(address_map & map)790 void intellec4_state::intellec4_ram_memory(address_map &map)
791 {
792 map.unmap_value_low();
793 map(0x0000, 0x00ff).ram().share("memory"); // 4 * 4002
794 }
795
intellec4_rom_ports(address_map & map)796 void intellec4_state::intellec4_rom_ports(address_map &map)
797 {
798 map.unmap_value_high();
799 map(0x0000, 0x07ff).m("rpbank", FUNC(address_map_bank_device::amap8));
800 }
801
intellec4_ram_status(address_map & map)802 void intellec4_state::intellec4_ram_status(address_map &map)
803 {
804 map.unmap_value_low();
805 map(0x0000, 0x003f).ram().share("status"); // 4 * 4002
806 }
807
intellec4_ram_ports(address_map & map)808 void intellec4_state::intellec4_ram_ports(address_map &map)
809 {
810 map(0x00, 0x00).w(FUNC(intellec4_state::ram0_out));
811 map(0x01, 0x01).w(FUNC(intellec4_state::ram1_out));
812 }
813
intellec4_program_memory(address_map & map)814 void intellec4_state::intellec4_program_memory(address_map &map)
815 {
816 map.unmap_value_low();
817 map(0x0000, 0x01ff).rw(FUNC(intellec4_state::pm_read), FUNC(intellec4_state::pm_write));
818 }
819
820
821 /*----------------------------------
822 Common machine configuration
823 ----------------------------------*/
824
825 DEVICE_INPUT_DEFAULTS_START(tty)
826 DEVICE_INPUT_DEFAULTS("RS232_TXBAUD", 0x00ff, RS232_BAUD_110)
827 DEVICE_INPUT_DEFAULTS("RS232_RXBAUD", 0x00ff, RS232_BAUD_110)
828 DEVICE_INPUT_DEFAULTS("RS232_STARTBITS", 0x00ff, RS232_STARTBITS_1)
829 DEVICE_INPUT_DEFAULTS("RS232_DATABITS", 0x00ff, RS232_DATABITS_8)
830 DEVICE_INPUT_DEFAULTS("RS232_PARITY", 0x00ff, RS232_PARITY_NONE)
831 DEVICE_INPUT_DEFAULTS("RS232_STOPBITS", 0x00ff, RS232_STOPBITS_2)
832 DEVICE_INPUT_DEFAULTS("TERM_CONF", 0x01c0, 0x0000)
833 DEVICE_INPUT_DEFAULTS("FLOW_CONTROL", 0x0001, 0x0000)
834 DEVICE_INPUT_DEFAULTS_END
835
intellec4(machine_config & config)836 void intellec4_state::intellec4(machine_config &config)
837 {
838 ADDRESS_MAP_BANK(config, m_program_banks, 0);
839 m_program_banks->set_map(&intellec4_state::intellec4_program_banks);
840 m_program_banks->set_endianness(ENDIANNESS_LITTLE);
841 m_program_banks->set_data_width(8);
842 m_program_banks->set_addr_width(14);
843 m_program_banks->set_stride(0x1000);
844
845 ADDRESS_MAP_BANK(config, m_rom_port_banks, 0);
846 m_rom_port_banks->set_map(&intellec4_state::intellec4_rom_port_banks);
847 m_rom_port_banks->set_endianness(ENDIANNESS_LITTLE);
848 m_rom_port_banks->set_data_width(8);
849 m_rom_port_banks->set_addr_width(14);
850 m_rom_port_banks->set_stride(0x1000);
851
852 INTEL_IMM6_76(config, m_prom_programmer, 0);
853
854 RS232_PORT(config, m_tty, default_rs232_devices, "terminal");
855 m_tty->set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(tty));
856 m_tty->set_option_device_input_defaults("null_modem", DEVICE_INPUT_DEFAULTS_NAME(tty));
857
858 INTELLEC4_UNIV_BUS(config, m_bus, 518000. / 7);
859 m_bus->set_rom_space(m_program_banks, AS_PROGRAM);
860 m_bus->set_rom_ports_space(m_rom_port_banks, AS_PROGRAM);
861 m_bus->set_memory_space(m_cpu, mcs40_cpu_device_base::AS_RAM_MEMORY);
862 m_bus->set_status_space(m_cpu, mcs40_cpu_device_base::AS_RAM_STATUS);
863 m_bus->set_ram_ports_space(m_cpu, mcs40_cpu_device_base::AS_RAM_PORTS);
864 m_bus->reset_4002_out_cb().set(FUNC(intellec4_state::bus_reset_4002));
865 m_bus->user_reset_out_cb().set(FUNC(intellec4_state::bus_user_reset));
866 INTELLEC4_UNIV_SLOT(config, "j7", 5.185_MHz_XTAL / 7, m_bus, intellec4_univ_cards, "imm4_90");
867 INTELLEC4_UNIV_SLOT(config, "j8", 5.185_MHz_XTAL / 7, m_bus, intellec4_univ_cards, "imm6_26");
868 INTELLEC4_UNIV_SLOT(config, "j9", 5.185_MHz_XTAL / 7, m_bus, intellec4_univ_cards, nullptr);
869 INTELLEC4_UNIV_SLOT(config, "j10", 5.185_MHz_XTAL / 7, m_bus, intellec4_univ_cards, nullptr);
870 INTELLEC4_UNIV_SLOT(config, "j11", 5.185_MHz_XTAL / 7, m_bus, intellec4_univ_cards, nullptr);
871 INTELLEC4_UNIV_SLOT(config, "j12", 5.185_MHz_XTAL / 7, m_bus, intellec4_univ_cards, nullptr);
872 INTELLEC4_UNIV_SLOT(config, "j13", 5.185_MHz_XTAL / 7, m_bus, intellec4_univ_cards, nullptr);
873 INTELLEC4_UNIV_SLOT(config, "j14", 5.185_MHz_XTAL / 7, m_bus, intellec4_univ_cards, nullptr);
874 INTELLEC4_UNIV_SLOT(config, "j15", 5.185_MHz_XTAL / 7, m_bus, intellec4_univ_cards, nullptr);
875 INTELLEC4_UNIV_SLOT(config, "j16", 5.185_MHz_XTAL / 7, m_bus, intellec4_univ_cards, nullptr);
876 INTELLEC4_UNIV_SLOT(config, "j17", 5.185_MHz_XTAL / 7, m_bus, intellec4_univ_cards, nullptr);
877 INTELLEC4_UNIV_SLOT(config, "j18", 5.185_MHz_XTAL / 7, m_bus, intellec4_univ_cards, nullptr);
878 INTELLEC4_UNIV_SLOT(config, "j19", 5.185_MHz_XTAL / 7, m_bus, intellec4_univ_cards, nullptr);
879 }
880
881
882 /*----------------------------------
883 Timer handlers
884 ----------------------------------*/
885
TIMER_CALLBACK_MEMBER(intellec4_state::reset_expired)886 TIMER_CALLBACK_MEMBER(intellec4_state::reset_expired)
887 {
888 if (m_cpu_reset)
889 {
890 m_cpu_reset = false;
891 m_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
892 m_bus->cpu_reset_in(1);
893 if (m_sw_reset_mode)
894 {
895 m_bus->reset_4002_in(1);
896 check_4002_reset();
897 }
898 }
899 }
900
901
902 /*----------------------------------
903 LED update helpers
904 ----------------------------------*/
905
display_address(u16 value,u16 mask)906 void intellec4_state::display_address(u16 value, u16 mask)
907 {
908 u16 const diff((value ^ m_display_addr) & mask);
909 m_display_addr ^= diff;
910 m_led_address[0][0] = BIT(m_display_addr, 0);
911 m_led_address[0][1] = BIT(m_display_addr, 1);
912 m_led_address[0][2] = BIT(m_display_addr, 2);
913 m_led_address[0][3] = BIT(m_display_addr, 3);
914 m_led_address[1][0] = BIT(m_display_addr, 4);
915 m_led_address[1][1] = BIT(m_display_addr, 5);
916 m_led_address[1][2] = BIT(m_display_addr, 6);
917 m_led_address[1][3] = BIT(m_display_addr, 7);
918 m_led_address[2][0] = BIT(m_display_addr, 8);
919 m_led_address[2][1] = BIT(m_display_addr, 9);
920 m_led_address[2][2] = BIT(m_display_addr, 10);
921 m_led_address[2][3] = BIT(m_display_addr, 11);
922 }
923
display_instruction(u8 value,u8 mask)924 void intellec4_state::display_instruction(u8 value, u8 mask)
925 {
926 u16 const diff((value ^ m_display_instr) & mask);
927 m_display_instr ^= diff;
928 m_led_instruction[1][0] = BIT(m_display_instr, 0);
929 m_led_instruction[1][1] = BIT(m_display_instr, 1);
930 m_led_instruction[1][2] = BIT(m_display_instr, 2);
931 m_led_instruction[1][3] = BIT(m_display_instr, 3);
932 m_led_instruction[0][0] = BIT(m_display_instr, 4);
933 m_led_instruction[0][1] = BIT(m_display_instr, 5);
934 m_led_instruction[0][2] = BIT(m_display_instr, 6);
935 m_led_instruction[0][3] = BIT(m_display_instr, 7);
936 }
937
display_active_bank(u8 value)938 void intellec4_state::display_active_bank(u8 value)
939 {
940 m_led_active_bank[0] = BIT(value, 0);
941 m_led_active_bank[1] = BIT(value, 1);
942 m_led_active_bank[2] = BIT(value, 2);
943 m_led_active_bank[3] = BIT(value, 3);
944 }
945
display_execution(u8 value,u8 mask)946 void intellec4_state::display_execution(u8 value, u8 mask)
947 {
948 u16 const diff((value ^ m_display_exec) & mask);
949 m_display_exec ^= diff;
950 m_led_execution[1][0] = BIT(m_display_exec, 0);
951 m_led_execution[1][1] = BIT(m_display_exec, 1);
952 m_led_execution[1][2] = BIT(m_display_exec, 2);
953 m_led_execution[1][3] = BIT(m_display_exec, 3);
954 m_led_execution[0][0] = BIT(m_display_exec, 4);
955 m_led_execution[0][1] = BIT(m_display_exec, 5);
956 m_led_execution[0][2] = BIT(m_display_exec, 6);
957 m_led_execution[0][3] = BIT(m_display_exec, 7);
958 }
959
display_pointer(u8 value,u8 mask)960 void intellec4_state::display_pointer(u8 value, u8 mask)
961 {
962 u16 const diff((value ^ m_display_ptr) & mask);
963 m_display_ptr ^= diff;
964 m_led_last_ptr[1][0] = BIT(m_display_ptr, 0);
965 m_led_last_ptr[1][1] = BIT(m_display_ptr, 1);
966 m_led_last_ptr[1][2] = BIT(m_display_ptr, 2);
967 m_led_last_ptr[1][3] = BIT(m_display_ptr, 3);
968 m_led_last_ptr[0][0] = BIT(m_display_ptr, 4);
969 m_led_last_ptr[0][1] = BIT(m_display_ptr, 5);
970 m_led_last_ptr[0][2] = BIT(m_display_ptr, 6);
971 m_led_last_ptr[0][3] = BIT(m_display_ptr, 7);
972 }
973
974
975 /*----------------------------------
976 Internal helpers
977 ----------------------------------*/
978
trigger_reset()979 void intellec4_state::trigger_reset()
980 {
981 // (re-)trigger the reset monostable
982 if (!m_sw_reset && !m_sw_prg_mode[0] && !m_sw_prg_mode[1] && !m_sw_prg_mode[2] && !m_bus_user_reset)
983 {
984 // 9602 with Rx = 27kΩ, Cx = 0.1µF
985 // K * Rx(kΩ) * Cx(pF) * (1 + (1 / Rx(kΩ))) = 0.34 * 27 * 100000 * (1 + (1 / 27)) = 952000ns
986 m_reset_timer->adjust(attotime::from_usec(952));
987 if (!m_cpu_reset)
988 {
989 m_cpu_reset = true;
990 m_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
991 m_bus->cpu_reset_in(0);
992 reset_panel();
993 if (m_sw_reset_mode)
994 {
995 m_bus->reset_4002_in(0);
996 check_4002_reset();
997 }
998 }
999 }
1000 }
1001
check_4002_reset()1002 void intellec4_state::check_4002_reset()
1003 {
1004 // FIXME: this really takes multiple cycles to erase, and prevents writes while held
1005 if ((m_cpu_reset && m_sw_reset_mode) || m_bus_reset_4002)
1006 {
1007 std::fill_n(&m_memory[0], m_memory.bytes(), 0U);
1008 std::fill_n(&m_status[0], m_memory.bytes(), 0U);
1009 }
1010 }
1011
reset_panel()1012 void intellec4_state::reset_panel()
1013 {
1014 if (!m_panel_reset)
1015 {
1016 m_pass_counter = 0U;
1017 m_panel_reset = true;
1018 m_adr_cmp_latch = false;
1019 if (m_search_complete && !m_next_inst)
1020 m_led_status_search = m_search_complete = false;
1021 if (m_pointer_valid)
1022 m_led_status_ptr_valid = m_pointer_valid = false;
1023 }
1024 }
1025
1026
1027
1028 /***********************************************************************
1029 MOD 4 driver
1030 ***********************************************************************/
1031
1032 class mod4_state : public intellec4_state
1033 {
1034 public:
mod4_state(machine_config const & mconfig,device_type type,char const * tag)1035 mod4_state(machine_config const &mconfig, device_type type, char const *tag)
1036 : intellec4_state(mconfig, type, tag)
1037 , m_led_status_cpu(*this, "led_status_cpu")
1038 {
1039 }
1040
1041 // universal slot outputs
1042 DECLARE_WRITE_LINE_MEMBER(bus_test);
1043
1044 // front panel switches
1045 DECLARE_INPUT_CHANGED_MEMBER(sw_hold);
1046 DECLARE_INPUT_CHANGED_MEMBER(sw_one_shot);
1047
1048 void mod4(machine_config &config);
1049
1050 protected:
1051 virtual void driver_start() override;
1052 virtual void driver_reset() override;
1053
1054 private:
1055 enum
1056 {
1057 BIT_SW_HOLD = 0,
1058 BIT_SW_ONE_SHOT
1059 };
1060
1061 TIMER_CALLBACK_MEMBER(one_shot_expired);
1062
1063 output_finder<> m_led_status_cpu;
1064
1065 emu_timer *m_one_shot_timer = nullptr;
1066
1067 // control board state
1068 bool m_one_shot = false;
1069
1070 // current state of signals from bus
1071 bool m_bus_test = false;
1072
1073 // current state of front panel switches
1074 bool m_sw_hold = false;
1075 };
1076
1077
1078 /*----------------------------------
1079 MOD 4-specific switches
1080 ----------------------------------*/
1081
1082 INPUT_PORTS_START(mod4)
PORT_INCLUDE(intellec4)1083 PORT_INCLUDE(intellec4)
1084
1085 PORT_MODIFY("MODE")
1086 PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("HOLD") PORT_CODE(KEYCODE_LEFT) PORT_CHANGED_MEMBER(DEVICE_SELF, mod4_state, sw_hold, 0)
1087 PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("ONE SHOT") PORT_CODE(KEYCODE_RIGHT) PORT_CHANGED_MEMBER(DEVICE_SELF, mod4_state, sw_one_shot, 0)
1088 INPUT_PORTS_END
1089
1090
1091 /*----------------------------------
1092 Bus signal handlers
1093 ----------------------------------*/
1094
1095 WRITE_LINE_MEMBER(mod4_state::bus_test)
1096 {
1097 if (!m_one_shot && !m_sw_hold)
1098 m_cpu->set_input_line(I4004_TEST_LINE, state ? CLEAR_LINE : ASSERT_LINE);
1099 m_bus_test = 0 == state;
1100 }
1101
1102
1103 /*----------------------------------
1104 Front panel switch handlers
1105 ----------------------------------*/
1106
INPUT_CHANGED_MEMBER(mod4_state::sw_hold)1107 INPUT_CHANGED_MEMBER(mod4_state::sw_hold)
1108 {
1109 // overridden by the one-shot monostable and the bus test signal
1110 if (!m_one_shot)
1111 {
1112 if (!m_bus_test)
1113 m_cpu->set_input_line(I4004_TEST_LINE, newval ? CLEAR_LINE : ASSERT_LINE);
1114 m_bus->test_in(newval ? 1 : 0);
1115 }
1116 m_sw_hold = !bool(newval);
1117 }
1118
INPUT_CHANGED_MEMBER(mod4_state::sw_one_shot)1119 INPUT_CHANGED_MEMBER(mod4_state::sw_one_shot)
1120 {
1121 if (newval && !oldval)
1122 {
1123 // 9602 with Rx = 20kΩ, Cx = 0.005µF
1124 // K * Rx(kΩ) * Cx(pF) * (1 + (1 / Rx(kΩ))) = 0.34 * 20 * 5000 * (1 + (1 / 20)) = 35700ns
1125 m_one_shot_timer->adjust(attotime::from_nsec(35700));
1126 if (!m_one_shot)
1127 {
1128 m_one_shot = true;
1129 if (!m_sw_hold)
1130 {
1131 m_bus->test_in(0);
1132 if (!m_bus_test)
1133 m_cpu->set_input_line(I4004_TEST_LINE, ASSERT_LINE);
1134 }
1135 }
1136 }
1137 }
1138
1139
1140 /*----------------------------------
1141 MOD 4-specific configuration
1142 ----------------------------------*/
1143
mod4(machine_config & config)1144 void mod4_state::mod4(machine_config &config)
1145 {
1146 intellec4(config);
1147
1148 i4004_cpu_device &cpu(I4004(config, m_cpu, 5.185_MHz_XTAL / 7));
1149 cpu.set_rom_map(&mod4_state::intellec4_rom);
1150 cpu.set_ram_memory_map(&mod4_state::intellec4_ram_memory);
1151 cpu.set_rom_ports_map(&mod4_state::intellec4_rom_ports);
1152 cpu.set_ram_status_map(&mod4_state::intellec4_ram_status);
1153 cpu.set_ram_ports_map(&mod4_state::intellec4_ram_ports);
1154 cpu.set_program_memory_map(&mod4_state::intellec4_program_memory);
1155 cpu.set_bus_cycle_cb(FUNC(mod4_state::bus_cycle));
1156 cpu.sync_cb().set(m_bus, FUNC(bus::intellec4::univ_bus_device::sync_in));
1157
1158 m_bus->test_out_cb().set(FUNC(mod4_state::bus_test));
1159
1160 config.set_default_layout(layout_intlc44);
1161 }
1162
1163
1164 /*----------------------------------
1165 driver_device implementation
1166 ----------------------------------*/
1167
driver_start()1168 void mod4_state::driver_start()
1169 {
1170 intellec4_state::driver_start();
1171
1172 m_led_status_cpu.resolve();
1173
1174 m_one_shot_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mod4_state::one_shot_expired), this));
1175
1176 save_item(NAME(m_one_shot));
1177
1178 save_item(NAME(m_bus_test));
1179
1180 save_item(NAME(m_sw_hold));
1181
1182 m_one_shot = false;
1183 }
1184
driver_reset()1185 void mod4_state::driver_reset()
1186 {
1187 intellec4_state::driver_reset();
1188
1189 // set stuff according to initial state of front panel
1190 m_sw_hold = BIT(~m_sw_mode->read(), BIT_SW_HOLD);
1191
1192 // ensure we're consistent with the state of the bus
1193 m_bus_test = 0 == m_bus->test_out();
1194
1195 // ensure device inputs are all in the correct state
1196 m_cpu->set_input_line(I4004_TEST_LINE, (m_one_shot || m_bus_test || m_sw_hold) ? ASSERT_LINE : CLEAR_LINE);
1197 m_bus->test_in((m_one_shot || m_sw_hold) ? 0 : 1);
1198
1199 // set front panel LEDs
1200 m_led_status_cpu = true; // actually driven by clock phase 2 - let's assume it's always running
1201 }
1202
1203
1204 /*----------------------------------
1205 Timer handlers
1206 ----------------------------------*/
1207
TIMER_CALLBACK_MEMBER(mod4_state::one_shot_expired)1208 TIMER_CALLBACK_MEMBER(mod4_state::one_shot_expired)
1209 {
1210 m_one_shot = false;
1211 if (!m_sw_hold)
1212 {
1213 m_bus->test_in(1);
1214 if (!m_bus_test)
1215 m_cpu->set_input_line(I4004_TEST_LINE, CLEAR_LINE);
1216 }
1217 }
1218
1219
1220
1221 /***********************************************************************
1222 MOD 40 driver
1223 ***********************************************************************/
1224
1225 class mod40_state : public intellec4_state
1226 {
1227 public:
mod40_state(machine_config const & mconfig,device_type type,char const * tag)1228 mod40_state(machine_config const &mconfig, device_type type, char const *tag)
1229 : intellec4_state(mconfig, type, tag)
1230 , m_led_status_run(*this, "led_status_run")
1231 {
1232 }
1233
1234 DECLARE_WRITE_LINE_MEMBER(stp_ack);
1235
1236 // universal slot outputs
1237 DECLARE_WRITE_LINE_MEMBER(bus_stop);
1238 DECLARE_WRITE_LINE_MEMBER(bus_test);
1239
1240 // front panel switches
1241 DECLARE_INPUT_CHANGED_MEMBER(sw_stop);
1242 DECLARE_INPUT_CHANGED_MEMBER(sw_single_step);
1243
1244 void mod40(machine_config &config);
1245
1246 protected:
1247 virtual void driver_start() override;
1248 virtual void driver_reset() override;
1249
1250 private:
1251 enum
1252 {
1253 BIT_SW_STOP = 0,
1254 BIT_SW_SINGLE_STEP
1255 };
1256
1257 TIMER_CALLBACK_MEMBER(single_step_expired);
1258
1259 output_finder<> m_led_status_run;
1260
1261 emu_timer *m_single_step_timer = nullptr;
1262
1263 // control board state
1264 bool m_stp_ack = false, m_single_step = false;
1265
1266 // current state of signals from bus
1267 bool m_bus_stop = false;
1268
1269 // current state of front panel switches
1270 bool m_sw_stop = false;
1271 };
1272
1273
1274 /*----------------------------------
1275 MOD 40-specific switches
1276 ----------------------------------*/
1277
1278 INPUT_PORTS_START(mod40)
PORT_INCLUDE(intellec4)1279 PORT_INCLUDE(intellec4)
1280
1281 PORT_MODIFY("MODE")
1282 PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("STOP") PORT_CODE(KEYCODE_LEFT) PORT_CHANGED_MEMBER(DEVICE_SELF, mod40_state, sw_stop, 0)
1283 PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("SINGLE STEP") PORT_CODE(KEYCODE_RIGHT) PORT_CHANGED_MEMBER(DEVICE_SELF, mod40_state, sw_single_step, 0)
1284 INPUT_PORTS_END
1285
1286
1287 /*----------------------------------
1288 CPU output handlers
1289 ----------------------------------*/
1290
1291 WRITE_LINE_MEMBER(mod40_state::stp_ack)
1292 {
1293 // resets the single-step monostable
1294 if (m_stp_ack && state)
1295 {
1296 m_single_step_timer->reset();
1297 m_single_step = false;
1298 if (m_sw_stop)
1299 {
1300 m_bus->stop_in(0);
1301 if (!m_bus_stop)
1302 m_cpu->set_input_line(I4040_STP_LINE, ASSERT_LINE);
1303 }
1304 }
1305 m_stp_ack = 0 == state;
1306 m_led_status_run = !m_stp_ack;
1307 m_bus->stop_acknowledge_in(state);
1308 }
1309
1310
WRITE_LINE_MEMBER(mod40_state::bus_stop)1311 WRITE_LINE_MEMBER(mod40_state::bus_stop)
1312 {
1313 // will not allow the CPU to step/run
1314 if (m_single_step || !m_sw_stop)
1315 m_cpu->set_input_line(I4040_STP_LINE, state ? CLEAR_LINE : ASSERT_LINE);
1316 m_bus_stop = 0 == state;
1317 }
1318
1319
1320 /*----------------------------------
1321 Bus signal handlers
1322 ----------------------------------*/
1323
WRITE_LINE_MEMBER(mod40_state::bus_test)1324 WRITE_LINE_MEMBER(mod40_state::bus_test)
1325 {
1326 m_cpu->set_input_line(I4040_TEST_LINE, state ? CLEAR_LINE : ASSERT_LINE);
1327 }
1328
1329
1330 /*----------------------------------
1331 Front panel switch handlers
1332 ----------------------------------*/
1333
INPUT_CHANGED_MEMBER(mod40_state::sw_stop)1334 INPUT_CHANGED_MEMBER(mod40_state::sw_stop)
1335 {
1336 // overridden by the single-step monostable and the bus stop signal
1337 if (!m_single_step)
1338 {
1339 if (!m_bus_stop)
1340 m_cpu->set_input_line(I4040_STP_LINE, newval ? CLEAR_LINE : ASSERT_LINE);
1341 m_bus->stop_in(newval ? 1 : 0);
1342 }
1343 m_sw_stop = !bool(newval);
1344 }
1345
INPUT_CHANGED_MEMBER(mod40_state::sw_single_step)1346 INPUT_CHANGED_MEMBER(mod40_state::sw_single_step)
1347 {
1348 // (re-)triggers the single-step monostable
1349 if (m_stp_ack && newval && !oldval)
1350 {
1351 // 9602 with Rx = 20kΩ, Cx = 0.005µF
1352 // K * Rx(kΩ) * Cx(pF) * (1 + (1 / Rx(kΩ))) = 0.34 * 20 * 5000 * (1 + (1 / 20)) = 35700ns
1353 m_single_step_timer->adjust(attotime::from_nsec(35700));
1354 if (!m_single_step)
1355 {
1356 m_single_step = true;
1357 if (m_sw_stop)
1358 {
1359 m_bus->stop_in(1);
1360 if (!m_bus_stop)
1361 m_cpu->set_input_line(I4040_STP_LINE, CLEAR_LINE);
1362 }
1363 }
1364 }
1365 }
1366
1367
1368 /*----------------------------------
1369 MOD 40-specific configuration
1370 ----------------------------------*/
1371
mod40(machine_config & config)1372 void mod40_state::mod40(machine_config &config)
1373 {
1374 intellec4(config);
1375
1376 i4040_cpu_device &cpu(I4040(config, m_cpu, 5.185_MHz_XTAL / 7));
1377 cpu.set_rom_map(&mod40_state::intellec4_rom);
1378 cpu.set_ram_memory_map(&mod40_state::intellec4_ram_memory);
1379 cpu.set_rom_ports_map(&mod40_state::intellec4_rom_ports);
1380 cpu.set_ram_status_map(&mod40_state::intellec4_ram_status);
1381 cpu.set_ram_ports_map(&mod40_state::intellec4_ram_ports);
1382 cpu.set_program_memory_map(&mod40_state::intellec4_program_memory);
1383 cpu.set_bus_cycle_cb(FUNC(mod40_state::bus_cycle));
1384 cpu.sync_cb().set(m_bus, FUNC(bus::intellec4::univ_bus_device::sync_in));
1385 cpu.stp_ack_cb().set(FUNC(mod40_state::stp_ack));
1386
1387 m_bus->stop_out_cb().set(FUNC(mod40_state::bus_stop));
1388 m_bus->test_out_cb().set(FUNC(mod40_state::bus_test));
1389
1390 config.set_default_layout(layout_intlc440);
1391 }
1392
1393
1394 /*----------------------------------
1395 driver_device implementation
1396 ----------------------------------*/
1397
driver_start()1398 void mod40_state::driver_start()
1399 {
1400 intellec4_state::driver_start();
1401
1402 m_led_status_run.resolve();
1403
1404 m_single_step_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mod40_state::single_step_expired), this));
1405
1406 save_item(NAME(m_stp_ack));
1407 save_item(NAME(m_single_step));
1408
1409 save_item(NAME(m_bus_stop));
1410
1411 save_item(NAME(m_sw_stop));
1412
1413 m_stp_ack = m_single_step = false;
1414 }
1415
driver_reset()1416 void mod40_state::driver_reset()
1417 {
1418 intellec4_state::driver_reset();
1419
1420 // set stuff according to initial state of front panel
1421 m_sw_stop = BIT(~m_sw_mode->read(), BIT_SW_STOP);
1422
1423 // ensure we're consistent with the state of the bus
1424 m_bus_stop = 0 == m_bus->stop_out();
1425
1426 // ensure device inputs are all in the correct state
1427 m_cpu->set_input_line(I4040_TEST_LINE, m_bus->test_out() ? CLEAR_LINE : ASSERT_LINE);
1428 m_cpu->set_input_line(I4040_STP_LINE, ((m_sw_stop && !m_single_step) || m_bus_stop) ? ASSERT_LINE : CLEAR_LINE);
1429 m_bus->test_in(1);
1430 m_bus->stop_in((m_sw_stop && !m_single_step) ? 0 : 1);
1431
1432 // set front panel LEDs
1433 m_led_status_run = !m_stp_ack;
1434 }
1435
1436
1437 /*----------------------------------
1438 Timer handlers
1439 ----------------------------------*/
1440
TIMER_CALLBACK_MEMBER(mod40_state::single_step_expired)1441 TIMER_CALLBACK_MEMBER(mod40_state::single_step_expired)
1442 {
1443 m_single_step = false;
1444 if (m_sw_stop)
1445 {
1446 m_bus->stop_in(0);
1447 if (!m_bus_stop)
1448 m_cpu->set_input_line(I4040_STP_LINE, ASSERT_LINE);
1449 }
1450 }
1451
1452
1453 /***********************************************************************
1454 ROM definitions
1455 ***********************************************************************/
1456
1457 ROM_START(intlc44)
1458 ROM_REGION(0x0400, "monitor", 0) // 4 * 1702A
1459 ROM_DEFAULT_BIOS("v2.1")
1460 ROM_SYSTEM_BIOS(0, "v2.1", "MON 4 V2.1")
1461 ROMX_LOAD("mon_4-000-v_2.1.a1", 0x0000, 0x0100, CRC(8d1f56ff) SHA1(96bc19be9be4e92195fad82d7a3cadb763ab6e3f), ROM_BIOS(0))
1462 ROMX_LOAD("mon_4-100-v_2.1.a2", 0x0100, 0x0100, CRC(66562a4f) SHA1(040749c45e95dfc39b3397d0c31c8b4c11f0a5fc), ROM_BIOS(0))
1463 ROMX_LOAD("mon_4-200-v_2.1.a3", 0x0200, 0x0100, CRC(fe039c68) SHA1(1801cfcc7514412865c0fdc7d1800fcf583a2d2a), ROM_BIOS(0))
1464 ROMX_LOAD("mon_4-300-v_2.1.a4", 0x0300, 0x0100, CRC(3724d5af) SHA1(b764b3bb3541fbda875f7a7655f46aa54b332631), ROM_BIOS(0))
1465 ROM_END
1466
1467 ROM_START(intlc440)
1468 ROM_REGION(0x0400, "monitor", 0) // 4 * 1702A
1469 ROM_DEFAULT_BIOS("v2.1")
1470 ROM_SYSTEM_BIOS(0, "v2.1", "MON 4 V2.1")
1471 ROMX_LOAD("mon_4-000-v_2.1.a1", 0x0000, 0x0100, CRC(8d1f56ff) SHA1(96bc19be9be4e92195fad82d7a3cadb763ab6e3f), ROM_BIOS(0))
1472 ROMX_LOAD("mon_4-100-v_2.1.a2", 0x0100, 0x0100, CRC(66562a4f) SHA1(040749c45e95dfc39b3397d0c31c8b4c11f0a5fc), ROM_BIOS(0))
1473 ROMX_LOAD("mon_4-200-v_2.1.a3", 0x0200, 0x0100, CRC(fe039c68) SHA1(1801cfcc7514412865c0fdc7d1800fcf583a2d2a), ROM_BIOS(0))
1474 ROMX_LOAD("mon_4-300-v_2.1.a4", 0x0300, 0x0100, CRC(3724d5af) SHA1(b764b3bb3541fbda875f7a7655f46aa54b332631), ROM_BIOS(0))
1475 ROM_SYSTEM_BIOS(1, "v2.1_1200", "MON 4 V2.1 1200 Baud hack")
1476 ROMX_LOAD("mon_4-000-v_2.1.a1", 0x0000, 0x0100, CRC(8d1f56ff) SHA1(96bc19be9be4e92195fad82d7a3cadb763ab6e3f), ROM_BIOS(1))
1477 ROMX_LOAD("i40_mon-1.a2", 0x0100, 0x0100, CRC(cd9fecd6) SHA1(9c4fb85118c881687fd4b324e5089df05d1e63d1), ROM_BIOS(1))
1478 ROMX_LOAD("i40_mon-2.a3", 0x0200, 0x0100, CRC(037de128) SHA1(3694636e1f4e23688b36ea9ee755a0c5888f4328), ROM_BIOS(1))
1479 ROMX_LOAD("1200_baud-i40_mon-f3.a4", 0x0300, 0x0100, CRC(f3198d79) SHA1(b7903073b69f487b6f78842c08694f12225d85f0), ROM_BIOS(1))
1480 ROM_END
1481
1482 } // anonymous namespace
1483
1484
1485 /***********************************************************************
1486 Machine definitions
1487 ***********************************************************************/
1488
1489 // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
1490 COMP( 1973?, intlc44, 0, 0, mod4, mod4, mod4_state, empty_init, "Intel", "INTELLEC 4/MOD 4", MACHINE_NO_SOUND_HW | MACHINE_CLICKABLE_ARTWORK | MACHINE_SUPPORTS_SAVE )
1491 COMP( 1974?, intlc440, 0, 0, mod40, mod40, mod40_state, empty_init, "Intel", "INTELLEC 4/MOD 40", MACHINE_NO_SOUND_HW | MACHINE_CLICKABLE_ARTWORK | MACHINE_SUPPORTS_SAVE )
1492