1 // license:BSD-3-Clause
2 // copyright-holders:Raphael Nabet
3 /*
4  * Note: Original Java source written by:
5  *
6  * Barry Silverman mailto:barry@disus.com or mailto:bss@media.mit.edu
7  * Vadim Gerasimov mailto:vadim@media.mit.edu
8  *
9  * MESS driver by Chris Salomon and Raphael Nabet.
10  *
11  * Basically, it has been rewritten entirely in order to perform cycle-level simulation
12  * (with only a few flip-flops being set one cycle too early or too late).  I don't know if
13  * it is a good thing or a bad thing (it makes emulation more accurate, but slower, and
14  * code is more complex and less readable), but it appears to be the only way we could emulate
15  * mid-instruction sequence break.  And it enables us to emulate the control panel fairly
16  * accurately.
17  *
18  * Additionally, IOT functions have been modified to be external: IOT callback pointers are set
19  * at emulation initiation, and most IOT callback functions are part of the machine emulation.
20  *
21  *
22  * for the runnable java applet, with applet and Spacewar! source, go to:
23  * http://lcs.www.media.mit.edu/groups/el/projects/spacewar/
24  *
25  * for a complete html version of the pdp1 handbook go to:
26  * http://www.dbit.com/~greeng3/pdp1/index.html
27  *
28  * there is another java simulator (by the same people) which runs the
29  * original pdp1 LISP interpreter, go to:
30  * http://lcs.www.media.mit.edu/groups/el/projects/pdp1
31  *
32  * Another PDP1 emulator (or simulator) is at:
33  * ftp://minnie.cs.adfa.oz.au/pub/PDP-11/Sims/Supnik_2.3
34  * It seems to emulate pdp1 I/O more accurately than we do.
35  * However, there is no CRT emulation.
36  *
37  * and finally, there is a nice article about SPACEWAR!, go to:
38  * http://ars-www.uchicago.edu/~eric/lore/spacewar/spacewar.html
39  *
40  * some extra documentation is available on spies:
41  * http://www.spies.com/~aek/pdf/dec/pdp1/
42  * The file "F17_PDP1Maint.pdf" explains operation procedures and much of the internals of pdp-1.
43  * It was the main reference for this emulator.
44  * The file "F25_PDP1_IO.pdf" has interesting information on the I/O system, too.
45  *
46  * Following is an extract from the handbook:
47  *
48  * INTRODUCTION
49  *
50  * The Programmed Data Processor (PDP-1) is a high speed, solid state digital computer designed to
51  * operate with many types of input-output devices with no internal machine changes. It is a single
52  * address, single instruction, stored program computer with powerful program features. Five-megacycle
53  * circuits, a magnetic core memory and fully parallel processing make possible a computation rate of
54  * 100,000 additions per second. The PDP-1 is unusually versatile. It is easy to install, operate and
55  * maintain. Conventional 110-volt power is used, neither air conditioning nor floor reinforcement is
56  * necessary, and preventive maintenance is provided for by built-in marginal checking circuits.
57  *
58  * PDP-1 circuits are based on the designs of DEC's highly successful and reliable System Modules.
59  * Flip-flops and most switches use saturating transistors. Primary active elements are
60  * Micro-Alloy-Diffused transistors.
61  *
62  * The entire computer occupies only 17 square feet of floor space. It consists of four equipment frames,
63  * one of which is used as the operating station.
64  *
65  * CENTRAL PROCESSOR
66  *
67  * The Central Processor contains the control, arithmetic and memory addressing elements, and the memory
68  * buffer register. The word length is 18 binary digits. Instructions are performed in multiples of the
69  * memory cycle time of five microseconds. Add, subtract, deposit, and load, for example, are two-cycle
70  * instructions requiring 10 microseconds. Multiplication requires and average of 20 microseconds.
71  * Program features include: single address instructions, multiple step indirect addressing and logical
72  * arithmetic commands. Console features include: flip-flop indicators grouped for convenient octal
73  * reading, six program flags for automatic setting and computer sensing, and six sense switches for
74  * manual setting and computer sensing.
75  *
76  * MEMORY SYSTEM
77  *
78  * The coincident-current, magnetic core memory of a standard PDP-1 holds 4096 words of 18 bits each.
79  * Memory capacity may be readily expanded, in increments of 4096 words, to a maximum of 65,536 words.
80  * The read-rewrite time of the memory is five microseconds, the basic computer rate. Driving currents
81  * are automatically adjusted to compensate for temperature variations between 50 and 110 degrees
82  * Fahrenheit. The core memory storage may be supplemented by up to 24 magnetic tape transports.
83  *
84  * INPUT-OUTPUT
85  *
86  * PDP-1 is designed to operate a variety of buffered input-output devices. Standard equipment consistes
87  * of a perforated tape reader with a read speed of 400 lines per second, and alphanuermic typewriter for
88  * on-line operation in both input and output, and a perforated tape punch (alphanumeric or binary) with
89  * a speed of 63 lines per second. A variety of optional equipment is available, including the following:
90  *
91  *     Precision CRT Display Type 30
92  *     Ultra-Precision CRT Display Type 31
93  *     Symbol Generator Type 33
94  *     Light Pen Type 32
95  *     Oscilloscope Display Type 34
96  *     Card Punch Control Type 40-1
97  *     Card Reader and Control Type 421
98  *     Magnetic Tape Transport Type 50
99  *     Programmed Magnetic Tape Control Type 51
100  *     Automatic Magnetic Tape Control Type 52
101  *     Automatic Magnetic Tape Control Type 510
102  *     Parallel Drum Type 23
103  *     Automatic Line Printer and Control Type 64
104  *     18-bit Real Time Clock
105  *     18-bit Output Relay Buffer Type 140
106  *     Multiplexed A-D Converter Type 138/139
107  *
108  * All in-out operations are performed through the In-Out Register or through the high speed input-output
109  * channels.
110  *
111  * The PDP-1 is also available with the optional Sequence Break System. This is a multi-channel priority
112  * interrupt feature which permits concurrent operation of several in-out devices. A one-channel Sequence
113  * Break System is included in the standard PDP-1. Optional Sequence Break Systems consist of 16, 32, 64,
114  * 128, and 256 channels.
115  *
116  * ...
117  *
118  * BASIC INSTRUCTIONS
119  *
120  *                                                                    OPER. TIME
121  * INSTRUCTION  CODE #  EXPLANATION                                     (usec)
122  * ------------------------------------------------------------------------------
123  * add Y        40      Add C(Y) to C(AC)                                 10
124  * and Y        02      Logical AND C(Y) with C(AC)                       10
125  * cal Y        16      Equals jda 100                                    10
126  * dac Y        24      Deposit C(AC) in Y                                10
127  * dap Y        26      Deposit contents of address part of AC in Y       10
128  * dio Y        32      Deposit C(IO) in Y                                10
129  * dip Y        30      Deposit contents of instruction part of AC in Y   10
130  * div Y        56      Divide                                          40 max
131  * dzm Y        34      Deposit zero in Y                                 10
132  * idx Y        44      Index (add one) C(Y), leave in Y & AC             10
133  * ior Y        04      Inclusive OR C(Y) with C(AC)                      10
134  * iot Y        72      In-out transfer, see below
135  * isp Y        46      Index and skip if result is positive              10
136  * jda Y        17      Equals dac Y and jsp Y+1                          10
137  * jmp Y        60      Take next instruction from Y                      5
138  * jsp Y        62      Jump to Y and save program counter in AC          5
139  * lac Y        20      Load the AC with C(Y)                             10
140  * law N        70      Load the AC with the number N                     5
141  * law-N        71      Load the AC with the number -N                    5
142  * lio Y        22      Load IO with C(Y)                                 10
143  * mul Y        54      Multiply                                        25 max
144  * opr          76      Operate, see below                                5
145  * sad Y        50      Skip next instruction if C(AC) <> C(Y)            10
146  * sas Y        52      Skip next instruction if C(AC) = C(Y)             10
147  * sft          66      Shift, see below                                  5
148  * skp          64      Skip, see below                                   5
149  * sub Y        42      Subtract C(Y) from C(AC)                          10
150  * xct Y        10      Execute instruction in Y                          5+
151  * xor Y        06      Exclusive OR C(Y) with C(AC)                      10
152  *
153  * OPERATE GROUP
154  *
155  *                                                                    OPER. TIME
156  * INSTRUCTION  CODE #   EXPLANATION                                    (usec)
157  * ------------------------------------------------------------------------------
158  * cla        760200     Clear AC                                         5
159  * clf        76000f     Clear selected Program Flag (f = flag #)         5
160  * cli        764000     Clear IO                                         5
161  * cma        761000     Complement AC                                    5
162  * hlt        760400     Halt                                             5
163  * lap        760100     Load AC with Program Counter                     5
164  * lat        762200     Load AC from Test Word switches                  5
165  * nop        760000     No operation                                     5
166  * stf        76001f     Set selected Program Flag                        5
167  *
168  * IN-OUT TRANSFER GROUP
169  *
170  * PERFORATED TAPE READER
171  *
172  * INSTRUCTION  CODE #   EXPLANATION
173  * ------------------------------------------------------------------------------
174  * rpa        720001     Read Perforated Tape Alphanumeric
175  * rpb        720002     Read Perforated Tape Binary
176  * rrb        720030     Read Reader Buffer
177  *
178  * PERFORATED TAPE PUNCH
179  *
180  * INSTRUCTION  CODE #   EXPLANATION
181  * ------------------------------------------------------------------------------
182  * ppa        720005     Punch Perforated Tape Alphanumeric
183  * ppb        720006     Punch Perforated Tape Binary
184  *
185  * ALPHANUMERIC ON-LINE TYPEWRITER
186  *
187  * INSTRUCTION  CODE #   EXPLANATION
188  * ------------------------------------------------------------------------------
189  * tyo        720003     Type Out
190  * tyi        720004     Type In
191  *
192  * SEQUENCE BREAK SYSTEM TYPE 120
193  *
194  * INSTRUCTION  CODE #   EXPLANATION
195  * ------------------------------------------------------------------------------
196  * esm        720055     Enter Sequence Break Mode
197  * lsm        720054     Leave Sequence Break Mode
198  * cbs        720056     Clear Sequence Break System
199  * dsc        72kn50     Deactivate Sequence Break Channel
200  * asc        72kn51     Activate Sequence Break Channel
201  * isb        72kn52     Initiate Sequence Break
202  * cac        720053     Clear All Channels
203  *
204  * HIGH SPEED DATA CONTROL TYPE 131
205  *
206  * INSTRUCTION  CODE #   EXPLANATION
207  * ------------------------------------------------------------------------------
208  * swc        72x046     Set Word Counter
209  * sia        720346     Set Location Counter
210  * sdf        720146     Stop Data Flow
211  * rlc        720366     Read Location Counter
212  * shr        720446     Set High Speed Channel Request
213  *
214  * PRECISION CRT DISPLAY TYPE 30
215  *
216  * INSTRUCTION  CODE #   EXPLANATION
217  * ------------------------------------------------------------------------------
218  * dpy        720007     Display One Point
219  *
220  * SYMBOL GENERATOR TYPE 33
221  *
222  * INSTRUCTION  CODE #   EXPLANATION
223  * ------------------------------------------------------------------------------
224  * gpl        722027     Generator Plot Left
225  * gpr        720027     Generator Plot Right
226  * glf        722026     Load Format
227  * gsp        720026     Space
228  * sdb        722007     Load Buffer, No Intensity
229  *
230  * ULTRA-PRECISION CRT DISPLAY TYPE 31
231  *
232  * INSTRUCTION  CODE #   EXPLANATION
233  * ------------------------------------------------------------------------------
234  * dpp        720407     Display One Point on Ultra Precision CRT
235  *
236  * CARD PUNCH CONTROL TYPE 40-1
237  *
238  * INSTRUCTION  CODE #   EXPLANATION
239  * ------------------------------------------------------------------------------
240  * lag        720044     Load a Group
241  * pac        720043     Punch a Card
242  *
243  * CARD READER TYPE 421
244  *
245  * INSTRUCTION  CODE #   EXPLANATION
246  * ------------------------------------------------------------------------------
247  * rac        720041     Read Card Alpha
248  * rbc        720042     Read Card Binary
249  * rcc        720032     Read Card Column
250  *
251  * PROGRAMMED MAGNETIC TAPE CONTROL TYPE 51
252  *
253  * INSTRUCTION  CODE #   EXPLANATION
254  * ------------------------------------------------------------------------------
255  * msm        720073     Select Mode
256  * mcs        720034     Check Status
257  * mcb        720070     Clear Buffer
258  * mwc        720071     Write a Character
259  * mrc        720072     Read Character
260  *
261  * AUTOMATIC MAGNETIC TAPE CONTROL TYPE 52
262  *
263  * INSTRUCTION  CODE #   EXPLANATION
264  * ------------------------------------------------------------------------------
265  * muf        72ue76     Tape Unit and FinalT
266  * mic        72ue75     Initial and Command
267  * mrf        72u067     Reset Final
268  * mri        72ug66     Reset Initial
269  * mes        72u035     Examine States
270  * mel        72u036     Examine Location
271  * inr        72ur67     Initiate a High Speed Channel Request
272  * ccr        72s067     Clear Command Register
273  *
274  * AUTOMATIC MAGNETIC TAPE CONTROL TYPE 510
275  *
276  * INSTRUCTION  CODE #   EXPLANATION
277  * ------------------------------------------------------------------------------
278  * sfc        720072     Skip if Tape Control Free
279  * rsr        720172     Read State Register
280  * crf        720272     Clear End-of-Record Flip-Flop
281  * cpm        720472     Clear Proceed Mode
282  * dur        72xx70     Load Density, Unit, Rewind
283  * mtf        73xx71     Load Tape Function Register
284  * cgo        720073     Clear Go
285  *
286  * MULTIPLEXED A-D CONVERTER TYPE 138/139
287  *
288  * INSTRUCTION  CODE #   EXPLANATION
289  * ------------------------------------------------------------------------------
290  * rcb        720031     Read Converter Buffer
291  * cad        720040     Convert a Voltage
292  * scv        72mm47     Select Multiplexer (1 of 64 Channels)
293  * icv        720060     Index Multiplexer
294  *
295  * AUTOMATIC LINE PRINTER TYPE 64
296  *
297  * INSTRUCTION  CODE #   EXPLANATION
298  * ------------------------------------------------------------------------------
299  * clrbuf     722045     Clear Buffer
300  * lpb        720045     Load Printer Buffer
301  * pas        721x45     Print and Space
302  *
303  * SKIP GROUP
304  *
305  *                                                                    OPER. TIME
306  * INSTRUCTION  CODE #   EXPLANATION                                    (usec)
307  * ------------------------------------------------------------------------------
308  * sma        640400     Dkip on minus AC                                 5
309  * spa        640200     Skip on plus AC                                  5
310  * spi        642000     Skip on plus IO                                  5
311  * sza        640100     Skip on ZERO (+0) AC                             5
312  * szf        6400f      Skip on ZERO flag                                5
313  * szo        641000     Skip on ZERO overflow (and clear overflow)       5
314  * szs        6400s0     Skip on ZERO sense switch                        5
315  *
316  * SHIFT/ROTATE GROUP
317  *
318  *                                                                      OPER. TIME
319  * INSTRUCTION  CODE #   EXPLANATION                                      (usec)
320  * ------------------------------------------------------------------------------
321  *   ral        661      Rotate AC left                                     5
322  *   rar        671      Rotate AC right                                    5
323  *   rcl        663      Rotate Combined AC & IO left                       5
324  *   rcr        673      Rotate Combined AC & IO right                      5
325  *   ril        662      Rotate IO left                                     5
326  *   rir        672      Rotate IO right                                    5
327  *   sal        665      Shift AC left                                      5
328  *   sar        675      Shift AC right                                     5
329  *   scl        667      Shift Combined AC & IO left                        5
330  *   scr        677      Shift Combined AC & IO right                       5
331  *   sil        666      Shift IO left                                      5
332  *   sir        676      Shift IO right                                     5
333  */
334 
335 
336 /*
337     TODO:
338     * support other extensions as time permits
339 */
340 
341 
342 #include "emu.h"
343 #include "debugger.h"
344 #include "pdp1.h"
345 #include "pdp1dasm.h"
346 
347 #define LOG 0
348 #define LOG_EXTRA 0
349 #define LOG_IOT_EXTRA 0
350 
351 #define READ_PDP_18BIT(A) ((signed)m_program->read_dword(A))
352 #define WRITE_PDP_18BIT(A,V) (m_program->write_dword((A),(V)))
353 
354 
355 #define PC      m_pc
356 #define IR      m_ir
357 #define MB      m_mb
358 #define MA      m_ma
359 #define AC      m_ac
360 #define IO      m_io
361 #define OV      m_ov
362 #define EXD     m_exd
363 /* note that we start counting flags/sense switches at 1, therefore n is in [1,6] */
364 #define FLAGS   m_pf
365 #define READFLAG(n) ((m_pf >> (6-(n))) & 1)
366 #define WRITEFLAG(n, data)  (m_pf = (m_pf & ~(1 << (6-(n)))) | (((data) & 1) << (6-(n))))
367 #define SENSE_SW    m_ss
368 #define READSENSE(n)    ((m_ss >> (6-(n))) & 1)
369 #define WRITESENSE(n, data) (m_ss = (m_ss & ~(1 << (6-(n)))) | (((data) & 1) << (6-(n))))
370 
371 #define EXTENDED_ADDRESS_MASK   m_extended_address_mask
372 #define ADDRESS_EXTENSION_MASK  m_address_extension_mask
373 #define BASE_ADDRESS_MASK       0007777
374 
375 #define INCREMENT_PC    (PC = (PC & ADDRESS_EXTENSION_MASK) | ((PC+1) & BASE_ADDRESS_MASK))
376 #define DECREMENT_PC    (PC = (PC & ADDRESS_EXTENSION_MASK) | ((PC-1) & BASE_ADDRESS_MASK))
377 #define INCREMENT_MA    (MA = (MA & ADDRESS_EXTENSION_MASK) | ((MA+1) & BASE_ADDRESS_MASK))
378 #define PREVIOUS_PC     ((PC & ADDRESS_EXTENSION_MASK) | ((PC-1) & BASE_ADDRESS_MASK))
379 
380 
381 DEFINE_DEVICE_TYPE(PDP1, pdp1_device, "pdp1_cpu", "DEC PDP-1 Central Processor")
382 
383 
pdp1_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)384 pdp1_device::pdp1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
385 	: cpu_device(mconfig, PDP1, tag, owner, clock)
386 	, m_program_config("program", ENDIANNESS_BIG, 32, 18, -2) // data is actually 18 bits wide
387 	, m_extern_iot(*this)
388 	, m_io_sc_callback(*this)
389 	, m_program(nullptr)
390 	, m_reset_param(nullptr)
391 {
392 	m_program_config.m_is_octal = true;
393 }
394 
memory_space_config() const395 device_memory_interface::space_config_vector pdp1_device::memory_space_config() const
396 {
397 	return space_config_vector {
398 		std::make_pair(AS_PROGRAM, &m_program_config)
399 	};
400 }
401 
device_config_complete()402 void pdp1_device::device_config_complete()
403 {
404 	// inherit a copy of the static data
405 	const pdp1_reset_param_t *intf = m_reset_param;
406 	if (intf != nullptr)
407 		*static_cast<pdp1_reset_param_t *>(this) = *intf;
408 
409 	// or initialize to defaults if none provided
410 	else
411 	{
412 		extend_support = 0;
413 		hw_mul_div = 0;
414 		type_20_sbs = 0;
415 	}
416 }
417 
418 
create_disassembler()419 std::unique_ptr<util::disasm_interface> pdp1_device::create_disassembler()
420 {
421 	return std::make_unique<pdp1_disassembler>();
422 }
423 
424 
425 /*
426     Interrupts are called "sequence break" in pdp1, but the general idea is the same.
427 
428     There are several interrupt lines.  With the standard sequence break system, all lines
429     are logically or'ed to trigger a single interrupt level.  Interrupts can be triggered
430     by either a pulse or a level on the interrupt lines.  With the optional type 120 sequence
431     break system, each of 16 lines triggers is wired to a different priority level: additionally,
432     each interrupt line can be masked out, and interrupt can be triggered through software.
433 
434     Also, instructions can be interrupted in the middle of execution.  This is done by
435     decrementing the PC register: therefore the instruction is re-executed from start.
436 
437     Interrupt routines should not execute most IOT, as the interrupt may interrupt another.
438 
439     More details can be found in the handbook and the maintenance manual.
440 */
441 /*
442     This function MUST be called every time m_sbm, m_b4, m_irq_state or m_b2 change.
443 */
field_interrupt()444 void pdp1_device::field_interrupt()
445 {
446 	/* current_irq: 1 bit for each active pending interrupt request
447 	Pending interrupts are in b3 (simulated by (m_irq_state & m_b1) | m_b2)), but they
448 	are only honored if no higher priority interrupt routine is in execution (one bit set in b4
449 	for each routine in execution).  The relevant mask is created with (m_b4 | (- m_b4)),
450 	as the carry chain (remember that -b4 = (~ b4) + 1) does precisely what we want.
451 	b4:    0001001001000
452 	-b4:   1110110111000
453 	b4|-b4:1111111111000
454 	Neat, uh?
455 	 */
456 	int current_irq = ((m_irq_state & m_b1) | m_b2) & ~ (m_b4 | (- m_b4));
457 	int i;
458 
459 	if (m_sbm && current_irq)
460 	{
461 		m_sbs_request = 1;
462 		for (i=0; /*i<16 &&*/ (! ((current_irq >> i) & 1)); i++)
463 			;
464 		m_sbs_level = i;
465 	}
466 	else
467 		m_sbs_request = 0;
468 }
469 
execute_set_input(int irqline,int state)470 void pdp1_device::execute_set_input(int irqline, int state)
471 {
472 	if (irqline == INPUT_LINE_NMI)
473 	{
474 		/* no specific NMI line */
475 	}
476 	else if ((irqline >= 0) && (irqline < (m_type_20_sbs ? 1 : 16)))
477 	{
478 		unsigned int new_state = state ? 1 : 0;
479 
480 		if (((m_irq_state >> irqline) & 1) != new_state)
481 		{
482 			m_irq_state = (m_irq_state & ~ (1 << irqline)) | (new_state << irqline);
483 
484 			if ((new_state) && ((m_b1 >> irqline) & 1))
485 				m_b2 |= (new_state << irqline);
486 
487 			/*m_b3 = m_irq_state | m_b2;*/
488 
489 			field_interrupt();  /* interrupt state has changed */
490 		}
491 	}
492 }
493 
494 
device_start()495 void pdp1_device::device_start()
496 {
497 	int i;
498 
499 	/* clean-up */
500 	m_pc = 0;
501 	m_ir = 0;
502 	m_mb = 0;
503 	m_ma = 0;
504 	m_ac = 0;
505 	m_io = 0;
506 	m_pf = 0;
507 	m_ta = 0;
508 	m_tw = 0;
509 	m_ss = 0;
510 	m_sngl_step = 0;
511 	m_sngl_inst = 0;
512 	m_extend_sw = 0;
513 	m_run = 0;
514 	m_cycle = 0;
515 	m_defer = 0;
516 	m_brk_ctr = 0;
517 	m_ov = 0;
518 	m_rim = 0;
519 	m_sbm = 0;
520 	m_exd = 0;
521 	m_exc = 0;
522 	m_ioc = 0;
523 	m_ioh = 0;
524 	m_ios = 0;
525 	m_irq_state = 0;
526 	m_b1 = 0;
527 	m_b2 = 0;
528 	m_b4 = 0;
529 	m_rim_step = 0;
530 	m_sbs_request = 0;
531 	m_sbs_level = 0;
532 	m_sbs_restore = 0;
533 	m_no_sequence_break = 0;
534 	m_debugger_temp = 0;
535 
536 	m_program = &space(AS_PROGRAM);
537 
538 	/* set up params and callbacks */
539 	for (i=0; i<64; i++)
540 	{
541 		m_extern_iot[i].resolve();
542 		if (m_extern_iot[i].isnull())
543 			m_extern_iot[i] = iot_delegate(*this, FUNC(pdp1_device::null_iot));
544 	}
545 	m_io_sc_callback.resolve();
546 	m_extend_support = extend_support;
547 	m_hw_mul_div = hw_mul_div;
548 	m_type_20_sbs = type_20_sbs;
549 
550 	switch (m_extend_support)
551 	{
552 	default:
553 		m_extend_support = 0;
554 	case 0:     /* no extension */
555 		m_extended_address_mask = 07777;
556 		m_address_extension_mask = 00000;
557 		break;
558 	case 1:     /* 15-bit extension */
559 		m_extended_address_mask = 077777;
560 		m_address_extension_mask = 070000;
561 		break;
562 	case 2:     /* 16-bit extension */
563 		m_extended_address_mask = 0177777;
564 		m_address_extension_mask = 0170000;
565 		break;
566 	}
567 
568 	if (m_extend_support)
569 	{
570 		m_extern_iot[074] = iot_delegate(*this, FUNC(pdp1_device::lem_eem_iot));
571 	}
572 	m_extern_iot[054] = m_extern_iot[055] = m_extern_iot[056] = iot_delegate(*this, FUNC(pdp1_device::sbs_iot));
573 	if (m_type_20_sbs)
574 	{
575 		m_extern_iot[050] = m_extern_iot[051] = m_extern_iot[052] = m_extern_iot[053]
576 				= iot_delegate(*this, FUNC(pdp1_device::type_20_sbs_iot));
577 	}
578 
579 	state_add( PDP1_PC,        "PC", m_pc).formatstr("%06O");
580 	state_add( PDP1_IR,        "IR", m_ir).formatstr("%02O");
581 	state_add( PDP1_MB,        "MB", m_mb).formatstr("%06O");
582 	state_add( PDP1_MA,        "MA", m_ma).formatstr("%06O");
583 	state_add( PDP1_AC,        "AC", m_ac).formatstr("%06O");
584 	state_add( PDP1_IO,        "IO", m_io).formatstr("%06O");
585 	state_add( PDP1_OV,        "OV", m_ov).formatstr("%1X");
586 	state_add( PDP1_PF,        "FLAGS", m_pf).formatstr("%02O");
587 	state_add( PDP1_PF1,       "FLAG1", m_debugger_temp).callimport().callexport().formatstr("%1X");
588 	state_add( PDP1_PF2,       "FLAG2", m_debugger_temp).callimport().callexport().formatstr("%1X");
589 	state_add( PDP1_PF3,       "FLAG3", m_debugger_temp).callimport().callexport().formatstr("%1X");
590 	state_add( PDP1_PF4,       "FLAG4", m_debugger_temp).callimport().callexport().formatstr("%1X");
591 	state_add( PDP1_PF5,       "FLAG5", m_debugger_temp).callimport().callexport().formatstr("%1X");
592 	state_add( PDP1_PF6,       "FLAG6", m_debugger_temp).callimport().callexport().formatstr("%1X");
593 	state_add( PDP1_TA,        "TA", m_ta).formatstr("%06O");
594 	state_add( PDP1_TW,        "TW", m_tw).formatstr("%06O");
595 	state_add( PDP1_SS,        "SS", m_ss).formatstr("%02O");
596 	state_add( PDP1_SS1,       "SENSE1", m_debugger_temp).callimport().callexport().formatstr("%1X");
597 	state_add( PDP1_SS2,       "SENSE2", m_debugger_temp).callimport().callexport().formatstr("%1X");
598 	state_add( PDP1_SS3,       "SENSE3", m_debugger_temp).callimport().callexport().formatstr("%1X");
599 	state_add( PDP1_SS4,       "SENSE4", m_debugger_temp).callimport().callexport().formatstr("%1X");
600 	state_add( PDP1_SS5,       "SENSE5", m_debugger_temp).callimport().callexport().formatstr("%1X");
601 	state_add( PDP1_SS6,       "SENSE6", m_debugger_temp).callimport().callexport().formatstr("%1X");
602 	state_add( PDP1_SNGL_STEP, "SNGLSTEP", m_sngl_step).mask(1).formatstr("%1X");
603 	state_add( PDP1_SNGL_INST, "SNGLINST", m_sngl_inst).mask(1).formatstr("%1X");
604 	state_add( PDP1_EXTEND_SW, "EXS", m_extend_sw).mask(1).formatstr("%1X");
605 	state_add( PDP1_RUN,       "RUN", m_run).mask(1).formatstr("%1X");
606 	state_add( PDP1_CYC,       "CYC", m_cycle).mask(1).formatstr("%1X");
607 	state_add( PDP1_DEFER,     "DF", m_defer).mask(1).formatstr("%1X");
608 	state_add( PDP1_BRK_CTR,   "BRKCTR", m_brk_ctr).mask(3).formatstr("%1X");
609 	state_add( PDP1_RIM,       "RIM", m_rim).mask(1).formatstr("%1X");
610 	state_add( PDP1_SBM,       "SBM", m_sbm).mask(1).formatstr("%1X");
611 	state_add( PDP1_EXD,       "EXD", m_exd).mask(1).formatstr("%1X");
612 	state_add( PDP1_IOC,       "IOC", m_ioc).mask(1).formatstr("%1X");
613 	state_add( PDP1_IOH,       "IOH", m_ioh).mask(1).formatstr("%1X");
614 	state_add( PDP1_IOS,       "IOS", m_ios).mask(1).formatstr("%1X");
615 
616 	state_add( STATE_GENPC, "GENPC", m_pc ).noshow();
617 	state_add( STATE_GENPCBASE, "CURPC", m_pc ).noshow();
618 	state_add( STATE_GENFLAGS, "GENFLAGS", m_pf ).formatstr("%13s").noshow();
619 
620 	set_icountptr(m_icount);
621 
622 	/* reset CPU flip-flops */
623 	pulse_start_clear();
624 }
625 
626 
state_import(const device_state_entry & entry)627 void pdp1_device::state_import(const device_state_entry &entry)
628 {
629 	switch (entry.index())
630 	{
631 		case PDP1_PF1:
632 			WRITEFLAG(1, m_debugger_temp ? 1 : 0);
633 			break;
634 		case PDP1_PF2:
635 			WRITEFLAG(2, m_debugger_temp ? 1 : 0);
636 			break;
637 		case PDP1_PF3:
638 			WRITEFLAG(3, m_debugger_temp ? 1 : 0);
639 			break;
640 		case PDP1_PF4:
641 			WRITEFLAG(4, m_debugger_temp ? 1 : 0);
642 			break;
643 		case PDP1_PF5:
644 			WRITEFLAG(5, m_debugger_temp ? 1 : 0);
645 			break;
646 		case PDP1_PF6:
647 			WRITEFLAG(6, m_debugger_temp ? 1 : 0);
648 			break;
649 		case PDP1_SS1:
650 			WRITESENSE(1, m_debugger_temp ? 1 : 0);
651 			break;
652 		case PDP1_SS2:
653 			WRITESENSE(2, m_debugger_temp ? 1 : 0);
654 			break;
655 		case PDP1_SS3:
656 			WRITESENSE(3, m_debugger_temp ? 1 : 0);
657 			break;
658 		case PDP1_SS4:
659 			WRITESENSE(4, m_debugger_temp ? 1 : 0);
660 			break;
661 		case PDP1_SS5:
662 			WRITESENSE(5, m_debugger_temp ? 1 : 0);
663 			break;
664 		case PDP1_SS6:
665 			WRITESENSE(6, m_debugger_temp ? 1 : 0);
666 			break;
667 	}
668 }
669 
670 
state_export(const device_state_entry & entry)671 void pdp1_device::state_export(const device_state_entry &entry)
672 {
673 	switch (entry.index())
674 	{
675 		case PDP1_PF1:
676 			m_debugger_temp = READFLAG(1);
677 			break;
678 		case PDP1_PF2:
679 			m_debugger_temp = READFLAG(2);
680 			break;
681 		case PDP1_PF3:
682 			m_debugger_temp = READFLAG(3);
683 			break;
684 		case PDP1_PF4:
685 			m_debugger_temp = READFLAG(4);
686 			break;
687 		case PDP1_PF5:
688 			m_debugger_temp = READFLAG(5);
689 			break;
690 		case PDP1_PF6:
691 			m_debugger_temp = READFLAG(6);
692 			break;
693 		case PDP1_SS1:
694 			m_debugger_temp = READSENSE(1);
695 			break;
696 		case PDP1_SS2:
697 			m_debugger_temp = READSENSE(2);
698 			break;
699 		case PDP1_SS3:
700 			m_debugger_temp = READSENSE(3);
701 			break;
702 		case PDP1_SS4:
703 			m_debugger_temp = READSENSE(4);
704 			break;
705 		case PDP1_SS5:
706 			m_debugger_temp = READSENSE(5);
707 			break;
708 		case PDP1_SS6:
709 			m_debugger_temp = READSENSE(6);
710 			break;
711 	}
712 }
713 
714 
state_string_export(const device_state_entry & entry,std::string & str) const715 void pdp1_device::state_string_export(const device_state_entry &entry, std::string &str) const
716 {
717 	switch (entry.index())
718 	{
719 		case STATE_GENFLAGS:
720 			str = string_format("%c%c%c%c%c%c-%c%c%c%c%c%c",
721 					(FLAGS & 040) ? '1' : '.',
722 					(FLAGS & 020) ? '2' : '.',
723 					(FLAGS & 010) ? '3' : '.',
724 					(FLAGS & 004) ? '4' : '.',
725 					(FLAGS & 002) ? '5' : '.',
726 					(FLAGS & 001) ? '6' : '.',
727 					(SENSE_SW & 040) ? '1' : '.',
728 					(SENSE_SW & 020) ? '2' : '.',
729 					(SENSE_SW & 010) ? '3' : '.',
730 					(SENSE_SW & 004) ? '4' : '.',
731 					(SENSE_SW & 002) ? '5' : '.',
732 					(SENSE_SW & 001) ? '6' : '.');
733 			break;
734 	}
735 }
736 
737 
device_reset()738 void pdp1_device::device_reset()
739 {
740 	// Nothing to do??
741 }
742 
743 /*
744     flags:
745     * 1 for each instruction which supports indirect addressing (memory reference instructions,
746       except cal and jda, and with the addition of jmp and jsp)
747     * 2 for memory reference instructions
748 */
749 static const uint8_t instruction_kind[32] =
750 {
751 /*      and ior xor xct         cal/jda */
752 	0,  3,  3,  3,  3,  0,  0,  2,
753 /*  lac lio dac dap dip dio dzm     */
754 	3,  3,  3,  3,  3,  3,  3,  0,
755 /*  add sub idx isp sad sas mus dis */
756 	3,  3,  3,  3,  3,  3,  3,  3,
757 /*  jmp jsp skp sft law iot     opr */
758 	1,  1,  0,  0,  0,  0,  0,  0
759 };
760 
761 
762 /* execute instructions on this CPU until icount expires */
execute_run()763 void pdp1_device::execute_run()
764 {
765 	do
766 	{
767 		/* ioh should be cleared at the end of the instruction cycle, and ios at the
768 		start of next instruction cycle, but who cares? */
769 		if (m_ioh && m_ios)
770 		{
771 			m_ioh = 0;
772 		}
773 
774 
775 		if ((! m_run) && (! m_rim))
776 		{
777 			debugger_instruction_hook(PC);
778 			m_icount = 0;   /* if processor is stopped, just burn cycles */
779 		}
780 		else if (m_rim)
781 		{
782 			switch (m_rim_step)
783 			{
784 			case 0:
785 				/* read first word as instruction */
786 				MB = 0;
787 				/* data will be transferred to IO register in response to RPB */
788 				m_extern_iot[2](2, 1, MB, IO, AC);
789 				m_rim_step = 1;
790 				m_ios = 0;
791 				break;
792 
793 			case 1:
794 				if (! m_ios)
795 				{   /* transfer incomplete: wait some more */
796 					m_icount = 0;
797 				}
798 				else
799 				{   /* data transfer complete */
800 					m_ios = 0;
801 
802 					MB = IO;
803 					IR = MB >> 13;      /* basic opcode */
804 					if (IR == JMP)      /* jmp instruction ? */
805 					{
806 						PC = (MA & ADDRESS_EXTENSION_MASK) | (MB & BASE_ADDRESS_MASK);
807 						m_rim = 0;  /* exit read-in mode */
808 						m_run = 1;
809 						m_rim_step = 0;
810 					}
811 					else if ((IR == DIO) || (IR == DAC))    /* dio or dac instruction ? */
812 					{   /* there is a discrepancy: the pdp1 handbook tells that only dio should be used,
813 					    but the lisp tape uses the dac instruction instead */
814 						/* Yet maintenance manual p. 6-25 states clearly that the data is located
815 						in IO and transferred to MB, so DAC is likely to be a mistake. */
816 						m_rim_step = 2;
817 					}
818 					else
819 					{
820 						/* what the heck? */
821 						if (LOG)
822 							logerror("It seems this tape should not be operated in read-in mode\n");
823 
824 						m_rim = 0;      /* exit read-in mode (right???) */
825 						m_rim_step = 0;
826 					}
827 				}
828 				break;
829 
830 			case 2:
831 				/* read second word as data */
832 				/* data will be transferred to IO register in response to RPB */
833 				m_extern_iot[2](2, 1, MB, IO, AC);
834 				m_rim_step = 3;
835 				m_ios = 0;
836 				break;
837 
838 			case 3:
839 				if (! m_ios)
840 				{   /* transfer incomplete: wait some more */
841 					m_icount = 0;
842 				}
843 				else
844 				{   /* data transfer complete */
845 					m_ios = 0;
846 
847 					MA = (PC & ADDRESS_EXTENSION_MASK) | (MB & BASE_ADDRESS_MASK);
848 
849 					MB = IO;
850 					WRITE_PDP_18BIT(MA, MB);
851 
852 					m_rim_step = 0;
853 				}
854 				break;
855 			}
856 		}
857 		else
858 		{
859 			/* yes, interrupt can occur in the midst of an instruction (impressing, huh?) */
860 			/* Note that break cannot occur during a one-cycle jump that is deferred only once,
861 			or another break cycle.  Also, it cannot interrupt the long cycle 1 of automatic
862 			multiply/divide.  (maintenance manual 6-19) */
863 			if (m_sbs_request && (! m_no_sequence_break) && (! m_brk_ctr))
864 			{   /* begin sequence break */
865 				m_brk_ctr = 1;
866 			}
867 			if (m_brk_ctr)
868 			{   /* sequence break in progress */
869 				switch (m_brk_ctr)
870 				{
871 				case 1:
872 					if (m_cycle)
873 						DECREMENT_PC;   /* set PC to point to aborted instruction, so that it can be re-run */
874 
875 					m_b4 |= (1 << m_sbs_level); /* set "interrupt in progress" flag */
876 					m_b2 &= ~(1 << m_sbs_level);    /* clear interrupt request */
877 					field_interrupt();
878 					MA = m_sbs_level << 2;  /* always 0 with standard sequence break system */
879 					MB = AC;            /* save AC to MB */
880 					AC = (OV << 17) | (EXD << 16) | PC; /* save OV/EXD/PC to AC */
881 					EXD = OV = 0;       /* according to maintenance manual p. 8-17 and ?-?? */
882 					m_cycle = m_defer = m_exc = 0;  /* mere guess */
883 					WRITE_PDP_18BIT(MA, MB);    /* save former AC to memory */
884 					INCREMENT_MA;
885 					m_icount -= 5;
886 					m_brk_ctr++;
887 					break;
888 
889 				case 2:
890 					WRITE_PDP_18BIT(MA, MB = AC);   /* save former OV/EXD/PC to memory */
891 					INCREMENT_MA;
892 					m_icount -= 5;
893 					m_brk_ctr++;
894 					break;
895 
896 				case 3:
897 					WRITE_PDP_18BIT(MA, MB = IO);   /* save IO to memory */
898 					INCREMENT_MA;
899 					PC = MA;
900 					m_icount -= 5;
901 					m_brk_ctr = 0;
902 					break;
903 				}
904 			}
905 			else
906 			{
907 				if (m_no_sequence_break)
908 					m_no_sequence_break = 0;
909 
910 				if (! m_cycle)
911 				{   /* no instruction in progress: time to fetch a new instruction, I guess */
912 					debugger_instruction_hook(PC);
913 					MB = READ_PDP_18BIT(MA = PC);
914 					INCREMENT_PC;
915 					IR = MB >> 13;      /* basic opcode */
916 
917 					if ((instruction_kind[IR] & 1) && (MB & 010000))
918 					{
919 						m_defer = 1;
920 						m_cycle = 1;            /* instruction shall be executed later */
921 
922 						/* detect deferred one-cycle jumps */
923 						if ((IR == JMP) || (IR == JSP))
924 						{
925 							m_no_sequence_break = 1;
926 							/* detect JMP *(4*n+1) to memory module 0 if in sequence break mode */
927 							if (((MB & 0777703) == 0610001) && (m_sbm) && ! (MA & 0170000))
928 							{
929 								int level = (MB & 0000074) >> 2;
930 
931 								if ((m_type_20_sbs) || (level == 0))
932 								{
933 									m_b4 &= ~(1 << level);
934 									field_interrupt();
935 									if (m_extend_support)
936 										EXD = 1;    /* according to maintenance manual p. 6-33 */
937 									m_sbs_restore = 1;
938 								}
939 							}
940 						}
941 					}
942 					else if (instruction_kind[IR] & 2)
943 						m_cycle = 1;            /* instruction shall be executed later */
944 					else
945 						execute_instruction();  /* execute instruction at once */
946 
947 					m_icount -= 5;
948 				}
949 				else if (m_defer)
950 				{   /* defer cycle : handle indirect addressing */
951 					MA = (PC & ADDRESS_EXTENSION_MASK) | (MB & BASE_ADDRESS_MASK);
952 
953 					MB = READ_PDP_18BIT(MA);
954 
955 					/* determinate new value of m_defer */
956 					if (EXD)
957 					{
958 						m_defer = 0;
959 						m_exc = 1;
960 					}
961 					else
962 						m_defer = (MB & 010000) ? 1 : 0;
963 
964 					/* execute JMP and JSP immediately if applicable */
965 					if ((! m_defer) && (! (instruction_kind[IR] & 2)))
966 					{
967 						execute_instruction();  /* execute instruction at once */
968 						/*m_cycle = 0;*/
969 						m_exc = 0;
970 
971 						if (m_sbs_restore)
972 						{   /* interrupt return: according to maintenance manual p. 6-33 */
973 							if (m_extend_support)
974 								EXD = (MB >> 16) & 1;
975 							OV = (MB >> 17) & 1;
976 							m_sbs_restore = 0;
977 						}
978 					}
979 
980 					m_icount -= 5;
981 				}
982 				else
983 				{   /* memory reference instruction in cycle 1 */
984 					if (m_exc)
985 					{
986 						MA = MB & EXTENDED_ADDRESS_MASK;
987 						m_exc = 0;
988 					}
989 					else
990 						MA = (PC & ADDRESS_EXTENSION_MASK) | (MB & BASE_ADDRESS_MASK);
991 
992 					execute_instruction();  /* execute instruction */
993 
994 					m_icount -= 5;
995 				}
996 
997 				if ((m_sngl_inst) && (! m_cycle))
998 					m_run = 0;
999 			}
1000 			if (m_sngl_step)
1001 				m_run = 0;
1002 		}
1003 	}
1004 	while (m_icount > 0);
1005 }
1006 
1007 
1008 /* execute one instruction */
execute_instruction()1009 void pdp1_device::execute_instruction()
1010 {
1011 	switch (IR)
1012 	{
1013 	case AND:       /* Logical And */
1014 		AC &= (MB = READ_PDP_18BIT(MA));
1015 		break;
1016 	case IOR:       /* Inclusive Or */
1017 		AC |= (MB = READ_PDP_18BIT(MA));
1018 		break;
1019 	case XOR:       /* Exclusive Or */
1020 		AC ^= (MB = READ_PDP_18BIT(MA));
1021 		break;
1022 	case XCT:       /* Execute */
1023 		MB = READ_PDP_18BIT(MA);
1024 		IR = MB >> 13;      /* basic opcode */
1025 		if ((instruction_kind[IR] & 1) && (MB & 010000))
1026 		{
1027 			m_defer = 1;
1028 			/*m_cycle = 1;*/            /* instruction shall be executed later */
1029 			goto no_fetch;          /* fall through to next instruction */
1030 		}
1031 		else if (instruction_kind[IR] & 2)
1032 		{
1033 			/*m_cycle = 1;*/            /* instruction shall be executed later */
1034 			goto no_fetch;          /* fall through to next instruction */
1035 		}
1036 		else
1037 			execute_instruction();  /* execute instruction at once */
1038 		break;
1039 	case CALJDA:    /* Call subroutine and Jump and Deposit Accumulator instructions */
1040 		if (MB & 010000)
1041 			/* JDA */
1042 			MA = (PC & ADDRESS_EXTENSION_MASK) | (MB & BASE_ADDRESS_MASK);
1043 		else
1044 			/* CAL: equivalent to JDA 100 */
1045 			/* Note that I cannot tell for sure what happens to extension bits, but I did notice
1046 			that setting the extension bits to 0 would make cal basically useless, since
1047 			there would be no simple way the call routine could return to the callee
1048 			if it were located in another module with extend mode off (i.e. exd == 0). */
1049 			MA = (PC & ADDRESS_EXTENSION_MASK) | 0100;
1050 
1051 		WRITE_PDP_18BIT(MA, (MB = AC));
1052 		INCREMENT_MA;
1053 		AC = (OV << 17) | (EXD << 16) | PC;
1054 		PC = MA;
1055 		break;
1056 	case LAC:       /* Load Accumulator */
1057 		AC = (MB = READ_PDP_18BIT(MA));
1058 		break;
1059 	case LIO:       /* Load i/o register */
1060 		IO = (MB = READ_PDP_18BIT(MA));
1061 		break;
1062 	case DAC:       /* Deposit Accumulator */
1063 		WRITE_PDP_18BIT(MA, (MB = AC));
1064 		break;
1065 	case DAP:       /* Deposit Address Part */
1066 		WRITE_PDP_18BIT(MA, (MB = ((READ_PDP_18BIT(MA) & 0770000) | (AC & 0007777))));
1067 		break;
1068 	case DIP:       /* Deposit Instruction Part */
1069 		WRITE_PDP_18BIT(MA, (MB = ((READ_PDP_18BIT(MA) & 0007777) | (AC & 0770000))));
1070 		break;
1071 	case DIO:       /* Deposit I/O Register */
1072 		WRITE_PDP_18BIT(MA, (MB = IO));
1073 		break;
1074 	case DZM:       /* Deposit Zero in Memory */
1075 		WRITE_PDP_18BIT(MA, (MB = 0));
1076 		break;
1077 	case ADD:       /* Add */
1078 		{
1079 			/* overflow is set if the 2 operands have the same sign and the final result has another */
1080 			int ov2;    /* 1 if the operands have the same sign*/
1081 
1082 			MB = READ_PDP_18BIT(MA);
1083 
1084 			ov2 = ((AC & 0400000) == (MB & 0400000));
1085 
1086 			AC = AC + MB;
1087 			AC = (AC + (AC >> 18)) & 0777777;   /* propagate carry around */
1088 
1089 			/* I think we need to check for overflow before checking for -0,
1090 			because the sum -0+-0 = -0 = +0 would generate an overflow
1091 			otherwise. */
1092 			if (ov2 && ((AC & 0400000) != (MB & 0400000)))
1093 				OV = 1;
1094 
1095 			if (AC == 0777777)      /* check for -0 */
1096 				AC = 0;
1097 
1098 			break;
1099 		}
1100 	case SUB:       /* Subtract */
1101 		{   /* maintenance manual 7-14 seems to imply that substract does not test for -0.
1102 		      The sim 2.3 source says so explicitely, though they do not give a reference.
1103 		      It sounds a bit weird, but the reason is probably that doing so would
1104 		      require additional logic that does not exist. */
1105 			/* overflow is set if the 2 operands have the same sign and the final result has another */
1106 			int ov2;    /* 1 if the operands have the same sign*/
1107 
1108 			AC ^= 0777777;
1109 
1110 			MB = READ_PDP_18BIT(MA);
1111 
1112 			ov2 = ((AC & 0400000) == (MB & 0400000));
1113 
1114 			AC = AC + MB;
1115 			AC = (AC + (AC >> 18)) & 0777777;   /* propagate carry around */
1116 
1117 			if (ov2 && ((AC & 0400000) != (MB & 0400000)))
1118 				OV = 1;
1119 
1120 			AC ^= 0777777;
1121 
1122 			break;
1123 		}
1124 	case IDX:       /* Index */
1125 		AC = READ_PDP_18BIT(MA) + 1;
1126 
1127 		#if 0
1128 			AC = (AC + (AC >> 18)) & 0777777;   /* propagate carry around */
1129 			if (AC == 0777777)      /* check for -0 */
1130 				AC = 0;
1131 		#else
1132 			if (AC >= 0777777)
1133 				AC = (AC + 1) & 0777777;
1134 		#endif
1135 
1136 		WRITE_PDP_18BIT(MA, (MB = AC));
1137 		break;
1138 	case ISP:       /* Index and Skip if Positive */
1139 		AC = READ_PDP_18BIT(MA) + 1;
1140 
1141 		#if 0
1142 			AC = (AC + (AC >> 18)) & 0777777;   /* propagate carry around */
1143 			if (AC == 0777777)      /* check for -0 */
1144 				AC = 0;
1145 		#else
1146 			if (AC >= 0777777)
1147 				AC = (AC + 1) & 0777777;
1148 		#endif
1149 
1150 		WRITE_PDP_18BIT(MA, (MB = AC));
1151 		if ((AC & 0400000) == 0)
1152 			INCREMENT_PC;
1153 		break;
1154 	case SAD:       /* Skip if Accumulator and Y differ */
1155 		if (AC != (MB = READ_PDP_18BIT(MA)))
1156 			INCREMENT_PC;
1157 		break;
1158 	case SAS:       /* Skip if Accumulator and Y are the same */
1159 		if (AC == (MB = READ_PDP_18BIT(MA)))
1160 			INCREMENT_PC;
1161 		break;
1162 	case MUS_MUL:   /* Multiply Step or Multiply */
1163 		if (m_hw_mul_div)
1164 		{   /* MUL */
1165 			int scr;
1166 			int smb, srm;
1167 			double etime = 4.;      /* approximative */
1168 
1169 			IO = MB = AC;
1170 			MB = READ_PDP_18BIT(MA);
1171 			scr = 0;
1172 			if (MB & 0400000)
1173 			{
1174 				smb = 1;
1175 				MB = MB ^ 0777777;
1176 			}
1177 			else
1178 				smb = 0;
1179 			if (IO & 0400000)
1180 			{
1181 				srm = 1;
1182 				IO = IO ^ 0777777;
1183 			}
1184 			else
1185 				srm = 0;
1186 			AC = 0;
1187 			scr++;
1188 			while (scr < 022)
1189 			{
1190 				if (IO & 1)
1191 				{
1192 					/*assert(! (AC & 0400000));*/
1193 					AC = AC + MB;
1194 					/* we can save carry around since both numbers are positive */
1195 					/*AC = (AC + (AC >> 18)) & 0777777;*/
1196 					etime += .65;       /* approximative */
1197 				}
1198 				IO = (IO >> 1) | ((AC & 1) << 17);
1199 				AC = AC >> 1;
1200 				scr++;
1201 			}
1202 			if (smb ^ srm)
1203 			{
1204 				AC = AC ^ 0777777;
1205 				IO = IO ^ 0777777;
1206 			}
1207 
1208 			m_icount -= etime+.5;   /* round to closest */
1209 		}
1210 		else
1211 		{   /* MUS */
1212 			/* should we check for -0??? (Maintenance manual 7-14 seems to imply we should not:
1213 			as a matter of fact, since the MUS instruction is supposed to have positive operands,
1214 			there is no need to check for -0, therefore such a simplification does not sound
1215 			absurd.) */
1216 			if ((IO & 1) == 1)
1217 			{
1218 				AC = AC + (MB = READ_PDP_18BIT(MA));
1219 				AC = (AC + (AC >> 18)) & 0777777;   /* propagate carry around */
1220 			}
1221 			IO = (IO >> 1 | AC << 17) & 0777777;
1222 			AC >>= 1;
1223 		}
1224 		break;
1225 	case DIS_DIV:   /* Divide Step or Divide */
1226 		if (m_hw_mul_div)
1227 		{   /* DIV */
1228 			/* As a side note, the order of -0 detection and overflow checking does not matter,
1229 			because the sum of two positive number cannot give 0777777 (since positive
1230 			numbers are 0377777 at most, their sum is 0777776 at most).
1231 			Additionally, we cannot have carry set and a result equal to 0777777  (since numbers
1232 			are 0777777 at most, their sum is 01777776 at most): this is nice, because it makes
1233 			the sequence:
1234 			    AC = (AC + (AC >> 18)) & 0777777;   // propagate carry around
1235 			    if (AC == 0777777)          // check for -0
1236 			        AC = 0;
1237 			equivalent to:
1238 			    if (AC >= 0777777)
1239 			        AC = (AC + 1) & 0777777;
1240 			which is a bit more efficient. */
1241 			int acl;
1242 			int scr;
1243 			int smb, srm;
1244 			double etime = 0;       /* approximative */
1245 
1246 			MB = READ_PDP_18BIT(MA);
1247 			scr = 0;
1248 			if (MB & 0400000)
1249 			{
1250 				smb = 1;
1251 			}
1252 			else
1253 			{
1254 				smb = 0;
1255 				MB = MB ^ 0777777;
1256 			}
1257 			if (AC & 0400000)
1258 			{
1259 				srm = 1;
1260 				AC = AC ^ 0777777;
1261 				IO = IO ^ 0777777;
1262 			}
1263 			else
1264 				srm = 0;
1265 			while (1)
1266 			{
1267 				AC = (AC + MB);
1268 				#if 1
1269 					AC = (AC + (AC >> 18)) & 0777777;   /* propagate carry around */
1270 					if (AC == 0777777)      /* check for -0 */
1271 						AC = 0;
1272 				#else
1273 					if (AC >= 0777777)
1274 						AC = (AC + 1) & 0777777;
1275 				#endif
1276 				if (MB & 0400000)
1277 					MB = MB ^ 0777777;
1278 
1279 				if (((scr == 0) && ! (AC & 0400000))
1280 					|| (scr == 022))
1281 					break;
1282 
1283 				scr++;
1284 
1285 				if (! (AC & 0400000))
1286 					MB = MB ^ 0777777;
1287 
1288 				acl = AC >> 17;
1289 				AC = (AC << 1 | IO >> 17) & 0777777;
1290 				IO = ((IO << 1 | acl) & 0777777) ^ 1;
1291 				if (acl)
1292 				{
1293 					AC++;
1294 					AC = (AC + (AC >> 18)) & 0777777;
1295 					etime += .6;        /* approximative */
1296 				}
1297 			}
1298 
1299 			AC = (AC + MB);
1300 			#if 1
1301 				AC = (AC + (AC >> 18)) & 0777777;   /* propagate carry around */
1302 				if (AC == 0777777)      /* check for -0 */
1303 					AC = 0;
1304 			#else
1305 				if (AC >= 0777777)
1306 					AC = (AC + 1) & 0777777;
1307 			#endif
1308 
1309 			if (scr)
1310 			{
1311 				INCREMENT_PC;
1312 				AC = AC >> 1;
1313 			}
1314 
1315 			if (srm && (AC != 0))
1316 				AC = AC ^ 0777777;
1317 
1318 			if (((! scr) && (srm))
1319 					|| (scr && (srm ^ smb) && (IO != 0)))
1320 				IO = IO ^ 0777777;
1321 
1322 			if (scr)
1323 			{
1324 				MB = AC;
1325 				AC = IO;
1326 				IO = MB;
1327 			}
1328 			if (scr)
1329 				etime += 20;        /* approximative */
1330 			else
1331 				etime += 2;         /* approximative */
1332 
1333 			m_icount -= etime+.5;   /* round to closest */
1334 		}
1335 		else
1336 		{   /* DIS */
1337 			int acl;
1338 
1339 			acl = AC >> 17;
1340 			AC = (AC << 1 | IO >> 17) & 0777777;
1341 			IO = ((IO << 1 | acl) & 0777777) ^ 1;
1342 			MB = READ_PDP_18BIT(MA);
1343 			if (IO & 1)
1344 				AC += (MB ^ 0777777);
1345 			else
1346 				/* Note that if AC+MB = 0777777, we are in trouble.  I don't
1347 				know how a real PDP-1 behaves in this case. */
1348 				AC += MB + 1;
1349 			AC = (AC + (AC >> 18)) & 0777777;   /* propagate carry around */
1350 			if (AC == 0777777)      /* check for -0 */
1351 				AC = 0;
1352 		}
1353 		break;
1354 	case JMP:       /* Jump */
1355 		if (m_exc)
1356 			PC = MB & EXTENDED_ADDRESS_MASK;
1357 		else
1358 			PC = (MA & ADDRESS_EXTENSION_MASK) | (MB & BASE_ADDRESS_MASK);
1359 		break;
1360 	case JSP:       /* Jump and Save Program Counter */
1361 		AC = (OV << 17) | (EXD << 16) | PC;
1362 		if (m_exc)
1363 			PC = MB & EXTENDED_ADDRESS_MASK;
1364 		else
1365 			PC = (MA & ADDRESS_EXTENSION_MASK) | (MB & BASE_ADDRESS_MASK);
1366 		break;
1367 	case SKP:       /* Skip Instruction Group */
1368 		{
1369 			int cond = ((MB & 0100) && (AC == 0))   /* ZERO Accumulator */
1370 				|| ((MB & 0200) && (AC >> 17 == 0)) /* Plus Accumulator */
1371 				|| ((MB & 0400) && (AC >> 17 == 1)) /* Minus Accumulator */
1372 				|| ((MB & 01000) && (OV == 0))      /* ZERO Overflow */
1373 				|| ((MB & 02000) && (IO >> 17 == 0))    /* Plus I/O Register */
1374 				|| (((MB & 7) != 0) && (((MB & 7) == 7) ? ! FLAGS : ! READFLAG(MB & 7)))    /* ZERO Flag (deleted by mistake in PDP-1 handbook) */
1375 				|| (((MB & 070) != 0) && (((MB & 070) == 070) ? ! SENSE_SW : ! READSENSE((MB & 070) >> 3)));    /* ZERO Switch */
1376 
1377 			if (! (MB & 010000))
1378 			{
1379 				if (cond)
1380 					INCREMENT_PC;
1381 			}
1382 			else
1383 			{
1384 				if (!cond)
1385 					INCREMENT_PC;
1386 			}
1387 			if (MB & 01000)
1388 				OV = 0;
1389 			break;
1390 		}
1391 	case SFT:       /* Shift Instruction Group */
1392 		{
1393 			/* Bit 5 specifies direction of shift, Bit 6 specifies the character of the shift
1394 			(arithmetic or logical), Bits 7 and 8 enable the registers (01 = AC, 10 = IO,
1395 			and 11 = both) and Bits 9 through 17 specify the number of steps. */
1396 			int nshift = 0;
1397 			int mask = MB & 0777;
1398 
1399 			while (mask != 0)
1400 			{
1401 				nshift += mask & 1;
1402 				mask >>= 1;
1403 			}
1404 			switch ((MB >> 9) & 017)
1405 			{
1406 				int i;
1407 
1408 			case 1:     /* ral rotate accumulator left */
1409 				for (i = 0; i < nshift; i++)
1410 					AC = (AC << 1 | AC >> 17) & 0777777;
1411 				break;
1412 			case 2:     /* ril rotate i/o register left */
1413 				for (i = 0; i < nshift; i++)
1414 					IO = (IO << 1 | IO >> 17) & 0777777;
1415 				break;
1416 			case 3:     /* rcl rotate AC and IO left */
1417 				for (i = 0; i < nshift; i++)
1418 				{
1419 					int tmp = AC;
1420 
1421 					AC = (AC << 1 | IO >> 17) & 0777777;
1422 					IO = (IO << 1 | tmp >> 17) & 0777777;
1423 				}
1424 				break;
1425 			case 5:     /* sal shift accumulator left */
1426 				for (i = 0; i < nshift; i++)
1427 					AC = ((AC << 1 | AC >> 17) & 0377777) + (AC & 0400000);
1428 				break;
1429 			case 6:     /* sil shift i/o register left */
1430 				for (i = 0; i < nshift; i++)
1431 					IO = ((IO << 1 | IO >> 17) & 0377777) + (IO & 0400000);
1432 				break;
1433 			case 7:     /* scl shift AC and IO left */
1434 				for (i = 0; i < nshift; i++)
1435 				{
1436 					int tmp = AC;
1437 
1438 					AC = ((AC << 1 | IO >> 17) & 0377777) + (AC & 0400000);     /* shouldn't that be IO?, no it is the sign! */
1439 					IO = (IO << 1 | tmp >> 17) & 0777777;
1440 				}
1441 				break;
1442 			case 9:     /* rar rotate accumulator right */
1443 				for (i = 0; i < nshift; i++)
1444 					AC = (AC >> 1 | AC << 17) & 0777777;
1445 				break;
1446 			case 10:    /* rir rotate i/o register right */
1447 				for (i = 0; i < nshift; i++)
1448 					IO = (IO >> 1 | IO << 17) & 0777777;
1449 				break;
1450 			case 11:    /* rcr rotate AC and IO right */
1451 				for (i = 0; i < nshift; i++)
1452 				{
1453 					int tmp = AC;
1454 
1455 					AC = (AC >> 1 | IO << 17) & 0777777;
1456 					IO = (IO >> 1 | tmp << 17) & 0777777;
1457 				}
1458 				break;
1459 			case 13:    /* sar shift accumulator right */
1460 				for (i = 0; i < nshift; i++)
1461 					AC = (AC >> 1) + (AC & 0400000);
1462 				break;
1463 			case 14:    /* sir shift i/o register right */
1464 				for (i = 0; i < nshift; i++)
1465 					IO = (IO >> 1) + (IO & 0400000);
1466 				break;
1467 			case 15:    /* scr shift AC and IO right */
1468 				for (i = 0; i < nshift; i++)
1469 				{
1470 					int tmp = AC;
1471 
1472 					AC = (AC >> 1) + (AC & 0400000);    /* shouldn't that be IO, no it is the sign */
1473 					IO = (IO >> 1 | tmp << 17) & 0777777;
1474 				}
1475 				break;
1476 			default:
1477 				if (LOG)
1478 					logerror("Undefined shift: 0%06o at 0%06o\n", MB, PREVIOUS_PC);
1479 				break;
1480 			}
1481 			break;
1482 		}
1483 	case LAW:       /* Load Accumulator with N */
1484 		AC = MB & 07777;
1485 		if (MB & 010000)
1486 			AC ^= 0777777;
1487 		break;
1488 	case IOT:       /* In-Out Transfer Instruction Group */
1489 		/*
1490 		    The variations within this group of instructions perform all the in-out control
1491 		    and information transfer functions.  If Bit 5 (normally the Indirect Address bit)
1492 		    is a ONE, the computer will enter a special waiting state until the completion pulse
1493 		    from the activated device has returned.  When this device delivers its completion,
1494 		    the computer will resume operation of the instruction sequence.
1495 
1496 		    The computer may be interrupted from the special waiting state to serve a sequence
1497 		    break request or a high speed channel request.
1498 
1499 		    Most in-out operations require a known minimum time before completion.  This time
1500 		    may be utilized for programming.  The appropriate In-Out Transfer can be given with
1501 		    no in-out wait (Bit 5 a ZERO and Bit 6 a ONE).  The instruction sequence then
1502 		    continues.  This sequence must include an iot instruction 730000 which performs
1503 		    nothing but the in-out wait. The computer will then enter the special waiting state
1504 		    until the device returns the in-out restart pulse.  If the device has already
1505 		    returned the completion pulse before the instruction 730000, the computer will
1506 		    proceed immediately.
1507 
1508 		    Bit 6 determines whether a completion pulse will or will not be received from
1509 		    the in-out device.  When it is different than Bit 5, a completion pulse will be
1510 		    received.  When it is the same as Bit 5, a completion pulse will not be received.
1511 
1512 		    In addition to the control function of Bits 5 and 6, Bits 7 through 11 are also
1513 		    used as control bits serving to extend greatly the power of the iot instructions.
1514 		    For example, Bits 12 through 17, which are used to designate a class of input or
1515 		    output devices such as typewriters, may be further defined by Bits 7 through 11
1516 		    as referring to Typewriter 1, 2, 3, etc.  In several of the optional in-out devices,
1517 		    in particular the magnetic tape, Bits 7 through 11 specify particular functions
1518 		    such as forward, backward etc.  If a large number of specialized devices are to
1519 		    be attached, these bits may be used to further the in-out transfer instruction
1520 		    to perform totally distinct functions.
1521 
1522 		    Note that ioc is supposed to be set at the beggining of the memory cycle after
1523 		    ioh is cleared.
1524 		    However, we cannot set ioc at the beggining of every memory cycle as we
1525 		    did before, because it breaks in the following case:
1526 		    a) IOT instruction enables IO wait
1527 		    b) sequence break in the middle of IO-halt
1528 		    c) ioh is cleared in middle of sequence break routine
1529 		    d) re-execute IOT instruction.  Unfortunately, ioc has been cleared, therefore
1530 		      we perform an IOT command pulse and IO wait again, which is completely WRONG.
1531 		    Therefore ioc is cleared only after a IOT with wait is executed.
1532 		*/
1533 		if (MB & 010000)
1534 		{   /* IOT with IO wait */
1535 			if (m_ioc)
1536 			{   /* the iot command line is pulsed only if ioc is asserted */
1537 				m_extern_iot[MB & 0000077](MB & 0000077, (MB & 0004000) == 0, MB, IO, AC);
1538 
1539 				m_ioh = 1;  /* enable io wait */
1540 
1541 				m_ioc = 0;  /* actually happens at the start of next memory cycle */
1542 
1543 				/* test ios now in case the IOT callback has sent a completion pulse immediately */
1544 				if (m_ioh && m_ios)
1545 				{
1546 					/* ioh should be cleared at the end of the instruction cycle, and ios at the
1547 					start of next instruction cycle, but who cares? */
1548 					m_ioh = 0;
1549 					//m_ios = 0;
1550 				}
1551 			}
1552 
1553 			if (m_ioh)
1554 				DECREMENT_PC;
1555 			else
1556 				m_ioc = 1;  /* actually happens at the start of next memory cycle */
1557 		}
1558 		else
1559 		{   /* IOT with no IO wait */
1560 			m_extern_iot[MB & 0000077](MB & 0000077, (MB & 0004000) != 0, MB, IO, AC);
1561 		}
1562 		break;
1563 	case OPR:       /* Operate Instruction Group */
1564 		{
1565 			int nflag;
1566 
1567 			if (MB & 00200)     /* clear AC */
1568 				AC = 0;
1569 			if (MB & 04000)     /* clear I/O register */
1570 				IO = 0;
1571 			if (MB & 02000)     /* load Accumulator from Test Word */
1572 				AC |= m_tw;
1573 			if (MB & 00100)     /* load Accumulator with Program Counter */
1574 				AC |= (OV << 17) | (EXD << 16) | PC;
1575 			nflag = MB & 7;
1576 			if (nflag)
1577 			{
1578 				if (nflag == 7)
1579 					FLAGS = (MB & 010) ? 077 : 000;
1580 				else
1581 					WRITEFLAG(nflag, (MB & 010) ? 1 : 0);
1582 			}
1583 			if (MB & 01000)     /* Complement AC */
1584 				AC ^= 0777777;
1585 			if (MB & 00400)     /* Halt */
1586 			{
1587 				if (LOG_EXTRA)
1588 					logerror("PDP1 Program executed HALT: at 0%06o\n", PREVIOUS_PC);
1589 
1590 				m_run = 0;
1591 			}
1592 			break;
1593 		}
1594 	default:
1595 		if (LOG)
1596 			logerror("Illegal instruction: 0%06o at 0%06o\n", MB, PREVIOUS_PC);
1597 
1598 		/* let us stop the CPU, like a real pdp-1 */
1599 		m_run = 0;
1600 
1601 		break;
1602 	}
1603 	m_cycle = 0;
1604 no_fetch:
1605 	;
1606 }
1607 
1608 
1609 /*
1610     Handle unimplemented IOT
1611 */
null_iot(int op2,int nac,int mb,int & io,int ac)1612 void pdp1_device::null_iot(int op2, int nac, int mb, int &io, int ac)
1613 {
1614 	/* Note that the dummy IOT 0 is used to wait for the completion pulse
1615 	generated by the a pending IOT (IOT with completion pulse but no IO wait) */
1616 	if (LOG_IOT_EXTRA)
1617 	{
1618 		if (op2 == 000)
1619 			logerror("IOT sync instruction: mb=0%06o, pc=0%06o\n", (unsigned) mb, (unsigned) m_pc);
1620 	}
1621 	if (LOG)
1622 	{
1623 		if (op2 != 000)
1624 			logerror("Not supported IOT command (no external IOT function given) 0%06o at 0%06o\n", mb, m_pc);
1625 	}
1626 }
1627 
1628 
1629 /*
1630     Memory expansion control (type 15)
1631 
1632     IOT 74: LEM/EEM
1633 */
lem_eem_iot(int op2,int nac,int mb,int & io,int ac)1634 void pdp1_device::lem_eem_iot(int op2, int nac, int mb, int &io, int ac)
1635 {
1636 	if (! m_extend_support) /* extend mode supported? */
1637 	{
1638 		if (LOG)
1639 			logerror("Ignoring internal error in file " __FILE__ " line %d.\n", __LINE__);
1640 		return;
1641 	}
1642 	if (LOG_EXTRA)
1643 	{
1644 		logerror("EEM/LEM instruction: mb=0%06o, pc=0%06o\n", mb, m_pc);
1645 	}
1646 	EXD = (mb & 0004000) ? 1 : 0;
1647 }
1648 
1649 
1650 /*
1651     Standard sequence break system
1652 
1653     IOT 54: lsm
1654     IOT 55: esm
1655     IOT 56: cbs
1656 */
sbs_iot(int op2,int nac,int mb,int & io,int ac)1657 void pdp1_device::sbs_iot(int op2, int nac, int mb, int &io, int ac)
1658 {
1659 	switch (op2)
1660 	{
1661 	case 054:   /* LSM */
1662 		if (LOG_EXTRA)
1663 			logerror("LSM instruction: mb=0%06o, pc=0%06o\n", mb, m_pc);
1664 
1665 		m_sbm = 0;
1666 		field_interrupt();
1667 		break;
1668 	case 055:   /* ESM */
1669 		if (LOG_EXTRA)
1670 			logerror("ESM instruction: mb=0%06o, pc=0%06o\n", mb, m_pc);
1671 
1672 		m_sbm = 1;
1673 		field_interrupt();
1674 		break;
1675 	case 056:   /* CBS */
1676 		if (LOG_EXTRA)
1677 			logerror("CBS instruction: mb=0%06o, pc=0%06o\n", mb, m_pc);
1678 
1679 		/*m_b3 = 0;*/
1680 		m_b4 = 0;
1681 		field_interrupt();
1682 		break;
1683 	default:
1684 		if (LOG)
1685 			logerror("Ignoring internal error in file " __FILE__ " line %d.\n", __LINE__);
1686 
1687 		break;
1688 	}
1689 }
1690 
1691 
1692 /*
1693     type 20 sequence break system
1694 
1695     IOT 50: dsc
1696     IOT 51: asc
1697     IOT 52: isb
1698     IOT 53: cac
1699 */
type_20_sbs_iot(int op2,int nac,int mb,int & io,int ac)1700 void pdp1_device::type_20_sbs_iot(int op2, int nac, int mb, int &io, int ac)
1701 {
1702 	int channel, mask;
1703 	if (! m_type_20_sbs)    /* type 20 sequence break system supported? */
1704 	{
1705 		if (LOG)
1706 			logerror("Ignoring internal error in file " __FILE__ " line %d.\n", __LINE__);
1707 		return;
1708 	}
1709 	channel = (mb >> 6) & 017;
1710 	mask = 1 << channel;
1711 	switch (op2)
1712 	{
1713 	case 050:   /* DSC */
1714 		if (LOG_EXTRA)
1715 			logerror("DSC instruction: mb=0%06o, pc=0%06o\n", mb, m_pc);
1716 
1717 		m_b1 &= ~mask;
1718 		field_interrupt();
1719 		break;
1720 	case 051:   /* ASC */
1721 		if (LOG_EXTRA)
1722 			logerror("ASC instruction: mb=0%06o, pc=0%06o\n", mb, m_pc);
1723 
1724 		m_b1 |= mask;
1725 		field_interrupt();
1726 		break;
1727 	case 052:   /* ISB */
1728 		if (LOG_EXTRA)
1729 			logerror("ISB instruction: mb=0%06o, pc=0%06o\n", mb, m_pc);
1730 
1731 		m_b2 |= mask;
1732 		field_interrupt();
1733 		break;
1734 	case 053:   /* CAC */
1735 		if (LOG_EXTRA)
1736 			logerror("CAC instruction: mb=0%06o, pc=0%06o\n", mb, m_pc);
1737 
1738 		m_b1 = 0;
1739 		field_interrupt();
1740 		break;
1741 	default:
1742 		if (LOG)
1743 			logerror("Ignoring internal error in file " __FILE__ " line %d.\n", __LINE__);
1744 
1745 		break;
1746 	}
1747 
1748 }
1749 
1750 
1751 /*
1752     Simulate a pulse on start/clear line:
1753     reset most registers and flip-flops, and initialize a few emulator state
1754     variables.
1755 */
pulse_start_clear()1756 void pdp1_device::pulse_start_clear()
1757 {
1758 	/* processor registers */
1759 	PC = 0;         /* according to maintenance manual p. 6-17 */
1760 	IR = 0;         /* according to maintenance manual p. 6-13 */
1761 	/*MB = 0;*/     /* ??? */
1762 	/*MA = 0;*/     /* ??? */
1763 	/*AC = 0;*/     /* ??? */
1764 	/*IO = 0;*/     /* ??? */
1765 	/*PF = 0;*/     /* ??? */
1766 
1767 	/* processor state flip-flops */
1768 	m_run = 0;      /* ??? */
1769 	m_cycle = 0;        /* mere guess */
1770 	m_defer = 0;        /* mere guess */
1771 	m_brk_ctr = 0;  /* mere guess */
1772 	m_ov = 0;       /* according to maintenance manual p. 7-18 */
1773 	m_rim = 0;      /* ??? */
1774 	m_sbm = 0;      /* ??? */
1775 	EXD = 0;            /* according to maintenance manual p. 8-16 */
1776 	m_exc = 0;      /* according to maintenance manual p. 8-16 */
1777 	m_ioc = 1;      /* according to maintenance manual p. 6-10 */
1778 	m_ioh = 0;      /* according to maintenance manual p. 6-10 */
1779 	m_ios = 0;      /* according to maintenance manual p. 6-10 */
1780 
1781 	m_b1 = m_type_20_sbs ? 0 : 1;   /* mere guess */
1782 	m_b2 = 0;       /* mere guess */
1783 	m_b4 = 0;       /* mere guess */
1784 
1785 
1786 	m_rim_step = 0;
1787 	m_sbs_restore = 0;      /* mere guess */
1788 	m_no_sequence_break = 0;    /* mere guess */
1789 
1790 	field_interrupt();
1791 
1792 	/* now, we kindly ask IO devices to reset, too */
1793 	if (!m_io_sc_callback.isnull())
1794 		m_io_sc_callback();
1795 }
1796