summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/pdp1
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/pdp1')
-rw-r--r--src/emu/cpu/pdp1/pdp1.c1818
-rw-r--r--src/emu/cpu/pdp1/pdp1.h199
-rw-r--r--src/emu/cpu/pdp1/pdp1dasm.c294
-rw-r--r--src/emu/cpu/pdp1/tx0.c1080
-rw-r--r--src/emu/cpu/pdp1/tx0.h179
-rw-r--r--src/emu/cpu/pdp1/tx0dasm.c123
6 files changed, 0 insertions, 3693 deletions
diff --git a/src/emu/cpu/pdp1/pdp1.c b/src/emu/cpu/pdp1/pdp1.c
deleted file mode 100644
index bb7beee4128..00000000000
--- a/src/emu/cpu/pdp1/pdp1.c
+++ /dev/null
@@ -1,1818 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Raphael Nabet
-/*
- * Note: Original Java source written by:
- *
- * Barry Silverman mailto:barry@disus.com or mailto:bss@media.mit.edu
- * Vadim Gerasimov mailto:vadim@media.mit.edu
- *
- * MESS driver by Chris Salomon and Raphael Nabet.
- *
- * Basically, it has been rewritten entirely in order to perform cycle-level simulation
- * (with only a few flip-flops being set one cycle too early or too late). I don't know if
- * it is a good thing or a bad thing (it makes emulation more accurate, but slower, and
- * code is more complex and less readable), but it appears to be the only way we could emulate
- * mid-instruction sequence break. And it enables us to emulate the control panel fairly
- * accurately.
- *
- * Additionnally, IOT functions have been modified to be external: IOT callback pointers are set
- * at emulation initiation, and most IOT callback functions are part of the machine emulation.
- *
- *
- * for the runnable java applet, with applet and Spacewar! source, go to:
- * http://lcs.www.media.mit.edu/groups/el/projects/spacewar/
- *
- * for a complete html version of the pdp1 handbook go to:
- * http://www.dbit.com/~greeng3/pdp1/index.html
- *
- * there is another java simulator (by the same people) which runs the
- * original pdp1 LISP interpreter, go to:
- * http://lcs.www.media.mit.edu/groups/el/projects/pdp1
- *
- * Another PDP1 emulator (or simulator) is at:
- * ftp://minnie.cs.adfa.oz.au/pub/PDP-11/Sims/Supnik_2.3
- * It seems to emulate pdp1 I/O more accurately than we do.
- * However, there is no CRT emulation.
- *
- * and finally, there is a nice article about SPACEWAR!, go to:
- * http://ars-www.uchicago.edu/~eric/lore/spacewar/spacewar.html
- *
- * some extra documentation is available on spies:
- * http://www.spies.com/~aek/pdf/dec/pdp1/
- * The file "F17_PDP1Maint.pdf" explains operation procedures and much of the internals of pdp-1.
- * It was the main reference for this emulator.
- * The file "F25_PDP1_IO.pdf" has interesting information on the I/O system, too.
- *
- * Following is an extract from the handbook:
- *
- * INTRODUCTION
- *
- * The Programmed Data Processor (PDP-1) is a high speed, solid state digital computer designed to
- * operate with many types of input-output devices with no internal machine changes. It is a single
- * address, single instruction, stored program computer with powerful program features. Five-megacycle
- * circuits, a magnetic core memory and fully parallel processing make possible a computation rate of
- * 100,000 additions per second. The PDP-1 is unusually versatile. It is easy to install, operate and
- * maintain. Conventional 110-volt power is used, neither air conditioning nor floor reinforcement is
- * necessary, and preventive maintenance is provided for by built-in marginal checking circuits.
- *
- * PDP-1 circuits are based on the designs of DEC's highly successful and reliable System Modules.
- * Flip-flops and most switches use saturating transistors. Primary active elements are
- * Micro-Alloy-Diffused transistors.
- *
- * The entire computer occupies only 17 square feet of floor space. It consists of four equipment frames,
- * one of which is used as the operating station.
- *
- * CENTRAL PROCESSOR
- *
- * The Central Processor contains the control, arithmetic and memory addressing elements, and the memory
- * buffer register. The word length is 18 binary digits. Instructions are performed in multiples of the
- * memory cycle time of five microseconds. Add, subtract, deposit, and load, for example, are two-cycle
- * instructions requiring 10 microseconds. Multiplication requires and average of 20 microseconds.
- * Program features include: single address instructions, multiple step indirect addressing and logical
- * arithmetic commands. Console features include: flip-flop indicators grouped for convenient octal
- * reading, six program flags for automatic setting and computer sensing, and six sense switches for
- * manual setting and computer sensing.
- *
- * MEMORY SYSTEM
- *
- * The coincident-current, magnetic core memory of a standard PDP-1 holds 4096 words of 18 bits each.
- * Memory capacity may be readily expanded, in increments of 4096 words, to a maximum of 65,536 words.
- * The read-rewrite time of the memory is five microseconds, the basic computer rate. Driving currents
- * are automatically adjusted to compensate for temperature variations between 50 and 110 degrees
- * Fahrenheit. The core memory storage may be supplemented by up to 24 magnetic tape transports.
- *
- * INPUT-OUTPUT
- *
- * PDP-1 is designed to operate a variety of buffered input-output devices. Standard equipment consistes
- * of a perforated tape reader with a read speed of 400 lines per second, and alphanuermic typewriter for
- * on-line operation in both input and output, and a perforated tape punch (alphanumeric or binary) with
- * a speed of 63 lines per second. A variety of optional equipment is available, including the following:
- *
- * Precision CRT Display Type 30
- * Ultra-Precision CRT Display Type 31
- * Symbol Generator Type 33
- * Light Pen Type 32
- * Oscilloscope Display Type 34
- * Card Punch Control Type 40-1
- * Card Reader and Control Type 421
- * Magnetic Tape Transport Type 50
- * Programmed Magnetic Tape Control Type 51
- * Automatic Magnetic Tape Control Type 52
- * Automatic Magnetic Tape Control Type 510
- * Parallel Drum Type 23
- * Automatic Line Printer and Control Type 64
- * 18-bit Real Time Clock
- * 18-bit Output Relay Buffer Type 140
- * Multiplexed A-D Converter Type 138/139
- *
- * All in-out operations are performed through the In-Out Register or through the high speed input-output
- * channels.
- *
- * The PDP-1 is also available with the optional Sequence Break System. This is a multi-channel priority
- * interrupt feature which permits concurrent operation of several in-out devices. A one-channel Sequence
- * Break System is included in the standard PDP-1. Optional Sequence Break Systems consist of 16, 32, 64,
- * 128, and 256 channels.
- *
- * ...
- *
- * BASIC INSTRUCTIONS
- *
- * OPER. TIME
- * INSTRUCTION CODE # EXPLANATION (usec)
- * ------------------------------------------------------------------------------
- * add Y 40 Add C(Y) to C(AC) 10
- * and Y 02 Logical AND C(Y) with C(AC) 10
- * cal Y 16 Equals jda 100 10
- * dac Y 24 Deposit C(AC) in Y 10
- * dap Y 26 Deposit contents of address part of AC in Y 10
- * dio Y 32 Deposit C(IO) in Y 10
- * dip Y 30 Deposit contents of instruction part of AC in Y 10
- * div Y 56 Divide 40 max
- * dzm Y 34 Deposit zero in Y 10
- * idx Y 44 Index (add one) C(Y), leave in Y & AC 10
- * ior Y 04 Inclusive OR C(Y) with C(AC) 10
- * iot Y 72 In-out transfer, see below
- * isp Y 46 Index and skip if result is positive 10
- * jda Y 17 Equals dac Y and jsp Y+1 10
- * jmp Y 60 Take next instruction from Y 5
- * jsp Y 62 Jump to Y and save program counter in AC 5
- * lac Y 20 Load the AC with C(Y) 10
- * law N 70 Load the AC with the number N 5
- * law-N 71 Load the AC with the number -N 5
- * lio Y 22 Load IO with C(Y) 10
- * mul Y 54 Multiply 25 max
- * opr 76 Operate, see below 5
- * sad Y 50 Skip next instruction if C(AC) <> C(Y) 10
- * sas Y 52 Skip next instruction if C(AC) = C(Y) 10
- * sft 66 Shift, see below 5
- * skp 64 Skip, see below 5
- * sub Y 42 Subtract C(Y) from C(AC) 10
- * xct Y 10 Execute instruction in Y 5+
- * xor Y 06 Exclusive OR C(Y) with C(AC) 10
- *
- * OPERATE GROUP
- *
- * OPER. TIME
- * INSTRUCTION CODE # EXPLANATION (usec)
- * ------------------------------------------------------------------------------
- * cla 760200 Clear AC 5
- * clf 76000f Clear selected Program Flag (f = flag #) 5
- * cli 764000 Clear IO 5
- * cma 761000 Complement AC 5
- * hlt 760400 Halt 5
- * lap 760100 Load AC with Program Counter 5
- * lat 762200 Load AC from Test Word switches 5
- * nop 760000 No operation 5
- * stf 76001f Set selected Program Flag 5
- *
- * IN-OUT TRANSFER GROUP
- *
- * PERFORATED TAPE READER
- *
- * INSTRUCTION CODE # EXPLANATION
- * ------------------------------------------------------------------------------
- * rpa 720001 Read Perforated Tape Alphanumeric
- * rpb 720002 Read Perforated Tape Binary
- * rrb 720030 Read Reader Buffer
- *
- * PERFORATED TAPE PUNCH
- *
- * INSTRUCTION CODE # EXPLANATION
- * ------------------------------------------------------------------------------
- * ppa 720005 Punch Perforated Tape Alphanumeric
- * ppb 720006 Punch Perforated Tape Binary
- *
- * ALPHANUMERIC ON-LINE TYPEWRITER
- *
- * INSTRUCTION CODE # EXPLANATION
- * ------------------------------------------------------------------------------
- * tyo 720003 Type Out
- * tyi 720004 Type In
- *
- * SEQUENCE BREAK SYSTEM TYPE 120
- *
- * INSTRUCTION CODE # EXPLANATION
- * ------------------------------------------------------------------------------
- * esm 720055 Enter Sequence Break Mode
- * lsm 720054 Leave Sequence Break Mode
- * cbs 720056 Clear Sequence Break System
- * dsc 72kn50 Deactivate Sequence Break Channel
- * asc 72kn51 Activate Sequence Break Channel
- * isb 72kn52 Initiate Sequence Break
- * cac 720053 Clear All Channels
- *
- * HIGH SPEED DATA CONTROL TYPE 131
- *
- * INSTRUCTION CODE # EXPLANATION
- * ------------------------------------------------------------------------------
- * swc 72x046 Set Word Counter
- * sia 720346 Set Location Counter
- * sdf 720146 Stop Data Flow
- * rlc 720366 Read Location Counter
- * shr 720446 Set High Speed Channel Request
- *
- * PRECISION CRT DISPLAY TYPE 30
- *
- * INSTRUCTION CODE # EXPLANATION
- * ------------------------------------------------------------------------------
- * dpy 720007 Display One Point
- *
- * SYMBOL GENERATOR TYPE 33
- *
- * INSTRUCTION CODE # EXPLANATION
- * ------------------------------------------------------------------------------
- * gpl 722027 Generator Plot Left
- * gpr 720027 Generator Plot Right
- * glf 722026 Load Format
- * gsp 720026 Space
- * sdb 722007 Load Buffer, No Intensity
- *
- * ULTRA-PRECISION CRT DISPLAY TYPE 31
- *
- * INSTRUCTION CODE # EXPLANATION
- * ------------------------------------------------------------------------------
- * dpp 720407 Display One Point on Ultra Precision CRT
- *
- * CARD PUNCH CONTROL TYPE 40-1
- *
- * INSTRUCTION CODE # EXPLANATION
- * ------------------------------------------------------------------------------
- * lag 720044 Load a Group
- * pac 720043 Punch a Card
- *
- * CARD READER TYPE 421
- *
- * INSTRUCTION CODE # EXPLANATION
- * ------------------------------------------------------------------------------
- * rac 720041 Read Card Alpha
- * rbc 720042 Read Card Binary
- * rcc 720032 Read Card Column
- *
- * PROGRAMMED MAGNETIC TAPE CONTROL TYPE 51
- *
- * INSTRUCTION CODE # EXPLANATION
- * ------------------------------------------------------------------------------
- * msm 720073 Select Mode
- * mcs 720034 Check Status
- * mcb 720070 Clear Buffer
- * mwc 720071 Write a Character
- * mrc 720072 Read Character
- *
- * AUTOMATIC MAGNETIC TAPE CONTROL TYPE 52
- *
- * INSTRUCTION CODE # EXPLANATION
- * ------------------------------------------------------------------------------
- * muf 72ue76 Tape Unit and FinalT
- * mic 72ue75 Initial and Command
- * mrf 72u067 Reset Final
- * mri 72ug66 Reset Initial
- * mes 72u035 Examine States
- * mel 72u036 Examine Location
- * inr 72ur67 Initiate a High Speed Channel Request
- * ccr 72s067 Clear Command Register
- *
- * AUTOMATIC MAGNETIC TAPE CONTROL TYPE 510
- *
- * INSTRUCTION CODE # EXPLANATION
- * ------------------------------------------------------------------------------
- * sfc 720072 Skip if Tape Control Free
- * rsr 720172 Read State Register
- * crf 720272 Clear End-of-Record Flip-Flop
- * cpm 720472 Clear Proceed Mode
- * dur 72xx70 Load Density, Unit, Rewind
- * mtf 73xx71 Load Tape Function Register
- * cgo 720073 Clear Go
- *
- * MULTIPLEXED A-D CONVERTER TYPE 138/139
- *
- * INSTRUCTION CODE # EXPLANATION
- * ------------------------------------------------------------------------------
- * rcb 720031 Read Converter Buffer
- * cad 720040 Convert a Voltage
- * scv 72mm47 Select Multiplexer (1 of 64 Channels)
- * icv 720060 Index Multiplexer
- *
- * AUTOMATIC LINE PRINTER TYPE 64
- *
- * INSTRUCTION CODE # EXPLANATION
- * ------------------------------------------------------------------------------
- * clrbuf 722045 Clear Buffer
- * lpb 720045 Load Printer Buffer
- * pas 721x45 Print and Space
- *
- * SKIP GROUP
- *
- * OPER. TIME
- * INSTRUCTION CODE # EXPLANATION (usec)
- * ------------------------------------------------------------------------------
- * sma 640400 Dkip on minus AC 5
- * spa 640200 Skip on plus AC 5
- * spi 642000 Skip on plus IO 5
- * sza 640100 Skip on ZERO (+0) AC 5
- * szf 6400f Skip on ZERO flag 5
- * szo 641000 Skip on ZERO overflow (and clear overflow) 5
- * szs 6400s0 Skip on ZERO sense switch 5
- *
- * SHIFT/ROTATE GROUP
- *
- * OPER. TIME
- * INSTRUCTION CODE # EXPLANATION (usec)
- * ------------------------------------------------------------------------------
- * ral 661 Rotate AC left 5
- * rar 671 Rotate AC right 5
- * rcl 663 Rotate Combined AC & IO left 5
- * rcr 673 Rotate Combined AC & IO right 5
- * ril 662 Rotate IO left 5
- * rir 672 Rotate IO right 5
- * sal 665 Shift AC left 5
- * sar 675 Shift AC right 5
- * scl 667 Shift Combined AC & IO left 5
- * scr 677 Shift Combined AC & IO right 5
- * sil 666 Shift IO left 5
- * sir 676 Shift IO right 5
- */
-
-
-/*
- TODO:
- * support other extensions as time permits
-*/
-
-
-#include "emu.h"
-#include "debugger.h"
-#include "pdp1.h"
-
-#define LOG 0
-#define LOG_EXTRA 0
-#define LOG_IOT_EXTRA 0
-
-#define READ_PDP_18BIT(A) ((signed)m_program->read_dword((A)<<2))
-#define WRITE_PDP_18BIT(A,V) (m_program->write_dword((A)<<2,(V)))
-
-
-#define PC m_pc
-#define IR m_ir
-#define MB m_mb
-#define MA m_ma
-#define AC m_ac
-#define IO m_io
-#define OV m_ov
-#define EXD m_exd
-/* note that we start counting flags/sense switches at 1, therefore n is in [1,6] */
-#define FLAGS m_pf
-#define READFLAG(n) ((m_pf >> (6-(n))) & 1)
-#define WRITEFLAG(n, data) (m_pf = (m_pf & ~(1 << (6-(n)))) | (((data) & 1) << (6-(n))))
-#define SENSE_SW m_ss
-#define READSENSE(n) ((m_ss >> (6-(n))) & 1)
-#define WRITESENSE(n, data) (m_ss = (m_ss & ~(1 << (6-(n)))) | (((data) & 1) << (6-(n))))
-
-#define EXTENDED_ADDRESS_MASK m_extended_address_mask
-#define ADDRESS_EXTENSION_MASK m_address_extension_mask
-#define BASE_ADDRESS_MASK 0007777
-
-#define INCREMENT_PC (PC = (PC & ADDRESS_EXTENSION_MASK) | ((PC+1) & BASE_ADDRESS_MASK))
-#define DECREMENT_PC (PC = (PC & ADDRESS_EXTENSION_MASK) | ((PC-1) & BASE_ADDRESS_MASK))
-#define INCREMENT_MA (MA = (MA & ADDRESS_EXTENSION_MASK) | ((MA+1) & BASE_ADDRESS_MASK))
-#define PREVIOUS_PC ((PC & ADDRESS_EXTENSION_MASK) | ((PC-1) & BASE_ADDRESS_MASK))
-
-
-const device_type PDP1 = &device_creator<pdp1_device>;
-
-
-pdp1_device::pdp1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : cpu_device(mconfig, PDP1, "PDP1", tag, owner, clock, "pdp1_cpu", __FILE__)
- , m_program_config("program", ENDIANNESS_BIG, 32, 18, 0)
-{
- m_is_octal = true;
-}
-
-
-void pdp1_device::device_config_complete()
-{
- // inherit a copy of the static data
- const pdp1_reset_param_t *intf = reinterpret_cast<const pdp1_reset_param_t *>(static_config());
- if (intf != NULL)
- *static_cast<pdp1_reset_param_t *>(this) = *intf;
-
- // or initialize to defaults if none provided
- else
- {
- memset(&read_binary_word, 0, sizeof(read_binary_word));
- memset(&io_sc_callback, 0, sizeof(io_sc_callback));
- extend_support = 0;
- hw_mul_div = 0;
- type_20_sbs = 0;
-
- for (int i = 0; i < 64; i++)
- {
- memset(&extern_iot[i], 0, sizeof(extern_iot[i]));
- }
- }
-}
-
-
-offs_t pdp1_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
-{
- extern CPU_DISASSEMBLE( pdp1 );
- return CPU_DISASSEMBLE_NAME(pdp1)(this, buffer, pc, oprom, opram, options);
-}
-
-
-/*
- Interrupts are called "sequence break" in pdp1, but the general idea is the same.
-
- There are several interrupt lines. With the standard sequence break system, all lines
- are logically or'ed to trigger a single interrupt level. Interrupts can be triggered
- by either a pulse or a level on the interrupt lines. With the optional type 120 sequence
- break system, each of 16 lines triggers is wired to a different priority level: additionnally,
- each interrupt line can be masked out, and interrupt can be triggered through software.
-
- Also, instructions can be interrupted in the middle of execution. This is done by
- decrementing the PC register: therefore the instruction is re-executed from start.
-
- Interrupt routines should not execute most IOT, as the interrupt may interrupt another.
-
- More details can be found in the handbook and the maintenance manual.
-*/
-/*
- This function MUST be called every time m_sbm, m_b4, m_irq_state or m_b2 change.
-*/
-void pdp1_device::field_interrupt()
-{
- /* current_irq: 1 bit for each active pending interrupt request
- Pending interrupts are in b3 (simulated by (m_irq_state & m_b1) | m_b2)), but they
- are only honored if no higher priority interrupt routine is in execution (one bit set in b4
- for each routine in execution). The relevant mask is created with (m_b4 | (- m_b4)),
- as the carry chain (remember that -b4 = (~ b4) + 1) does precisely what we want.
- b4: 0001001001000
- -b4: 1110110111000
- b4|-b4:1111111111000
- Neat, uh?
- */
- int current_irq = ((m_irq_state & m_b1) | m_b2) & ~ (m_b4 | (- m_b4));
- int i;
-
- if (m_sbm && current_irq)
- {
- m_sbs_request = 1;
- for (i=0; /*i<16 &&*/ (! ((current_irq >> i) & 1)); i++)
- ;
- m_sbs_level = i;
- }
- else
- m_sbs_request = 0;
-}
-
-void pdp1_device::execute_set_input(int irqline, int state)
-{
- if (irqline == INPUT_LINE_NMI)
- {
- /* no specific NMI line */
- }
- else if ((irqline >= 0) && (irqline < (m_type_20_sbs ? 1 : 16)))
- {
- unsigned int new_state = state ? 1 : 0;
-
- if (((m_irq_state >> irqline) & 1) != new_state)
- {
- m_irq_state = (m_irq_state & ~ (1 << irqline)) | (new_state << irqline);
-
- if ((new_state) && ((m_b1 >> irqline) & 1))
- m_b2 |= (new_state << irqline);
-
- /*m_b3 = m_irq_state | m_b2;*/
-
- field_interrupt(); /* interrupt state has changed */
- }
- }
-}
-
-
-static void null_iot(device_t *device, int op2, int nac, int mb, int *io, int ac)
-{
- pdp1_device *pdp1 = dynamic_cast<pdp1_device*>(device);
-
- pdp1->pdp1_null_iot(op2, nac, mb, io, ac);
-}
-
-static void lem_eem_iot(device_t *device, int op2, int nac, int mb, int *io, int ac)
-{
- pdp1_device *pdp1 = dynamic_cast<pdp1_device*>(device);
-
- pdp1->pdp1_lem_eem_iot(op2, nac, mb, io, ac);
-}
-
-static void sbs_iot(device_t *device, int op2, int nac, int mb, int *io, int ac)
-{
- pdp1_device *pdp1 = dynamic_cast<pdp1_device*>(device);
-
- pdp1->pdp1_sbs_iot(op2, nac, mb, io, ac);
-}
-
-static void type_20_sbs_iot(device_t *device, int op2, int nac, int mb, int *io, int ac)
-{
- pdp1_device *pdp1 = dynamic_cast<pdp1_device*>(device);
-
- pdp1->pdp1_type_20_sbs_iot(op2, nac, mb, io, ac);
-}
-
-void pdp1_device::device_start()
-{
- int i;
-
- /* clean-up */
- m_pc = 0;
- m_ir = 0;
- m_mb = 0;
- m_ma = 0;
- m_ac = 0;
- m_io = 0;
- m_pf = 0;
- m_ta = 0;
- m_tw = 0;
- m_ss = 0;
- m_sngl_step = 0;
- m_sngl_inst = 0;
- m_extend_sw = 0;
- m_run = 0;
- m_cycle = 0;
- m_defer = 0;
- m_brk_ctr = 0;
- m_ov = 0;
- m_rim = 0;
- m_sbm = 0;
- m_exd = 0;
- m_exc = 0;
- m_ioc = 0;
- m_ioh = 0;
- m_ios = 0;
- m_irq_state = 0;
- m_b1 = 0;
- m_b2 = 0;
- m_b4 = 0;
- m_rim_step = 0;
- m_sbs_request = 0;
- m_sbs_level = 0;
- m_sbs_restore = 0;
- m_no_sequence_break = 0;
- m_debugger_temp = 0;
-
- m_program = &space(AS_PROGRAM);
-
- /* set up params and callbacks */
- for (i=0; i<64; i++)
- {
- m_extern_iot[i] = (extern_iot[i])
- ? extern_iot[i]
- : null_iot;
- }
- m_read_binary_word = read_binary_word;
- m_io_sc_callback = io_sc_callback;
- m_extend_support = extend_support;
- m_hw_mul_div = hw_mul_div;
- m_type_20_sbs = type_20_sbs;
-
- switch (m_extend_support)
- {
- default:
- m_extend_support = 0;
- case 0: /* no extension */
- m_extended_address_mask = 07777;
- m_address_extension_mask = 00000;
- break;
- case 1: /* 15-bit extension */
- m_extended_address_mask = 077777;
- m_address_extension_mask = 070000;
- break;
- case 2: /* 16-bit extension */
- m_extended_address_mask = 0177777;
- m_address_extension_mask = 0170000;
- break;
- }
-
- if (m_extend_support)
- {
- m_extern_iot[074] = lem_eem_iot;
- }
- m_extern_iot[054] = m_extern_iot[055] = m_extern_iot[056] = sbs_iot;
- if (m_type_20_sbs)
- {
- m_extern_iot[050] = m_extern_iot[051] = m_extern_iot[052] = m_extern_iot[053]
- = type_20_sbs_iot;
- }
-
- state_add( PDP1_PC, "PC", m_pc).formatstr("%06O");
- state_add( PDP1_IR, "IR", m_ir).formatstr("%02O");
- state_add( PDP1_MB, "MB", m_mb).formatstr("%06O");
- state_add( PDP1_MA, "MA", m_ma).formatstr("%06O");
- state_add( PDP1_AC, "AC", m_ac).formatstr("%06O");
- state_add( PDP1_IO, "IO", m_io).formatstr("%06O");
- state_add( PDP1_OV, "OV", m_ov).formatstr("%1X");
- state_add( PDP1_PF, "FLAGS", m_pf).formatstr("%02O");
- state_add( PDP1_PF1, "FLAG1", m_debugger_temp).callimport().callexport().formatstr("%1X");
- state_add( PDP1_PF2, "FLAG2", m_debugger_temp).callimport().callexport().formatstr("%1X");
- state_add( PDP1_PF3, "FLAG3", m_debugger_temp).callimport().callexport().formatstr("%1X");
- state_add( PDP1_PF4, "FLAG4", m_debugger_temp).callimport().callexport().formatstr("%1X");
- state_add( PDP1_PF5, "FLAG5", m_debugger_temp).callimport().callexport().formatstr("%1X");
- state_add( PDP1_PF6, "FLAG6", m_debugger_temp).callimport().callexport().formatstr("%1X");
- state_add( PDP1_TA, "TA", m_ta).formatstr("%06O");
- state_add( PDP1_TW, "TW", m_tw).formatstr("%06O");
- state_add( PDP1_SS, "SS", m_ss).formatstr("%02O");
- state_add( PDP1_SS1, "SENSE1", m_debugger_temp).callimport().callexport().formatstr("%1X");
- state_add( PDP1_SS2, "SENSE2", m_debugger_temp).callimport().callexport().formatstr("%1X");
- state_add( PDP1_SS3, "SENSE3", m_debugger_temp).callimport().callexport().formatstr("%1X");
- state_add( PDP1_SS4, "SENSE4", m_debugger_temp).callimport().callexport().formatstr("%1X");
- state_add( PDP1_SS5, "SENSE5", m_debugger_temp).callimport().callexport().formatstr("%1X");
- state_add( PDP1_SS6, "SENSE6", m_debugger_temp).callimport().callexport().formatstr("%1X");
- state_add( PDP1_SNGL_STEP, "SNGLSTEP", m_sngl_step).mask(1).formatstr("%1X");
- state_add( PDP1_SNGL_INST, "SNGLINST", m_sngl_inst).mask(1).formatstr("%1X");
- state_add( PDP1_EXTEND_SW, "EXS", m_extend_sw).mask(1).formatstr("%1X");
- state_add( PDP1_RUN, "RUN", m_run).mask(1).formatstr("%1X");
- state_add( PDP1_CYC, "CYC", m_cycle).mask(1).formatstr("%1X");
- state_add( PDP1_DEFER, "DF", m_defer).mask(1).formatstr("%1X");
- state_add( PDP1_BRK_CTR, "BRKCTR", m_brk_ctr).mask(3).formatstr("%1X");
- state_add( PDP1_RIM, "RIM", m_rim).mask(1).formatstr("%1X");
- state_add( PDP1_SBM, "SBM", m_sbm).mask(1).formatstr("%1X");
- state_add( PDP1_EXD, "EXD", m_exd).mask(1).formatstr("%1X");
- state_add( PDP1_IOC, "IOC", m_ioc).mask(1).formatstr("%1X");
- state_add( PDP1_IOH, "IOH", m_ioh).mask(1).formatstr("%1X");
- state_add( PDP1_IOS, "IOS", m_ios).mask(1).formatstr("%1X");
-
- state_add( STATE_GENPC, "GENPC", m_pc ).noshow();
- state_add( STATE_GENFLAGS, "GENFLAGS", m_pf ).formatstr("%13s").noshow();
-
- m_icountptr = &m_icount;
-
- /* reset CPU flip-flops */
- pulse_start_clear();
-}
-
-
-void pdp1_device::state_import(const device_state_entry &entry)
-{
- switch (entry.index())
- {
- case PDP1_PF1:
- WRITEFLAG(1, m_debugger_temp ? 1 : 0);
- break;
- case PDP1_PF2:
- WRITEFLAG(2, m_debugger_temp ? 1 : 0);
- break;
- case PDP1_PF3:
- WRITEFLAG(3, m_debugger_temp ? 1 : 0);
- break;
- case PDP1_PF4:
- WRITEFLAG(4, m_debugger_temp ? 1 : 0);
- break;
- case PDP1_PF5:
- WRITEFLAG(5, m_debugger_temp ? 1 : 0);
- break;
- case PDP1_PF6:
- WRITEFLAG(6, m_debugger_temp ? 1 : 0);
- break;
- case PDP1_SS1:
- WRITESENSE(1, m_debugger_temp ? 1 : 0);
- break;
- case PDP1_SS2:
- WRITESENSE(2, m_debugger_temp ? 1 : 0);
- break;
- case PDP1_SS3:
- WRITESENSE(3, m_debugger_temp ? 1 : 0);
- break;
- case PDP1_SS4:
- WRITESENSE(4, m_debugger_temp ? 1 : 0);
- break;
- case PDP1_SS5:
- WRITESENSE(5, m_debugger_temp ? 1 : 0);
- break;
- case PDP1_SS6:
- WRITESENSE(6, m_debugger_temp ? 1 : 0);
- break;
- }
-}
-
-
-void pdp1_device::state_export(const device_state_entry &entry)
-{
- switch (entry.index())
- {
- case PDP1_PF1:
- m_debugger_temp = READFLAG(1);
- break;
- case PDP1_PF2:
- m_debugger_temp = READFLAG(2);
- break;
- case PDP1_PF3:
- m_debugger_temp = READFLAG(3);
- break;
- case PDP1_PF4:
- m_debugger_temp = READFLAG(4);
- break;
- case PDP1_PF5:
- m_debugger_temp = READFLAG(5);
- break;
- case PDP1_PF6:
- m_debugger_temp = READFLAG(6);
- break;
- case PDP1_SS1:
- m_debugger_temp = READSENSE(1);
- break;
- case PDP1_SS2:
- m_debugger_temp = READSENSE(2);
- break;
- case PDP1_SS3:
- m_debugger_temp = READSENSE(3);
- break;
- case PDP1_SS4:
- m_debugger_temp = READSENSE(4);
- break;
- case PDP1_SS5:
- m_debugger_temp = READSENSE(5);
- break;
- case PDP1_SS6:
- m_debugger_temp = READSENSE(6);
- break;
- }
-}
-
-
-void pdp1_device::state_string_export(const device_state_entry &entry, std::string &str)
-{
- switch (entry.index())
- {
- case STATE_GENFLAGS:
- strprintf(str, "%c%c%c%c%c%c-%c%c%c%c%c%c",
- (FLAGS & 040) ? '1' : '.',
- (FLAGS & 020) ? '2' : '.',
- (FLAGS & 010) ? '3' : '.',
- (FLAGS & 004) ? '4' : '.',
- (FLAGS & 002) ? '5' : '.',
- (FLAGS & 001) ? '6' : '.',
- (SENSE_SW & 040) ? '1' : '.',
- (SENSE_SW & 020) ? '2' : '.',
- (SENSE_SW & 010) ? '3' : '.',
- (SENSE_SW & 004) ? '4' : '.',
- (SENSE_SW & 002) ? '5' : '.',
- (SENSE_SW & 001) ? '6' : '.');
- break;
- }
-}
-
-
-void pdp1_device::device_reset()
-{
- // Nothing to do??
-}
-
-/*
- flags:
- * 1 for each instruction which supports indirect addressing (memory reference instructions,
- except cal and jda, and with the addition of jmp and jsp)
- * 2 for memory reference instructions
-*/
-static const UINT8 instruction_kind[32] =
-{
-/* and ior xor xct cal/jda */
- 0, 3, 3, 3, 3, 0, 0, 2,
-/* lac lio dac dap dip dio dzm */
- 3, 3, 3, 3, 3, 3, 3, 0,
-/* add sub idx isp sad sas mus dis */
- 3, 3, 3, 3, 3, 3, 3, 3,
-/* jmp jsp skp sft law iot opr */
- 1, 1, 0, 0, 0, 0, 0, 0
-};
-
-
-/* execute instructions on this CPU until icount expires */
-void pdp1_device::execute_run()
-{
- do
- {
- debugger_instruction_hook(this, PC);
-
-
- /* ioh should be cleared at the end of the instruction cycle, and ios at the
- start of next instruction cycle, but who cares? */
- if (m_ioh && m_ios)
- {
- m_ioh = 0;
- }
-
-
- if ((! m_run) && (! m_rim))
- m_icount = 0; /* if processor is stopped, just burn cycles */
- else if (m_rim)
- {
- switch (m_rim_step)
- {
- case 0:
- /* read first word as instruction */
- if (m_read_binary_word)
- (*m_read_binary_word)(this); /* data will be transferred to IO register */
- m_rim_step = 1;
- m_ios = 0;
- break;
-
- case 1:
- if (! m_ios)
- { /* transfer incomplete: wait some more */
- m_icount = 0;
- }
- else
- { /* data transfer complete */
- m_ios = 0;
-
- MB = IO;
- IR = MB >> 13; /* basic opcode */
- if (IR == JMP) /* jmp instruction ? */
- {
- PC = (MA & ADDRESS_EXTENSION_MASK) | (MB & BASE_ADDRESS_MASK);
- m_rim = 0; /* exit read-in mode */
- m_run = 1;
- m_rim_step = 0;
- }
- else if ((IR == DIO) || (IR == DAC)) /* dio or dac instruction ? */
- { /* there is a discrepancy: the pdp1 handbook tells that only dio should be used,
- but the lisp tape uses the dac instruction instead */
- /* Yet maintenance manual p. 6-25 states clearly that the data is located
- in IO and transfered to MB, so DAC is likely to be a mistake. */
- m_rim_step = 2;
- }
- else
- {
- /* what the heck? */
- if (LOG)
- logerror("It seems this tape should not be operated in read-in mode\n");
-
- m_rim = 0; /* exit read-in mode (right???) */
- m_rim_step = 0;
- }
- }
- break;
-
- case 2:
- /* read second word as data */
- if (m_read_binary_word)
- (*m_read_binary_word)(this); /* data will be transferred to IO register */
- m_rim_step = 3;
- m_ios = 0;
- break;
-
- case 3:
- if (! m_ios)
- { /* transfer incomplete: wait some more */
- m_icount = 0;
- }
- else
- { /* data transfer complete */
- m_ios = 0;
-
- MA = (PC & ADDRESS_EXTENSION_MASK) | (MB & BASE_ADDRESS_MASK);
-
- MB = IO;
- WRITE_PDP_18BIT(MA, MB);
-
- m_rim_step = 0;
- }
- break;
- }
- }
- else
- {
- /* yes, interrupt can occur in the midst of an instruction (impressing, huh?) */
- /* Note that break cannot occur during a one-cycle jump that is deferred only once,
- or another break cycle. Also, it cannot interrupt the long cycle 1 of automatic
- multiply/divide. (maintenance manual 6-19) */
- if (m_sbs_request && (! m_no_sequence_break) && (! m_brk_ctr))
- { /* begin sequence break */
- m_brk_ctr = 1;
- }
- if (m_brk_ctr)
- { /* sequence break in progress */
- switch (m_brk_ctr)
- {
- case 1:
- if (m_cycle)
- DECREMENT_PC; /* set PC to point to aborted instruction, so that it can be re-run */
-
- m_b4 |= (1 << m_sbs_level); /* set "interrupt in progress" flag */
- m_b2 &= ~(1 << m_sbs_level); /* clear interrupt request */
- field_interrupt();
- MA = m_sbs_level << 2; /* always 0 with standard sequence break system */
- MB = AC; /* save AC to MB */
- AC = (OV << 17) | (EXD << 16) | PC; /* save OV/EXD/PC to AC */
- EXD = OV = 0; /* according to maintenance manual p. 8-17 and ?-?? */
- m_cycle = m_defer = m_exc = 0; /* mere guess */
- WRITE_PDP_18BIT(MA, MB); /* save former AC to memory */
- INCREMENT_MA;
- m_icount -= 5;
- m_brk_ctr++;
- break;
-
- case 2:
- WRITE_PDP_18BIT(MA, MB = AC); /* save former OV/EXD/PC to memory */
- INCREMENT_MA;
- m_icount -= 5;
- m_brk_ctr++;
- break;
-
- case 3:
- WRITE_PDP_18BIT(MA, MB = IO); /* save IO to memory */
- INCREMENT_MA;
- PC = MA;
- m_icount -= 5;
- m_brk_ctr = 0;
- break;
- }
- }
- else
- {
- if (m_no_sequence_break)
- m_no_sequence_break = 0;
-
- if (! m_cycle)
- { /* no instruction in progress: time to fetch a new instruction, I guess */
- MB = READ_PDP_18BIT(MA = PC);
- INCREMENT_PC;
- IR = MB >> 13; /* basic opcode */
-
- if ((instruction_kind[IR] & 1) && (MB & 010000))
- {
- m_defer = 1;
- m_cycle = 1; /* instruction shall be executed later */
-
- /* detect deferred one-cycle jumps */
- if ((IR == JMP) || (IR == JSP))
- {
- m_no_sequence_break = 1;
- /* detect JMP *(4*n+1) to memory module 0 if in sequence break mode */
- if (((MB & 0777703) == 0610001) && (m_sbm) && ! (MA & 0170000))
- {
- int level = (MB & 0000074) >> 2;
-
- if ((m_type_20_sbs) || (level == 0))
- {
- m_b4 &= ~(1 << level);
- field_interrupt();
- if (m_extend_support)
- EXD = 1; /* according to maintenance manual p. 6-33 */
- m_sbs_restore = 1;
- }
- }
- }
- }
- else if (instruction_kind[IR] & 2)
- m_cycle = 1; /* instruction shall be executed later */
- else
- execute_instruction(); /* execute instruction at once */
-
- m_icount -= 5;
- }
- else if (m_defer)
- { /* defer cycle : handle indirect addressing */
- MA = (PC & ADDRESS_EXTENSION_MASK) | (MB & BASE_ADDRESS_MASK);
-
- MB = READ_PDP_18BIT(MA);
-
- /* determinate new value of m_defer */
- if (EXD)
- {
- m_defer = 0;
- m_exc = 1;
- }
- else
- m_defer = (MB & 010000) ? 1 : 0;
-
- /* execute JMP and JSP immediately if applicable */
- if ((! m_defer) && (! (instruction_kind[IR] & 2)))
- {
- execute_instruction(); /* execute instruction at once */
- /*m_cycle = 0;*/
- m_exc = 0;
-
- if (m_sbs_restore)
- { /* interrupt return: according to maintenance manual p. 6-33 */
- if (m_extend_support)
- EXD = (MB >> 16) & 1;
- OV = (MB >> 17) & 1;
- m_sbs_restore = 0;
- }
- }
-
- m_icount -= 5;
- }
- else
- { /* memory reference instruction in cycle 1 */
- if (m_exc)
- {
- MA = MB & EXTENDED_ADDRESS_MASK;
- m_exc = 0;
- }
- else
- MA = (PC & ADDRESS_EXTENSION_MASK) | (MB & BASE_ADDRESS_MASK);
-
- execute_instruction(); /* execute instruction */
-
- m_icount -= 5;
- }
-
- if ((m_sngl_inst) && (! m_cycle))
- m_run = 0;
- }
- if (m_sngl_step)
- m_run = 0;
- }
- }
- while (m_icount > 0);
-}
-
-
-/* execute one instruction */
-void pdp1_device::execute_instruction()
-{
- switch (IR)
- {
- case AND: /* Logical And */
- AC &= (MB = READ_PDP_18BIT(MA));
- break;
- case IOR: /* Inclusive Or */
- AC |= (MB = READ_PDP_18BIT(MA));
- break;
- case XOR: /* Exclusive Or */
- AC ^= (MB = READ_PDP_18BIT(MA));
- break;
- case XCT: /* Execute */
- MB = READ_PDP_18BIT(MA);
- IR = MB >> 13; /* basic opcode */
- if ((instruction_kind[IR] & 1) && (MB & 010000))
- {
- m_defer = 1;
- /*m_cycle = 1;*/ /* instruction shall be executed later */
- goto no_fetch; /* fall through to next instruction */
- }
- else if (instruction_kind[IR] & 2)
- {
- /*m_cycle = 1;*/ /* instruction shall be executed later */
- goto no_fetch; /* fall through to next instruction */
- }
- else
- execute_instruction(); /* execute instruction at once */
- break;
- case CALJDA: /* Call subroutine and Jump and Deposit Accumulator instructions */
- if (MB & 010000)
- /* JDA */
- MA = (PC & ADDRESS_EXTENSION_MASK) | (MB & BASE_ADDRESS_MASK);
- else
- /* CAL: equivalent to JDA 100 */
- /* Note that I cannot tell for sure what happens to extension bits, but I did notice
- that setting the extension bits to 0 would make cal basically useless, since
- there would be no simple way the call routine could return to the callee
- if it were located in another module with extend mode off (i.e. exd == 0). */
- MA = (PC & ADDRESS_EXTENSION_MASK) | 0100;
-
- WRITE_PDP_18BIT(MA, (MB = AC));
- INCREMENT_MA;
- AC = (OV << 17) | (EXD << 16) | PC;
- PC = MA;
- break;
- case LAC: /* Load Accumulator */
- AC = (MB = READ_PDP_18BIT(MA));
- break;
- case LIO: /* Load i/o register */
- IO = (MB = READ_PDP_18BIT(MA));
- break;
- case DAC: /* Deposit Accumulator */
- WRITE_PDP_18BIT(MA, (MB = AC));
- break;
- case DAP: /* Deposit Address Part */
- WRITE_PDP_18BIT(MA, (MB = ((READ_PDP_18BIT(MA) & 0770000) | (AC & 0007777))));
- break;
- case DIP: /* Deposit Instruction Part */
- WRITE_PDP_18BIT(MA, (MB = ((READ_PDP_18BIT(MA) & 0007777) | (AC & 0770000))));
- break;
- case DIO: /* Deposit I/O Register */
- WRITE_PDP_18BIT(MA, (MB = IO));
- break;
- case DZM: /* Deposit Zero in Memory */
- WRITE_PDP_18BIT(MA, (MB = 0));
- break;
- case ADD: /* Add */
- {
- /* overflow is set if the 2 operands have the same sign and the final result has another */
- int ov2; /* 1 if the operands have the same sign*/
-
- MB = READ_PDP_18BIT(MA);
-
- ov2 = ((AC & 0400000) == (MB & 0400000));
-
- AC = AC + MB;
- AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */
-
- /* I think we need to check for overflow before checking for -0,
- because the sum -0+-0 = -0 = +0 would generate an overflow
- otherwise. */
- if (ov2 && ((AC & 0400000) != (MB & 0400000)))
- OV = 1;
-
- if (AC == 0777777) /* check for -0 */
- AC = 0;
-
- break;
- }
- case SUB: /* Subtract */
- { /* maintenance manual 7-14 seems to imply that substract does not test for -0.
- The sim 2.3 source says so explicitely, though they do not give a reference.
- It sounds a bit weird, but the reason is probably that doing so would
- require additionnal logic that does not exist. */
- /* overflow is set if the 2 operands have the same sign and the final result has another */
- int ov2; /* 1 if the operands have the same sign*/
-
- AC ^= 0777777;
-
- MB = READ_PDP_18BIT(MA);
-
- ov2 = ((AC & 0400000) == (MB & 0400000));
-
- AC = AC + MB;
- AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */
-
- if (ov2 && ((AC & 0400000) != (MB & 0400000)))
- OV = 1;
-
- AC ^= 0777777;
-
- break;
- }
- case IDX: /* Index */
- AC = READ_PDP_18BIT(MA) + 1;
-
- #if 0
- AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */
- if (AC == 0777777) /* check for -0 */
- AC = 0;
- #else
- if (AC >= 0777777)
- AC = (AC + 1) & 0777777;
- #endif
-
- WRITE_PDP_18BIT(MA, (MB = AC));
- break;
- case ISP: /* Index and Skip if Positive */
- AC = READ_PDP_18BIT(MA) + 1;
-
- #if 0
- AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */
- if (AC == 0777777) /* check for -0 */
- AC = 0;
- #else
- if (AC >= 0777777)
- AC = (AC + 1) & 0777777;
- #endif
-
- WRITE_PDP_18BIT(MA, (MB = AC));
- if ((AC & 0400000) == 0)
- INCREMENT_PC;
- break;
- case SAD: /* Skip if Accumulator and Y differ */
- if (AC != (MB = READ_PDP_18BIT(MA)))
- INCREMENT_PC;
- break;
- case SAS: /* Skip if Accumulator and Y are the same */
- if (AC == (MB = READ_PDP_18BIT(MA)))
- INCREMENT_PC;
- break;
- case MUS_MUL: /* Multiply Step or Multiply */
- if (m_hw_mul_div)
- { /* MUL */
- int scr;
- int smb, srm;
- double etime = 4.; /* approximative */
-
- IO = MB = AC;
- MB = READ_PDP_18BIT(MA);
- scr = 0;
- if (MB & 0400000)
- {
- smb = 1;
- MB = MB ^ 0777777;
- }
- else
- smb = 0;
- if (IO & 0400000)
- {
- srm = 1;
- IO = IO ^ 0777777;
- }
- else
- srm = 0;
- AC = 0;
- scr++;
- while (scr < 022)
- {
- if (IO & 1)
- {
- /*assert(! (AC & 0400000));*/
- AC = AC + MB;
- /* we can save carry around since both numbers are positive */
- /*AC = (AC + (AC >> 18)) & 0777777;*/
- etime += .65; /* approximative */
- }
- IO = (IO >> 1) | ((AC & 1) << 17);
- AC = AC >> 1;
- scr++;
- }
- if (smb ^ srm)
- {
- AC = AC ^ 0777777;
- IO = IO ^ 0777777;
- }
-
- m_icount -= etime+.5; /* round to closest */
- }
- else
- { /* MUS */
- /* should we check for -0??? (Maintenance manual 7-14 seems to imply we should not:
- as a matter of fact, since the MUS instruction is supposed to have positive operands,
- there is no need to check for -0, therefore such a simplification does not sound
- absurd.) */
- if ((IO & 1) == 1)
- {
- AC = AC + (MB = READ_PDP_18BIT(MA));
- AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */
- }
- IO = (IO >> 1 | AC << 17) & 0777777;
- AC >>= 1;
- }
- break;
- case DIS_DIV: /* Divide Step or Divide */
- if (m_hw_mul_div)
- { /* DIV */
- /* As a side note, the order of -0 detection and overflow checking does not matter,
- because the sum of two positive number cannot give 0777777 (since positive
- numbers are 0377777 at most, their sum is 0777776 at most).
- Additionnally, we cannot have carry set and a result equal to 0777777 (since numbers
- are 0777777 at most, their sum is 01777776 at most): this is nice, because it makes
- the sequence:
- AC = (AC + (AC >> 18)) & 0777777; // propagate carry around
- if (AC == 0777777) // check for -0
- AC = 0;
- equivalent to:
- if (AC >= 0777777)
- AC = (AC + 1) & 0777777;
- which is a bit more efficient. */
- int acl;
- int scr;
- int smb, srm;
- double etime = 0; /* approximative */
-
- MB = READ_PDP_18BIT(MA);
- scr = 0;
- if (MB & 0400000)
- {
- smb = 1;
- }
- else
- {
- smb = 0;
- MB = MB ^ 0777777;
- }
- if (AC & 0400000)
- {
- srm = 1;
- AC = AC ^ 0777777;
- IO = IO ^ 0777777;
- }
- else
- srm = 0;
- while (1)
- {
- AC = (AC + MB);
- #if 1
- AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */
- if (AC == 0777777) /* check for -0 */
- AC = 0;
- #else
- if (AC >= 0777777)
- AC = (AC + 1) & 0777777;
- #endif
- if (MB & 0400000)
- MB = MB ^ 0777777;
-
- if (((scr == 0) && ! (AC & 0400000))
- || (scr == 022))
- break;
-
- scr++;
-
- if (! (AC & 0400000))
- MB = MB ^ 0777777;
-
- acl = AC >> 17;
- AC = (AC << 1 | IO >> 17) & 0777777;
- IO = ((IO << 1 | acl) & 0777777) ^ 1;
- if (acl)
- {
- AC++;
- AC = (AC + (AC >> 18)) & 0777777;
- etime += .6; /* approximative */
- }
- }
-
- AC = (AC + MB);
- #if 1
- AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */
- if (AC == 0777777) /* check for -0 */
- AC = 0;
- #else
- if (AC >= 0777777)
- AC = (AC + 1) & 0777777;
- #endif
-
- if (scr)
- {
- INCREMENT_PC;
- AC = AC >> 1;
- }
-
- if (srm && (AC != 0))
- AC = AC ^ 0777777;
-
- if (((! scr) && (srm))
- || (scr && (srm ^ smb) && (IO != 0)))
- IO = IO ^ 0777777;
-
- if (scr)
- {
- MB = AC;
- AC = IO;
- IO = MB;
- }
- if (scr)
- etime += 20; /* approximative */
- else
- etime += 2; /* approximative */
-
- m_icount -= etime+.5; /* round to closest */
- }
- else
- { /* DIS */
- int acl;
-
- acl = AC >> 17;
- AC = (AC << 1 | IO >> 17) & 0777777;
- IO = ((IO << 1 | acl) & 0777777) ^ 1;
- MB = READ_PDP_18BIT(MA);
- if (IO & 1)
- AC += (MB ^ 0777777);
- else
- /* Note that if AC+MB = 0777777, we are in trouble. I don't
- know how a real PDP-1 behaves in this case. */
- AC += MB + 1;
- AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */
- if (AC == 0777777) /* check for -0 */
- AC = 0;
- }
- break;
- case JMP: /* Jump */
- if (m_exc)
- PC = MB & EXTENDED_ADDRESS_MASK;
- else
- PC = (MA & ADDRESS_EXTENSION_MASK) | (MB & BASE_ADDRESS_MASK);
- break;
- case JSP: /* Jump and Save Program Counter */
- AC = (OV << 17) | (EXD << 16) | PC;
- if (m_exc)
- PC = MB & EXTENDED_ADDRESS_MASK;
- else
- PC = (MA & ADDRESS_EXTENSION_MASK) | (MB & BASE_ADDRESS_MASK);
- break;
- case SKP: /* Skip Instruction Group */
- {
- int cond = ((MB & 0100) && (AC == 0)) /* ZERO Accumulator */
- || ((MB & 0200) && (AC >> 17 == 0)) /* Plus Accumulator */
- || ((MB & 0400) && (AC >> 17 == 1)) /* Minus Accumulator */
- || ((MB & 01000) && (OV == 0)) /* ZERO Overflow */
- || ((MB & 02000) && (IO >> 17 == 0)) /* Plus I/O Register */
- || (((MB & 7) != 0) && (((MB & 7) == 7) ? ! FLAGS : ! READFLAG(MB & 7))) /* ZERO Flag (deleted by mistake in PDP-1 handbook) */
- || (((MB & 070) != 0) && (((MB & 070) == 070) ? ! SENSE_SW : ! READSENSE((MB & 070) >> 3))); /* ZERO Switch */
-
- if (! (MB & 010000))
- {
- if (cond)
- INCREMENT_PC;
- }
- else
- {
- if (!cond)
- INCREMENT_PC;
- }
- if (MB & 01000)
- OV = 0;
- break;
- }
- case SFT: /* Shift Instruction Group */
- {
- /* Bit 5 specifies direction of shift, Bit 6 specifies the character of the shift
- (arithmetic or logical), Bits 7 and 8 enable the registers (01 = AC, 10 = IO,
- and 11 = both) and Bits 9 through 17 specify the number of steps. */
- int nshift = 0;
- int mask = MB & 0777;
-
- while (mask != 0)
- {
- nshift += mask & 1;
- mask >>= 1;
- }
- switch ((MB >> 9) & 017)
- {
- int i;
-
- case 1: /* ral rotate accumulator left */
- for (i = 0; i < nshift; i++)
- AC = (AC << 1 | AC >> 17) & 0777777;
- break;
- case 2: /* ril rotate i/o register left */
- for (i = 0; i < nshift; i++)
- IO = (IO << 1 | IO >> 17) & 0777777;
- break;
- case 3: /* rcl rotate AC and IO left */
- for (i = 0; i < nshift; i++)
- {
- int tmp = AC;
-
- AC = (AC << 1 | IO >> 17) & 0777777;
- IO = (IO << 1 | tmp >> 17) & 0777777;
- }
- break;
- case 5: /* sal shift accumulator left */
- for (i = 0; i < nshift; i++)
- AC = ((AC << 1 | AC >> 17) & 0377777) + (AC & 0400000);
- break;
- case 6: /* sil shift i/o register left */
- for (i = 0; i < nshift; i++)
- IO = ((IO << 1 | IO >> 17) & 0377777) + (IO & 0400000);
- break;
- case 7: /* scl shift AC and IO left */
- for (i = 0; i < nshift; i++)
- {
- int tmp = AC;
-
- AC = ((AC << 1 | IO >> 17) & 0377777) + (AC & 0400000); /* shouldn't that be IO?, no it is the sign! */
- IO = (IO << 1 | tmp >> 17) & 0777777;
- }
- break;
- case 9: /* rar rotate accumulator right */
- for (i = 0; i < nshift; i++)
- AC = (AC >> 1 | AC << 17) & 0777777;
- break;
- case 10: /* rir rotate i/o register right */
- for (i = 0; i < nshift; i++)
- IO = (IO >> 1 | IO << 17) & 0777777;
- break;
- case 11: /* rcr rotate AC and IO right */
- for (i = 0; i < nshift; i++)
- {
- int tmp = AC;
-
- AC = (AC >> 1 | IO << 17) & 0777777;
- IO = (IO >> 1 | tmp << 17) & 0777777;
- }
- break;
- case 13: /* sar shift accumulator right */
- for (i = 0; i < nshift; i++)
- AC = (AC >> 1) + (AC & 0400000);
- break;
- case 14: /* sir shift i/o register right */
- for (i = 0; i < nshift; i++)
- IO = (IO >> 1) + (IO & 0400000);
- break;
- case 15: /* scr shift AC and IO right */
- for (i = 0; i < nshift; i++)
- {
- int tmp = AC;
-
- AC = (AC >> 1) + (AC & 0400000); /* shouldn't that be IO, no it is the sign */
- IO = (IO >> 1 | tmp << 17) & 0777777;
- }
- break;
- default:
- if (LOG)
- logerror("Undefined shift: 0%06o at 0%06o\n", MB, PREVIOUS_PC);
- break;
- }
- break;
- }
- case LAW: /* Load Accumulator with N */
- AC = MB & 07777;
- if (MB & 010000)
- AC ^= 0777777;
- break;
- case IOT: /* In-Out Transfer Instruction Group */
- /*
- The variations within this group of instructions perform all the in-out control
- and information transfer functions. If Bit 5 (normally the Indirect Address bit)
- is a ONE, the computer will enter a special waiting state until the completion pulse
- from the activated device has returned. When this device delivers its completion,
- the computer will resume operation of the instruction sequence.
-
- The computer may be interrupted from the special waiting state to serve a sequence
- break request or a high speed channel request.
-
- Most in-out operations require a known minimum time before completion. This time
- may be utilized for programming. The appropriate In-Out Transfer can be given with
- no in-out wait (Bit 5 a ZERO and Bit 6 a ONE). The instruction sequence then
- continues. This sequence must include an iot instruction 730000 which performs
- nothing but the in-out wait. The computer will then enter the special waiting state
- until the device returns the in-out restart pulse. If the device has already
- returned the completion pulse before the instruction 730000, the computer will
- proceed immediately.
-
- Bit 6 determines whether a completion pulse will or will not be received from
- the in-out device. When it is different than Bit 5, a completion pulse will be
- received. When it is the same as Bit 5, a completion pulse will not be received.
-
- In addition to the control function of Bits 5 and 6, Bits 7 through 11 are also
- used as control bits serving to extend greatly the power of the iot instructions.
- For example, Bits 12 through 17, which are used to designate a class of input or
- output devices such as typewriters, may be further defined by Bits 7 through 11
- as referring to Typewriter 1, 2, 3, etc. In several of the optional in-out devices,
- in particular the magnetic tape, Bits 7 through 11 specify particular functions
- such as forward, backward etc. If a large number of specialized devices are to
- be attached, these bits may be used to further the in-out transfer instruction
- to perform totally distinct functions.
-
- Note that ioc is supposed to be set at the beggining of the memory cycle after
- ioh is cleared.
- However, we cannot set ioc at the beggining of every memory cycle as we
- did before, because it breaks in the following case:
- a) IOT instruction enables IO wait
- b) sequence break in the middle of IO-halt
- c) ioh is cleared in middle of sequence break routine
- d) re-execute IOT instruction. Unfortunately, ioc has been cleared, therefore
- we perform an IOT command pulse and IO wait again, which is completely WRONG.
- Therefore ioc is cleared only after a IOT with wait is executed.
- */
- if (MB & 010000)
- { /* IOT with IO wait */
- if (m_ioc)
- { /* the iot command line is pulsed only if ioc is asserted */
- (*m_extern_iot[MB & 0000077])(this, MB & 0000077, (MB & 0004000) == 0, MB, &IO, AC);
-
- m_ioh = 1; /* enable io wait */
-
- m_ioc = 0; /* actually happens at the start of next memory cycle */
-
- /* test ios now in case the IOT callback has sent a completion pulse immediately */
- if (m_ioh && m_ios)
- {
- /* ioh should be cleared at the end of the instruction cycle, and ios at the
- start of next instruction cycle, but who cares? */
- m_ioh = 0;
- //m_ios = 0;
- }
- }
-
- if (m_ioh)
- DECREMENT_PC;
- else
- m_ioc = 1; /* actually happens at the start of next memory cycle */
- }
- else
- { /* IOT with no IO wait */
- (*m_extern_iot[MB & 0000077])(this, MB & 0000077, (MB & 0004000) != 0, MB, &IO, AC);
- }
- break;
- case OPR: /* Operate Instruction Group */
- {
- int nflag;
-
- if (MB & 00200) /* clear AC */
- AC = 0;
- if (MB & 04000) /* clear I/O register */
- IO = 0;
- if (MB & 02000) /* load Accumulator from Test Word */
- AC |= m_tw;
- if (MB & 00100) /* load Accumulator with Program Counter */
- AC |= (OV << 17) | (EXD << 16) | PC;
- nflag = MB & 7;
- if (nflag)
- {
- if (nflag == 7)
- FLAGS = (MB & 010) ? 077 : 000;
- else
- WRITEFLAG(nflag, (MB & 010) ? 1 : 0);
- }
- if (MB & 01000) /* Complement AC */
- AC ^= 0777777;
- if (MB & 00400) /* Halt */
- {
- if (LOG_EXTRA)
- logerror("PDP1 Program executed HALT: at 0%06o\n", PREVIOUS_PC);
-
- m_run = 0;
- }
- break;
- }
- default:
- if (LOG)
- logerror("Illegal instruction: 0%06o at 0%06o\n", MB, PREVIOUS_PC);
-
- /* let us stop the CPU, like a real pdp-1 */
- m_run = 0;
-
- break;
- }
- m_cycle = 0;
-no_fetch:
- ;
-}
-
-
-/*
- Handle unimplemented IOT
-*/
-void pdp1_device::pdp1_null_iot(int op2, int nac, int mb, int *io, int ac)
-{
- /* Note that the dummy IOT 0 is used to wait for the completion pulse
- generated by the a pending IOT (IOT with completion pulse but no IO wait) */
- if (LOG_IOT_EXTRA)
- {
- if (op2 == 000)
- logerror("IOT sync instruction: mb=0%06o, pc=0%06o\n", (unsigned) mb, (unsigned) m_pc);
- }
- if (LOG)
- {
- if (op2 != 000)
- logerror("Not supported IOT command (no external IOT function given) 0%06o at 0%06o\n", mb, m_pc);
- }
-}
-
-
-/*
- Memory expansion control (type 15)
-
- IOT 74: LEM/EEM
-*/
-void pdp1_device::pdp1_lem_eem_iot(int op2, int nac, int mb, int *io, int ac)
-{
- if (! m_extend_support) /* extend mode supported? */
- {
- if (LOG)
- logerror("Ignoring internal error in file " __FILE__ " line %d.\n", __LINE__);
- return;
- }
- if (LOG_EXTRA)
- {
- logerror("EEM/LEM instruction: mb=0%06o, pc=0%06o\n", mb, m_pc);
- }
- EXD = (mb & 0004000) ? 1 : 0;
-}
-
-
-/*
- Standard sequence break system
-
- IOT 54: lsm
- IOT 55: esm
- IOT 56: cbs
-*/
-void pdp1_device::pdp1_sbs_iot(int op2, int nac, int mb, int *io, int ac)
-{
- switch (op2)
- {
- case 054: /* LSM */
- if (LOG_EXTRA)
- logerror("LSM instruction: mb=0%06o, pc=0%06o\n", mb, m_pc);
-
- m_sbm = 0;
- field_interrupt();
- break;
- case 055: /* ESM */
- if (LOG_EXTRA)
- logerror("ESM instruction: mb=0%06o, pc=0%06o\n", mb, m_pc);
-
- m_sbm = 1;
- field_interrupt();
- break;
- case 056: /* CBS */
- if (LOG_EXTRA)
- logerror("CBS instruction: mb=0%06o, pc=0%06o\n", mb, m_pc);
-
- /*m_b3 = 0;*/
- m_b4 = 0;
- field_interrupt();
- break;
- default:
- if (LOG)
- logerror("Ignoring internal error in file " __FILE__ " line %d.\n", __LINE__);
-
- break;
- }
-}
-
-
-/*
- type 20 sequence break system
-
- IOT 50: dsc
- IOT 51: asc
- IOT 52: isb
- IOT 53: cac
-*/
-void pdp1_device::pdp1_type_20_sbs_iot(int op2, int nac, int mb, int *io, int ac)
-{
- int channel, mask;
- if (! m_type_20_sbs) /* type 20 sequence break system supported? */
- {
- if (LOG)
- logerror("Ignoring internal error in file " __FILE__ " line %d.\n", __LINE__);
- return;
- }
- channel = (mb >> 6) & 017;
- mask = 1 << channel;
- switch (op2)
- {
- case 050: /* DSC */
- if (LOG_EXTRA)
- logerror("DSC instruction: mb=0%06o, pc=0%06o\n", mb, m_pc);
-
- m_b1 &= ~mask;
- field_interrupt();
- break;
- case 051: /* ASC */
- if (LOG_EXTRA)
- logerror("ASC instruction: mb=0%06o, pc=0%06o\n", mb, m_pc);
-
- m_b1 |= mask;
- field_interrupt();
- break;
- case 052: /* ISB */
- if (LOG_EXTRA)
- logerror("ISB instruction: mb=0%06o, pc=0%06o\n", mb, m_pc);
-
- m_b2 |= mask;
- field_interrupt();
- break;
- case 053: /* CAC */
- if (LOG_EXTRA)
- logerror("CAC instruction: mb=0%06o, pc=0%06o\n", mb, m_pc);
-
- m_b1 = 0;
- field_interrupt();
- break;
- default:
- if (LOG)
- logerror("Ignoring internal error in file " __FILE__ " line %d.\n", __LINE__);
-
- break;
- }
-
-}
-
-
-/*
- Simulate a pulse on start/clear line:
- reset most registers and flip-flops, and initialize a few emulator state
- variables.
-*/
-void pdp1_device::pulse_start_clear()
-{
- /* processor registers */
- PC = 0; /* according to maintenance manual p. 6-17 */
- IR = 0; /* according to maintenance manual p. 6-13 */
- /*MB = 0;*/ /* ??? */
- /*MA = 0;*/ /* ??? */
- /*AC = 0;*/ /* ??? */
- /*IO = 0;*/ /* ??? */
- /*PF = 0;*/ /* ??? */
-
- /* processor state flip-flops */
- m_run = 0; /* ??? */
- m_cycle = 0; /* mere guess */
- m_defer = 0; /* mere guess */
- m_brk_ctr = 0; /* mere guess */
- m_ov = 0; /* according to maintenance manual p. 7-18 */
- m_rim = 0; /* ??? */
- m_sbm = 0; /* ??? */
- EXD = 0; /* according to maintenance manual p. 8-16 */
- m_exc = 0; /* according to maintenance manual p. 8-16 */
- m_ioc = 1; /* according to maintenance manual p. 6-10 */
- m_ioh = 0; /* according to maintenance manual p. 6-10 */
- m_ios = 0; /* according to maintenance manual p. 6-10 */
-
- m_b1 = m_type_20_sbs ? 0 : 1; /* mere guess */
- m_b2 = 0; /* mere guess */
- m_b4 = 0; /* mere guess */
-
-
- m_rim_step = 0;
- m_sbs_restore = 0; /* mere guess */
- m_no_sequence_break = 0; /* mere guess */
-
- field_interrupt();
-
- /* now, we kindly ask IO devices to reset, too */
- if (m_io_sc_callback)
- (*m_io_sc_callback)(this);
-}
diff --git a/src/emu/cpu/pdp1/pdp1.h b/src/emu/cpu/pdp1/pdp1.h
deleted file mode 100644
index f4d1281aa07..00000000000
--- a/src/emu/cpu/pdp1/pdp1.h
+++ /dev/null
@@ -1,199 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Raphael Nabet
-#pragma once
-
-#ifndef __PDP1_H__
-#define __PDP1_H__
-
-
-
-/* register ids for pdp1_get_reg/pdp1_set_reg */
-enum
-{
- PDP1_PC=1, PDP1_IR, PDP1_MB, PDP1_MA, PDP1_AC, PDP1_IO,
- PDP1_PF, PDP1_PF1, PDP1_PF2, PDP1_PF3, PDP1_PF4, PDP1_PF5, PDP1_PF6,
- PDP1_TA, PDP1_TW,
- PDP1_SS, PDP1_SS1, PDP1_SS2, PDP1_SS3, PDP1_SS4, PDP1_SS5, PDP1_SS6,
- PDP1_SNGL_STEP, PDP1_SNGL_INST, PDP1_EXTEND_SW,
- PDP1_RUN, PDP1_CYC, PDP1_DEFER, PDP1_BRK_CTR, PDP1_OV, PDP1_RIM, PDP1_SBM, PDP1_EXD,
- PDP1_IOC, PDP1_IOH, PDP1_IOS
-};
-
-
-typedef void (*pdp1_extern_iot_func)(device_t *device, int op2, int nac, int mb, int *io, int ac);
-typedef void (*pdp1_read_binary_word_func)(device_t *device);
-typedef void (*pdp1_io_sc_func)(device_t *device);
-
-
-struct pdp1_reset_param_t
-{
- /* callbacks for iot instructions (required for any I/O) */
- pdp1_extern_iot_func extern_iot[64];
- /* read a word from the perforated tape reader (required for read-in mode) */
- pdp1_read_binary_word_func read_binary_word;
- /* callback called when sc is pulsed: IO devices should reset */
- pdp1_io_sc_func io_sc_callback;
-
- /* 0: no extend support, 1: extend with 15-bit address, 2: extend with 16-bit address */
- int extend_support;
- /* 1 to use hardware multiply/divide (MUL, DIV) instead of MUS, DIS */
- int hw_mul_div;
- /* 0: standard sequence break system 1: type 20 sequence break system */
- int type_20_sbs;
-};
-
-#define IOT_NO_COMPLETION_PULSE -1
-
-
-#define AND 001
-#define IOR 002
-#define XOR 003
-#define XCT 004
-#define CALJDA 007
-#define LAC 010
-#define LIO 011
-#define DAC 012
-#define DAP 013
-#define DIP 014
-#define DIO 015
-#define DZM 016
-#define ADD 020
-#define SUB 021
-#define IDX 022
-#define ISP 023
-#define SAD 024
-#define SAS 025
-#define MUS_MUL 026
-#define DIS_DIV 027
-#define JMP 030
-#define JSP 031
-#define SKP 032
-#define SFT 033
-#define LAW 034
-#define IOT 035
-#define OPR 037
-
-
-class pdp1_device : public cpu_device
- , public pdp1_reset_param_t
-{
-public:
- // construction/destruction
- pdp1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-
- void pulse_start_clear();
- void io_complete() { m_ios = 1; }
- void pdp1_null_iot(int op2, int nac, int mb, int *io, int ac);
- void pdp1_lem_eem_iot(int op2, int nac, int mb, int *io, int ac);
- void pdp1_sbs_iot(int op2, int nac, int mb, int *io, int ac);
- void pdp1_type_20_sbs_iot(int op2, int nac, int mb, int *io, int ac);
-
-protected:
- // device-level overrides
- virtual void device_config_complete();
- virtual void device_start();
- virtual void device_reset();
-
- // device_execute_interface overrides
- virtual UINT32 execute_min_cycles() const { return 5; }
- virtual UINT32 execute_max_cycles() const { return 31; }
- virtual UINT32 execute_input_lines() const { return 16; }
- virtual void execute_run();
- virtual void execute_set_input(int inputnum, int state);
-
- // device_memory_interface overrides
- virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : NULL; }
-
- // device_state_interface overrides
- virtual void state_import(const device_state_entry &entry);
- virtual void state_export(const device_state_entry &entry);
- void state_string_export(const device_state_entry &entry, std::string &str);
-
- // device_disasm_interface overrides
- virtual UINT32 disasm_min_opcode_bytes() const { return 4; }
- virtual UINT32 disasm_max_opcode_bytes() const { return 4; }
- virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
-
-private:
- address_space_config m_program_config;
-
- /* processor registers */
- UINT32 m_pc; /* program counter (12, 15 or 16 bits) */
- int m_ir; /* basic operation code of current instruction (5 bits) */
- int m_mb; /* memory buffer (used for holding the current instruction only) (18 bits) */
- int m_ma; /* memory address (12, 15 or 16 bits) */
- int m_ac; /* accumulator (18 bits) */
- int m_io; /* i/o register (18 bits) */
- int m_pf; /* program flag register (6 bits) */
-
- /* operator panel switches */
- int m_ta; /* current state of the 12 or 16 address switches */
- int m_tw; /* current state of the 18 test word switches */
- int m_ss; /* current state of the 6 sense switches on the operator panel (6 bits) */
- unsigned int m_sngl_step; /* stop every memory cycle */
- unsigned int m_sngl_inst; /* stop every instruction */
- unsigned int m_extend_sw; /* extend switch (loaded into the extend flip-flop on start/read-in) */
-
- /* processor state flip-flops */
- unsigned int m_run; /* processor is running */
- unsigned int m_cycle; /* processor is in the midst of an instruction */
- unsigned int m_defer; /* processor is handling deferred (i.e. indirect) addressing */
- unsigned int m_brk_ctr; /* break counter */
- unsigned int m_ov; /* overflow flip-flop */
- unsigned int m_rim; /* processor is in read-in mode */
-
- unsigned int m_sbm; /* processor is in sequence break mode (i.e. interrupts are enabled) */
-
- unsigned int m_exd; /* extend mode: processor is in extend mode */
- unsigned int m_exc : 1; /* extend-mode cycle: current instruction cycle is done in extend mode */
- unsigned int m_ioc; /* i-o commands: seems to be equivalent to (! ioh) */
- unsigned int m_ioh; /* i-o halt: processor is executing an Input-Output Transfer wait */
- unsigned int m_ios; /* i-o synchronizer: set on i-o operation completion */
-
- /* sequence break system */
- UINT16 m_irq_state; /* mirrors the state of the interrupt pins */
- UINT16 m_b1; /* interrupt enable */
- UINT16 m_b2; /* interrupt pulse request pending - asynchronous with computer operation (set by pulses on irq_state, cleared when interrupt is taken) */
- /*UINT16 m_b3;*/ /* interrupt request pending - synchronous with computer operation (logical or of irq_state and b2???) */
- UINT16 m_b4; /* interrupt in progress */
-
- /* additional emulator state variables */
- int m_rim_step; /* current step in rim execution */
- int m_sbs_request; /* interrupt request (i.e. (b3 & (~ b4)) && (! sbm)) */
- int m_sbs_level; /* interrupt request level (first bit in (b3 & (~ b4)) */
- int m_sbs_restore; /* set when a jump instruction is an interrupt return */
- int m_no_sequence_break; /* disable sequence break recognition for one cycle */
-
- /* callbacks for iot instructions (required for any I/O) */
- pdp1_extern_iot_func m_extern_iot[64];
- /* read a word from the perforated tape reader (required for read-in mode) */
- pdp1_read_binary_word_func m_read_binary_word;
- /* callback called when sc is pulsed: IO devices should reset */
- pdp1_io_sc_func m_io_sc_callback;
-
- /* 0: no extend support, 1: extend with 15-bit address, 2: extend with 16-bit address */
- int m_extend_support;
-
- int m_extended_address_mask; /* 07777 with no extend support, 077777 or 0177777 with extend support */
- int m_address_extension_mask; /* 00000 with no extend support, 070000 or 0170000 with extend support */
-
- /* 1 to use hardware multiply/divide (MUL, DIV) instead of MUS, DIS */
- int m_hw_mul_div;
-
- /* 1 for 16-line sequence break system, 0 for default break system */
- int m_type_20_sbs;
-
- address_space *m_program;
- int m_icount;
- UINT32 m_debugger_temp;
-
- void field_interrupt();
- void execute_instruction();
-
-};
-
-
-extern const device_type PDP1;
-
-
-#endif /* __PDP1_H__ */
diff --git a/src/emu/cpu/pdp1/pdp1dasm.c b/src/emu/cpu/pdp1/pdp1dasm.c
deleted file mode 100644
index c8682ca1491..00000000000
--- a/src/emu/cpu/pdp1/pdp1dasm.c
+++ /dev/null
@@ -1,294 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Raphael Nabet
-#include "emu.h"
-#include "cpu/pdp1/pdp1.h"
-
-/* PDP1 registers */
-static int ib;
-static int y;
-
-INLINE void ea (void)
-{
-/* while (1)
- {
- if (ib == 0)
- return;
- ib = (READ_PDP_18BIT (y) >> 12) & 1;
- y = READ_PDP_18BIT (y) & 07777;
- }*/
-}
-
-#define IN if (ib) sprintf(buffer+strlen(buffer)," i")
-
-CPU_DISASSEMBLE( pdp1 )
-{
- int md;
- //int etime = 0;
-
- md = oprom[0] << 24 | oprom[1] << 16 | oprom[2] << 8 | oprom[3];
-
- y = md & 07777;
- ib = (md >> 12) & 1; /* */
- switch (md >> 13)
- {
- case AND:
- ea ();
- sprintf (buffer, "AND (0%06o)", y);
- IN;
- //etime = 10;
- break;
- case IOR:
- ea ();
- sprintf (buffer, "IOR (0%06o)", y);
- IN;
- //etime = 10;
- break;
- case XOR:
- ea ();
- sprintf (buffer, "XOR (0%06o)", y);
- IN;
- //etime = 10;
- break;
- case XCT:
- ea ();
- sprintf (buffer, "XCT (0%06o)", y);
- IN;
- //etime = 5;
- break;
- case CALJDA:
- {
- if (ib == 1)
- sprintf (buffer, "JDA 0%06o ", y);
- if (ib == 0)
- sprintf (buffer, "CAL ");
- //etime = 10;
- break;
- }
- case LAC:
- ea ();
- sprintf (buffer, "LAC (0%06o)", y);
- IN;
- //etime = 10;
- break;
- case LIO:
- ea ();
- sprintf (buffer, "LIO (0%06o)", y);
- IN;
- //etime = 10;
- break;
- case DAC:
- ea ();
- sprintf (buffer, "DAC 0%06o ", y);
- IN;
- //etime = 10;
- break;
- case DAP:
- ea ();
- sprintf (buffer, "DAP 0%06o ", y);
- IN;
- //etime = 10;
- break;
- case DIP:
- ea ();
- sprintf (buffer, "DIP 0%06o ", y);
- IN;
- //etime = 10;
- break;
- case DIO:
- ea ();
- sprintf (buffer, "DIO 0%06o ", y);
- IN;
- //etime = 10;
- break;
- case DZM:
- ea ();
- sprintf (buffer, "DZM 0%06o ", y);
- IN;
- //etime = 10;
- break;
- case ADD:
- ea ();
- sprintf (buffer, "ADD (0%06o)", y);
- IN;
- //etime = 10;
- break;
- case SUB:
- ea ();
- sprintf (buffer, "SUB (0%06o)", y);
- IN;
- //etime = 10;
- break;
- case IDX:
- ea ();
- sprintf (buffer, "IDX (0%06o)", y);
- IN;
- //etime = 10;
- break;
- case ISP:
- ea ();
- sprintf (buffer, "ISP (0%06o)", y);
- IN;
- //etime = 10;
- break;
- case SAD:
- ea ();
- sprintf (buffer, "SAD (0%06o)", y);
- IN;
- //etime = 10;
- break;
- case SAS:
- ea ();
- sprintf (buffer, "SAS (0%06o)", y);
- IN;
- //etime = 10;
- break;
- case MUS_MUL:
- ea ();
- sprintf (buffer, "MUS (0%06o)", y);
- IN;
- //etime = 10;
- break;
- case DIS_DIV:
- ea ();
- sprintf (buffer, "DIS (0%06o)", y);
- IN;
- //etime = 10;
- break;
- case JMP:
- ea ();
- sprintf (buffer, "JMP 0%06o ", y);
- IN;
- //etime = 5;
- break;
- case JSP:
- ea ();
- sprintf (buffer, "JSP 0%06o ", y);
- IN;
- //etime = 5;
- break;
- case SKP:
- {
- buffer[0] = 0;
- if ((y & 0100) == 0100)
- sprintf (buffer, "SZA ");
- if ((y & 0200) == 0200)
- sprintf (buffer + strlen (buffer), "SPA ");
- if ((y & 0400) == 0400)
- sprintf (buffer + strlen (buffer), "SMA ");
- if ((y & 01000) == 01000)
- sprintf (buffer + strlen (buffer), "SZO ");
- if ((y & 02000) == 02000)
- sprintf (buffer + strlen (buffer), "SPI ");
- if (y & 070)
- sprintf (buffer + strlen (buffer), "SZS 0%01o ", (y & 070));
- if (y & 7)
- sprintf (buffer + strlen (buffer), "SZF 0%01o ", (y & 7));
- IN;
- //etime = 5;
- break;
- }
- case SFT:
- {
- int nshift = 0;
- int mask = md & 0777;
-
- while (mask != 0)
- {
- nshift += mask & 1;
- mask = mask >> 1;
- }
- switch ((md >> 9) & 017)
- {
- case 1:
- sprintf (buffer, "RAL 0%02o", nshift);
- //etime = 5;
- break;
- case 2:
- sprintf (buffer, "RIL 0%02o", nshift);
- //etime = 5;
- break;
- case 3:
- sprintf (buffer, "RCL 0%02o", nshift);
- //etime = 5;
- break;
- case 5:
- sprintf (buffer, "SAL 0%02o", nshift);
- //etime = 5;
- break;
- case 6:
- sprintf (buffer, "SIL 0%02o", nshift);
- //etime = 5;
- break;
- case 7:
- sprintf (buffer, "SCL 0%02o", nshift);
- //etime = 5;
- break;
- case 9:
- sprintf (buffer, "RAR 0%02o", nshift);
- //etime = 5;
- break;
- case 10:
- sprintf (buffer, "RIR 0%02o", nshift);
- //etime = 5;
- break;
- case 11:
- sprintf (buffer, "RCR 0%02o", nshift);
- //etime = 5;
- break;
- case 13:
- sprintf (buffer, "SAR 0%02o", nshift);
- //etime = 5;
- break;
- case 14:
- sprintf (buffer, "SIR 0%02o", nshift);
- //etime = 5;
- break;
- case 15:
- sprintf (buffer, "SCR 0%02o", nshift);
- //etime = 5;
- break;
- default:
- sprintf (buffer, "SKP ???");
- //etime = 5;
- break;
- }
- break;
- }
- case LAW:
- sprintf (buffer, "LAW 0%06o", y);
- IN;
- //etime = 5;
- break;
- case IOT:
- sprintf (buffer, "IOT 0%06o", md);
- //etime = 10;
- break;
- case OPR:
- {
- buffer[0] = 0;
- if ((y & 04000) == 04000)
- sprintf (buffer + strlen (buffer), "CLI ");
- if ((y & 02000) == 02000)
- sprintf (buffer + strlen (buffer), "LAT ");
- if ((y & 01000) == 01000)
- sprintf (buffer + strlen (buffer), "CMA ");
- if ((y & 0400) == 0400)
- sprintf (buffer + strlen (buffer), "HLT ");
- if ((y & 0100) == 0100)
- sprintf (buffer + strlen (buffer), "LAP ");
- if ((y & 010) && (y & 7))
- sprintf (buffer + strlen (buffer), "STF 0%01o ", (y & 7));
- if ((!(y & 010)) && (y & 7))
- sprintf (buffer + strlen (buffer), "CLF 0%01o ", (y & 7));
- if (!(y))
- sprintf (buffer + strlen (buffer), "NOP ");
- //etime = 5;
- break;
- }
- default:
- sprintf (buffer, "ILLEGAL");
- //etime = 5;
- break;
- }
- return 4;
-}
diff --git a/src/emu/cpu/pdp1/tx0.c b/src/emu/cpu/pdp1/tx0.c
deleted file mode 100644
index 03c8441d88f..00000000000
--- a/src/emu/cpu/pdp1/tx0.c
+++ /dev/null
@@ -1,1080 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Raphael Nabet
-/*
- TX-0 emulator
-
- Two variants:
- * initial model 64kWord RAM
- * later model 8kWord RAM
-
- Raphael Nabet 2004
-*/
-
-#include "emu.h"
-#include "debugger.h"
-#include "tx0.h"
-
-#define LOG 0
-#define LOG_EXTRA 0
-
-
-#define READ_TX0_18BIT(A) ((signed)m_program->read_dword((A)<<2))
-#define WRITE_TX0_18BIT(A,V) (m_program->write_dword((A)<<2,(V)))
-
-
-#define io_handler_rim 3
-
-#define PC m_pc
-#define IR m_ir
-#define MBR m_mbr
-#define MAR m_mar
-#define AC m_ac
-#define LR m_lr
-#define XR m_xr
-#define PF m_pf
-
-#define ADDRESS_MASK_64KW 0177777
-#define ADDRESS_MASK_8KW 0017777
-
-#define INCREMENT_PC_64KW (PC = (PC+1) & ADDRESS_MASK_64KW)
-#define INCREMENT_PC_8KW (PC = (PC+1) & ADDRESS_MASK_8KW)
-
-
-const device_type TX0_8KW = &device_creator<tx0_8kw_device>;
-const device_type TX0_64KW = &device_creator<tx0_64kw_device>;
-
-
-tx0_device::tx0_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source, int addr_bits, int address_mask, int ir_mask)
- : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
- , m_program_config("program", ENDIANNESS_BIG, 32, addr_bits , -2)
- , m_address_mask(address_mask)
- , m_ir_mask(ir_mask)
- , m_cpy_handler(*this)
- , m_r1l_handler(*this)
- , m_dis_handler(*this)
- , m_r3l_handler(*this)
- , m_prt_handler(*this)
- , m_rsv_handler(*this)
- , m_p6h_handler(*this)
- , m_p7h_handler(*this)
- , m_sel_handler(*this)
- , m_io_reset_callback(*this)
-{
- m_is_octal = true;
-}
-
-tx0_8kw_device::tx0_8kw_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tx0_device(mconfig, TX0_8KW, "TX-0 8KW", tag, owner, clock, "tx0_8w_cpu", __FILE__, 13, ADDRESS_MASK_8KW, 037)
-{
-}
-
-
-tx0_64kw_device::tx0_64kw_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tx0_device(mconfig, TX0_64KW, "TX-0 64KW", tag, owner, clock, "tx0_64kw_cpu", __FILE__, 16, ADDRESS_MASK_64KW, 03)
-{
-}
-
-
-int tx0_device::tx0_read(offs_t address)
-{
- if ((address >= 16) || (m_gbl_cm_sel) || ((m_cm_sel >> address) & 1))
- /* core memory (CM) */
- return READ_TX0_18BIT(address);
- else if ((m_lr_sel >> address) & 1)
- /* live register (LR) */
- return LR;
-
- /* toggle switch storage (TSS) */
- return m_tss[address];
-}
-
-void tx0_device::tx0_write(offs_t address, int data)
-{
- if ((address >= 16) || (m_gbl_cm_sel) || ((m_cm_sel >> address) & 1))
- /* core memory (CM) */
- WRITE_TX0_18BIT(address, data);
- else if ((m_lr_sel >> address) & 1)
- /* live register (LR) */
- LR = data;
- else
- /* toggle switch storage (TSS) */
- /* TSS is read-only */
- {
- /* nothing */
- }
-}
-
-
-void tx0_device::device_start()
-{
- m_mbr = 0;
- m_ac = 0;
- m_mar = 0;
- m_lr = 0;
- m_xr = 0;
- m_pf = 0;
- m_tbr = 0;
- m_tac = 0;
- for ( int i = 0; i < 16; i++ )
- {
- m_tss[i] = 0;
- }
- m_cm_sel = 0;
- m_lr_sel = 0;
- m_gbl_cm_sel = 0;
- m_stop_cyc0 = 0;
- m_stop_cyc1 = 0;
- m_cycle = 0;
- m_pc = 0;
- m_ir = 0;
- m_run = 0;
- m_rim = 0;
- m_ioh = 0;
- m_ios = 0;
-
- // Resolve callbacks
- m_cpy_handler.resolve();
- m_r1l_handler.resolve();
- m_dis_handler.resolve();
- m_r3l_handler.resolve();
- m_prt_handler.resolve();
- m_rsv_handler.resolve();
- m_p6h_handler.resolve();
- m_p7h_handler.resolve();
- m_sel_handler.resolve();
- m_io_reset_callback.resolve();
-
- m_program = &space(AS_PROGRAM);
-
- save_item(NAME(m_mbr));
- save_item(NAME(m_ac));
- save_item(NAME(m_mar));
- save_item(NAME(m_pc));
- save_item(NAME(m_ir));
- save_item(NAME(m_lr));
- save_item(NAME(m_xr));
- save_item(NAME(m_pf));
- save_item(NAME(m_tbr));
- save_item(NAME(m_tac));
- save_item(NAME(m_tss));
- save_item(NAME(m_cm_sel));
- save_item(NAME(m_lr_sel));
- save_item(NAME(m_gbl_cm_sel));
- save_item(NAME(m_stop_cyc0));
- save_item(NAME(m_stop_cyc1));
- save_item(NAME(m_run));
- save_item(NAME(m_rim));
- save_item(NAME(m_cycle));
- save_item(NAME(m_ioh));
- save_item(NAME(m_ios));
- save_item(NAME(m_rim_step));
-
- // Register state for debugger
- state_add( TX0_PC, "PC", m_pc ).mask(m_address_mask).formatstr("0%06O");
- state_add( TX0_IR, "IR", m_ir ).mask(m_ir_mask) .formatstr("0%02O");
- state_add( TX0_MBR, "MBR", m_mbr ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_MAR, "MAR", m_mar ).mask(m_address_mask).formatstr("0%06O");
- state_add( TX0_AC, "AC", m_ac ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_LR, "LR", m_lr ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_XR, "XR", m_xr ).mask(0037777) .formatstr("0%05O");
- state_add( TX0_PF, "PF", m_pf ).mask(077) .formatstr("0%02O");
- state_add( TX0_TBR, "TBR", m_tbr ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TAC, "TAC", m_tac ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TSS00, "TSS00", m_tss[000] ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TSS01, "TSS01", m_tss[001] ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TSS02, "TSS02", m_tss[002] ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TSS03, "TSS03", m_tss[003] ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TSS04, "TSS04", m_tss[004] ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TSS05, "TSS05", m_tss[005] ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TSS06, "TSS06", m_tss[006] ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TSS07, "TSS07", m_tss[007] ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TSS10, "TSS10", m_tss[010] ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TSS11, "TSS11", m_tss[011] ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TSS12, "TSS12", m_tss[012] ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TSS13, "TSS13", m_tss[013] ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TSS14, "TSS14", m_tss[014] ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TSS15, "TSS15", m_tss[015] ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TSS16, "TSS16", m_tss[016] ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_TSS17, "TSS17", m_tss[017] ).mask(0777777) .formatstr("0%06O");
- state_add( TX0_CM_SEL, "CMSEL", m_cm_sel ).mask(0177777) .formatstr("0%06O");
- state_add( TX0_LR_SEL, "LRSEL", m_lr_sel ).mask(0177777) .formatstr("0%06O");
- state_add( TX0_GBL_CM_SEL, "GBLCMSEL", m_gbl_cm_sel ).mask(1) .formatstr("%1X");
- state_add( TX0_STOP_CYC0, "STOPCYC0", m_stop_cyc0 ).mask(1) .formatstr("%1X");
- state_add( TX0_STOP_CYC1, "STOPCYC1", m_stop_cyc1 ).mask(1) .formatstr("%1X");
- state_add( TX0_RUN, "RUN", m_run ).mask(1) .formatstr("%1X");
- state_add( TX0_RIM, "RIM", m_rim ).mask(1) .formatstr("%1X");
- state_add( TX0_CYCLE, "CYCLE", m_cycle ) .formatstr("%1X");
- state_add( TX0_IOH, "IOH", m_ioh ) .formatstr("%1X");
- state_add( TX0_IOS, "IOS", m_ios ).mask(1) .formatstr("%1X");
-
- state_add(STATE_GENPC, "GENPC", m_pc).formatstr("0%06O").noshow();
- state_add(STATE_GENFLAGS, "GENFLAGS", m_ir).noshow();
-
- m_icountptr = &m_icount;
-}
-
-
-void tx0_device::device_reset()
-{
- /* reset CPU flip-flops */
- pulse_reset();
-
- m_gbl_cm_sel = 1; /* HACK */
-}
-
-
-void tx0_device::call_io_handler(int io_handler)
-{
- /* data will be transferred to AC */
- switch (io_handler)
- {
- case 0: m_cpy_handler(ASSERT_LINE); break;
- case 1: m_r1l_handler(ASSERT_LINE); break;
- case 2: m_dis_handler(ASSERT_LINE); break;
- case 3: m_r3l_handler(ASSERT_LINE); break;
- case 4: m_prt_handler(ASSERT_LINE); break;
- case 5: m_rsv_handler(ASSERT_LINE); break;
- case 6: m_p6h_handler(ASSERT_LINE); break;
- case 7: m_p7h_handler(ASSERT_LINE); break;
- }
-}
-
-
-/* execute instructions on this CPU until icount expires */
-void tx0_64kw_device::execute_run()
-{
- do
- {
- debugger_instruction_hook(this, PC);
-
-
- if (m_ioh && m_ios)
- {
- m_ioh = 0;
- }
-
-
- if ((! m_run) && (! m_rim))
- m_icount = 0; /* if processor is stopped, just burn cycles */
- else if (m_rim)
- {
- switch (m_rim_step)
- {
- case 0:
- /* read first word as instruction */
- AC = 0;
- call_io_handler(io_handler_rim);
- m_rim_step = 1;
- m_ios = 0;
- break;
-
- case 1:
- if (! m_ios)
- { /* transfer incomplete: wait some more */
- m_icount = 0;
- }
- else
- { /* data transfer complete */
- m_ios = 0;
-
- MBR = AC;
- IR = MBR >> 16; /* basic opcode */
- if ((IR == 2) || (IR == 1)) /* trn or add instruction? */
- {
- PC = MBR & ADDRESS_MASK_64KW;
- m_rim = 0; /* exit read-in mode */
- m_run = (IR == 2) ? 1 : 0; /* stop if add instruction */
- m_rim_step = 0;
- }
- else if ((IR == 0) || (IR == 3)) /* sto or opr instruction? */
- {
- MAR = MBR & ADDRESS_MASK_64KW;
- m_rim_step = 2;
- }
- }
- break;
-
- case 2:
- /* read second word as data */
- AC = 0;
- call_io_handler(io_handler_rim);
- m_rim_step = 3;
- m_ios = 0;
- break;
-
- case 3:
- if (! m_ios)
- { /* transfer incomplete: wait some more */
- m_icount = 0;
- }
- else
- { /* data transfer complete */
- m_ios = 0;
-
- tx0_write(MAR, MBR = AC);
-
- m_rim_step = 0;
- }
- break;
- }
- }
- else
- {
- if (m_cycle == 0)
- { /* fetch new instruction */
- MBR = tx0_read(MAR = PC);
- INCREMENT_PC_64KW;
- IR = MBR >> 16; /* basic opcode */
- MAR = MBR & ADDRESS_MASK_64KW;
- }
-
- if (! m_ioh)
- {
- if ((m_stop_cyc0 && (m_cycle == 0))
- || (m_stop_cyc1 && (m_cycle == 1)))
- m_run = 0;
-
- execute_instruction_64kw();
- }
-
- m_icount --;
- }
- }
- while (m_icount > 0);
-}
-
-/* execute instructions on this CPU until icount expires */
-void tx0_8kw_device::execute_run()
-{
- do
- {
- debugger_instruction_hook(this, PC);
-
-
- if (m_ioh && m_ios)
- {
- m_ioh = 0;
- }
-
-
- if ((! m_run) && (! m_rim))
- m_icount = 0; /* if processor is stopped, just burn cycles */
- else if (m_rim)
- {
- switch (m_rim_step)
- {
- case 0:
- /* read first word as instruction */
- AC = 0;
- call_io_handler(io_handler_rim);
- m_rim_step = 1;
- m_ios = 0;
- break;
-
- case 1:
- if (! m_ios)
- { /* transfer incomplete: wait some more */
- m_icount = 0;
- }
- else
- { /* data transfer complete */
- m_ios = 0;
-
- MBR = AC;
- IR = MBR >> 13; /* basic opcode */
- if ((IR == 16) || (IR == 8)) /* trn or add instruction? */
- {
- PC = MBR & ADDRESS_MASK_8KW;
- m_rim = 0; /* exit read-in mode */
- m_run = (IR == 16) ? 1 : 0; /* stop if add instruction */
- m_rim_step = 0;
- }
- else if ((IR == 0) || (IR == 24)) /* sto or opr instruction? */
- {
- MAR = MBR & ADDRESS_MASK_8KW;
- m_rim_step = 2;
- }
- }
- break;
-
- case 2:
- /* read second word as data */
- AC = 0;
- call_io_handler(io_handler_rim);
- m_rim_step = 3;
- m_ios = 0;
- break;
-
- case 3:
- if (! m_ios)
- { /* transfer incomplete: wait some more */
- m_icount = 0;
- }
- else
- { /* data transfer complete */
- m_ios = 0;
-
- tx0_write(MAR, MBR = AC);
-
- m_rim_step = 0;
- }
- break;
- }
- }
- else
- {
- if (m_cycle == 0)
- { /* fetch new instruction */
- MBR = tx0_read(MAR = PC);
- INCREMENT_PC_8KW;
- IR = MBR >> 13; /* basic opcode */
- MAR = MBR & ADDRESS_MASK_8KW;
- }
-
- if (! m_ioh)
- {
- if ((m_stop_cyc0 && (m_cycle == 0))
- || (m_stop_cyc1 && (m_cycle == 1)))
- m_run = 0;
-
- execute_instruction_8kw();
- }
-
- m_icount -= 1;
- }
- }
- while (m_icount > 0);
-}
-
-
-/* execute one instruction */
-void tx0_64kw_device::execute_instruction_64kw()
-{
- if (! m_cycle)
- {
- m_cycle = 1; /* most frequent case */
- switch (IR)
- {
- case 0: /* STOre */
- case 1: /* ADD */
- break;
-
- case 2: /* TRansfer on Negative */
- if (AC & 0400000)
- {
- PC = MAR & ADDRESS_MASK_64KW;
- m_cycle = 0; /* instruction only takes one cycle if branch
- is taken */
- }
- break;
-
- case 3: /* OPeRate */
- if (MAR & 0100000)
- /* (0.8) CLL = Clear the left nine digital positions of the AC */
- AC &= 0000777;
-
- if (MAR & 0040000)
- /* (0.8) CLR = Clear the right nine digital positions of the AC */
- AC &= 0777000;
-
- if (((MAR & 0030000) >> 12) == 1)
- /* (0.8) IOS In-Out Stop = Stop machine so that an In-Out command
- (specified by digits 6 7 8 of MAR) may be executed */
- m_ioh = 1;
-
- if (((MAR & 0007000) >> 9) != 0)
- {
- /* ((MAR & 0007000) >> 9) is device ID */
- /* 7: */
- /* (0.8) P7H = Punch holes 1-6 in flexo tape specified by AC
- digital positions 2, 5, 8, 11, 14, and 17. Also punches a 7th
- hole on tape. */
- /* 6: */
- /* (0.8) P6H = Same as P7H but no seventh hole */
- /* 4: */
- /* (0.8) PNT = Print one flexowriter character specified by AC
- digits 2, 5, 8, 11, 14, and 17. */
- /* 1: */
- /* (0.8) R1C = Read one line of flexo tape so that tape positions
- 1, 2, 3, 4, 5, and 6 will be put in the AC digital positions 0,
- 3, 6, 9, 12 and 15. */
- /* 3: */
- /* (0.8) R3C = Read one line of flexo tape into AC digits 0, 3, 6,
- 9, 12 and 15. Then cycle the AC one digital position; read the
- next line on tape into AC digits 0, 3, 6, 9, 12 and 15, cycle
- the AC right one digital position and read the third and last
- line into AC digits 0, 3, 6, 9, 12 and 15. (This command is
- equal to a triple CYR-R1C.) */
- /* 2: */
- /* (0.8) DIS = Intensify a point on the scope with x and y
- coordinates where x is specified by AC digits 0-8 with digit 0
- being used as the sign and y is specified by AC digits 9-17
- with digit 9 being used as the sign for y. The complement
- system is in effect when the signs are negative. */
- /* (5 is undefined) */
- int index = (MAR & 0007000) >> 9;
-
- call_io_handler(index);
- m_ioh = 1;
- }
- break;
- }
- }
- else
- {
- m_cycle = 0; /* always true */
- switch (IR)
- {
- case 0: /* STOre */
- tx0_write(MAR, (MBR = AC));
- break;
-
- case 1: /* ADD */
- MBR = tx0_read(MAR);
-
- AC = AC + MBR;
- AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */
-
- if (AC == 0777777) /* check for -0 */
- AC = 0;
- break;
-
- case 2: /* TRansfer on Negative */
- break;
-
- case 3: /* OPeRate */
- if ((MAR & 0000104) == 0000100)
- /* (1.1) PEN = Read the light pen flip-flops 1 and 2 into AC(0) and
- AC(1). */
- /*...*/{ }
-
- if ((MAR & 0000104) == 0000004)
- /* (1.1) TAC = Insert a one in each digital position of the AC
- wherever there is a one in the corresponding digital position
- of the TAC. */
- /*...*/ { }
-
- if (MAR & 0000040)
- /* (1.2) COM = Complement every digit in the accumulator */
- AC ^= 0777777;
-
- if ((MAR & 0000003) == 1)
- /* (1.2) AMB = Store the contents of the AC in the MBR. */
- MBR = AC;
-
- if ((MAR & 0000003) == 3)
- /* (1.2) TBR = Store the contents of the TBR in the MBR. */
- /*...*/ { }
-
- if ((MAR & 0000003) == 2)
- /* (1.3) LMB = Store the contents of the LR in the MBR. */
- MBR = LR;
- break;
-
- if (((MAR & 0000600) >> 7) == 1)
- /* (1.3) MLR = Store the contents of the MBR (memory buffer
- register) in the live reg. */
- LR = MBR;
-
- if (((MAR & 0000600) >> 7) == 2)
- /* (1.4) SHR = Shift the AC right one place, i.e. multiply the AC
- by 2^-1 */
- AC >>= 1;
-
- if (((MAR & 0000600) >> 7) == 3)
- /* (1.4) CYR = Cycle the AC right one digital position (AC(17) will
- become AC(0)) */
- AC = (AC >> 1) | ((AC & 1) << 17);
-
- if (MAR & 0000020)
- /* (1.4) PAD = Partial add AC to MBR, that is, for every digital
- position of the MBR that contains a one, complement the digit
- in the corresponding digital position of the AC. This is also
- called a half add. */
- AC ^= MBR;
-
- if (MAR & 0000010)
- { /* (1.7) CRY = Partial add the 18 digits of the AC to the
- corresponding 18 digits of the carry.
-
- To determine what the 18 digits of the carry are, use the
- following rule:
-
- "Grouping the AC and MBR digits into pairs and proceeding from
- right to left, assign the carry digit of the next pair to a one
- if in the present pair MBR = 1 and AC = 0 or if in the present
- pair AC = 1 and carry 1.
-
- (Note: the 0th digit pair determines the 17th pair's carry
- digit)" */
- AC ^= MBR;
-
- AC = AC + MBR;
- AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */
-
- if (AC == 0777777) /* check for -0 */
- AC = 0;
- }
-
- if (((MAR & 0030000) >> 12) == 3)
- /* (1.8) Hlt = Halt the computer */
- m_run = 0;
-
- break;
- }
- }
-}
-
-void tx0_device::indexed_address_eval()
-{
- MAR = MAR + XR;
- MAR = (MAR + (MAR >> 14)) & 0037777; /* propagate carry around */
- //if (MAR == 0037777) /* check for -0 */
- // MAR = 0;
- if (MAR & 0020000) /* fix negative (right???) */
- MAR = (MAR + 1) & 0017777;
-}
-
-/* execute one instruction */
-void tx0_8kw_device::execute_instruction_8kw()
-{
- if (! m_cycle)
- {
- m_cycle = 1; /* most frequent case */
- switch (IR)
- {
- case 0: /* STOre */
- case 1: /* STore indeXed */
- case 2: /* Store indeX in Address */
- case 3: /* ADd One */
- case 4: /* Store LR */
- case 5: /* Store Lr indeXed */
- case 6: /* STore Zero */
- case 8: /* ADD */
- case 9: /* ADd indeXed */
- case 10: /* LoaD indeX */
- case 11: /* AUgment indeX */
- case 12: /* Load LR */
- case 13: /* Load Lr indeXed */
- case 14: /* LoaD Ac */
- case 15: /* Load Ac indeXed */
- break;
-
- case 16: /* TRansfer on Negative */
- if (AC & 0400000)
- {
- PC = MAR & 0017777;
- m_cycle = 0; /* instruction only takes one cycle if branch
- is taken */
- }
- break;
-
- case 17: /* Transfer on ZEro */
- if ((AC == 0000000) || (AC == 0777777))
- {
- PC = MAR & 0017777;
- m_cycle = 0; /* instruction only takes one cycle if branch
- is taken */
- }
- break;
-
- case 18: /* Transfer and Set indeX */
- XR = PC;
- PC = MAR & 0017777;
- m_cycle = 0; /* instruction only takes one cycle if branch
- is taken */
- break;
-
- case 19: /* Transfer and IndeX */
- if ((XR != 0000000) && (XR != 0037777))
- {
- if (XR & 0020000)
- XR ++;
- else
- XR--;
- PC = MAR & 0017777;
- m_cycle = 0; /* instruction only takes one cycle if branch
- is taken */
- }
- break;
-
- case 21: /* TRansfer indeXed */
- indexed_address_eval();
- case 20: /* TRAnsfer */
- PC = MAR & 0017777;
- m_cycle = 0; /* instruction only takes one cycle if branch
- is taken */
- break;
-
- case 22: /* Transfer on external LeVel */
- /*if (...)
- {
- PC = MAR & 0017777;
- m_cycle = 0;*/ /* instruction only takes one cycle if branch
- is taken */
- /*}*/
- break;
-
- case 24: /* OPeRate */
- case 25:
- case 26:
- case 27:
- case 28:
- case 29:
- case 30:
- case 31:
- if (((IR & 001) == 00) && ((MAR & 017000) == 004000))
- { /* Select class instruction */
- if (IR & 004)
- /* (0.8???) CLA = CLear Ac */
- AC = 0;
-
- /* (IOS???) SEL = SELect */
- m_sel_handler(ASSERT_LINE);
- }
- else
- { /* Normal operate class instruction */
- if (((IR & 001) == 01) && ((MAR & 017000) == 011000))
- /* (0.6) CLL = CLear Left 9 bits of ac */
- AC &= 0000777;
-
- if (((IR & 001) == 01) && ((MAR & 017000) == 012000))
- /* (0.6) CLR = CLear Right 9 bits of ac */
- AC &= 0777000;
-
- if (IR & 002)
- /* (0.7) AMB = transfer Ac to MBr */
- MBR = AC;
-
- if (IR & 004)
- /* (0.8) CLA = CLear Ac */
- AC = 0;
-
- if (((IR & 001) == 01) && ((MAR & 010000) == 000000))
- { /* (IOS) In-Out group commands */
- /* ((MAR & 0007000) >> 9) is device ID */
- /* 0: */
- /* (***) CPY = CoPY synchronizes transmission of information
- between in-out equipment and computer. */
- /* 1: */
- /* (IOS) R1L = Read 1 Line of tape from PETR into AC bits 0, 3,
- 6, 9, 12, 15, with CYR before read (inclusive or) */
- /* 3: */
- /* (IOS) R3L = Read 3 Lines of tape from PETR into AC bits 0,
- 3, 6, 9, 12, 15, with CYR before each read (inclusive or) */
- /* 2: */
- /* (IOS) DIS = DISplay a point on scope (AC bits 0-8 specify x
- coordinate, AC bits 9-17 specify y coordinate). The
- coordinate (0, 0) is usually at the lower left hand corner
- of the scope. A console switch is available to relocate
- (0,0) to the center. */
- /* 6: */
- /* (IOS) P6H = Punch one 6-bit line of flexo tape (without 7th
- hole) from ac bits 2, 5, 8, 11, 14, 17. Note: lines
- without 7th hole are ignored by PETR. */
- /* 7: */
- /* (IOS) P7H = same as P6H, but with 7th hole */
- /* 4: */
- /* (IOS) PRT = Print one six bit flexo character from AC bits
- 2, 5, 8, 11, 14, 17. */
- /* (5 is undefined) */
- int index = (MAR & 0007000) >> 9;
-
- call_io_handler(index);
- m_ioh = 1;
- }
-
- if (((IR & 001) == 00) && ((MAR & 010000) == 010000))
- { /* (IOS) EX0 through EX7 = operate user's EXternal equipment. */
- switch ((MAR & 0007000) >> 9)
- {
- /* ... */
- }
- }
- }
- break;
- }
- }
- else
- {
- if (((IR != 2) && (IR != 3)) || (m_cycle == 2))
- m_cycle = 0;
- else
- m_cycle = 2; /* SXA and ADO have an extra cycle 2 */
- switch (IR)
- {
- case 1: /* STore indeXed */
- indexed_address_eval();
- case 0: /* STOre */
- tx0_write(MAR, (MBR = AC));
- break;
-
- case 2: /* Store indeX in Address */
- if (m_cycle)
- { /* cycle 1 */
- MBR = tx0_read(MAR);
- MBR = (MBR & 0760000) | (XR & 0017777);
- }
- else
- { /* cycle 2 */
- tx0_write(MAR, MBR);
- }
- break;
-
- case 3: /* ADd One */
- if (m_cycle)
- { /* cycle 1 */
- AC = tx0_read(MAR) + 1;
-
- #if 0
- AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */
- if (AC == 0777777) /* check for -0 (right???) */
- AC = 0;
- #else
- if (AC >= 0777777)
- AC = (AC + 1) & 0777777;
- #endif
- }
- else
- { /* cycle 2 */
- tx0_write(MAR, (MBR = AC));
- }
- break;
-
- case 5: /* Store Lr indeXed */
- indexed_address_eval();
- case 4: /* Store LR */
- tx0_write(MAR, (MBR = LR));
- break;
-
- case 6: /* STore Zero */
- tx0_write(MAR, (MBR = 0));
- break;
-
- case 9: /* ADd indeXed */
- indexed_address_eval();
- case 8: /* ADD */
- MBR = tx0_read(MAR);
-
- AC = AC + MBR;
- AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */
-
- if (AC == 0777777) /* check for -0 */
- AC = 0;
- break;
-
- case 10: /* LoaD indeX */
- MBR = tx0_read(MAR);
- XR = (MBR & 0017777) | ((MBR >> 4) & 0020000);
- break;
-
- case 11: /* AUgment indeX */
- MBR = tx0_read(MAR);
-
- XR = XR + ((MBR & 0017777) | ((MBR >> 4) & 0020000));
- XR = (XR + (XR >> 14)) & 0037777; /* propagate carry around */
-
- //if (XR == 0037777) /* check for -0 */
- // XR = 0;
- break;
-
- case 13: /* Load Lr indeXed */
- indexed_address_eval();
- case 12: /* Load LR */
- LR = MBR = tx0_read(MAR);
- break;
-
- case 15: /* Load Ac indeXed */
- indexed_address_eval();
- case 14: /* LoaD Ac */
- AC = MBR = tx0_read(MAR);
- break;
-
- case 16: /* TRansfer on Negative */
- case 17: /* Transfer on ZEro */
- case 18: /* Transfer and Set indeX */
- case 19: /* Transfer and IndeX */
- case 20: /* TRAnsfer */
- case 21: /* TRansfer indeXed */
- case 22: /* Transfer on external LeVel */
- break;
-
- case 24: /* OPeRate */
- case 25:
- case 26:
- case 27:
- case 28:
- case 29:
- case 30:
- case 31:
- if (((IR & 001) == 00) && ((MAR & 017000) == 004000))
- { /* Select class instruction */
- }
- else
- { /* Normal operate class instruction */
- if (((IR & 001) == 00) && ((MAR & 017000) == 003000))
- { /* (1.1) PEN = set ac bit 0 from light PEN ff, and ac bit 1 from
- light gun ff. (ffs contain one if pen or gun saw displayed
- point.) Then clear both light pen and light gun ffs */
- /*AC = (AC & 0177777) |?...;*/
- /*... = 0;*/
- }
-
- if (((IR & 001) == 00) && ((MAR & 017000) == 001000))
- /* (1.1) TAC = transfer TAC into ac (inclusive or) */
- AC |= m_tac;
-
- if (((IR & 001) == 00) && ((MAR & 017000) == 002000))
- /* (1.2) TBR = transfer TBR into mbr (inclusive or) */
- MBR |= m_tbr;
-
- if (((IR & 001) == 00) && ((MAR & 017000) == 006000))
- /* (1.2) RPF = Read Program Flag register into mbr (inclusive or) */
- MBR |= PF << 8;
-
- if (MAR & 0000040)
- /* (1.2) COM = COMplement ac */
- AC ^= 0777777;
-
- if ((! (MAR & 0000400)) && (MAR & 0000100))
- { /* (1.2) XMB = Transfer XR contents to MBR */
- MBR = XR;
- if (XR & 0020000)
- MBR |= 0740000;
- }
-
- if (MAR & 0000004)
- {
- switch (MAR & 0000003)
- {
- case 0000003: /* (1.2) And LR and MBR */
- MBR &= LR;
- break;
-
- case 0000001: /* (1.3) Or LR into MBR */
- MBR |= LR;
- break;
-
- default:
- if (LOG)
- logerror("unrecognized instruction");
- break;
- }
- }
-
- if (((! (MAR & 0000400)) && (MAR & 0000200)) && ((! (MAR & 0000004)) && (MAR & 0000002)))
- { /* LMB and MBL used simultaneously interchange LR and MBR */
- int tmp = MBR;
- MBR = LR;
- LR = tmp;
- }
- else if ((! (MAR & 0000400)) && (MAR & 0000200))
- /* (1.4) MBL = Transfer MBR contents to LR */
- LR = MBR;
- else if ((! (MAR & 0000004)) && (MAR & 0000002))
- /* (1.4) LMB = Store the contents of the LR in the MBR. */
- MBR = LR;
-
- if (MAR & 0000020)
- /* (1.5) PAD = Partial ADd mbr to ac */
- AC ^= MBR;
-
- if (MAR & 0000400)
- {
- switch (MAR & 0000300)
- {
- case 0000000: /* (1.6) CYR = CYcle ac contents Right one binary
- position (AC(17) -> AC(0)) */
- AC = (AC >> 1) | ((AC & 1) << 17);
- break;
-
- case 0000200: /* (1.6) CYcle ac contents Right one binary
- position (AC(0) unchanged) */
- AC = (AC >> 1) | (AC & 0400000);
- break;
-
- default:
- if (LOG)
- logerror("unrecognized instruction");
- break;
- }
- }
-
- if (((IR & 001) == 00) && ((MAR & 017000) == 007000))
- /* (1.6) SPF = Set Program Flag register from mbr */
- PF = (MBR >> 8) & 077;
-
- if (MAR & 0000010)
- { /* (1.7?) CRY = Partial ADd the 18 digits of the AC to the
- corresponding 18 digits of the carry. */
- AC ^= MBR;
-
- AC = AC + MBR;
- AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */
-
- if (AC == 0777777) /* check for -0 */
- AC = 0;
- }
-
- if ((! (MAR & 0000004)) && (MAR & 0000001))
- /* (1.8) MBX = Transfer MBR contents to XR */
- XR = (MBR & 0017777) | ((MBR >> 4) & 0020000);
-
- if (((IR & 001) == 01) && ((MAR & 017000) == 010000))
- /* (1.8) HLT = HaLT the computer and sound chime */
- m_run = 0;
- }
- break;
-
- default: /* Illegal */
- /* ... */
- break;
- }
- }
-}
-
-/*
- Simulate a pulse on reset line:
- reset most registers and flip-flops, and initialize a few emulator state
- variables.
-*/
-void tx0_device::pulse_reset()
-{
- /* processor registers */
- PC = 0; /* ??? */
- IR = 0; /* ??? */
- /*MBR = 0;*/ /* ??? */
- /*MAR = 0;*/ /* ??? */
- /*AC = 0;*/ /* ??? */
- /*LR = 0;*/ /* ??? */
-
- /* processor state flip-flops */
- m_run = 0; /* ??? */
- m_rim = 0; /* ??? */
- m_ioh = 0; /* ??? */
- m_ios = 0; /* ??? */
-
- m_rim_step = 0;
-
- /* now, we kindly ask IO devices to reset, too */
- m_io_reset_callback(ASSERT_LINE);
-}
-
-void tx0_device::io_complete()
-{
- m_ios = 1;
-}
-
-
-offs_t tx0_8kw_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
-{
- extern CPU_DISASSEMBLE( tx0_8kw );
- return CPU_DISASSEMBLE_NAME(tx0_8kw)(this, buffer, pc, oprom, opram, options);
-}
-
-
-offs_t tx0_64kw_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
-{
- extern CPU_DISASSEMBLE( tx0_64kw );
- return CPU_DISASSEMBLE_NAME(tx0_64kw)(this, buffer, pc, oprom, opram, options);
-}
diff --git a/src/emu/cpu/pdp1/tx0.h b/src/emu/cpu/pdp1/tx0.h
deleted file mode 100644
index e88172bc8ff..00000000000
--- a/src/emu/cpu/pdp1/tx0.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Raphael Nabet
-#pragma once
-
-#ifndef __TX0_H__
-#define __TX0_H__
-
-
-
-/* register ids for tx0_get_reg/tx0_set_reg */
-enum
-{
- TX0_MBR=1, TX0_AC, TX0_MAR, TX0_PC, TX0_IR, TX0_LR, TX0_XR, TX0_PF,
- TX0_TBR, TX0_TAC,
- TX0_TSS00, TX0_TSS01, TX0_TSS02, TX0_TSS03, TX0_TSS04, TX0_TSS05, TX0_TSS06, TX0_TSS07,
- TX0_TSS10, TX0_TSS11, TX0_TSS12, TX0_TSS13, TX0_TSS14, TX0_TSS15, TX0_TSS16, TX0_TSS17,
- TX0_CM_SEL, TX0_LR_SEL, TX0_GBL_CM_SEL,
- TX0_STOP_CYC0, TX0_STOP_CYC1,
- TX0_RUN, TX0_RIM,
- TX0_CYCLE, TX0_IOH, TX0_IOS
-};
-
-
-#define MCFG_TX0_CONFIG(_cpy_devcb, _r1l_devcb, _dis_devcb, _r3l_devcb, _prt_devcb, _rsv_devcb, _p6h_devcb, _p7h_devcb, _sel_devcb, _res_devcb) \
- tx0_device::set_cpy_cb(*device, DEVCB_##_cpy_devcb); \
- tx0_device::set_r1l_cb(*device, DEVCB_##_r1l_devcb); \
- tx0_device::set_dis_cb(*device, DEVCB_##_dis_devcb); \
- tx0_device::set_r3l_cb(*device, DEVCB_##_r3l_devcb); \
- tx0_device::set_prt_cb(*device, DEVCB_##_prt_devcb); \
- tx0_device::set_rsv_cb(*device, DEVCB_##_rsv_devcb); \
- tx0_device::set_p6h_cb(*device, DEVCB_##_p6h_devcb); \
- tx0_device::set_p7h_cb(*device, DEVCB_##_p7h_devcb); \
- tx0_device::set_sel_cb(*device, DEVCB_##_sel_devcb); \
- tx0_device::set_res_cb(*device, DEVCB_##_res_devcb);
-
-
-class tx0_device : public cpu_device
-{
-public:
- // construction/destruction
- tx0_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source, int addr_bits, int address_mask, int ir_mask);
-
- // static configuration helpers
- template<class _Object> static devcb_base &set_cpy_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_cpy_handler.set_callback(object); }
- template<class _Object> static devcb_base &set_r1l_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_r1l_handler.set_callback(object); }
- template<class _Object> static devcb_base &set_dis_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_dis_handler.set_callback(object); }
- template<class _Object> static devcb_base &set_r3l_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_r3l_handler.set_callback(object); }
- template<class _Object> static devcb_base &set_prt_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_prt_handler.set_callback(object); }
- template<class _Object> static devcb_base &set_rsv_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_rsv_handler.set_callback(object); }
- template<class _Object> static devcb_base &set_p6h_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_p6h_handler.set_callback(object); }
- template<class _Object> static devcb_base &set_p7h_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_p7h_handler.set_callback(object); }
- template<class _Object> static devcb_base &set_sel_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_sel_handler.set_callback(object); }
- template<class _Object> static devcb_base &set_res_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_io_reset_callback.set_callback(object); }
-
- void pulse_reset();
- void io_complete();
-
-protected:
- // device-level overrides
- virtual void device_start();
- virtual void device_reset();
-
- // device_execute_interface overrides
- virtual UINT32 execute_min_cycles() const { return 1; }
- virtual UINT32 execute_max_cycles() const { return 3; }
-
- // device_memory_interface overrides
- virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : NULL; }
-
- // device_disasm_interface overrides
- virtual UINT32 disasm_min_opcode_bytes() const { return 4; }
- virtual UINT32 disasm_max_opcode_bytes() const { return 4; }
-
-protected:
- address_space_config m_program_config;
-
- /* processor registers */
- int m_mbr; /* memory buffer register (18 bits) */
- int m_ac; /* accumulator (18 bits) */
- int m_mar; /* memory address register (16 (64kW) or 13 (8kW) bits) */
- int m_pc; /* program counter (16 (64kW) or 13 (8kW) bits) */
- int m_ir; /* instruction register (2 (64kW) or 5 (8kW) bits) */
- int m_lr; /* live register (18 bits) */
- int m_xr; /* index register (14 bits) (8kW only) */
- int m_pf; /* program flags (6 bits expandable to 10) (8kW only) */
-
- /* operator panel switches */
- int m_tbr; /* toggle switch buffer register (18 bits) */
- int m_tac; /* toggle switch accumulator (18 bits) */
- int m_tss[16]; /* toggle switch storage (18 bits * 16) */
- UINT16 m_cm_sel; /* individual cm select (1 bit * 16) */
- UINT16 m_lr_sel; /* individual lr select (1 bit * 16) */
- unsigned int m_gbl_cm_sel;/* global cm select (1 bit) */
- unsigned int m_stop_cyc0; /* stop on cycle 0 */
- unsigned int m_stop_cyc1; /* stop on cycle 1 */
-
- /* processor state flip-flops */
- unsigned int m_run; /* processor is running */
- unsigned int m_rim; /* processor is in read-in mode */
- unsigned int m_cycle; /* 0 -> fetch */
- /* 1 -> execute (except for taken branches) */
- /* 2 -> extra execute cycle for SXA and ADO */
-
- unsigned int m_ioh; /* i-o halt: processor is executing an Input-Output Transfer wait */
- unsigned int m_ios; /* i-o synchronizer: set on i-o operation completion */
-
- /* additional emulator state variables */
- int m_rim_step; /* current step in rim execution */
-
- int m_address_mask; /* address mask */
- int m_ir_mask; /* IR mask */
-
- int m_icount;
-
- address_space *m_program;
-
- /* 8 standard I/O handlers:
- 0: cpy (8kW only)
- 1: r1l
- 2: dis
- 3: r3l
- 4: prt
- 5: reserved (for unimplemented typ instruction?)
- 6: p6h
- 7: p7h */
- devcb_write_line m_cpy_handler;
- devcb_write_line m_r1l_handler;
- devcb_write_line m_dis_handler;
- devcb_write_line m_r3l_handler;
- devcb_write_line m_prt_handler;
- devcb_write_line m_rsv_handler;
- devcb_write_line m_p6h_handler;
- devcb_write_line m_p7h_handler;
- /* select instruction handler */
- devcb_write_line m_sel_handler;
- /* callback called when reset line is pulsed: IO devices should reset */
- devcb_write_line m_io_reset_callback;
-
- int tx0_read(offs_t address);
- void tx0_write(offs_t address, int data);
- void call_io_handler(int io_handler);
- void indexed_address_eval();
-};
-
-
-class tx0_8kw_device : public tx0_device
-{
-public:
- // construction/destruction
- tx0_8kw_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
-
-protected:
- virtual void execute_run();
- virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
-
-private:
- void execute_instruction_8kw();
-};
-
-
-class tx0_64kw_device : public tx0_device
-{
-public:
- // construction/destruction
- tx0_64kw_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
-
-protected:
- virtual void execute_run();
- virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
-
-private:
- void execute_instruction_64kw();
-};
-
-
-extern const device_type TX0_64KW;
-extern const device_type TX0_8KW;
-
-#endif /* __TX0_H__ */
diff --git a/src/emu/cpu/pdp1/tx0dasm.c b/src/emu/cpu/pdp1/tx0dasm.c
deleted file mode 100644
index 3d8a1daf9e1..00000000000
--- a/src/emu/cpu/pdp1/tx0dasm.c
+++ /dev/null
@@ -1,123 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Raphael Nabet
-#include "emu.h"
-#include "cpu/pdp1/tx0.h"
-
-CPU_DISASSEMBLE( tx0_64kw )
-{
- int md;
- int x;
-
- md = oprom[0] << 24 | oprom[1] << 16 | oprom[2] << 8 | oprom[3];
-
- x = md & 0177777;
- switch (md >> 16)
- {
- case 0:
- sprintf (buffer, "sto 0%06o", x);
- break;
- case 1:
- sprintf (buffer, "add 0%06o", x);
- break;
- case 2:
- sprintf (buffer, "trn 0%06o", x);
- break;
- case 3:
- sprintf (buffer, "opr 0%06o", x);
- break;
- }
- return 1;
-}
-
-CPU_DISASSEMBLE( tx0_8kw )
-{
- int md;
- int x;
-
- md = oprom[0] << 24 | oprom[1] << 16 | oprom[2] << 8 | oprom[3];
-
- x = md & 0017777;
- switch (md >> 13)
- {
- case 0:
- sprintf (buffer, "sto 0%05o", x);
- break;
- case 1:
- sprintf (buffer, "stx 0%05o", x);
- break;
- case 2:
- sprintf (buffer, "sxa 0%05o", x);
- break;
- case 3:
- sprintf (buffer, "ado 0%05o", x);
- break;
- case 4:
- sprintf (buffer, "slr 0%05o", x);
- break;
- case 5:
- sprintf (buffer, "slx 0%05o", x);
- break;
- case 6:
- sprintf (buffer, "stz 0%05o", x);
- break;
- case 8:
- sprintf (buffer, "add 0%05o", x);
- break;
- case 9:
- sprintf (buffer, "adx 0%05o", x);
- break;
- case 10:
- sprintf (buffer, "ldx 0%05o", x);
- break;
- case 11:
- sprintf (buffer, "aux 0%05o", x);
- break;
- case 12:
- sprintf (buffer, "llr 0%05o", x);
- break;
- case 13:
- sprintf (buffer, "llx 0%05o", x);
- break;
- case 14:
- sprintf (buffer, "lda 0%05o", x);
- break;
- case 15:
- sprintf (buffer, "lax 0%05o", x);
- break;
- case 16:
- sprintf (buffer, "trn 0%05o", x);
- break;
- case 17:
- sprintf (buffer, "tze 0%05o", x);
- break;
- case 18:
- sprintf (buffer, "tsx 0%05o", x);
- break;
- case 19:
- sprintf (buffer, "tix 0%05o", x);
- break;
- case 20:
- sprintf (buffer, "tra 0%05o", x);
- break;
- case 21:
- sprintf (buffer, "trx 0%05o", x);
- break;
- case 22:
- sprintf (buffer, "tlv 0%05o", x);
- break;
- case 24:
- case 25:
- case 26:
- case 27:
- case 28:
- case 29:
- case 30:
- case 31:
- sprintf (buffer, "opr 0%06o", md & 0177777);
- break;
- default:
- sprintf (buffer, "illegal");
- break;
- }
- return 1;
-}