Notes For V3.3-1

1. New Features in 3.3-1

1.1 H316

TTY	- implemented paper-tape reader and punch
	- added ASCII file support

PTR,PTP	- added ASCII file support

1.2 HP2100

CPU	- added SET CPU 21MX-M, 21MX-E (from Dave Brian)
	- disabled TIMER/EXECUTE/DIAG instructions for 21MX-M (from Dave Bryan)
	- added post-processor to maintain T/M consistency (from Dave Bryan)

DS	- released 13037 disk controller

1.3 Interdata

MT	- added read-only file support

1.4 SDS

MT	- added read-only file support

1.5 PDP-11

TM,TS	- added read-only file support

2. Bugs Fixed in 3.3

2.1 H316

CPU	- fixed bug in divide

LPT	- fixed bug in DMA/DMC support

MT	- fixed bug in DMA/DMC support

DP	- fixed bug in skip on not seeking

TTY	- fixed bugs in SKS '104, '504

2.2 HP2100

CPU	- fixed DMA reset to clear alternate CTL flop (from Dave Bryan)
	- fixed bug in JPY (from Dave Bryan)
	- fixed bugs in CBS, SBS, TBS
	- separate A/B from M[0/1] for DMA (found by Dave Bryan)

LPS	- added restart when set online, etc. (from Dave Bryan)
	- fixed col count for non-printing chars (from Dave Bryan)

LPT	- added restart when set online, etc. (from Dave Bryan)

2.3 PDP-11

CPU	- fixed WAIT to work in all modes (from John Dundas)
This commit is contained in:
Bob Supnik 2005-01-09 13:55:00 -08:00 committed by Mark Pizzolato
parent b6393b36b4
commit 9b5c8c9711
42 changed files with 1698 additions and 584 deletions

View file

@ -1,143 +1,63 @@
Notes For V3.3
Notes For V3.3-1
RESTRICTION: The HP DS disk is not debugged. DO NOT enable this
feature for normal operations.
WARNING: Massive changes in the PDP-11 make all previous SAVEd
file obsolete. Do not attempt to use a PDP-11 SAVE file from a
prior release with V3.3!
1. New Features in 3.3-1
1. New Features in 3.3
1.1 H316
1.1 SCP
TTY - implemented paper-tape reader and punch
- added ASCII file support
- Added -p (powerup) qualifier to RESET
- Changed SET <unit> ONLINE/OFFLINE to SET <unit> ENABLED/DISABLED
- Moved SET DEBUG under SET CONSOLE hierarchy
- Added optional parameter value to SHOW command
- Added output file option to SHOW command
PTR,PTP - added ASCII file support
1.2 PDP-11
1.2 HP2100
- Separated RH Massbus adapter from RP controller
- Added TU tape support
- Added model emulation framework
- Added model details
CPU - added SET CPU 21MX-M, 21MX-E (from Dave Brian)
- disabled TIMER/EXECUTE/DIAG instructions for 21MX-M (from Dave Bryan)
- added post-processor to maintain T/M consistency (from Dave Bryan)
1.3 VAX
DS - released 13037 disk controller
- Separated out CVAX-specific features from core instruction simulator
- Implemented capability for CIS, octaword, compatibility mode instructions
- Added instruction display and parse for compatibility mode
- Changed SET CPU VIRTUAL=n to SHOW CPU VIRTUAL=n
- Added =n optional parameter to SHOW CPU HISTORY
1.3 Interdata
1.4 Unibus/Qbus simulators (PDP-11, VAX, PDP-10)
MT - added read-only file support
- Simplified DMA API's
- Modified DMA peripherals to use simplified API's
1.4 SDS
1.5 HP2100 (all changes from Dave Bryan)
MT - added read-only file support
CPU - moved MP into its own device; added MP option jumpers
- modified DMA to allow disabling
- modified SET CPU 2100/2116 to truncate memory > 32K
- added -F switch to SET CPU to force memory truncation
- modified WRU to be REG_HRO
- added BRK and DEL to save console settings
1.5 PDP-11
DR - provided protected tracks and "Writing Enabled" status bit
- added "parity error" status return on writes for 12606
- added track origin test for 12606
- added SCP test for 12606
- added "Sector Flag" status bit
- added "Read Inhibit" status bit for 12606
- added TRACKPROT modifier
LPS - added SET OFFLINE/ONLINE, POWEROFF/POWERON
- added fast/realistic timing
- added debug printouts
LPT - added SET OFFLINE/ONLINE, POWEROFF/POWERON
PTR - added paper tape loop mode, DIAG/READER modifiers to PTR
- added PV_LEFT to PTR TRLLIM register
CLK - modified CLK to permit disable
1.6 IBM 1401, IBM 1620, Interdata 16b, SDS 940, PDP-10
- Added instruction history
1.7 H316, PDP-15, PDP-8
- Added =n optional value to SHOW CPU HISTORY
TM,TS - added read-only file support
2. Bugs Fixed in 3.3
2.1 SCP
2.1 H316
- Fixed comma-separated SET options (from Dave Bryan)
- Fixed duplicate HELP displays with user-specified commands
CPU - fixed bug in divide
2.2 PDP-10
LPT - fixed bug in DMA/DMC support
MT - fixed bug in DMA/DMC support
DP - fixed bug in skip on not seeking
TTY - fixed bugs in SKS '104, '504
2.2 HP2100
CPU - fixed DMA reset to clear alternate CTL flop (from Dave Bryan)
- fixed bug in JPY (from Dave Bryan)
- fixed bugs in CBS, SBS, TBS
- separate A/B from M[0/1] for DMA (found by Dave Bryan)
LPS - added restart when set online, etc. (from Dave Bryan)
- fixed col count for non-printing chars (from Dave Bryan)
LPT - added restart when set online, etc. (from Dave Bryan)
- Replicated RP register state per drive
- Fixed TU to set FCE on short record
- Fixed TU to return bit<15> in drive type
- Fixed TU format specification, 1:0 are don't cares
- Fixed TU handling of TMK status
- Fixed TU handling of DONE, ATA at end of operation
- Implemented TU write check
2.3 PDP-11
- Replicated RP register state per drive
- Fixed RQ, TQ to report correct controller type and stage 1 configuration
flags on a Unibus system
- Fixed HK CS2<output_ready> flag
CPU - fixed WAIT to work in all modes (from John Dundas)
2.4 VAX
- Fixed parsing of indirect displacement modes in instruction input
2.5 HP2100 (all fixes from Dave Bryan)
CPU - fixed S-register behavior on 2116
- fixed LIx/MIx behavior for DMA on 2116 and 2100
- fixed LIx/MIx behavior for empty I/O card slots
DP - fixed enable/disable from either device
- fixed ANY ERROR status for 12557A interface
- fixed unattached drive status for 12557A interface
- status cmd without prior STC DC now completes (12557A)
- OTA/OTB CC on 13210A interface also does CLC CC
- fixed RAR model
- fixed seek check on 13210 if sector out of range
DQ - fixed enable/disable from either device
- shortened xtime from 5 to 3 (drive avg 156KW/second)
- fixed not ready/any error status
- fixed RAR model
DR - fixed enable/disable from either device
- fixed sector return in status word
- fixed DMA last word write, incomplete sector fill value
- fixed 12610 SFC operation
- fixed current-sector determination
IPL - fixed enable/disable from either device
LPS - fixed status returns for error conditions
- fixed handling of non-printing characters
- fixed handling of characters after column 80
- improved timing model accuracy for RTE
LPT - fixed status returns for error conditions
- fixed TOF handling so form remains on line 0
SYS - fixed display of CCA/CCB/CCE instructions
2.5 PDP-15
FPP - fixed URFST to mask low 9b of fraction
- fixed exception PC setting

View file

@ -25,6 +25,7 @@
cpu H316/H516 CPU
01-Dec-04 RMS Fixed bug in DIV
06-Nov-04 RMS Added =n to SHOW HISTORY
04-Jan-04 RMS Removed unnecessary compare
31-Dec-03 RMS Fixed bug in cpu_set_hist
@ -496,11 +497,10 @@ case 003: case 023: case 043: case 063: /* ANA */
case 004: case 024: case 044: case 064: /* STA */
if (reason = Ea (MB, &Y)) break; /* eff addr */
Write (Y, AR); /* store A */
if (dp) { /* double prec? */
if ((Y & 1) == 0) Write (Y, AR); /* if even, store A */
Write (Y | 1, BR); /* store B */
sc = 0; }
else Write (Y, AR); /* no, store word */
break;
case 005: case 025: case 045: case 065: /* ERA */
@ -585,7 +585,7 @@ case 017: case 037: case 057: case 077: /* DIV */
if (reason = Ea (MB, &Y)) break; /* eff addr */
t2 = SEXT (Read (Y)); /* divr */
if (t2) { /* divr != 0? */
t1 = GETDBL_S (AR, BR); /* get A'B */
t1 = GETDBL_S (SEXT (AR), BR); /* get A'B signed */
BR = (t1 % t2) & DMASK; /* remainder */
t1 = t1 / t2; /* quotient */
AR = t1 & DMASK;
@ -934,8 +934,8 @@ int32 Add16 (int32 v1, int32 v2)
{
int32 r = v1 + v2;
C = 0;
if (((v1 ^ ~v2) & (v1 ^ r)) & SIGN) C = 1;
else C = 0;
return (r & DMASK);
}
@ -943,8 +943,8 @@ int32 Add31 (int32 v1, int32 v2)
{
int32 r = v1 + v2;
C = 0;
if (((v1 ^ ~v2) & (v1 ^ r)) & (1u << 30)) C = 1;
if (((v1 ^ ~v2) & (v1 ^ r)) & DP_SIGN) C = 1;
else C = 0;
return r;
}

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
01-Dec-04 RMS Added double precision constants
24-Oct-03 RMS Added DMA/DMC support
25-Apr-03 RMS Revised for extended file support
*/
@ -55,6 +56,7 @@
/* Architectural constants */
#define SIGN 0100000 /* sign */
#define DP_SIGN 010000000000
#define DMASK 0177777 /* data mask */
#define MMASK (DMASK & ~SIGN) /* magnitude mask */
#define XR M[0]

View file

@ -174,6 +174,23 @@ The paper tape reader (PTR) reads data from a disk file. The POS
register specifies the number of the next data item to be read.
Thus, by changing POS, the user can backspace or advance the reader.
The paper tape reader can bet set to operate in binary, ASCII, or
Unix ASCII mode:
sim> set ptr binary -- binary mode
sim> set ptr ascii -- ASCII mode
sim> set ptr uascii -- Unix ASCII mode
The mode can also be set by a switch setting in the attach command:
sim> att -b ptr <file> -- binary mode
sim> att -a ptr <file> -- ASCII mode
sim> att -u ptr <file> -- Unix ASCII mode
In ASCII or Unix ASCII mode, all non-zero characters have the high
order bit forced on. In Unix ASCII mode, newline is converted to
CR, and LF in inserted as the following character.
The paper tape reader supports the BOOT command. BOOT PTR copies the
absolute binary loader into memory and starts it running.
@ -207,6 +224,23 @@ The paper tape punch (PTP) writes data to a disk file. The POS
register specifies the number of the next data item to be written.
Thus, by changing POS, the user can backspace or advance the punch.
The paper tape punch can bet set to operate in binary, ASCII, or
Unix ASCII mode:
sim> set ptp binary -- binary mode
sim> set ptp ascii -- ASCII mode
sim> set ptp uascii -- Unix ASCII mode
The mode can also be set by a switch setting in the attach command:
sim> att -b ptp <file> -- binary mode
sim> att -a ptp <file> -- ASCII mode
sim> att -u ptp <file> -- Unix ASCII mode
In ASCII or Unix ASCII mode, all characters are masked to 7b
before being written to the output file. In Unix ASCII mode, LF
is converted to newline, and CR is discarded.
The paper tape punch implements these registers:
name size comments
@ -232,15 +266,65 @@ Error handling is as follows:
2.2.3 316/516-33 Console Teletype (TTY)
The Teletype units (TTY0, TTY1) can be set to one of three modes:
The console Teletype (TTY) consists of four separate units:
TTY0 keyboard
TTY1 printer
TTY2 paper tape reader
TTY3 paper tape punch
The keyboard and printer (TTY0, TTY1) can be set to one of three modes:
KSR, 7B, or 8B. In KSR mode, lower case input and output characters
are automatically converted to upper case, and the high order bit is
forced to one on input. In 7B mode, input and output characters are
masked to 7 bits. In 8B mode, characters are not modified. Changing
the mode of either unit changes both. The default mode is KSR.
the mode of either unit changes both. The default mode is KSR. The
Teletype keyboard reads from the console keyboard, and the printer
prites to the simulator console window.
The Teletype reads from the console keyboard and writes to the
simulator console window. It implements these registers:
The paper tape reader (TTY2) can bet set to operate in binary, ASCII, or
Unix ASCII mode:
sim> set tty2 binary -- binary mode
sim> set tty2 ascii -- ASCII mode
sim> set tty2 uascii -- Unix ASCII mode
The mode can also be set by a switch setting in the attach command:
sim> att -b tty2 <file> -- binary mode
sim> att -a tty2 <file> -- ASCII mode
sim> att -u tty2 <file> -- Unix ASCII mode
In ASCII or Unix ASCII mode, all non-zero characters have the high
order bit forced on. In Unix ASCII mode, newline is converted to
CR, and LF in inserted as the following character.
The paper tape reader is started by program output of XON or by
the command SET TTY2 START. The paper tape reader is stopped by
reader input of XOFF or by the command SET TTY2 STOP.
The paper tape punch (TTY3) can bet set to operate in binary, ASCII, or
Unix ASCII mode:
sim> set tty3 binary -- binary mode
sim> set tty3 ascii -- ASCII mode
sim> set tty3 uascii -- Unix ASCII mode
The mode can also be set by a switch setting in the attach command:
sim> att -b tty3 <file> -- binary mode
sim> att -a tty3 <file> -- ASCII mode
sim> att -u tty3 <file> -- Unix ASCII mode
In ASCII or Unix ASCII mode, all characters are masked to 7b
before being written to the output file. In Unix ASCII mode, LF
is converted to newline, and CR is discarded.
The paper tape punch is started by program output of TAPE or by
the command SET TTY3 START. The paper tape punch is stopped by
program output of XOFF or by the command SET TTY3 STOP.
It implements these registers:
name size comments
@ -249,10 +333,12 @@ simulator console window. It implements these registers:
INTREQ 1 device interrupt request
READY 1 device ready
ENABLE 1 device interrupts enabled
KPOS 32 number of characters input
KPOS 32 number of keyboard characters input
KTIME 24 keyboard polling interval
TPOS 32 number of characters output
TPOS 32 number of printer characters output
TTIME 24 time from I/O initiation to interrupt
RPOS 32 current reader character position
PPOS 32 current punch character position
2.2.4 316/516-12 Real Time Clock (CLK)

View file

@ -27,6 +27,8 @@
4651 disk subsystem
4720 disk subsystem
01-Dec-04 RMS Fixed bug in skip on !seeking
The Honeywell disks have the unique characteristic of supporting variable
formatting, on a per track basis. To accomodate this, each track is
simulated as 2048 words, divided into records. (2048 words accomodates
@ -433,7 +435,8 @@ case ioSKS: /* SKS */
u = fnc - 011;
case 007: /* !not seeking 7 */
if (!sim_is_active (&dp_unit[u]) || /* quiescent? */
(dp_unit[u].FNC & 017) != FNC_SEEK) return IOSKIP (dat);
(dp_unit[u].FNC != (FNC_SEEK | FNC_2ND)))
return IOSKIP (dat); /* seeking sets late */
break; }
break;
case ioEND: /* end of range */
@ -816,6 +819,8 @@ for (i = 0; i < DP_NUMDRV; i++) { /* loop thru drives */
sim_cancel (&dp_unit[i]); /* cancel activity */
dp_unit[i].FNC = 0; /* clear function */
dp_unit[i].CYL = 0; }
CLR_INT (INT_DP); /* clear int, enb */
CLR_ENB (INT_DP);
return SCPE_OK;
}

View file

@ -25,6 +25,7 @@
lpt line printer
01-Dec-04 RMS Fixed bug in DMA/DMC support
24-Oct-03 RMS Added DMA/DMC support
25-Apr-03 RMS Revised for extended file support
30-May-02 RMS Widened POS to 32b
@ -153,7 +154,7 @@ case ioOCP: /* OCP */
lpt_wdpos = 0; /* init scan pos */
lpt_eor = 0;
if (ch >= 0) lpt_dma = 1; /* try for DMA/DMC */
lpt_dma = 0;
else lpt_dma = 0;
if (!sim_is_active (&lpt_unit)) {
lpt_rdy = 1;
if (lpt_dma) SET_CH_REQ (ch); }

View file

@ -25,6 +25,8 @@
mt 516-4100 seven track magnetic tape
01-Dec-04 RMS Fixed bug in DMA/DMC support
Magnetic tapes are represented as a series of variable records
of the form:
@ -183,7 +185,8 @@ case ioOCP:
case FNC_DMANM: /* set DMA/DMC */
case FNC_DMAAU:
mt_usel = u; /* save unit select */
if (mt_dib.chan) mt_dma = 1; /* if configured */
if (mt_dib.chan) mt_dma = 1; /* set DMA if configured */
else mt_dma = 0;
break;
case FNC_IOBUS: /* set IOBUS */
mt_usel = u; /* save unit select */

View file

@ -28,6 +28,11 @@
tty 316/516-33 teleprinter
clk/options 316/516-12 real time clocks/internal options
01-Dec-04 RMS Fixed problem in SKS '104 (reported by Philipp Hachtmann)
Fixed bug in SKS '504
Added PTR detach routine, stops motion
Added PTR/PTP ASCII file support
Added TTR/TTP support
24-Oct-03 RMS Added DMA/DMC support
25-Apr-03 RMS Revised for extended file support
01-Mar-03 RMS Added SET/SHOW CLK FREQ support
@ -37,26 +42,72 @@
03-Nov-01 RMS Implemented upper case for console output
29-Nov-01 RMS Added read only unit support
07-Sep-01 RMS Moved function prototypes
The ASR-33/35 reader/punch logic, and the ASCII file support for all paper tape
devices, logic is taken, with grateful thanks, from Adrian Wise's H316 emulator.
Teletype reader transitions:
- SET TTY2 START puts the reader in RUN
- XOFF from keyboard/reader stops the reader after 1-2 more characters are read
- XON from program starts the reader
- Detach, SET TTY2 STOP, or end of file stops the reader
Teletype punch transitions:
- SET TTY3 START puts the punch in RUN
- XOFF from program stops the punch after 1 more character is punched
- TAPE from program starts the punch after 1 character delay
- Detach or SET TTY3 STOP stops the punch
*/
#include "h316_defs.h"
#include <ctype.h>
#define CHAR_FLAG(c) (1u << (c))
#define BEL_FLAG CHAR_FLAG('\a')
#define LF_FLAG CHAR_FLAG('\n')
#define CR_FLAG CHAR_FLAG('\r')
#define HT_FLAG CHAR_FLAG('\t')
#define CNTL_SET (BEL_FLAG | HT_FLAG | LF_FLAG | CR_FLAG)
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8B */
#define UNIT_V_KSR (UNIT_V_UF + 1) /* KSR33 */
#define UNIT_V_ASC (UNIT_V_UF + 2) /* ASCII */
#define UNIT_V_UASC (UNIT_V_UF + 3) /* Unix ASCII */
#define UNIT_8B (1 << UNIT_V_8B)
#define UNIT_KSR (1 << UNIT_V_KSR)
#define UNIT_ASC (1 << UNIT_V_ASC)
#define UNIT_UASC (1 << UNIT_V_UASC)
#define STA u3 /* state bits */
#define LF_PEND 01 /* lf pending */
#define RUNNING 02 /* tape running */
#define XON 0021
#define TAPE 0022
#define XOFF 0023
#define RUBOUT 0377
extern uint16 M[];
extern int32 PC;
extern int32 stop_inst;
extern int32 C, dp, ext, extoff_pending, sc;
extern int32 dev_int, dev_enb;
extern int32 sim_switches;
extern UNIT cpu_unit;
int32 ptr_stopioe = 0, ptp_stopioe = 0; /* stop on error */
int32 ptp_power = 0, ptp_ptime; /* punch power, time */
int32 tty_mode = 0, tty_buf = 0; /* tty mode, buf */
uint32 ptr_stopioe = 0; /* stop on error */
uint32 ptp_stopioe = 0;
uint32 ptp_power = 0; /* punch power, time */
int32 ptp_ptime;
uint32 ttr_stopioe = 0;
uint32 tty_mode = 0; /* input (0), output (1) */
uint32 tty_buf = 0; /* tty buffer */
uint32 ttr_xoff_read = 0;
uint32 ttp_tape_rcvd = 0;
uint32 ttp_xoff_rcvd = 0;
int32 clk_tps = 60; /* ticks per second */
int32 ptrio (int32 inst, int32 fnc, int32 dat, int32 dev);
@ -70,12 +121,18 @@ int32 ttyio (int32 inst, int32 fnc, int32 dat, int32 dev);
t_stat tti_svc (UNIT *uptr);
t_stat tto_svc (UNIT *uptr);
t_stat tty_reset (DEVICE *dptr);
t_stat tty_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat ttio_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat ttrp_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat ttrp_set_start_stop (UNIT *uptr, int32 val, char *cptr, void *desc);
int32 clkio (int32 inst, int32 fnc, int32 dat, int32 dev);
t_stat clk_svc (UNIT *uptr);
t_stat clk_reset (DEVICE *dptr);
t_stat clk_set_freq (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat clk_show_freq (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat pt_attach (UNIT *uptr, char *cptr);
t_stat pt_detach (UNIT *uptr);
t_stat tto_write (int32 c);
t_stat ttp_write (int32 c);
/* PTR data structures
@ -97,14 +154,20 @@ REG ptr_reg[] = {
{ FLDATA (ENABLE, dev_enb, INT_V_PTR) },
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
{ ORDATA (RSTATE, ptr_unit.STA, 2), REG_HIDDEN },
{ FLDATA (STOP_IOE, ptr_stopioe, 0) },
{ NULL } };
MTAB pt_mod[] = {
{ UNIT_ATT+UNIT_ASC+UNIT_UASC, UNIT_ATT+UNIT_ASC, "ASCII", NULL },
{ UNIT_ATT+UNIT_ASC+UNIT_UASC, UNIT_ATT+UNIT_ASC+UNIT_UASC, "Unix ASCII", NULL },
{ 0 } };
DEVICE ptr_dev = {
"PTR", &ptr_unit, ptr_reg, NULL,
"PTR", &ptr_unit, ptr_reg, pt_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &ptr_reset,
&ptr_boot, NULL, NULL,
&ptr_boot, &pt_attach, &pt_detach,
&ptr_dib, 0 };
/* PTP data structures
@ -126,16 +189,17 @@ REG ptp_reg[] = {
{ FLDATA (ENABLE, dev_enb, INT_V_PTP) },
{ FLDATA (POWER, ptp_power, 0) },
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
{ ORDATA (PSTATE, ptp_unit.STA, 2), REG_HIDDEN },
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
{ DRDATA (PWRTIME, ptp_ptime, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptp_stopioe, 0) },
{ NULL } };
DEVICE ptp_dev = {
"PTP", &ptp_unit, ptp_reg, NULL,
"PTP", &ptp_unit, ptp_reg, pt_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &ptp_reset,
NULL, NULL, NULL,
NULL, &pt_attach, NULL,
&ptp_dib, 0 };
/* TTY data structures
@ -148,12 +212,16 @@ DEVICE ptp_dev = {
#define TTI 0
#define TTO 1
#define TTR 2
#define TTP 3
DIB tty_dib = { TTY, IOBUS, 1, &ttyio };
UNIT tty_unit[] = {
{ UDATA (&tti_svc, UNIT_KSR, 0), KBD_POLL_WAIT },
{ UDATA (&tto_svc, UNIT_KSR, 0), SERIAL_OUT_WAIT } };
{ UDATA (&tto_svc, UNIT_KSR, 0), SERIAL_OUT_WAIT },
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0) },
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) } };
REG tty_reg[] = {
{ ORDATA (BUF, tty_buf, 8) },
@ -164,19 +232,35 @@ REG tty_reg[] = {
{ DRDATA (KTIME, tty_unit[TTI].wait, 24), REG_NZ + PV_LEFT },
{ DRDATA (TPOS, tty_unit[TTO].pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TTIME, tty_unit[TTO].wait, 24), REG_NZ + PV_LEFT },
{ ORDATA (RXOFF, ttr_xoff_read, 2), REG_HIDDEN },
{ ORDATA (RSTATE, tty_unit[TTR].STA, 2), REG_HIDDEN },
{ DRDATA (RPOS, tty_unit[TTR].pos, T_ADDR_W), PV_LEFT },
{ ORDATA (PTAPE, ttp_tape_rcvd, 2), REG_HIDDEN },
{ ORDATA (PXOFF, ttp_xoff_rcvd, 2), REG_HIDDEN },
{ ORDATA (PSTATE, tty_unit[TTP].STA, 2), REG_HIDDEN },
{ DRDATA (PPOS, tty_unit[TTP].pos, T_ADDR_W), PV_LEFT },
{ FLDATA (STOP_IOE, ttr_stopioe, 0) },
{ NULL } };
MTAB tty_mod[] = {
{ UNIT_KSR+UNIT_8B, UNIT_KSR, "KSR", "KSR", &tty_set_mode },
{ UNIT_KSR+UNIT_8B, 0 , "7b" , "7B" , &tty_set_mode },
{ UNIT_KSR+UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode },
{ UNIT_KSR+UNIT_8B+UNIT_ATTABLE, UNIT_KSR, "KSR", "KSR", &ttio_set_mode },
{ UNIT_KSR+UNIT_8B+UNIT_ATTABLE, 0 , "7b" , "7B" , &ttio_set_mode },
{ UNIT_KSR+UNIT_8B+UNIT_ATTABLE, UNIT_8B , "8b" , "8B" , &ttio_set_mode },
{ UNIT_ATTABLE+UNIT_ASC+UNIT_UASC, UNIT_ATTABLE, NULL, "BINARY",
&ttrp_set_mode },
{ UNIT_ATTABLE+UNIT_ASC+UNIT_UASC, UNIT_ATTABLE+UNIT_ASC, "ASCII", "ASCII",
&ttrp_set_mode },
{ UNIT_ATTABLE+UNIT_ASC+UNIT_UASC, UNIT_ATTABLE+UNIT_ASC+UNIT_UASC, "Unix ASCII", "UASCII",
&ttrp_set_mode },
{ MTAB_XTD|MTAB_VUN|MTAB_NMO, 1, NULL, "START", &ttrp_set_start_stop },
{ MTAB_XTD|MTAB_VUN|MTAB_NMO, 0, NULL, "STOP", &ttrp_set_start_stop },
{ 0 } };
DEVICE tty_dev = {
"TTY", tty_unit, tty_reg, tty_mod,
2, 10, 31, 1, 8, 8,
4, 10, 31, 1, 8, 8,
NULL, NULL, &tty_reset,
NULL, NULL, NULL,
NULL, &pt_attach, &pt_detach,
&tty_dib, 0 };
/* CLK data structures
@ -227,8 +311,8 @@ case ioOCP: /* OCP */
break;
case ioSKS: /* SKS */
if (fnc & 013) return IOBADFNC (dat); /* only fnc 0,4 */
if (((fnc == 0) && TST_INT (INT_PTR)) || /* fnc 0? skip rdy */
((fnc == 4) && !TST_INTREQ (INT_PTR))) /* fnc 4? skip !int */
if (((fnc == 000) && TST_INT (INT_PTR)) || /* fnc 0? skip rdy */
((fnc == 004) && !TST_INTREQ (INT_PTR))) /* fnc 4? skip !int */
return IOSKIP (dat);
break;
case ioINA: /* INA */
@ -244,24 +328,61 @@ return dat;
t_stat ptr_svc (UNIT *uptr)
{
int32 temp;
int32 c;
if ((ptr_unit.flags & UNIT_ATT) == 0) /* attached? */
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (ptr_stopioe, SCPE_UNATT);
if ((temp = getc (ptr_unit.fileref)) == EOF) { /* read byte */
if (feof (ptr_unit.fileref)) {
if (uptr->STA & LF_PEND) { /* lf pending? */
uptr->STA &= ~LF_PEND; /* clear flag */
c = 0212; /* insert LF */
}
else { if ((c = getc (uptr->fileref)) == EOF) { /* read byte */
if (feof (uptr->fileref)) {
if (ptr_stopioe) printf ("PTR end of file\n");
else return SCPE_OK; }
else perror ("PTR I/O error");
clearerr (ptr_unit.fileref);
clearerr (uptr->fileref);
return SCPE_IOERR; }
if ((uptr->flags & UNIT_UASC) && (c == '\n')) { /* Unix newline? */
c = 0215; /* insert CR */
uptr->STA |= LF_PEND; } /* lf pending */
else if ((uptr->flags & UNIT_ASC) && (c != 0)) /* ASCII? */
c = c | 0200;
uptr->pos = ftell (uptr->fileref); /* update pos */
}
SET_INT (INT_PTR); /* set ready flag */
ptr_unit.buf = temp & 0377; /* get byte */
ptr_unit.pos = ftell (ptr_unit.fileref); /* update pos */
sim_activate (&ptr_unit, ptr_unit.wait); /* reactivate */
uptr->buf = c & 0377; /* get byte */
sim_activate (uptr, uptr->wait); /* reactivate */
return SCPE_OK;
}
/* Paper tape attach routine - set or clear ASC/UASC flags if specified */
t_stat pt_attach (UNIT *uptr, char *cptr)
{
t_stat r;
if (!(uptr->flags & UNIT_ATTABLE)) return SCPE_NOFNC;
if (r = attach_unit (uptr, cptr)) return r;
if (sim_switches & SWMASK ('A')) /* -a? ASCII */
uptr->flags |= UNIT_ASC;
else if (sim_switches & SWMASK ('U')) /* -u? Unix ASCII */
uptr->flags |= (UNIT_ASC|UNIT_UASC);
else if (sim_switches & SWMASK ('B')) /* -b? binary */
uptr->flags &= ~(UNIT_ASC|UNIT_UASC);
uptr->STA = 0;
return r;
}
/* Detach routine - stop motion if not restore */
t_stat pt_detach (UNIT *uptr)
{
if (!(sim_switches & SIM_SW_REST)) sim_cancel (uptr); /* stop motion */
uptr->STA = 0;
return detach_unit (uptr);
}
/* Reset routine */
t_stat ptr_reset (DEVICE *dptr)
@ -269,6 +390,7 @@ t_stat ptr_reset (DEVICE *dptr)
CLR_INT (INT_PTR); /* clear ready, enb */
CLR_ENB (INT_PTR);
ptr_unit.buf = 0; /* clear buffer */
ptr_unit.STA = 0;
sim_cancel (&ptr_unit); /* deactivate unit */
return SCPE_OK;
}
@ -323,10 +445,10 @@ case ioOCP: /* OCP */
case ioSKS: /* SKS */
if ((fnc & 012) || (fnc == 005)) /* only 0, 1, 4 */
return IOBADFNC (dat);
if (((fnc == 00) && TST_INT (INT_PTP)) || /* fnc 0? skip rdy */
((fnc == 01) /* fnc 1? skip ptp on */
&& (ptp_power || sim_is_active (&ptp_unit))) ||
((fnc == 04) && !TST_INTREQ (INT_PTP))) /* fnc 4? skip !int */
if (((fnc == 000) && TST_INT (INT_PTP)) || /* fnc 0? skip rdy */
((fnc == 001) && /* fnc 1? skip ptp on */
(ptp_power || sim_is_active (&ptp_unit))) ||
((fnc == 004) && !TST_INTREQ (INT_PTP))) /* fnc 4? skip !int */
return IOSKIP (dat);
break;
case ioOTA: /* OTA */
@ -344,18 +466,25 @@ return dat;
t_stat ptp_svc (UNIT *uptr)
{
int32 c;
SET_INT (INT_PTP); /* set flag */
if (ptp_power == 0) { /* power on? */
ptp_power = 1; /* ptp is ready */
return SCPE_OK; }
if ((ptp_unit.flags & UNIT_ATT) == 0) /* attached? */
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (ptp_stopioe, SCPE_UNATT);
if (putc (ptp_unit.buf, ptp_unit.fileref) == EOF) { /* output byte */
if (uptr->flags & UNIT_ASC) { /* ASCII? */
c = uptr->buf & 0177; /* mask to 7b */
if ((uptr->flags & UNIT_UASC) && (c == 015)) /* cr? drop if Unix */
return SCPE_OK;
else if (c == 012) c = '\n'; } /* lf? cvt to nl */
else c = uptr->buf & 0377; /* no, binary */
if (putc (c, uptr->fileref) == EOF) { /* output byte */
perror ("PTP I/O error");
clearerr (ptp_unit.fileref);
clearerr (uptr->fileref);
return SCPE_IOERR; }
ptp_unit.pos = ftell (ptp_unit.fileref); /* update pos */
uptr->pos = ftell (uptr->fileref); /* update pos */
return SCPE_OK;
}
@ -367,6 +496,7 @@ CLR_INT (INT_PTP); /* clear ready, enb */
CLR_ENB (INT_PTP);
ptp_power = 0; /* power off */
ptp_unit.buf = 0; /* clear buffer */
ptp_unit.STA = 0;
sim_cancel (&ptp_unit); /* deactivate unit */
return SCPE_OK;
}
@ -388,12 +518,12 @@ case ioOCP: /* OCP */
break;
case ioSKS: /* SKS */
if (fnc & 012) return IOBADFNC (dat); /* fnc 0,1,4,5 */
if (((fnc == 0) && TST_INT (INT_TTY)) || /* fnc 0? skip rdy */
((fnc == 1) && /* fnc 1? skip !busy */
tty_mode && !sim_is_active (&tty_unit[TTO])) ||
((fnc == 4) && !TST_INTREQ (INT_TTY)) || /* fnc 4? skip !int */
((fnc == 5) && /* fnc 5? skip !xoff */
!tty_mode && ((tty_buf & 0177) == 023)))
if (((fnc == 000) && TST_INT (INT_TTY)) || /* fnc 0? skip rdy */
((fnc == 001) && /* fnc 1? skip !busy */
(!tty_mode || !sim_is_active (&tty_unit[TTO]))) ||
((fnc == 004) && !TST_INTREQ (INT_TTY)) || /* fnc 4? skip !int */
((fnc == 005) && (tty_mode || /* fnc 5? skip !xoff */
((tty_buf & 0177) != XOFF)))) /* input & XOFF char */
return IOSKIP (dat);
break;
case ioINA: /* INA */
@ -418,42 +548,132 @@ case ioOTA:
return dat;
}
/* Unit service routines */
/* Input service - keyboard and reader */
t_stat tti_svc (UNIT *uptr)
{
int32 out, c;
UNIT *ruptr = &tty_unit[TTR];
sim_activate (&tty_unit[TTI], tty_unit[TTI].wait); /* continue poll */
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c; /* no char or error? */
sim_activate (uptr, uptr->wait); /* continue poll */
if ((c = sim_poll_kbd ()) >= SCPE_KFLAG) { /* character? */
out = c & 0177; /* mask echo to 7b */
if (c & SCPE_BREAK) c = 0; /* break? */
else if (tty_unit[TTI].flags & UNIT_KSR) { /* KSR? */
else if (uptr->flags & UNIT_KSR) { /* KSR? */
if (islower (out)) out = toupper (out); /* cvt to UC */
c = out | 0200; } /* add TTY bit */
else c = c & ((tty_unit[TTI].flags & UNIT_8B)? 0377: 0177);
if (tty_mode == 0) { /* input mode? */
tty_buf = c; /* put char in buf */
tty_unit[TTI].pos = tty_unit[TTI].pos + 1;
SET_INT (INT_TTY); /* set flag */
if (out) sim_putchar (out); } /* echo */
return SCPE_OK;
else if (!(uptr->flags & UNIT_8B)) c = out; /* 7b? */
uptr->pos = uptr->pos + 1;
}
else if (c != SCPE_OK) return c; /* error? */
else if ((ruptr->flags & UNIT_ATT) && /* TTR attached */
(ruptr->STA & RUNNING)) { /* and running? */
if (ruptr->STA & LF_PEND) { /* lf pending? */
c = 0212; /* char is lf */
ruptr->STA &= LF_PEND; } /* clear flag */
else { /* normal read */
if ((c = getc (ruptr->fileref)) == EOF) { /* read byte */
if (feof (ruptr->fileref)) { /* EOF? */
ruptr->STA &= ~RUNNING; /* stop reader */
if (ttr_stopioe) printf ("TTR end of file\n");
else return SCPE_OK; }
else perror ("TTR I/O error");
clearerr (ruptr->fileref);
return SCPE_IOERR; }
if ((ruptr->flags & UNIT_UASC) && (c == '\n')) {
c = 0215; /* Unix ASCII NL? */
ruptr->STA |= LF_PEND; } /* LF pending */
else if ((ruptr->flags & UNIT_ASC) && (c != 0))
c = c | 0200; /* ASCII nz? cvt */
ruptr->pos = ftell (ruptr->fileref);
}
if (ttr_xoff_read != 0) { /* reader stopping? */
if (c == RUBOUT) ttr_xoff_read = 0; /* rubout? stop */
else ttr_xoff_read--; /* else decr state */
if (ttr_xoff_read == 0) /* delay done? */
ruptr->STA &= ~RUNNING; } /* stop reader */
else if ((c & 0177) == XOFF) ttr_xoff_read = 2; /* XOFF read? */
out = c; /* echo char */
}
else return SCPE_OK; /* no char */
if (tty_mode == 0) { /* input mode? */
tty_buf = c & 0377; /* put char in buf */
SET_INT (INT_TTY); } /* set flag */
tto_write (out); /* echo to printer */
return ttp_write (out); /* and punch */
}
/* Output service - printer and punch */
t_stat tto_svc (UNIT *uptr)
{
int32 c;
uint32 c7b;
UNIT *ruptr = &tty_unit[TTR];
UNIT *puptr = &tty_unit[TTP];
t_stat r;
if (tty_unit[TTO].flags & UNIT_KSR) { /* UC only? */
c = tty_buf & 0177; /* mask to 7b */
if (islower (c)) c = toupper (c); } /* cvt to UC */
else c = tty_buf & ((tty_unit[TTO].flags & UNIT_8B)? 0377: 0177);
if ((r = sim_putchar_s (c)) != SCPE_OK) { /* output; error? */
c7b = tty_buf & 0177;
if (ttp_tape_rcvd != 0) { /* prev = tape? */
ttp_tape_rcvd--; /* decrement state */
if ((ttp_tape_rcvd == 0) && (puptr->flags & UNIT_ATT))
puptr->STA |= RUNNING; } /* start after delay */
else if (c7b == TAPE) ttp_tape_rcvd = 2; /* char = TAPE? */
if (ttp_xoff_rcvd != 0) { /* prev = XOFF? */
ttp_xoff_rcvd--; /* decrement state */
if (ttp_xoff_rcvd == 0) puptr->STA &= RUNNING; } /* stop after delay */
else if (c7b == XOFF) ttp_xoff_rcvd = 2; /* char = XOFF? */
if ((c7b == XON) && (ruptr->flags & UNIT_ATT)) { /* char = XON? */
ruptr->STA |= RUNNING; /* start reader */
ttr_xoff_read = 0; } /* cancel stop */
if ((r = tto_write (tty_buf)) != SCPE_OK) { /* print; error? */
sim_activate (uptr, uptr->wait); /* try again */
return ((r == SCPE_STALL)? SCPE_OK: r); } /* !stall? report */
if ((r = ttp_write (tty_buf)) != SCPE_OK) return r; /* punch; error? */
SET_INT (INT_TTY); /* set done flag */
tty_unit[TTO].pos = tty_unit[TTO].pos + 1;
return SCPE_OK;
}
/* Output to printer */
t_stat tto_write (int32 c)
{
uint32 c7b;
UNIT *tuptr = &tty_unit[TTO];
c7b = c & 0177;
if (!(tuptr->flags & UNIT_8B)) { /* 7b or KSR? */
if (c7b == 0) return SCPE_OK; /* supress NUL */
if (tuptr->flags & UNIT_KSR) { /* KSR? */
if ((c7b < 040) && /* not in ctrl set? */
!(CNTL_SET & CHAR_FLAG (c7b))) return SCPE_OK;
if (islower (c7b)) c = toupper (c7b); } /* cvt to UC */
else c = c7b; } /* full 7b */
tuptr->pos = tuptr->pos + 1;
return sim_putchar_s (c);
}
/* Output to punch */
t_stat ttp_write (int32 c)
{
uint32 p, c7b;
UNIT *puptr = &tty_unit[TTP];
if ((puptr->flags & UNIT_ATT) && /* TTP attached */
(puptr->STA & RUNNING)) { /* and running? */
c7b = c & 0177;
if (!(puptr->flags & UNIT_UASC) || (c7b != 015)) {
if (puptr->flags & UNIT_ASC) { /* ASCII? */
if (c7b == 012) p = '\n'; /* cvt LF */
else p = c7b; } /* else 7b */
else p = c; /* untouched */
if (putc (p, puptr->fileref) == EOF) { /* output byte */
perror ("TTP I/O error");
clearerr (puptr->fileref);
return SCPE_IOERR; }
puptr->pos = ftell (puptr->fileref); /* update pos */
}
}
return SCPE_OK;
}
@ -465,17 +685,47 @@ CLR_INT (INT_TTY); /* clear ready, enb */
CLR_ENB (INT_TTY);
tty_mode = 0; /* mode = input */
tty_buf = 0;
ttr_xoff_read = 0; /* clr TTR, TTP flags */
ttp_tape_rcvd = 0;
ttp_xoff_rcvd = 0;
tty_unit[TTR].STA = 0;
tty_unit[TTP].STA = 0;
sim_activate (&tty_unit[TTI], tty_unit[TTI].wait); /* activate poll */
sim_cancel (&tty_unit[TTO]); /* cancel output */
return SCPE_OK;
}
t_stat tty_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc)
/* Set keyboard/printer mode - make sure flags agree */
t_stat ttio_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (uptr->flags & UNIT_ATTABLE) return SCPE_NOFNC; /* not TTR, TTP */
tty_unit[TTI].flags = (tty_unit[TTI].flags & ~(UNIT_KSR | UNIT_8B)) | val;
tty_unit[TTO].flags = (tty_unit[TTO].flags & ~(UNIT_KSR | UNIT_8B)) | val;
return SCPE_OK;
}
/* Set reader/punch mode */
t_stat ttrp_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (!(uptr->flags & UNIT_ATTABLE)) return SCPE_NOFNC; /* TTR, TTP only */
if (!(val & UNIT_UASC)) uptr->STA &= ~LF_PEND;
return SCPE_OK;
}
/* Set reader/punch start/stop */
t_stat ttrp_set_start_stop (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (!(uptr->flags & UNIT_ATTABLE)) return SCPE_NOFNC; /* TTR, TTP only */
if (!(uptr->flags & UNIT_ATT)) return SCPE_UNATT; /* must be attached */
if (val) uptr->STA |= RUNNING; /* start? set running */
else uptr->STA &= ~RUNNING; /* stop? clr running */
if (uptr->flags & UNIT_ROABLE) ttr_xoff_read = 0; /* TTR? cancel stop */
else ttp_tape_rcvd = ttp_xoff_rcvd = 0; /* TTP? cancel all */
return SCPE_OK;
}
/* Clock/options: IO routine */
@ -492,7 +742,7 @@ case ioOCP: /* OCP */
sim_rtc_init (clk_unit.wait)); } /* init calibr */
break;
case ioSKS: /* SKS */
if (fnc == 0) { /* clock skip !int */
if (fnc == 000) { /* clock skip !int */
if (!TST_INTREQ (INT_CLK)) return IOSKIP (dat); }
else if ((fnc & 007) == 002) { /* mem parity? */
if (((fnc == 002) && !TST_INT (INT_MPE)) ||

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
01-Dec-04 RMS Fixed fprint_opr calling sequence
24-Oct-03 RMS Added DMA/DMC support
17-Sep-01 RMS Removed multiconsole support
*/
@ -196,17 +197,17 @@ static const int32 opc_val[] = {
status = space needed
*/
int32 fprint_opr (FILE *of, int32 inst, int32 class, int32 sp)
void fprint_opr (FILE *of, int32 inst, int32 class)
{
int32 i, j;
int32 i, j, sp;
for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
for (i = sp = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */
if ((j == class) && (opc_val[i] & inst)) { /* same class? */
inst = inst & ~opc_val[i]; /* mask bit set? */
fprintf (of, (sp? " %s": "%s"), opcode[i]);
sp = 1; } }
return sp;
return;
}
/* Symbolic decode
@ -268,7 +269,7 @@ for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
fprintf (of, "%s %o", opcode[i], disp);
break;
case I_V_SK0: case I_V_SK1: /* skips */
fprint_opr (of, inst & 0777, j, 0); /* print skips */
fprint_opr (of, inst & 0777, j); /* print skips */
break; } /* end case */
return SCPE_OK; } /* end if */
} /* end for */

View file

@ -23,10 +23,19 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
CPU 2116A/2100A/21MXE central processing unit
CPU 2116A/2100A/21MX-M/21MX-E central processing unit
MP 12892B memory protect
DMA0,DMA1 12895A/12897B direct memory access/dual channel port controller
26-Dec-04 RMS DMA reset doesn't clear alternate CTL flop (from Dave Bryan)
DMA reset shouldn't clear control words (from Dave Bryan)
Alternate CTL flop not visible as register (from Dave Bryan)
Fixed CBS, SBS, TBS to perform virtual reads
Separated A/B from M[0/1] for DMA IO (from Dave Bryan)
Fixed bug in JPY (from Dave Bryan)
25-Dec-04 JDB Added SET CPU 21MX-M, 21MX-E (21MX defaults to MX-E)
TIMER/EXECUTE/DIAG instructions disabled for 21MX-M
T-register reflects changes in M-register when halted
25-Sep-04 JDB Moved MP into its own device; added MP option jumpers
Modified DMA to allow disabling
Modified SET CPU 2100/2116 to truncate memory > 32K
@ -327,13 +336,14 @@
#define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = err_PC
#define UNIT_V_2100 (UNIT_V_UF + 0) /* 2100 */
#define UNIT_V_21MX (UNIT_V_UF + 1) /* 21MX */
#define UNIT_V_21MX (UNIT_V_UF + 1) /* 21MX-E or 21MX-M */
#define UNIT_V_EAU (UNIT_V_UF + 2) /* EAU */
#define UNIT_V_FP (UNIT_V_UF + 3) /* FP */
#define UNIT_V_DMS (UNIT_V_UF + 4) /* DMS */
#define UNIT_V_IOP (UNIT_V_UF + 5) /* 2100 IOP */
#define UNIT_V_IOPX (UNIT_V_UF + 6) /* 21MX IOP */
#define UNIT_V_MSIZE (UNIT_V_UF + 7) /* dummy mask */
#define UNIT_V_MXM (UNIT_V_UF + 8) /* 21MX is M-series */
#define UNIT_2116 (0)
#define UNIT_2100 (1 << UNIT_V_2100)
#define UNIT_21MX (1 << UNIT_V_21MX)
@ -343,6 +353,7 @@
#define UNIT_IOP (1 << UNIT_V_IOP)
#define UNIT_IOPX (1 << UNIT_V_IOPX)
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
#define UNIT_MXM (1 << UNIT_V_MXM)
#define UNIT_V_MP_JSB (UNIT_V_UF + 0) /* MP jumper W5 out */
#define UNIT_V_MP_INT (UNIT_V_UF + 1) /* MP jumper W6 out */
@ -365,6 +376,7 @@
uint16 *M = NULL; /* memory */
uint32 saved_AR = 0; /* A register */
uint32 saved_BR = 0; /* B register */
uint16 ABREG[2]; /* during execution */
uint32 PC = 0; /* P register */
uint32 SR = 0; /* S register */
uint32 MR = 0; /* M register */
@ -433,11 +445,14 @@ uint16 ReadW (uint32 addr);
uint16 ReadWA (uint32 addr);
uint32 ReadF (uint32 addr);
uint16 ReadIO (uint32 addr, uint32 map);
uint16 ReadPW (uint32 addr);
uint16 ReadTAB (uint32 addr);
void WriteB (uint32 addr, uint32 dat);
void WriteBA (uint32 addr, uint32 dat);
void WriteW (uint32 addr, uint32 dat);
void WriteWA (uint32 addr, uint32 dat);
void WriteIO (uint32 addr, uint32 dat, uint32 map);
void WritePW (uint32 addr, uint32 dat);
t_stat iogrp (uint32 ir, uint32 iotrap);
uint32 dms (uint32 va, uint32 map, uint32 prot);
uint32 dms_io (uint32 va, uint32 map);
@ -460,6 +475,7 @@ t_stat dma1_reset (DEVICE *dptr);
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat cpu_set_opt (UNIT *uptr, int32 val, char *cptr, void *desc);
t_bool dev_conflict (void);
void hp_post_cmd (t_bool from_scp);
extern uint32 f_as (uint32 op, t_bool sub);
extern uint32 f_mul (uint32 op);
@ -467,6 +483,7 @@ extern uint32 f_div (uint32 op);
extern uint32 f_fix (void);
extern uint32 f_flt (void);
extern int32 clk_delay (int32 flg);
extern void (*sim_vm_post) (t_bool from_scp);
/* CPU data structures
@ -525,12 +542,16 @@ MTAB cpu_mod[] = {
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_EAU+UNIT_FP+UNIT_DMS+UNIT_IOP+UNIT_IOPX,
UNIT_2100+UNIT_EAU, NULL, "2100", &cpu_set_opt,
NULL, (void *) UNIT_2100 },
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_EAU+UNIT_FP+UNIT_DMS+UNIT_IOP+UNIT_IOPX,
UNIT_21MX+UNIT_EAU+UNIT_FP+UNIT_DMS, NULL, "21MX", &cpu_set_opt,
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_MXM+UNIT_EAU+UNIT_FP+UNIT_DMS+UNIT_IOP+UNIT_IOPX,
UNIT_21MX+UNIT_EAU+UNIT_FP+UNIT_DMS, NULL, "21MX-E", &cpu_set_opt,
NULL, (void *) UNIT_21MX },
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_MXM+UNIT_EAU+UNIT_FP+UNIT_DMS+UNIT_IOP+UNIT_IOPX,
UNIT_21MX+UNIT_MXM+UNIT_EAU+UNIT_FP+UNIT_DMS, NULL, "21MX-M", &cpu_set_opt,
NULL, (void *) UNIT_21MX },
{ UNIT_2116+UNIT_2100+UNIT_21MX, UNIT_2116, "2116", NULL, NULL },
{ UNIT_2116+UNIT_2100+UNIT_21MX, UNIT_2100, "2100", NULL, NULL },
{ UNIT_2116+UNIT_2100+UNIT_21MX, UNIT_21MX, "21MX", NULL, NULL },
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_MXM, UNIT_21MX, "21MX-E", NULL, NULL },
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_MXM, UNIT_21MX+UNIT_MXM, "21MX-M", NULL, NULL },
{ UNIT_EAU, UNIT_EAU, "EAU", "EAU", &cpu_set_opt,
NULL, (void *) UNIT_EAU },
{ UNIT_EAU, 0, "no EAU", "NOEAU", &cpu_set_opt,
@ -616,6 +637,7 @@ REG dma0_reg[] = {
{ FLDATA (CTL, dev_ctl[DMA0/32], INT_V (DMA0)) },
{ FLDATA (FLG, dev_flg[DMA0/32], INT_V (DMA0)) },
{ FLDATA (FBF, dev_fbf[DMA0/32], INT_V (DMA0)) },
{ FLDATA (CTLALT, dev_ctl[DMALT0/32], INT_V (DMALT0)) },
{ ORDATA (CW1, dmac[0].cw1, 16) },
{ ORDATA (CW2, dmac[0].cw2, 16) },
{ ORDATA (CW3, dmac[0].cw3, 16) },
@ -635,6 +657,7 @@ REG dma1_reg[] = {
{ FLDATA (CTL, dev_ctl[DMA1/32], INT_V (DMA1)) },
{ FLDATA (FLG, dev_flg[DMA1/32], INT_V (DMA1)) },
{ FLDATA (FBF, dev_fbf[DMA1/32], INT_V (DMA1)) },
{ FLDATA (CTLALT, dev_ctl[DMALT1/32], INT_V (DMALT1)) },
{ ORDATA (CW1, dmac[1].cw1, 16) },
{ ORDATA (CW2, dmac[1].cw2, 16) },
{ ORDATA (CW3, dmac[1].cw3, 16) },
@ -735,7 +758,7 @@ static const uint32 e_inst[512] = {
X_MR,X_NO,X_MR,X_MR,X_NO,X_MR,X_MR,X_NO, /* S*X,C*X,L*X,STX,CX*,LDX,ADX,X*X */
X_MR,X_NO,X_MR,X_MR,X_NO,X_MR,X_MR,X_NO, /* S*Y,C*Y,L*Y,STY,CY*,LDY,ADY,X*Y */
X_NO,X_NO,X_MR,X_NO,X_NO,X_AZ,X_AZ,X_NO, /* ISX,DSX,JLY,LBT,SBT,MBT,CBT,SFB */
X_NO,X_NO,X_MR,X_AA,X_AA,X_AA,X_AZ,X_AZ }; /* ISY,DSY,JPY,SBS,CBS,TBS,CMW,MVW */
X_NO,X_NO,X_NO,X_AA,X_AA,X_AA,X_AZ,X_AZ }; /* ISY,DSY,JPY,SBS,CBS,TBS,CMW,MVW */
/* Interrupt defer table */
@ -1095,16 +1118,31 @@ case 0214:case 0215:case 0216:case 0217:
intrq = calc_int (); /* recalc interrupts */
break; /* end if I/O */
/* Extended arithmetic */
/* Extended arithmetic
The 21MX-E adds three "special instructions" that do not exist in earlier
CPUs, including the 21MX-M. They are: TIMER (100060), EXECUTE (100120), and
DIAG (100000). On the 21MX-M, these instruction codes map to the
microroutines for MPY, ASL, and RRL, respectively.
Under simulation, these cause undefined instruction stops if the CPU is set
to 2100 or 2116. They do not cause stops on the 21MX-M, as TIMER in
particular is used by several HP programs to differentiate between M- and
E-series machines. */
case 0200: /* EAU group 0 */
if ((cpu_unit.flags & UNIT_EAU) == 0) { /* implemented? */
reason = stop_inst;
break; }
switch ((IR >> 4) & 017) { /* decode IR<7:4> */
case 000: /* diagnostic */
break;
case 001: /* ASL */
case 005: /* EXECUTE */
if (!(cpu_unit.flags & UNIT_21MX)) { /* must be 21MX */
reason = stop_inst; /* trap if not */
break; }
else if (!(cpu_unit.flags & UNIT_MXM)) { /* E-series? */
PC = (PC + 1) & VAMASK; /* not simulated */
break; }
case 001: /* ASL (+ EXECUTE on 21MX-M) */
sc = (IR & 017)? (IR & 017): 16; /* get sc */
O = 0; /* clear ovflo */
while (sc-- != 0) { /* bit by bit */
@ -1118,17 +1156,27 @@ case 0200: /* EAU group 0 */
BR = ((BR << sc) | (AR >> (16 - sc))) & DMASK;
AR = (AR << sc) & DMASK; /* BR'AR lsh left */
break;
case 003: /* TIMER */
BR = (BR + 1) & DMASK; /* increment B */
if (BR) PC = err_PC; /* if !=0, repeat */
break;
case 004: /* RRL */
case 000: /* DIAG */
if (!(cpu_unit.flags & UNIT_21MX)) { /* must be 21MX */
reason = stop_inst; /* trap if not */
break; }
else if (!(cpu_unit.flags & UNIT_MXM)) /* E-series? */
break; /* is NOP unless halted */
case 004: /* RRL (+ DIAG on 21MX-M) */
sc = (IR & 017)? (IR & 017): 16; /* get sc */
t = BR; /* BR'AR rot left */
BR = ((BR << sc) | (AR >> (16 - sc))) & DMASK;
AR = ((AR << sc) | (t >> (16 - sc))) & DMASK;
break;
case 010: /* MPY */
case 003: /* TIMER */
if (!(cpu_unit.flags & UNIT_21MX)) { /* must be 21MX */
reason = stop_inst; /* trap if not */
break; }
else if (!(cpu_unit.flags & UNIT_MXM)) { /* E-series? */
BR = (BR + 1) & DMASK; /* increment B */
if (BR) PC = err_PC; /* if !=0, repeat */
break; }
case 010: /* MPY (+ TIMER on 21MX-M) */
if (reason = Ea1 (&MA, intrq)) break; /* get opnd addr */
sop1 = SEXT (AR); /* sext AR */
sop2 = SEXT (ReadW (MA)); /* sext mem */
@ -1844,13 +1892,19 @@ case 0203:case 0213: /* MAC1 ext */
/* Bit, word instructions */
case 0773: /* SBS (E_AA) */
WriteW (M1, M[M1] | M [MA]); /* set bit */
v1 = ReadW (MA);
v2 = ReadW (M1);
WriteW (M1, v2 | v1); /* set bit */
break;
case 0774: /* CBS (E_AA) */
WriteW (M1, M[M1] & ~M[MA]); /* clear bit */
v1 = ReadW (MA);
v2 = ReadW (M1);
WriteW (M1, v2 & ~v1); /* clear bit */
break;
case 0775: /* TBS (E_AA) */
if ((M[MA] & M[M1]) != M[MA]) /* test bit */
v1 = ReadW (MA);
v2 = ReadW (M1);
if ((v2 & v1) != v1) /* test bits */
PC = (PC + 1) & VAMASK;
break;
case 0776: /* CMW (E_AZ) */
@ -1900,13 +1954,13 @@ if (reason == STOP_INDINT) { /* indirect intr? */
/* Simulation halted */
if (iotrap && (reason == STOP_HALT)) MR = intaddr; /* HLT in trap cell? */
else MR = (PC - 1) & VAMASK; /* no, M = P - 1 */
TR = ReadIO (MR, dms_ump); /* last word fetched */
if ((reason == STOP_RSRV) || (reason == STOP_IODV) || /* instr error? */
(reason == STOP_IND)) PC = err_PC; /* back up PC */
saved_AR = AR & DMASK;
saved_BR = BR & DMASK;
if (iotrap && (reason == STOP_HALT)) MR = intaddr; /* HLT in trap cell? */
else MR = (PC - 1) & VAMASK; /* no, M = P - 1 */
TR = ReadTAB (MR); /* last word fetched */
if ((reason == STOP_RSRV) || (reason == STOP_IODV) || /* instr error? */
(reason == STOP_IND)) PC = err_PC; /* back up PC */
dms_upd_sr (); /* update dms_sr */
for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru dev */
dibp = (DIB *) dptr->ctxt; /* get DIB */
@ -2096,8 +2150,8 @@ int32 pa;
if (dms_enb) pa = dms (va >> 1, dms_ump, RD);
else pa = va >> 1;
if (va & 1) return (M[pa] & 0377);
else return ((M[pa] >> 8) & 0377);
if (va & 1) return (ReadPW (pa) & 0377);
else return ((ReadPW (pa) >> 8) & 0377);
}
uint8 ReadBA (uint32 va)
@ -2106,8 +2160,8 @@ uint32 pa;
if (dms_enb) pa = dms (va >> 1, dms_ump ^ MAP_LNT, RD);
else pa = va >> 1;
if (va & 1) return (M[pa] & 0377);
else return ((M[pa] >> 8) & 0377);
if (va & 1) return (ReadPW (pa) & 0377);
else return ((ReadPW (pa) >> 8) & 0377);
}
uint16 ReadW (uint32 va)
@ -2116,7 +2170,7 @@ uint32 pa;
if (dms_enb) pa = dms (va, dms_ump, RD);
else pa = va;
return M[pa];
return ReadPW (pa);
}
uint16 ReadWA (uint32 va)
@ -2125,7 +2179,7 @@ uint32 pa;
if (dms_enb) pa = dms (va, dms_ump ^ MAP_LNT, RD);
else pa = va;
return M[pa];
return ReadPW (pa);
}
uint32 ReadF (uint32 va)
@ -2144,6 +2198,19 @@ else pa = va;
return M[pa];
}
uint16 ReadPW (uint32 pa)
{
if (pa <= 1) return ABREG[pa];
return M[pa];
}
uint16 ReadTAB (uint32 addr)
{
if (addr == 0) return saved_AR;
else if (addr == 1) return saved_BR;
else return ReadIO (addr, dms_ump);
}
/* Memory protection test for writes
From Dave Bryan: The problem is that memory writes aren't being checked for
@ -2157,20 +2224,22 @@ return M[pa];
void WriteB (uint32 va, uint32 dat)
{
uint32 pa;
uint32 pa, t;
if (dms_enb) pa = dms (va >> 1, dms_ump, WR);
else pa = va >> 1;
if (MP_TEST (va >> 1)) ABORT (ABORT_PRO);
if (MEM_ADDR_OK (pa)) {
if (va & 1) M[pa] = (M[pa] & 0177400) | (dat & 0377);
else M[pa] = (M[pa] & 0377) | ((dat & 0377) << 8); }
t = ReadPW (pa);
if (va & 1) t = (t & 0177400) | (dat & 0377);
else t = (t & 0377) | ((dat & 0377) << 8);
WritePW (pa, t); }
return;
}
void WriteBA (uint32 va, uint32 dat)
{
uint32 pa;
uint32 pa, t;
if (dms_enb) {
dms_viol (va >> 1, MVI_WPR); /* viol if prot */
@ -2178,8 +2247,10 @@ if (dms_enb) {
else pa = va >> 1;
if (MP_TEST (va >> 1)) ABORT (ABORT_PRO);
if (MEM_ADDR_OK (pa)) {
if (va & 1) M[pa] = (M[pa] & 0177400) | (dat & 0377);
else M[pa] = (M[pa] & 0377) | ((dat & 0377) << 8); }
t = ReadPW (pa);
if (va & 1) t = (t & 0177400) | (dat & 0377);
else t = (t & 0377) | ((dat & 0377) << 8);
WritePW (pa, t); }
return;
}
@ -2190,7 +2261,7 @@ uint32 pa;
if (dms_enb) pa = dms (va, dms_ump, WR);
else pa = va;
if (MP_TEST (va)) ABORT (ABORT_PRO);
if (MEM_ADDR_OK (pa)) M[pa] = dat;
if (MEM_ADDR_OK (pa)) WritePW (pa, dat);
return;
}
@ -2203,7 +2274,7 @@ if (dms_enb) {
pa = dms (va, dms_ump ^ MAP_LNT, WR); }
else pa = va;
if (MP_TEST (va)) ABORT (ABORT_PRO);
if (MEM_ADDR_OK (pa)) M[pa] = dat;
if (MEM_ADDR_OK (pa)) WritePW (pa, dat);
return;
}
@ -2213,7 +2284,14 @@ uint32 pa;
if (dms_enb) pa = dms_io (va, map);
else pa = va;
if (MEM_ADDR_OK (pa)) M[pa] = dat;
if (MEM_ADDR_OK (pa)) M[pa] = dat & DMASK;
return;
}
void WritePW (uint32 pa, uint32 dat)
{
if (pa <= 1) ABREG[pa] = dat & DMASK;
else M[pa] = dat & DMASK;
return;
}
@ -2630,6 +2708,7 @@ if (M == NULL) M = calloc (PASIZE, sizeof (uint16));
if (M == NULL) return SCPE_MEM;
if (pcq_r) pcq_r->qptr = 0;
else return SCPE_IERR;
sim_vm_post = &hp_post_cmd; /* set cmd post proc */
return SCPE_OK;
}
@ -2652,6 +2731,8 @@ clrCMD (DMA0);
clrCTL (DMA0);
setFLG (DMA0);
clrSRQ (DMA0);
clrCTL (DMALT0);
if (sim_switches & SWMASK ('P')) /* power up? */
dmac[0].cw1 = dmac[0].cw2 = dmac[0].cw3 = 0;
return SCPE_OK;
}
@ -2663,6 +2744,8 @@ clrCMD (DMA1);
clrCTL (DMA1);
setFLG (DMA1);
clrSRQ (DMA1);
clrCTL (DMALT1);
if (sim_switches & SWMASK ('P')) /* power up? */
dmac[1].cw1 = dmac[1].cw2 = dmac[1].cw3 = 0;
return SCPE_OK;
}
@ -2675,8 +2758,8 @@ int32 d;
addr = dms_cons (addr, sw);
if (addr >= MEMSIZE) return SCPE_NXM;
if (addr == 0) d = saved_AR;
else if (addr == 1) d = saved_BR;
if (!(sw & SIM_SW_REST) && (addr == 0)) d = saved_AR;
else if (!(sw & SIM_SW_REST) && (addr == 1)) d = saved_BR;
else d = M[addr];
if (vptr != NULL) *vptr = d & DMASK;
return SCPE_OK;
@ -2688,8 +2771,8 @@ t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw)
{
addr = dms_cons (addr, sw);
if (addr >= MEMSIZE) return SCPE_NXM;
if (addr == 0) saved_AR = val & DMASK;
else if (addr == 1) saved_BR = val & DMASK;
if (!(sw & SIM_SW_REST) && (addr == 0)) saved_AR = val & DMASK;
else if (!(sw & SIM_SW_REST) && (addr == 1)) saved_BR = val & DMASK;
else M[addr] = val & DMASK;
return SCPE_OK;
}
@ -2758,6 +2841,16 @@ else dcp->flags = dcp->flags & ~DEV_DIS;
return;
}
/* Command post-processor
Update T register to contents of memory addressed by M register. */
void hp_post_cmd (t_bool from_scp)
{
TR = ReadTAB (MR); /* sync T with M */
return;
}
/* Test for device conflict */
t_bool dev_conflict (void)

View file

@ -23,6 +23,8 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
30-Dec-04 JDB Added IBL_DS_HEAD head number mask
19-Nov-04 JDB Added STOP_OFFLINE, STOP_PWROFF stop codes
25-Apr-04 RMS Added additional IBL definitions
Added DMA EDT I/O pseudo-opcode
25-Apr-03 RMS Revised for extended file support
@ -35,7 +37,7 @@
14-Apr-99 RMS Changed t_addr to unsigned
The author gratefully acknowledges the help of Jeff Moffat in answering
questions about the HP2100; and of Dave Bryan in adding featurs and
questions about the HP2100; and of Dave Bryan in adding features and
correcting errors throughout the simulator.
*/
@ -50,6 +52,8 @@
#define STOP_IND 5 /* indirect loop */
#define STOP_INDINT 6 /* indirect intr */
#define STOP_NOCONN 7 /* no connection */
#define STOP_OFFLINE 8 /* device offline */
#define STOP_PWROFF 9 /* device powered off */
#define ABORT_PRO 1 /* protection abort */
@ -69,9 +73,8 @@
#define SIGN32 020000000000 /* 32b sign */
#define SIGN 0100000 /* 16b sign */
#define DMASK 0177777 /* 16b data mask */
#define AR M[0] /* A = location 0 */
#define BR M[1] /* B = location 1 */
#define ABREG M /* register array */
#define AR ABREG[0] /* A = reg 0 */
#define BR ABREG[1] /* B = reg 1 */
#define SEXT(x) ((int32) (((x) & SIGN)? ((x) | ~DMASK): ((x) & DMASK)))
/* Memory reference instructions */
@ -232,6 +235,7 @@ struct DMA { /* DMA channel */
#define IBL_V_DEV 6 /* dev in <11:6> */
#define IBL_OPT 0000070 /* options in <5:3> */
#define IBL_DP_REM 0000001 /* DP removable */
#define IBL_DS_HEAD 0000003 /* DS head number */
#define IBL_LNT 64 /* boot length */
#define IBL_MASK (IBL_LNT - 1) /* boot length mask */
#define IBL_DPC (IBL_LNT - 2) /* DMA ctrl word */

View file

@ -1,6 +1,6 @@
SIMH/HP 21XX DIAGNOSTICS PERFORMANCE
====================================
Last update: 2004-11-02
Last update: 2004-12-29
The HP 24396 diagnostic suite has been run against the SIMH HP 21xx simulation.
@ -28,7 +28,7 @@ The results of the diagnostic runs are summarized below:
101100 Memory Reference Instruction Group 1624 3.2-3 Passed
101001 Alter-Skip Instruction Group 1431 3.2-3 Passed
101002 Shift-Rotate Instruction Group 1431 3.2-3 Passed
102200 Core Memory (2100/16/15/14) 1624 - No simulation
102200 Core Memory (2100/16/15/14) 1624 3.3-0 Passed
102104 Semiconductor Memory (21MX) 1644 3.2-3 Passed
101004 EAU Instruction Group 1431 3.2-3 Passed
@ -75,7 +75,7 @@ The results of the diagnostic runs are summarized below:
111104 12732 Flexible Disc Subsystem 1708 - No simulation
151302 7900/01 Cartridge Disc 1805 3.2-3 Partial
151403 7905/06/20/25 Disc 1805 - No simulation
151403 7905/06/20/25 Disc 1805 3.3-1 Partial
104117 92900 Terminal Subsystem 1814 - No simulation
112200 9-Track Magnetic Tape (7970, 13181/3) 2040 3.2-3 Partial
@ -225,6 +225,24 @@ TEST RESULT: Passed.
----------------------------------------
DSN 102200 - Core Memory (2100/16/15/14)
----------------------------------------
TESTED DEVICE: CPU (hp2100_cpu.c)
CONFIGURATION: sim> set CPU 2100
sim> set CPU 32K
sim> deposit S 000000
sim> reset
sim> go 100
TEST REPORT: HALT instruction 102077
TEST RESULT: Passed.
---------------------------------
DSN 102104 - Semiconductor Memory
---------------------------------
@ -953,17 +971,381 @@ TEST NOTES: Steps 4, 7, 8, and 9 test the defective and protected cylinder
-------------------------------
DSN 151403 - 7905/06/20/25 Disc
-------------------------------
-----------------------------------------------
DSN 151403 - 7905/06/20/25 Disc (multiple unit)
-----------------------------------------------
TESTED DEVICE: DS (hp2100_ds.c)
CONFIGURATION:
CONFIGURATION: sim> set DS0 7905
sim> set DS1 7906
sim> set DS2 7920
sim> set DS3 7925
sim> set DS4 7905
sim> set DS5 7906
sim> set DS6 7920
sim> set DS7 7925
sim> attach DS0 scratch.U0.7905.disc
sim> attach DS1 scratch.U1.7906.disc
sim> attach DS2 scratch.U2.7920.disc
sim> attach DS3 scratch.U3.7925.disc
sim> attach DS4 scratch.U4.7905.disc
sim> attach DS5 scratch.U5.7906.disc
sim> attach DS6 scratch.U6.7920.disc
sim> attach DS7 scratch.U7.7925.disc
sim> deposit S 000034
sim> reset
sim> go 100
TEST REPORT:
HALT instruction 102074
TEST RESULT: Not tested.
sim> deposit S 000004
sim> reset
sim> go
H0 79XX/13037 DISC MEMORY DIAGNOSTIC
H37 UNIT TABLE: 01 DRIVE(S); 0
H25 WISH TO CHANGE?
YES
H34 ENTER UNIT NUMBERS(0-7)SEPARATED BY COMMAS
0,1,2,3,4,5,6,7
H37 UNIT TABLE: 08 DRIVE(S); 0 1 2 3 4 5 6 7
H25 WISH TO CHANGE?
NO
ENTER:(U)NIT,(?) ERRS,(H)EAD,(O)UTPUT,(P)ATT,(S)OFT,(C)YL,(M)CPU,(E)XIT
H
H62 HEAD TABLE; UNIT 0 7905A , 02 HEAD(S) 0 1
H62 HEAD TABLE; UNIT 1 7906A , 02 HEAD(S) 0 1
H62 HEAD TABLE; UNIT 2 7920A , 05 HEAD(S) 0 1 2 3 4
H62 HEAD TABLE; UNIT 3 7925A , 09 HEAD(S) 0 1 2 3 4 5 6 7 8
H62 HEAD TABLE; UNIT 4 7905A , 02 HEAD(S) 0 1
H62 HEAD TABLE; UNIT 5 7906A , 02 HEAD(S) 0 1
H62 HEAD TABLE; UNIT 6 7920A , 05 HEAD(S) 0 1 2 3 4
H62 HEAD TABLE; UNIT 7 7925A , 09 HEAD(S) 0 1 2 3 4 5 6 7 8
H25 WISH TO CHANGE?
YES
H132 TYPE UNITS YOU WISH TO CHANGE SEPERATED BY COMMAS
0,1,4,5
H62 HEAD TABLE; UNIT 0 7905A , 02 HEAD(S) 0 1
H106 ENTER HEADS SEPARATED BY COMMAS
0,1,2
H62 HEAD TABLE; UNIT 0 7905A , 03 HEAD(S) 0 1 2
H25 WISH TO CHANGE?
NO
H62 HEAD TABLE; UNIT 1 7906A , 02 HEAD(S) 0 1
H106 ENTER HEADS SEPARATED BY COMMAS
0,1,2,3
H62 HEAD TABLE; UNIT 1 7906A , 04 HEAD(S) 0 1 2 3
H25 WISH TO CHANGE?
NO
H62 HEAD TABLE; UNIT 4 7905A , 02 HEAD(S) 0 1
H106 ENTER HEADS SEPARATED BY COMMAS
0,1,2
H62 HEAD TABLE; UNIT 4 7905A , 03 HEAD(S) 0 1 2
H25 WISH TO CHANGE?
NO
H62 HEAD TABLE; UNIT 5 7906A , 02 HEAD(S) 0 1
H106 ENTER HEADS SEPARATED BY COMMAS
0,1,2,3
H62 HEAD TABLE; UNIT 5 7906A , 04 HEAD(S) 0 1 2 3
H25 WISH TO CHANGE?
NO
ENTER:(U)NIT,(?) ERRS,(H)EAD,(O)UTPUT,(P)ATT,(S)OFT,(C)YL,(M)CPU,(E)XIT
E
TEST REPORT: H121 WARNING-FORMAT SWITCH OFF
H65 LONG PASS 0001,HEAD 012 ,UNIT 0,0000 ERRORS-0000 SOFT
H65 LONG PASS 0002,HEAD 0123 ,UNIT 1,0000 ERRORS-0000 SOFT
H65 LONG PASS 0003,HEAD 01234 ,UNIT 2,0000 ERRORS-0000 SOFT
H65 LONG PASS 0004,HEAD 012345678,UNIT 3,0000 ERRORS-0000 SOFT
H65 LONG PASS 0005,HEAD 012 ,UNIT 4,0000 ERRORS-0000 SOFT
H65 LONG PASS 0006,HEAD 0123 ,UNIT 5,0000 ERRORS-0000 SOFT
H65 LONG PASS 0007,HEAD 01234 ,UNIT 6,0000 ERRORS-0000 SOFT
H65 LONG PASS 0008,HEAD 012345678,UNIT 7,0000 ERRORS-0000 SOFT,MULTI-UNIT
[CTRL+E]
Simulation stopped
TEST RESULT: Passed.
TEST NOTES: Eight passes are required to test all head/unit combinations.
--------------------------------------------------
DSN 151403 - 7905/06/20/25 Disc (user interaction)
--------------------------------------------------
TESTED DEVICE: DS (hp2100_ds.c)
CONFIGURATION: sim> set DS0 7905
sim> attach DS0 scratch.U0.7905.disc
sim> deposit S 000034
sim> reset
sim> go 100
HALT instruction 102074
sim> deposit S 000120
sim> reset
sim> go
H0 79XX/13037 DISC MEMORY DIAGNOSTIC
H37 UNIT TABLE: 01 DRIVE(S); 0
H25 WISH TO CHANGE?
NO
TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
HALT instruction 102002
sim> set DS0 FORMAT
sim> go
H46 READ IN STEP 04
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
SHOULD BE 0 1 0 00000 XXXX XXXX / 0 000010 0 0 0 1 0 0 0 0 0
H137 TERMINATION STATUS IS "NORMAL COMPLET"
START 0000/00/00-LAST 0000/00/01 WORD COUNT 00128,OLD CYL 0000,UNIT 00
HALT instruction 102001
sim> go
H22 VERIFY IN STEP 04
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
SHOULD BE 0 1 0 00000 XXXX XXXX / 0 000010 0 0 0 1 0 0 0 0 0
H137 TERMINATION STATUS IS "NORMAL COMPLET"
START 0000/00/00-LAST 0001/00/00 WORD COUNT 00048,OLD CYL 0000,UNIT 00
HALT instruction 102001
sim> go
H67 CLEAR FORMAT SWITCH ON UNIT 0,PUSH RUN
HALT instruction 102002
sim> set DS0 NOFORMAT
sim> go
H46 READ IN STEP 07
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 0 0 0 0 0 0
SHOULD BE 0 0 1 10001 XXXX XXXX / 0 000010 0 0 0 0 0 0 0 0 0
H137 TERMINATION STATUS IS "NORMAL COMPLET" SHOULD BE "DEFECTIVE TRK "
START 0001/00/00-LAST 0001/00/01 WORD COUNT 00128,OLD CYL 0000,UNIT 00
HALT instruction 102001
sim> go
H45 WRITE IN STEP 08
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 0 0 0 0 0 0
SHOULD BE 0 1 0 10110 XXXX XXXX / 0 000010 0 0 0 0 0 0 0 0 0
H137 TERMINATION STATUS IS "NORMAL COMPLET" SHOULD BE "WRT PROTEC TRK"
START 0000/00/00-LAST 0000/00/01 WORD COUNT 00128,OLD CYL 0001,UNIT 00
HALT instruction 102001
sim> go
H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
HALT instruction 102002
sim> set DS0 FORMAT
sim> go
H45 WRITE IN STEP 10
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
SHOULD BE 0 1 0 00000 XXXX XXXX / 0 000010 0 0 0 1 0 0 0 0 0
H137 TERMINATION STATUS IS "NORMAL COMPLET"
START 0000/00/00-LAST 0000/00/08 WORD COUNT 01024,OLD CYL 0000,UNIT 00
HALT instruction 102001
sim> go
H70 UNLOAD UNIT 0,PUSH RUN
HALT instruction 102002
sim> detach DS0
sim> go
H107 READY UNIT 0
[CTRL+E]
Simulation stopped
sim> attach DS0 scratch.U0.7905.disc
sim> go
H142 PROTECT U/D,PUSH RUN
HALT instruction 102002
sim> set DS0 LOCKED
sim> go
H143 CLEAR U/D PROTECT,PUSH RUN
HALT instruction 102002
sim> set DS0 WRITEENABLED
sim> go
H110 PRESS PRESET(S),PRESS RUN
HALT instruction 102002
sim> reset
sim> go
H46 READ IN STEP 38
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
SHOULD BE 0 0 0 00111 0000 0000 / 0 000010 0 0 0 X 0 0 0 0 0
H137 TERMINATION STATUS IS "NORMAL COMPLET" SHOULD BE "CYL CMP ERROR "
START 0000/00/01-LAST 0000/00/03 WORD COUNT 00138,OLD CYL 0000,UNIT 00
HALT instruction 102001
sim> go
H46 READ IN STEP 39
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
SHOULD BE 0 0 0 01001 XXXX XXXX / 0 000010 0 0 0 X 0 0 0 0 0
H137 TERMINATION STATUS IS "NORMAL COMPLET" SHOULD BE "HD/SEC CMP ERR"
START 0000/00/01-LAST 0000/00/03 WORD COUNT 00138,OLD CYL 0000,UNIT 00
HALT instruction 102001
sim> go
H46 READ IN STEP 40
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
SHOULD BE 0 0 0 01001 XXXX XXXX / 0 000010 0 0 0 X 0 0 0 0 0
H137 TERMINATION STATUS IS "NORMAL COMPLET" SHOULD BE "HD/SEC CMP ERR"
START 0000/00/01-LAST 0000/00/03 WORD COUNT 00138,OLD CYL 0000,UNIT 00
HALT instruction 102001
sim> go
H46 READ IN STEP 41
E47 DATA WORD 0065 IS 075126 SHOULD BE 030400
E47 DATA WORD 0066 IS 000762 SHOULD BE 030400
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
SHOULD BE 0 0 0 01111 XXXX XXXX / 0 000010 0 0 0 X 0 0 0 0 0
H137 TERMINATION STATUS IS "NORMAL COMPLET" SHOULD BE "POSS CORR DATA"
START 0000/00/00-LAST 0000/00/03 WORD COUNT 00128,OLD CYL 0000,UNIT 00
HALT instruction 102001
sim> go
H46 READ IN STEP 42
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
SHOULD BE 0 0 0 01000 XXXX XXXX / 0 000010 0 0 0 X 0 0 0 0 0
H137 TERMINATION STATUS IS "NORMAL COMPLET" SHOULD BE "UNCOR DATA ERR"
START 0000/00/00-LAST 0000/00/03 WORD COUNT 00276,OLD CYL 0000,UNIT 00
HALT instruction 102001
sim> go
H22 VERIFY IN STEP 43
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
SHOULD BE 0 0 1 10001 XXXX XXXX / 0 000010 0 0 0 X 0 0 0 0 0
H137 TERMINATION STATUS IS "NORMAL COMPLET" SHOULD BE "DEFECTIVE TRK "
START 0016/00/00-LAST 0017/00/00 WORD COUNT 00048,OLD CYL 0128,UNIT 00
HALT instruction 102001
sim> go
H22 VERIFY IN STEP 43
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
SHOULD BE 1 0 0 10000 XXXX XXXX / 0 000010 0 0 0 X 0 0 0 0 0
H137 TERMINATION STATUS IS "NORMAL COMPLET" SHOULD BE "SPR TRK ACCESS"
START 0128/01/00-LAST 0129/01/00 WORD COUNT 00048,OLD CYL 0016,UNIT 00
HALT instruction 102001
sim> go
H45 WRITE IN STEP 43
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
SHOULD BE 1 0 0 00000 XXXX XXXX / 0 000010 0 0 0 X 0 0 0 0 0
H137 TERMINATION STATUS IS "NORMAL COMPLET"
START 0016/00/33-LAST 0016/00/34 WORD COUNT 00128,OLD CYL 0128,UNIT 00
HALT instruction 102001
sim> go
H46 READ IN STEP 43
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
SHOULD BE 1 0 0 00000 XXXX XXXX / 0 000010 0 0 0 X 0 0 0 0 0
H137 TERMINATION STATUS IS "NORMAL COMPLET"
START 0016/00/33-LAST 0016/00/34 WORD COUNT 00128,OLD CYL 0016,UNIT 00
HALT instruction 102001
sim> go
H46 READ IN STEP 43
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
E64 STATUS IS 0 0 0 00111 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
SHOULD BE 1 0 0 00000 XXXX XXXX / 0 000010 0 0 0 X 0 0 0 0 0
H137 TERMINATION STATUS IS "CYL CMP ERROR " SHOULD BE "NORMAL COMPLET"
E13 0000 WORDS TRANSFERRED 0128 EXPECTED
START 0016/00/33-LAST 0016/00/33 WORD COUNT 00128,OLD CYL 0016,UNIT 00
HALT instruction 102001
sim> go
H65 SHORT PASS 0001,HEAD 01 ,UNIT 0,0015 ERRORS-0015 SOFT
[CTRL+E]
Simulation stopped
TEST RESULT: Partially passed.
TEST NOTES: Steps 4, 8, and 10 test the protected cylinder bit. Step 7
tests the defective cylinder bit. Steps 38, 39, and 40 test the
Write Full Sector command. Steps 41 and 42 test error
correction. Step 43 tests the spare cylinder bit and track
sparing. These features are not simulated.

View file

@ -1,7 +1,7 @@
To: Users
From: Bob Supnik
Subj: HP2100 Simulator Usage
Date: 26-Oct-2004
Date: 22-Dec-2004
COPYRIGHT NOTICE
@ -59,6 +59,7 @@ sim/hp2100/ hp2100_defs.h
hp2100_dp.c
hp2100_dq.c
hp2100_dr.c
hp2100_ds.c
hp2100_ipl.c
hp2100_lps.c
hp2100_lpt.c
@ -77,7 +78,7 @@ name(s)
CPU 2116 CPU with 32KW memory
2100 CPU with 32KW memory, FP or IOP instructions
21MX CPU with 1024KW memory, FP, DMS, and/or IOP instructions
21MX-M/E CPU with 1024KW memory, FP, DMS, and/or IOP instructions
MP 12892B memory protect
DMA0, DMA1 12895A/12897B direct memory access/dual channel port controller
PTR 12597A duplex register interface with 2748 paper tape reader
@ -93,6 +94,7 @@ DP 12557A disk controller with four 2871 drives
DQ 12565A disk controller with two 2883 drives
DR 12606B fixed head disk controller with 2770/2771 disk
12610B drum controller with 2773/2774/2775 drum
DS 13037 disk controller with eight 7905/7906/7920/7925 drives
MT 12559C magnetic tape controller with one 3030 drive
MS 13181A magnetic tape controller with four 7970B drives
13183A magnetic tape controller with four 7970E drives
@ -120,7 +122,8 @@ Options that may be specified are:
SET CPU 2116 2116 CPU
SET CPU 2100 2100 CPU
SET CPU 21MX 21MX CPU
SET CPU 21MX-M 21MX M-series CPU
SET CPU 21MX-E 21MX E-series CPU
SET CPU EAU EAU instructions (2116 only)
SET CPU NOEAU no EAU instructions (2116 only)
SET CPU FP FP instructions (2100 only)
@ -141,7 +144,9 @@ Options that may be specified are:
On the 2100, EAU is standard, and the FP and IOP options are mutually
exclusive. On the 21MX, EAU and FP are standard. The 21MX optionally
includes DMS (dynamic mapping system) and IOP instructions.
includes DMS (dynamic mapping system) and IOP instructions. The 21MX-E
supports the TIMER instruction; on the 21MX-M, this instruction decodes
as MPY.
Setting the CPU type to 2116, 2100, or 21MX establishes a consistent set
of common options. Additional SET CPU commands may follow to fine-tune
@ -274,6 +279,7 @@ DMA1). Each DMA channel has the following visible state:
CTL 1 interrupt enabled
FLG 1 channel ready
FBF 1 channel ready buffer
CTLALT 1 command word 2/3 selector
CW1 16 command word 1
CW2 16 command word 2
CW3 16 command word 3
@ -532,8 +538,18 @@ In printer mode, error handling is as follows:
not attached 1 report error and stop
0 out of paper
SET POWEROFF 1 report error and stop
0 powered off
SET OFFLINE 1 report error and stop
0 offline
OS I/O error x report error and stop
With STOP_IOE set to 0, output performed when the device is powered off
or offline will initiate but then hang, waiting for the device to be
returned online. When it is, the output operation will complete.
In diagnostic mode, there are no errors; data sent to the output
buffer is looped back to the status register with a fixed delay of 1.
@ -573,8 +589,18 @@ Error handling is as follows:
not attached 1 report error and stop
0 out of paper
SET POWEROFF 1 report error and stop
0 powered off
SET OFFLINE 1 report error and stop
0 offline
OS I/O error x report error and stop
With STOP_IOE set to 0, output performed when the device is powered off
or offline will initiate but then hang, waiting for the device to be
returned online. When it is, the output operation will complete.
2.5.6 12539C Time Base Generator (CLK)
The time base generator (CLK) may be set for diagnostic mode:
@ -754,7 +780,9 @@ Both IPLI and IPLO implement these registers:
TIME 24 polling interval for input
STOP_IOE 1 stop on I/O error
2.6 12557A Disk Controller (DPC, DPD) with Four 2781 Drives
2.6 Disk Controllers
2.6.1 12557A Disk Controller (DPC, DPD) with Four 2781 Drives
13210A Disk Controller (DPC, DPD) with Four 7900 Drives
The 12557A/13210A disk controller can be configured as either a
@ -773,9 +801,19 @@ a command channel. The data channel includes a 128-word (one sector)
buffer for reads and writes. The command channel includes the four
disk drives. Disk drives can be set DISABLED or ENABLED.
Individual drives may be protected against writing. These commands
simulate the Upper/Lower Disc Protect switches on the drives:
SET DPCn LOCKED set unit n write locked
SET DPCn WRITEENABLED set unit n write enabled
Separate protection for the upper and lower platters of the 7900 drive
is not supported. Also, the drive Protect/Override switch is not
supported; drive protection is permanently overridden.
The 12557A/13210A supports the BOOT command. BOOT DPC copies the IBL
for 7900 class disks into memory and starts it running. BOOT -R DPC
boots from the removable platter (head 2). The switch register (S) is
boots from the removable platter (head 0). The switch register (S) is
set automatically to the value expected by the IBL loader:
<15:14> = 01
@ -829,19 +867,24 @@ Error handling is as follows:
error processed as
not attached disk not ready
not attached disk not ready (drive unloaded)
end of file assume rest of disk is zero
OS I/O error report error and stop
2.7 12565A Disk Controller (DQC, DQD) with Two 2883 Drives
2.6.2 12565A Disk Controller (DQC, DQD) with Two 2883 Drives
The 12565A disk controller has two separate devices, a data channel and
a command channel. The data channel includes a 128-word (one sector)
buffer for reads and writes. The command channel includes the two
disk drives. Disk drives can be set DISABLED or ENABLED.
Individual drives may be protected against writing:
SET DQCn LOCKED set unit n write locked
SET DQCn WRITEENABLED set unit n write enabled
The 12565A supports the BOOT command. BOOT DQC copies the IBL for 2883
class disks into memory and starts it running. The switch register (S)
is set automatically to the value expected by the IBL loader:
@ -900,7 +943,7 @@ Error handling is as follows:
OS I/O error report error and stop
2.8 12606B Fixed Head Disk Controller (DRC, DRD) with 2770/2771 Disk
2.6.3 12606B Fixed Head Disk Controller (DRC, DRD) with 2770/2771 Disk
12610B Drum Controller (DRC, DRD) with 2773/2774/2775 Drum
The 12606B/12610B fixed head disk/drum controller has two separate devices,
@ -982,7 +1025,93 @@ Error handling is as follows:
12606B/12610B data files are buffered in memory; therefore, end of file
and OS I/O errors cannot occur.
2.9 12559C Magnetic Tape Controller (MTC, MTD) with One 3030 Drive
2.6.4 13037 Disk Controller (DS) with Eight 7905/7906/7920/7925 Drives
The 13037 disk controller supports 7905 (15MB), 7906 (20MB), 7920 (50MB),
or 7925 (120MB) disk drives, as well as autosizing, based on the size
of the disk image file:
SET DSn 7905 drive n is a 15MB drive
SET DSn 7906 drive n is a 20MB drive
SET DSn 7920 drive n is a 50MB drive
SET DSn 7925 drive n is a 120MB drive
SET DSn AUTOSIZE drive n type based on file size at attach
Drive types can be intermixed. The 7905 is selected by default. Drives
can be set DISABLED or ENABLED.
Individual drives may be protected against writing. These commands
simulate the Disc Protect/Read Only switches on the drives:
SET DSn LOCKED set unit n write locked
SET DSn WRITEENABLED set unit n write enabled
Separate protection for the upper and lower platters of the 7905 and
7906 drives is not supported. Protecting a 7905 or 7906 drive behaves
as though both of the Disc Protect switches were on.
The setting of the drive Format switch may be changed with:
SET DSn FORMAT set format enabled
SET DSn NOFORMAT set format disabled
The 13037 supports the BOOT command. BOOT DS copies the IBL loader for
the 13037 controller into memory and starts it running. The switch register
(S) is set automatically to the value expected by the IBL loader:
<15:14> = 11
<13:12> = 01
<11:6> = data channel device code
<5:3> = unchanged
<2> = 0
<1:0> = unchanged (head number)
The DS controller implements these registers:
name size comments
CMD 16 command register
FIFO[0:15] 16 data FIFO
SR1 16 status register 1
VCTR 16 verify counter
FMASK 8 file mask
CYL 16 cylinder address register
HS 16 head/sector address register
STATE 2 controller state
LASTA 3 last unit polled for attention flag
FIP 4 FIFO insertion pointer
FRP 4 FIFO removal pointer
FCNT 5 FIFO counter
CTL 1 interrupt enable
FLG 1 ready flag
FBF 1 ready flag buffer
SRQ 1 DMA service request
BUSY 1 visible busy status
CMDF 1 command follows flag
CMDP 1 command pending flag
EOC 1 end of cylinder flag
EOD 1 end of data flag
DBUF[0:127] 16 sector buffer
DPTR 8 sector buffer pointer
CTIME 24 command response time
DTIME 24 data transfer response time
STIME 24 seek time (per cylinder)
RTIME 24 rotation time
TIMEOUT 31 controller timeout
Error handling is as follows:
error processed as
not attached disk not ready
end of file assume rest of disk is zero
OS I/O error report error and stop
2.7 Magnetic Tape
2.7.1 12559C Magnetic Tape Controller (MTC, MTD) with One 3030 Drive
Magnetic tape options include the ability to make the unit write enabled
or write locked.
@ -1037,7 +1166,7 @@ Error handling is as follows:
OS I/O error parity error; if STOP_IOE, stop
2.10 13181A Magnetic Tape Controller (MSC, MSD) with Four 7970B Drives
2.7.2 13181A Magnetic Tape Controller (MSC, MSD) with Four 7970B Drives
18183A Magnetic Tape Controller (MSC, MSD) with Four 7970E Drives
Magnetic tape options include the ability to make the unit write enabled
@ -1126,7 +1255,7 @@ Error handling is as follows:
OS I/O error parity error; if STOP_IOE, stop
2.11 Symbolic Display and Input
2.8 Symbolic Display and Input
The HP2100 simulator implements symbolic display and input. Display is
controlled by command line switches:

View file

@ -199,7 +199,6 @@
#define STA_UNLOADED (dp_ctype ? (STA_NRDY | STA_BSY) : STA_NRDY)
#define STA_MBZ13 (STA_ATN | STA_RWU | STA_SKI) /* zero in 13210 */
extern uint16 *M;
extern uint32 PC, SR;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
extern int32 sim_switches;

View file

@ -136,7 +136,6 @@
#define STA_ERR 0000001 /* any error */
#define STA_ANYERR (STA_NRDY | STA_EOC | STA_AER | STA_FLG | STA_DTE)
extern uint16 *M;
extern uint32 PC, SR;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
extern int32 sim_switches;

View file

@ -39,6 +39,11 @@
- Busy. The controller is processing a command. The controller does not
respond to new commands or to drive attention interrupts.
The controller busy state is loosely related to the testable (visible) busy
flop. If the visible busy flop is set, the controller is in the busy state;
but the controller can also be busy (processing an invalid opcode or invalid
unit) while visible busy is clear.
Omissions: the following features are not implemented:
- Drive hold. Since this is a single CPU implementation, the drives are
@ -46,6 +51,9 @@
- Spare, defective, protected. The disk files carry only data.
- Formatting. The disk files carry only data.
- ECC. Data errors are always uncorrectable.
Reference:
- 13037 Disc Controller Technical Information Package (13037-90902, Aug-1980)
*/
#include "hp2100_defs.h"
@ -60,10 +68,9 @@
#define DS_FHS 2
#define DS_FDATA 3
#define DS_FIFO_SIZE 16 /* fifo size */
#define DS_FIFO_EMPTY (ds_fifo_cnt == 0)
#define ds_ctrl ds_unit[DS_NUMDR] /* ctrl thread */
#define ds_timer ds_unit[DS_NUMDR + 1] /* timeout thread */
#define GET_DA(x,y,z,t) \
((((((x) * drv_tab[t].hd) + (y)) * drv_tab[t].sc) + (z)) * DS_NUMWD)
#define GET_CURSEC(x,d) ((int32) fmod (sim_gtime() / ((double) (x)), \
((double) (drv_tab[d].sc))))
@ -112,9 +119,9 @@
#define DSC_RFULL 006 /* read full */
#define DSC_VFY 007 /* verify */
#define DSC_WRITE 010 /* write */
#define DSC_WFULL 011 /* write full - na */
#define DSC_WFULL 011 /* write full */
#define DSC_CLEAR 012 /* clear */
#define DSC_INIT 013 /* initialize - na */
#define DSC_INIT 013 /* initialize */
#define DSC_AREC 014 /* address record */
#define DSC_RSYN 015 /* request syndrome */
#define DSC_ROFF 016 /* read with offset */
@ -124,7 +131,7 @@
#define DSC_RDA 024 /* request disk addr */
#define DSC_END 025 /* end */
#define DSC_WAKE 026 /* wakeup */
#define DSC_ATTN 035 /* pseudo: ATTN */
#define DSC_ATN 035 /* pseudo: ATN */
#define DSC_BADU 036 /* pseudo: bad unit */
#define DSC_BADF 037 /* pseudo: bad opcode */
#define DSC_NEXT 0040 /* state increment */
@ -138,24 +145,30 @@
#define DSC_V_RTY 4 /* retry count */
#define DSC_M_RTY 017
#define DSC_V_DECR 3 /* seek decrement */
#define DSC_V_SPAR 2 /* enable sparing */
#define DSC_V_SPEN 2 /* enable sparing */
#define DSC_V_CYLM 1 /* cylinder mode */
#define DSC_V_AUTO 0 /* auto seek */
#define DSC_V_HOLD 7 /* hold flag */
#define DSC_V_UNIT 0 /* unit */
#define DSC_M_UNIT 017
#define DSC_V_SPAR 15 /* INIT spare */
#define DSC_V_PROT 14 /* INIT protected */
#define DSC_V_DFCT 13 /* INIT defective */
#define DSC_HOLD (1u << DSC_V_HOLD)
#define DSC_DECR (1u << DSC_V_DECR)
#define DSC_SPAR (1u << DSC_V_SPAR)
#define DSC_SPEN (1u << DSC_V_SPEN)
#define DSC_CYLM (1u << DSC_V_CYLM)
#define DSC_AUTO (1u << DSC_V_AUTO)
#define DSC_FMASK ((DSC_M_RTY << DSC_V_RTY)|DSC_DECR|\
DSC_SPAR|DSC_CYLM|DSC_AUTO)
DSC_SPEN|DSC_CYLM|DSC_AUTO)
#define DSC_GETOP(x) (((x) >> DSC_V_OP) & DSC_M_OP)
#define DSC_GETUNIT(x) (((x) >> DSC_V_UNIT) & DSC_M_UNIT)
#define DSC_GETCHD(x) (((x) >> DSC_V_CHD) & DSC_M_CHD)
#define DSC_GETCSC(x) (((x) >> DSC_V_CSC) & DSC_M_CSC)
#define DSC_SPAR (1u << DSC_V_SPAR)
#define DSC_PROT (1u << DSC_V_PROT)
#define DSC_DFCT (1u << DSC_V_DFCT)
/* Command flags */
@ -199,15 +212,19 @@
#define DS1_S2ERR (023 << DS1_V_STAT) /* status 2 error */
#define DS1_TKPER (026 << DS1_V_STAT) /* protected trk - na */
#define DS1_UNAVL (027 << DS1_V_STAT) /* illegal unit */
#define DS1_ATTN (037 << DS1_V_STAT) /* attention */
#define DS1_ATN (037 << DS1_V_STAT) /* attention */
#define DS1_V_UNIT 0
#define DS1_SPAR (1u << DS1_V_SPAR)
#define DS1_PROT (1u << DS1_V_PROT)
#define DS1_DFCT (1u << DS1_V_DFCT)
/* Status 2, ^ = kept in unit status, * = dynamic */
#define DS2_ERR 0100000 /* *error */
#define DS2_V_ID 9 /* drive type */
#define DS2_ATN 0000200 /* ^attention */
#define DS2_RO 0000100 /* *read only */
#define DS2_FRM 0000040 /* format - na */
#define DS2_FRM 0000040 /* *format */
#define DS2_FLT 0000020 /* fault - na */
#define DS2_FS 0000010 /* ^first status */
#define DS2_SC 0000004 /* ^seek error */
@ -234,34 +251,69 @@
In theory, each drive can be a different type. The size field in
each unit selects the drive capacity for each drive and thus the
drive type. DISKS MUST BE DECLARED IN ASCENDING SIZE.
The 7905 and 7906 have fixed and removable platters. Consequently,
they are almost always accessed with cylinders limited to each
platter. The 7920 and 7925 have multiple-platter packs, and so are
almost always accessed with cylinders that span all surfaces.
Disk image files are arranged as a linear set of tracks. To improve
locality, tracks on the 7905 and 7906 images are grouped per-platter,
i.e., all tracks on heads 0 and 1, followed by all tracks on head 2
(and, for the 7906, head 3), whereas tracks on the 7920 and 7925 are
sequential by cylinder and head number.
This variable-access geometry is accomplished by defining a "heads
per cylinder" value for the fixed and removable sections of each
drive that indicates the number of heads that should be grouped for
locality. The removable values are set to 2 on the 7905 and 7906,
indicating that those drives typically use cylinders of two surfaces.
They are set to the number of surfaces per drive for the 7920 and
7925, as those typically use cylinders encompassing the entire
spindle.
*/
#define GET_DA(x,y,z,t) \
(((((y) < drv_tab[t].rh)? \
(x) * drv_tab[t].rh + (y): \
drv_tab[t].cyl * drv_tab[t].rh + \
((x) * drv_tab[t].fh + (y) - drv_tab[t].rh)) * \
drv_tab[t].sc + (z)) * DS_NUMWD)
#define D7905_DTYPE 0
#define D7905_SECT 48
#define D7905_SURF 3
#define D7905_RH 2
#define D7905_FH (D7905_SURF - D7905_RH)
#define D7905_CYL 411
#define D7905_ID 2
#define D7905_ID (2 << DS2_V_ID)
#define D7905_SIZE (D7905_SECT * D7905_SURF * D7905_CYL * DS_NUMWD)
#define D7906_DTYPE 1
#define D7906_SECT 48
#define D7906_SURF 4
#define D7906_RH 2
#define D7906_FH (D7906_SURF - D7906_RH)
#define D7906_CYL 411
#define D7906_ID 0
#define D7906_ID (0 << DS2_V_ID)
#define D7906_SIZE (D7906_SECT * D7906_SURF * D7906_CYL * DS_NUMWD)
#define D7920_DTYPE 2
#define D7920_SECT 48
#define D7920_SURF 5
#define D7920_RH D7920_SURF
#define D7920_FH (D7920_SURF - D7920_RH)
#define D7920_CYL 823
#define D7920_ID 1
#define D7920_ID (1 << DS2_V_ID)
#define D7920_SIZE (D7920_SECT * D7920_SURF * D7920_CYL * DS_NUMWD)
#define D7925_DTYPE 3
#define D7925_SECT 64
#define D7925_SURF 9
#define D7925_RH D7925_SURF
#define D7925_FH (D7925_SURF - D7925_RH)
#define D7925_CYL 823
#define D7925_ID 3
#define D7925_ID (3 << DS2_V_ID)
#define D7925_SIZE (D7925_SECT * D7925_SURF * D7925_CYL * DS_NUMWD)
struct drvtyp {
@ -270,16 +322,17 @@ struct drvtyp {
uint32 cyl; /* cylinders */
uint32 size; /* #blocks */
uint32 id; /* device type */
uint32 rh; /* removable surfaces */
uint32 fh; /* fixed surfaces */
};
static struct drvtyp drv_tab[] = {
{ D7905_SECT, D7905_SURF, D7905_CYL, D7905_SIZE, D7905_ID },
{ D7906_SECT, D7906_SURF, D7906_CYL, D7906_SIZE, D7906_ID },
{ D7920_SECT, D7920_SURF, D7920_CYL, D7920_SIZE, D7920_ID },
{ D7925_SECT, D7925_SURF, D7925_CYL, D7925_SIZE, D7925_ID },
{ D7905_SECT, D7905_SURF, D7905_CYL, D7905_SIZE, D7905_ID, D7905_RH, D7905_FH },
{ D7906_SECT, D7906_SURF, D7906_CYL, D7906_SIZE, D7906_ID, D7906_RH, D7906_FH },
{ D7920_SECT, D7920_SURF, D7920_CYL, D7920_SIZE, D7920_ID, D7920_RH, D7920_FH },
{ D7925_SECT, D7925_SURF, D7925_CYL, D7925_SIZE, D7925_ID, D7925_RH, D7925_FH },
{ 0 } };
extern uint16 *M;
extern uint32 PC, SR;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
extern int32 sim_switches;
@ -291,7 +344,6 @@ uint32 ds_fifo_rp = 0; /* removal ptr */
uint32 ds_fifo_cnt = 0; /* count */
uint32 ds_cmd = 0; /* command word */
uint32 ds_sr1 = 0; /* status word 1 */
uint32 ds_u = 0; /* saved unit */
uint32 ds_busy = 0; /* busy flag */
uint32 ds_eoc = 0; /* end of cylinder */
uint32 ds_eod = 0; /* end of data */
@ -302,12 +354,12 @@ uint32 ds_cyl = 0; /* disk address: cyl */
uint32 ds_hs = 0; /* disk address: hs */
uint32 ds_vctr = 0; /* verify counter */
uint32 ds_state = 0; /* controller state */
uint32 ds_lastatn = 0; /* last attn intr */
uint32 ds_lastatn = 0; /* last atn intr */
int32 ds_stime = 100; /* seek time */
int32 ds_rtime = 100; /* inter-sector time */
int32 ds_ctime = 3; /* command time */
int32 ds_dtime = 1; /* dch time */
int32 ds_tmo = 1000000; /* timeout */
int32 ds_tmo = 2749200; /* timeout = 1.74 sec */
uint32 ds_ptr = 0; /* buffer ptr */
uint16 dsxb[DS_NUMWDF]; /* sector buffer */
@ -351,7 +403,6 @@ t_stat ds_svc_c (UNIT *uptr);
t_stat ds_svc_u (UNIT *uptr);
t_stat ds_svc_t (UNIT *uptr);
t_stat ds_reset (DEVICE *dptr);
t_stat ds_vlock (UNIT *uptr, int32 val);
t_stat ds_attach (UNIT *uptr, char *cptr);
t_stat ds_detach (UNIT *uptr);
t_stat ds_boot (int32 unitno, DEVICE *dptr);
@ -359,7 +410,7 @@ t_stat ds_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
void ds_poll (void);
void ds_docmd (uint32 cmd);
void ds_doatn (void);
uint32 ds_updds2 (UNIT *uptr, uint32 clear);
uint32 ds_updds2 (UNIT *uptr);
void ds_cmd_done (t_bool sf, uint32 sr1);
void ds_wait_for_cpu (UNIT *uptr, uint32 newst);
void ds_set_idle (void);
@ -376,7 +427,7 @@ t_stat ds_cont_wr (UNIT *uptr, uint32 off, uint32 bsize);
void ds_end_rw (UNIT *uptr, uint32 newst);
t_stat ds_set_uncorr (UNIT *uptr);
t_stat ds_reset_cmn (DEVICE *dptr);
void ds_sched_attn (UNIT *uptr);
void ds_sched_atn (UNIT *uptr);
uint32 ds_fifo_read (void);
void ds_fifo_write (uint32 dat);
void ds_fifo_reset (void);
@ -416,7 +467,6 @@ REG ds_reg[] = {
{ BRDATA (FIFO, ds_fifo, 8, 16, DS_FIFO_SIZE) },
{ ORDATA (SR1, ds_sr1, 16) },
{ ORDATA (VCTR, ds_vctr, 16) },
{ ORDATA (UNIT, ds_u, 4) },
{ ORDATA (FMASK, ds_fmask, 8) },
{ ORDATA (CYL, ds_cyl, 16) },
{ ORDATA (HS, ds_hs, 16) },
@ -440,9 +490,9 @@ REG ds_reg[] = {
{ DRDATA (CTIME, ds_ctime, 24), PV_LEFT + REG_NZ },
{ DRDATA (DTIME, ds_dtime, 24), PV_LEFT + REG_NZ },
{ DRDATA (STIME, ds_stime, 24), PV_LEFT + REG_NZ },
{ DRDATA (TTIME, ds_rtime, 24), PV_LEFT + REG_NZ },
{ DRDATA (RTIME, ds_rtime, 24), PV_LEFT + REG_NZ },
{ DRDATA (TIMEOUT, ds_tmo, 31), PV_LEFT + REG_NZ },
{ URDATA (UCYL, ds_unit[0].CYL, 10, 8, 0,
{ URDATA (UCYL, ds_unit[0].CYL, 10, 10, 0,
DS_NUMDR + 1, PV_LEFT | REG_HRO) },
{ URDATA (UFNC, ds_unit[0].FNC, 8, 8, 0,
DS_NUMDR + 1, REG_HRO) },
@ -493,15 +543,14 @@ DEVICE ds_dev = {
DS_NUMDR + 2, 8, 27, 1, 8, 16,
NULL, NULL, &ds_reset,
&ds_boot, &ds_attach, &ds_detach,
&ds_dib, DEV_DISABLE | DEV_DIS };
&ds_dib, DEV_DISABLE };
/* IO instructions */
int32 dsio (int32 inst, int32 IR, int32 dat)
{
int32 dev;
uint32 dev = IR & I_DEVMASK;
dev = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (dev); } /* STF */
@ -516,7 +565,8 @@ case ioOTX: /* output */
if (ds_cmdf) { /* expecting command? */
ds_cmd = dat; /* save command */
ds_cmdf = 0;
ds_cmdp = 1; } /* command present */
ds_cmdp = 1; /* command present */
}
else ds_fifo_write (dat); /* put in fifo */
break;
case ioMIX: /* merge */
@ -530,9 +580,11 @@ case ioCTL: /* control clear/set */
clrCTL (dev); /* clear control */
ds_cmdf = 1; /* expecting command */
ds_cmdp = 0; /* none pending */
ds_fifo_reset (); } /* clear fifo */
ds_fifo_reset (); /* clear fifo */
}
else { /* STC */
setCTL (dev); } /* set ctl */
setCTL (dev); /* set ctl */
}
break;
case ioEDT: /* end of transfer */
ds_eod = 1; /* flag end transfer */
@ -546,7 +598,7 @@ return dat;
/* Run the controller polling loop, based on ds_state:
IDLE commands and ATTN interrupts
IDLE commands and ATN interrupts
WAIT commands only
BUSY nothing
*/
@ -556,7 +608,7 @@ void ds_poll (void)
int32 dev = ds_dib.devno;
if ((ds_state != DS_BUSY) && ds_cmdp) ds_docmd (ds_cmd);/* cmd pending? */
if ((ds_state == DS_IDLE) && CTL (dev)) ds_doatn (); /* idle? chk atn */
if ((ds_state == DS_IDLE) && CTL (dev)) ds_doatn (); /* idle? check ATN */
return;
}
@ -571,29 +623,31 @@ return;
void ds_docmd (uint32 cmd)
{
uint32 op, f, dtyp;
uint32 op, f, dtyp, unum;
op = DSC_GETOP (cmd); /* operation */
f = ds_opflags[op]; /* flags */
if (op == DSC_COLD) ds_u = 0; /* boot force unit 0 */
else ds_u = DSC_GETUNIT (cmd); /* get unit */
if ((f & CMF_UIDLE) && (ds_u < DS_NUMDR) && /* idle required */
sim_is_active (&ds_unit[ds_u])) { /* but unit busy? */
if (op == DSC_COLD) unum = 0; /* boot force unit 0 */
else unum = DSC_GETUNIT (cmd); /* get unit */
if ((f & CMF_UIDLE) && (unum < DS_NUMDR) && /* idle required */
sim_is_active (&ds_unit[unum])) { /* but unit busy? */
ds_state = DS_WAIT; /* wait */
return; }
return;
}
ds_cmdp = 0; /* flush command */
ds_state = DS_BUSY; /* ctrl is busy */
if (f & CMF_CLRS) ds_sr1 = 0; /* clear status */
if (f & CMF_CLREC) ds_eoc = 0; /* clear end cyl */
if (f & CMF_UNDF) { /* illegal op? */
ds_sched_ctrl_op (DSC_BADF, 0, CLR_BUSY); /* sched, not busy */
return; }
ds_sched_ctrl_op (DSC_BADF, 0, CLR_BUSY); /* sched, clr busy */
return;
}
switch (op) {
/* Drive commands */
case DSC_COLD: /* cold load read */
ds_fmask = DSC_SPAR; /* sparing enabled */
ds_fmask = DSC_SPEN; /* sparing enabled */
ds_cyl = 0; /* cylinder 0 */
ds_hs = (DSC_GETCHD (ds_cmd) << DSHS_V_HD) | /* reformat hd/sec */
(DSC_GETCSC (ds_cmd) << DSHS_V_SC);
@ -607,13 +661,19 @@ case DSC_VFY: /* verify */
case DSC_WRITE: /* write */
case DSC_WFULL: /* write full */
case DSC_INIT: /* init */
ds_sr1 = ds_u; /* init status */
if (ds_u >= DS_NUMDR) { /* invalid unit? */
ds_sched_ctrl_op (DSC_BADU, ds_u, CLR_BUSY);/* sched, not busy */
return; }
ds_unit[ds_u].FNC = op; /* save op */
ds_unit[ds_u].STA &= ~DS2_ATN; /* clear ATTN */
sim_activate (&ds_unit[ds_u], ds_ctime); /* schedule unit */
ds_sr1 = unum; /* init status */
if (unum >= DS_NUMDR) { /* invalid unit? */
ds_sched_ctrl_op (DSC_BADU, unum, CLR_BUSY);/* sched, not busy */
return;
}
if (op == DSC_INIT) ds_sr1 |= /* init? */
((cmd & DSC_SPAR)? DS1_SPAR: 0) | /* copy SPD to stat1 */
((cmd & DSC_PROT)? DS1_PROT: 0) |
((cmd & DSC_DFCT)? DS1_DFCT: 0);
ds_unit[unum].FNC = op; /* save op */
ds_unit[unum].STA &= ~DS2_ATN; /* clear ATN */
sim_cancel (&ds_unit[unum]); /* cancel current */
sim_activate (&ds_unit[unum], ds_ctime); /* schedule unit */
ds_busy = 1; /* set visible busy */
break;
@ -621,12 +681,15 @@ case DSC_INIT: /* init */
case DSC_RSTA: /* read status */
dsxb[1] = ds_sr1; /* return SR1 */
if (ds_u >= DS_NUMDR) dsxb[0] = DS2_ERR|DS2_NR|ds_u; /* SR2 */
else dsxb[0] = ds_updds2 (&ds_unit[ds_u], DS2_FS);
if (unum < DS_NUMDR) { /* and SR2 */
dsxb[0] = ds_updds2 (&ds_unit[unum]);
ds_unit[unum].STA &= ~DS2_FS; /* clear 1st */
}
else dsxb[0] = DS2_ERR|DS2_NR;
ds_sched_ctrl_op (DSC_RSTA, 2, SET_BUSY); /* sched 2 wds, busy */
break;
case DSC_RSA: /* read sector address */
dtyp = GET_DTYPE (ds_unit[ds_u].flags); /* get unit type */
dtyp = GET_DTYPE (ds_unit[unum].flags); /* get unit type */
dsxb[0] = GET_CURSEC (ds_dtime * DS_NUMWD, dtyp); /* rot position */
ds_sched_ctrl_op (DSC_RSTA, 1, SET_BUSY); /* sched 1 wd, busy */
break;
@ -653,7 +716,8 @@ case DSC_WTIO: /* write TIO */
case DSC_END: /* end */
ds_set_idle (); /* idle ctrl */
break; }
break;
}
return;
}
@ -669,9 +733,11 @@ for (i = 0; i < DS_NUMDR; i++) { /* intr disabled? */
if (ds_unit[ds_lastatn].STA & DS2_ATN) { /* ATN set? */
ds_unit[ds_lastatn].STA &= ~DS2_ATN; /* clear ATN */
setFLG (dev); /* request interrupt */
ds_sr1 = DS1_ATTN | ds_lastatn; /* set up status 1 */
ds_state = DS_WAIT; /* block attn intrs */
return; } }
ds_sr1 = DS1_ATN | ds_lastatn; /* set up status 1 */
ds_state = DS_WAIT; /* block atn intrs */
return;
}
}
return;
}
@ -691,28 +757,31 @@ case DSC_AREC: /* address record */
ds_wait_for_cpu (uptr, DSC_AREC|DSC_2ND); /* set flag, new state */
break;
case DSC_AREC | DSC_2ND: /* poll done */
if (!FLG (dev)) { /* OTA x,C? */
if (!DS_FIFO_EMPTY) { /* OTA ds? */
ds_cyl = ds_fifo_read (); /* save cylinder */
ds_wait_for_cpu (uptr, DSC_AREC|DSC_3RD); }/* set flag, new state */
ds_wait_for_cpu (uptr, DSC_AREC|DSC_3RD); /* set flag, new state */
}
else sim_activate (uptr, ds_ctime); /* no, continue poll */
break;
case DSC_AREC | DSC_3RD: /* poll done */
if (!FLG (dev)) { /* OTA x,C? */
if (!DS_FIFO_EMPTY) { /* OTA ds? */
ds_hs = ds_fifo_read (); /* save head/sector */
ds_cmd_done (0, DS1_OK); } /* op done, no flag */
ds_cmd_done (0, DS1_OK); /* op done, no flag */
}
else sim_activate (uptr, ds_ctime); /* no, continue poll */
break;
case DSC_RSTA: /* rd stat (all forms) */
if (!FLG (dev)) { /* buffer clear? */
if (DS_FIFO_EMPTY) { /* fifo empty? */
uptr->CYL--;
ds_fifo_write (dsxb[uptr->CYL]); /* store next status */
ds_wait_for_cpu (uptr, DSC_RSTA |
(uptr->CYL? 0: DSC_2ND)); } /* set flag, new state */
(uptr->CYL? 0: DSC_2ND)); /* set flag, new state */
}
else sim_activate (uptr, ds_ctime); /* no, continue poll */
break;
case DSC_RSTA | DSC_2ND: /* poll done */
if (!FLG (dev)) ds_cmd_done (0, DS1_OK); /* op done? no flag */
if (DS_FIFO_EMPTY) ds_cmd_done (0, DS1_OK); /* op done? no flag */
else sim_activate (uptr, ds_ctime); /* no, continue poll */
break;
@ -758,7 +827,7 @@ t_stat ds_svc_t (UNIT *uptr)
{
int32 i;
for (i = 0; i < DS_NUMDR; i++) /* cancel all ops */
for (i = 0; i < (DS_NUMDR + 1); i++) /* cancel all ops */
sim_cancel (&ds_unit[i]);
ds_set_idle (); /* idle the controller */
ds_fmask = 0; /* clear file mask */
@ -783,7 +852,8 @@ switch (op) { /* case on function */
case DSC_RECAL: /* recalibrate */
if (uptr->flags & UNIT_ATT) { /* attached? */
ds_start_seek (uptr, 0, DSC_RECAL|DSC_2ND); /* set up seek */
ds_set_idle (); } /* ctrl is idle */
ds_set_idle (); /* ctrl is idle */
}
else ds_cmd_done (1, DS1_S2ERR); /* not ready error */
break;
case DSC_RECAL | DSC_2ND: /* recal complete */
@ -794,18 +864,21 @@ case DSC_SEEK: /* seek */
ds_wait_for_cpu (uptr, DSC_SEEK|DSC_2ND); /* set flag, new state */
break;
case DSC_SEEK | DSC_2ND: /* waiting for word 1 */
if (!FLG (dev)) { /* OTA x,C? */
if (!DS_FIFO_EMPTY) { /* OTA ds? */
ds_cyl = ds_fifo_read (); /* save cylinder */
ds_wait_for_cpu (uptr, DSC_SEEK|DSC_3RD); }/* set flag, new state */
ds_wait_for_cpu (uptr, DSC_SEEK|DSC_3RD); /* set flag, new state */
}
else sim_activate (uptr, ds_ctime); /* no, continue poll */
break;
case DSC_SEEK | DSC_3RD: /* waiting for word 2 */
if (!FLG (dev)) { /* OTA x,C? */
if (!DS_FIFO_EMPTY) { /* OTA ds? */
ds_hs = ds_fifo_read (); /* save head/sector */
if (uptr->flags & UNIT_ATT) { /* attached? */
ds_start_seek (uptr, ds_cyl, DSC_SEEK|DSC_4TH); /* set up seek */
ds_set_idle (); } /* ctrl is idle */
else ds_cmd_done (1, DS1_S2ERR); } /* else not ready error */
ds_set_idle (); /* ctrl is idle */
}
else ds_cmd_done (1, DS1_S2ERR); /* else not ready error */
}
else sim_activate (uptr, ds_ctime); /* continue poll */
break;
case DSC_SEEK | DSC_4TH: /* seek complete */
@ -818,7 +891,11 @@ case DSC_ROFF: /* read with offset */
ds_wait_for_cpu (uptr, DSC_ROFF|DSC_2ND); /* set flag, new state */
break;
case DSC_ROFF | DSC_2ND: /* poll done */
if (!FLG (dev)) uptr->FNC = DSC_READ; /* OTA x,C? new state */
if (!DS_FIFO_EMPTY) { /* OTA ds? new state */
ds_fifo_read (); /* drain fifo */
uptr->FNC = DSC_READ;
setFLG (dev); /* handshake */
}
sim_activate (uptr, ds_ctime); /* schedule unit */
break;
@ -829,8 +906,7 @@ case DSC_COLD: /* cold load read */
break;
case DSC_READ: /* read */
if (r = ds_start_rd (uptr, 0, 1)) /* new sector; error? */
return r;
if (r = ds_start_rd (uptr, 0, 1)) return r; /* new sector; error? */
break;
case DSC_READ | DSC_2ND: /* word transfer */
ds_cont_rd (uptr, DS_NUMWD); /* xfr wd, check end */
@ -840,8 +916,7 @@ case DSC_READ | DSC_3RD: /* end of sector */
break;
case DSC_RNOVFY: /* read, no verify */
if (r = ds_start_rd (uptr, 0, 0)) /* new sector; error? */
return r;
if (r = ds_start_rd (uptr, 0, 0)) return r; /* new sector; error? */
break;
case DSC_RNOVFY | DSC_2ND: /* word transfer */
ds_cont_rd (uptr, DS_NUMWD); /* xfr wd, check end */
@ -868,10 +943,11 @@ case DSC_VFY: /* verify */
ds_wait_for_cpu (uptr, DSC_VFY|DSC_2ND); /* set flag, new state */
break;
case DSC_VFY | DSC_2ND: /* poll done */
if (!FLG (dev)) { /* OTA x,C? */
if (!DS_FIFO_EMPTY) { /* OTA ds? */
ds_vctr = ds_fifo_read (); /* save count */
uptr->FNC = DSC_VFY | DSC_3RD; /* next state */
sim_activate (uptr, ds_rtime); } /* delay for transfer */
sim_activate (uptr, ds_rtime); /* delay for transfer */
}
else sim_activate (uptr, ds_ctime); /* no, continue poll */
break;
case DSC_VFY | DSC_3RD: /* start sector */
@ -978,9 +1054,9 @@ sim_activate (&ds_timer, ds_tmo);
return;
}
/* Return drive status (status word 2), clear specified flags */
/* Return drive status (status word 2) */
uint32 ds_updds2 (UNIT *uptr, uint32 clear)
uint32 ds_updds2 (UNIT *uptr)
{
uint32 sta;
uint32 dtyp = GET_DTYPE (uptr->flags);
@ -988,10 +1064,10 @@ uint32 dtyp = GET_DTYPE (uptr->flags);
sta = drv_tab[dtyp].id | /* form status */
uptr->STA | /* static bits */
((uptr->flags & UNIT_WPR)? DS2_RO: 0) | /* dynamic bits */
((uptr->flags & UNIT_ATT)? 0: DS2_NR) |
((uptr->flags & UNIT_FMT)? DS2_FRM: 0) |
((uptr->flags & UNIT_ATT)? 0: DS2_NR | DS2_BS) |
(sim_is_active (uptr)? DS2_BS: 0);
if (sta & DS2_ALLERR) sta = sta | DS2_ERR; /* set error */
uptr->STA = uptr->STA & ~clear; /* clear static */
return sta;
}
@ -1022,16 +1098,23 @@ return;
void ds_start_seek (UNIT *uptr, uint32 cyl, uint32 newst)
{
int32 t;
uint32 hd, sc;
uint32 dtyp = GET_DTYPE (uptr->flags);
uptr->FNC = newst; /* set new state */
if (cyl >= drv_tab[dtyp].cyl) { /* out of bounds? */
uptr->CYL = t = drv_tab[dtyp].cyl; /* put off edge */
uptr->STA = uptr->STA | DS2_SC; } /* set seek check */
else { /* seek in range */
t = abs (uptr->CYL - cyl); /* delta cylinders */
t = 0; /* don't change cyl */
uptr->STA = uptr->STA | DS2_SC; /* set seek check */
}
else { t = abs (uptr->CYL - cyl); /* delta cylinders */
uptr->CYL = cyl; /* put on cylinder */
uptr->STA = uptr->STA & ~DS2_SC; } /* clear seek check */
hd = DSHS_GETHD (ds_hs); /* invalid head or sec? */
sc = DSHS_GETSC (ds_hs);
if ((hd >= drv_tab[dtyp].hd) ||
(sc >= drv_tab[dtyp].sc))
uptr->STA = uptr->STA | DS2_SC; /* set seek check */
else uptr->STA = uptr->STA & ~DS2_SC; /* clear seek check */
}
sim_activate (uptr, ds_stime * (t + 1)); /* schedule */
return;
}
@ -1048,29 +1131,36 @@ t_bool ds_start_rw (UNIT *uptr, int32 tm, t_bool vfy)
uint32 da, hd, sc;
uint32 dtyp = GET_DTYPE (uptr->flags);
ds_eod = 0; /* clear eod */
ds_eod = 0; /* init eod */
ds_ptr = 0; /* init buffer ptr */
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
ds_cmd_done (1, DS1_S2ERR);
return TRUE; }
return TRUE;
}
if (ds_eoc) { /* at end of cylinder? */
ds_next_cyl (uptr); /* auto seek to next */
return TRUE; } /* or error */
if (vfy && ((uint32) uptr->CYL != ds_cyl)) { /* on proper cylinder? */
ds_cmd_done (1, DS1_CYLCE); /* no, error */
return TRUE; }
return TRUE; /* or error */
}
if (vfy && ((uint32) uptr->CYL != ds_cyl)) { /* on wrong cylinder? */
if (ds_cyl >= drv_tab[dtyp].cyl) /* seeking to bad? */
ds_cmd_done (1, DS1_CYLCE); /* lose */
else ds_start_seek (uptr, ds_cyl, uptr->FNC); /* seek right cyl */
return TRUE;
}
hd = DSHS_GETHD (ds_hs);
sc = DSHS_GETSC (ds_hs);
if ((uint32) uptr->CYL >= drv_tab[dtyp].cyl) { /* valid cylinder? */
uptr->STA = uptr->STA | DS2_SC; /* set seek check */
ds_cmd_done (1, DS1_S2ERR); /* error */
return TRUE; }
return TRUE;
}
if ((hd >= drv_tab[dtyp].hd) || /* valid head, sector? */
(sc >= drv_tab[dtyp].sc)) {
ds_cmd_done (1, DS1_HSCE); /* no, error */
return TRUE; }
return TRUE;
}
da = GET_DA (uptr->CYL, hd, sc, dtyp); /* position in file */
sim_fseek (uptr->fileref, da * sizeof (uint16), SEEK_SET); /* set file pos */
ds_ptr = 0; /* init buffer ptr */
uptr->FNC += DSC_NEXT; /* next state */
sim_activate (uptr, tm); /* activate unit */
return FALSE;
@ -1080,7 +1170,8 @@ return FALSE;
- Do common start for read and write
- If error, return, command has been terminated, nothing scheduled
- If no error, state has been advanced and unit scheduled
- If implicit seek, return, seek scheduled
- If no error or seek, state has been advanced and unit scheduled
- Read sector
- If read error, terminate command and return, nothing scheduled
- If no error, advance head/sector, next state scheduled */
@ -1089,8 +1180,7 @@ t_stat ds_start_rd (UNIT *uptr, uint32 off, t_bool vfy)
{
uint32 t;
if (ds_start_rw (uptr, ds_rtime, vfy)) /* new sector; error? */
return SCPE_OK; /* nothing scheduled */
if (ds_start_rw (uptr, ds_rtime, vfy)) return SCPE_OK; /* new sec; err or seek? */
t = sim_fread (dsxb + off, sizeof (uint16), DS_NUMWD, uptr->fileref);
for (t = t + off ; t < DS_NUMWDF; t++) dsxb[t] = 0; /* fill sector */
if (ferror (uptr->fileref)) /* error? */
@ -1103,20 +1193,22 @@ return SCPE_OK;
- Do common start for read and write
- If error, return, command has been terminated, nothing scheduled
- If no error, state has been advanced and unit scheduled
- If implicit seek, return, seek scheduled
- If no error or seek, state has been advanced and unit scheduled
- Clear buffer
- Set service request */
void ds_start_wr (UNIT *uptr, t_bool vfy)
{
uint32 i, dev;
uint32 i;
uint32 dev = ds_dib.devno;
dev = ds_dib.devno;
if ((uptr->flags & UNIT_WPR) || /* write protected? */
(!vfy && ((uptr->flags & UNIT_FMT) == 0))) { /* format, not enbl? */
ds_cmd_done (1, DS1_S2ERR); /* error */
return; }
if (ds_start_rw (uptr, ds_rtime, vfy)) return; /* new sector; error? */
return;
}
if (ds_start_rw (uptr, ds_rtime, vfy)) return; /* new sec; err or seek? */
for (i = 0; i < DS_NUMWDF; i++) dsxb[i] = 0; /* clear buffer */
setSRQ (dev); /* request word */
return;
@ -1134,7 +1226,8 @@ ds_hs = ds_hs & ~DSHS_SC; /* yes, wrap sector */
if (ds_fmask & DSC_CYLM) { /* cylinder mode? */
ds_hs = ds_hs + (1 << DSHS_V_HD); /* increment head */
if (DSHS_GETHD (ds_hs) < drv_tab[dtyp].hd) return; /* end of cyl? */
ds_hs = ds_hs & ~DSHS_HD; } /* 0 head */
ds_hs = ds_hs & ~DSHS_HD; /* 0 head */
}
ds_eoc = 1; /* flag end cylinder */
return;
}
@ -1146,13 +1239,12 @@ return;
void ds_next_cyl (UNIT *uptr)
{
uint32 dtyp = GET_DTYPE (uptr->flags);
if (ds_fmask & DSC_AUTO) { /* auto seek allowed? */
if (ds_fmask & DSC_DECR) ds_cyl = (ds_cyl - 1) & DMASK;
else ds_cyl = (ds_cyl + 1) & DMASK;
ds_eoc = 0; /* clear end cylinder */
ds_start_seek (uptr, ds_cyl, uptr->FNC); } /* seek, same state */
ds_start_seek (uptr, ds_cyl, uptr->FNC); /* seek, same state */
}
else ds_cmd_done (1, DS1_EOCYL); /* no, end of cyl err */
return;
}
@ -1167,10 +1259,15 @@ void ds_cont_rd (UNIT *uptr, uint32 bsize)
uint32 dev = ds_dib.devno;
if (ds_eod) ds_cmd_done (1, DS1_OK); /* DMA end? done */
else if (SRQ (dev)) { /* overrun? */
ds_cmd_done (1, DS1_OVRUN); /* set done */
return;
}
else { ds_fifo_write (dsxb[ds_ptr++]); /* next word */
setSRQ (dev); /* request service */
if (ds_ptr >= bsize) uptr->FNC += DSC_NEXT; /* sec done? next state */
sim_activate (uptr, ds_dtime); } /* schedule */
sim_activate (uptr, ds_dtime); /* schedule */
}
return;
}
@ -1183,18 +1280,26 @@ return;
t_stat ds_cont_wr (UNIT *uptr, uint32 off, uint32 bsize)
{
uint32 i, dat;
uint32 dev = ds_dib.devno;
dsxb[ds_ptr++] = ds_fifo_read (); /* next word */
if (SRQ (dev)) { /* overrun? */
ds_cmd_done (1, DS1_OVRUN); /* set done */
return SCPE_OK;
}
dsxb[ds_ptr++] = dat = ds_fifo_read (); /* next word */
if (ds_eod || (ds_ptr >= bsize)) { /* xfr or sector done? */
for (i = ds_ptr; i < bsize; i++) dsxb[i] = dat; /* fill sector */
sim_fwrite (dsxb + off, sizeof (uint16), DS_NUMWD, uptr->fileref);
if (ferror (uptr->fileref)) /* error on write? */
return ds_set_uncorr (uptr); /* uncorrectable */
ds_next_sec (uptr); /* increment hd, sc */
if (ds_eod) { /* end data? */
ds_cmd_done (1, DS1_OK); /* set done */
return SCPE_OK; }
else uptr->FNC += DSC_NEXT; } /* no, next state */
return SCPE_OK;
}
else uptr->FNC += DSC_NEXT; /* no, next state */
}
else { setSRQ (dev); } /* request next word */
sim_activate (uptr, ds_dtime); /* schedule */
return SCPE_OK;
@ -1278,7 +1383,8 @@ for (i = 0; i < DS_NUMDR; i++) { /* loop thru drives */
sim_cancel (&ds_unit[i]); /* cancel activity */
ds_unit[i].FNC = 0; /* clear function */
ds_unit[i].CYL = 0;
ds_unit[i].STA = 0; }
ds_unit[i].STA = 0;
}
sim_cancel (&ds_ctrl);
sim_cancel (&ds_timer);
return SCPE_OK;
@ -1305,14 +1411,16 @@ uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size;
r = attach_unit (uptr, cptr); /* attach unit */
if (r != SCPE_OK) return r; /* error? */
uptr->STA = DS2_ATN | DS2_FS; /* update drive status */
ds_sched_attn (uptr); /* schedule attention */
ds_sched_atn (uptr); /* schedule attention */
if (((uptr->flags & UNIT_AUTO) == 0) || /* static size? */
((p = sim_fsize (uptr->fileref)) == 0)) return SCPE_OK; /* new file? */
for (i = 0; drv_tab[i].sc != 0; i++) { /* find best fit */
if (p <= (drv_tab[i].size * sizeof (uint16))) {
uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (i << UNIT_V_DTYPE);
uptr->capac = drv_tab[i].size;
return SCPE_OK; } }
return SCPE_OK;
}
}
return SCPE_OK;
}
@ -1321,20 +1429,21 @@ return SCPE_OK;
t_stat ds_detach (UNIT *uptr)
{
uptr->STA = DS2_ATN; /* update drive status */
ds_sched_attn (uptr); /* schedule attention */
ds_sched_atn (uptr); /* schedule attention */
return detach_unit (uptr);
}
/* Schedule attention interrupt if CTL set, not restore, and controller idle */
void ds_sched_attn (UNIT *uptr)
void ds_sched_atn (UNIT *uptr)
{
int32 i;
if (!ds_dib.ctl || (sim_switches & SIM_SW_REST)) return;
for (i = 0; i < (DS_NUMDR + 1); i++) { /* check units, ctrl */
if (sim_is_active (ds_dev.units + i)) return; }
uptr->FNC = DSC_ATTN; /* pseudo operation */
if (sim_is_active (ds_dev.units + i)) return;
}
uptr->FNC = DSC_ATN; /* pseudo operation */
sim_activate (uptr, 1); /* do immediately */
return;
}
@ -1424,6 +1533,6 @@ int32 dev;
if (unitno != 0) return SCPE_NOFNC; /* only unit 0 */
dev = ds_dib.devno; /* get data chan dev */
if (ibl_copy (ds_rom, dev)) return SCPE_IERR; /* copy boot to memory */
SR = (SR & IBL_OPT) | IBL_DS | IBL_MAN | (dev << IBL_V_DEV); /* set SR */
SR = (SR & (IBL_OPT | IBL_DS_HEAD)) | IBL_DS | IBL_MAN | (dev << IBL_V_DEV);
return SCPE_OK;
}

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
26-Dec-04 RMS Separated A/B from M[0/1] for DMA IO (from Dave Bryan)
15-Jul-03 RMS Fixed signed/unsigned warning
21-Oct-02 RMS Recoded for compatibility with 21MX microcode algorithms
@ -102,7 +103,7 @@ struct ufp { /* unpacked fp */
#define FR_NEG(v) ((~(v) + 1) & DMASK32)
extern uint16 *M;
extern uint16 ABREG[2];
uint32 UnpackFP (struct ufp *fop, uint32 opnd);
void NegFP (struct ufp *fop);
void NormFP (struct ufp *fop);

View file

@ -26,6 +26,8 @@
lps 12653A 2767 line printer
(based on 12566B microcircuit interface)
19-Nov-04 JDB Added restart when set online, etc.
Fixed col count for non-printing chars
01-Oct-04 JDB Added SET OFFLINE/ONLINE, POWEROFF/POWERON
Fixed status returns for error conditions
Fixed handling of non-printing characters
@ -164,6 +166,9 @@ DEVICE lps_dev;
int32 lpsio (int32 inst, int32 IR, int32 dat);
t_stat lps_svc (UNIT *uptr);
t_stat lps_reset (DEVICE *dptr);
t_stat lps_restart (UNIT *uptr, int32 value, char *cptr, void *desc);
t_stat lps_poweroff (UNIT *uptr, int32 value, char *cptr, void *desc);
t_stat lps_poweron (UNIT *uptr, int32 value, char *cptr, void *desc);
t_stat lps_attach (UNIT *uptr, char *cptr);
t_stat lps_set_timing (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat lps_show_timing (FILE *st, UNIT *uptr, int32 val, void *desc);
@ -204,10 +209,10 @@ REG lps_reg[] = {
MTAB lps_mod[] = {
{ UNIT_DIAG, UNIT_DIAG, "diagnostic mode", "DIAG", NULL },
{ UNIT_DIAG, 0, "printer mode", "PRINTER", NULL },
{ UNIT_POWEROFF, UNIT_POWEROFF, "power off", "POWEROFF", NULL },
{ UNIT_POWEROFF, 0, "power on", "POWERON", NULL },
{ UNIT_POWEROFF, UNIT_POWEROFF, "power off", "POWEROFF", lps_poweroff },
{ UNIT_POWEROFF, 0, "power on", "POWERON", lps_poweron },
{ UNIT_OFFLINE, UNIT_OFFLINE, "offline", "OFFLINE", NULL },
{ UNIT_OFFLINE, 0, "online", "ONLINE", NULL },
{ UNIT_OFFLINE, 0, "online", "ONLINE", lps_restart },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "REALTIME",
&lps_set_timing, NULL, NULL },
{ MTAB_XTD | MTAB_VDV, 1, NULL, "FASTTIME",
@ -250,27 +255,13 @@ case ioOTX: /* output */
case ioLIX: /* load */
dat = 0; /* default sta = 0 */
case ioMIX: /* merge */
if ((lps_unit.flags & UNIT_DIAG) == 0) { /* real lpt? */
if (lps_power == LPS_ON) { /* power on? */
if (lps_unit.flags & UNIT_POWEROFF) { /* power just turned off? */
lps_power = LPS_OFF; /* change state */
lps_sta = LPS_PWROFF;
if (DEBUG_PRS (lps_dev))
fputs (">>LPS LIx: Power state is OFF\n", sim_deb); }
else if (((lps_unit.flags & UNIT_ATT) == 0) ||
(lps_unit.flags & UNIT_OFFLINE) ||
if ((lps_unit.flags & UNIT_DIAG) == 0) /* real lpt? */
if (lps_power == LPS_ON) /* power on? */
if (((lps_unit.flags & UNIT_ATT) == 0) || /* paper out? */
(lps_unit.flags & UNIT_OFFLINE) || /* offline? */
sim_is_active (&lps_unit)) lps_sta = LPS_BUSY;
else lps_sta = 0; }
else if (lps_power == LPS_TURNING_ON) /* printer warming up? */
lps_sta = LPS_PWROFF;
else if (!(lps_unit.flags & UNIT_POWEROFF)) { /* power just turned on? */
lps_power = LPS_TURNING_ON; /* change state */
lps_unit.flags |= UNIT_OFFLINE; /* set offline */
sim_activate (&lps_unit, lps_rtime); /* schedule printer ready */
lps_sta = LPS_PWROFF;
if (DEBUG_PRS (lps_dev)) fprintf (sim_deb,
">>LPS LIx: Power state is TURNING ON, scheduled time = %d\n",
lps_rtime ); } }
else lps_sta = 0;
else lps_sta = LPS_PWROFF;
dat = dat | lps_sta; /* diag, rtn status */
if (DEBUG_PRS (lps_dev))
fprintf (sim_deb, ">>LPS LIx: Status %06o returned\n", dat);
@ -291,13 +282,10 @@ case ioCTL: /* control clear/set */
if ((lps_unit.buf != '\f') &&
(lps_unit.buf != '\n') &&
(lps_unit.buf != '\r')) { /* normal char */
if ((lps_unit.buf < ' ') || (lps_unit.buf > '_'))
sched = lps_ctime; /* non-printing char */
else { /* printing char */
lps_ccnt = lps_ccnt + 1; /* incr char counter */
if (lps_ccnt % LPS_ZONECNT == 0) /* end of zone? */
sched = lps_ptime; /* print zone */
else sched = lps_ctime; } } /* xfer char */
else sched = lps_ctime; } /* xfer char */
else { /* print cmd */
if (lps_ccnt % LPS_ZONECNT == 0) /* last zone printed? */
sched = lps_ctime; /* yes, so just char time */
@ -328,22 +316,29 @@ int32 c = uptr->buf & 0177;
if (lps_power == LPS_TURNING_ON) { /* printer warmed up? */
lps_power = LPS_ON; /* change state */
lps_restart (uptr, 0, NULL, NULL); /* restart I/O if hung */
if (DEBUG_PRS (lps_dev))
fputs (">>LPS svc: Power state is ON\n", sim_deb);
return SCPE_OK; } /* done */
dev = lps_dib.devno; /* get dev no */
clrCMD (dev); /* clear cmd */
setFSR (dev); /* set flag, fbf */
if (uptr->flags & UNIT_DIAG) { /* diagnostic? */
lps_sta = uptr->buf; /* loop back */
clrCMD (dev); /* clear cmd */
setFSR (dev); /* set flag, fbf */
return SCPE_OK; } /* done */
if ((uptr->flags & UNIT_ATT) == 0) /* real lpt, att? */
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (lps_stopioe, SCPE_UNATT);
else if (uptr->flags & UNIT_OFFLINE) /* offline? */
return IORETURN (lps_stopioe, STOP_OFFLINE);
else if (uptr->flags & UNIT_POWEROFF) /* powered off? */
return IORETURN (lps_stopioe, STOP_PWROFF);
clrCMD (dev); /* clear cmd */
setFSR (dev); /* set flag, fbf */
if (((c < ' ') || (c > '_')) && /* non-printing char? */
(c != '\f') && (c != '\n') && (c != '\r')) {
c = ' '; /* replace with blank */
if (DEBUG_PRS (lps_dev))
fprintf (sim_deb, ">>LPS svc: Character %06o erased\n", c); }
fprintf (sim_deb, ">>LPS svc: Character %06o erased\n", c);
c = ' '; } /* replace with blank */
if (lps_ccnt > LPS_PAGECNT) { /* 81st character? */
fputc ('\r', uptr->fileref); /* return to line start */
uptr->pos = uptr->pos + 1; /* update pos */
@ -379,11 +374,60 @@ lps_set_timing (NULL, lps_timing, NULL, NULL); /* init timing set */
return SCPE_OK;
}
/* Restart I/O routine
If I/O is started via STC, and the printer is powered off, offline,
or out of paper, the CTL and CMD flip-flops will set, a service event
will be scheduled, and the service routine will be entered. If
STOP_IOE is not set, the I/O operation will "hang" at that point
until the printer is powered on, set online, or paper is supplied
(attached).
If a pending operation is "hung" when this routine is called, it is
restarted, which clears CTL and sets FBF and FLG, completing the
original I/O request.
*/
t_stat lps_restart (UNIT *uptr, int32 value, char *cptr, void *desc)
{
if (lps_dib.cmd && lps_dib.ctl && !sim_is_active (uptr))
sim_activate (uptr, 0); /* reschedule I/O */
return SCPE_OK;
}
/* Printer power off */
t_stat lps_poweroff (UNIT *uptr, int32 value, char *cptr, void *desc)
{
lps_power = LPS_OFF; /* change state */
if (DEBUG_PRS (lps_dev)) fputs (">>LPS set: Power state is OFF\n", sim_deb);
return SCPE_OK;
}
/* Printer power on */
t_stat lps_poweron (UNIT *uptr, int32 value, char *cptr, void *desc)
{
if (lps_unit.flags & UNIT_DIAG) { /* diag mode? */
lps_power = LPS_ON; /* no delay */
if (DEBUG_PRS (lps_dev))
fputs (">>LPS set: Power state is ON\n", sim_deb); }
else {
lps_power = LPS_TURNING_ON; /* change state */
lps_unit.flags |= UNIT_OFFLINE; /* set offline */
sim_activate (&lps_unit, lps_rtime); /* schedule ready */
if (DEBUG_PRS (lps_dev)) fprintf (sim_deb,
">>LPS set: Power state is TURNING ON, scheduled time = %d\n",
lps_rtime ); }
return SCPE_OK;
}
/* Attach routine */
t_stat lps_attach (UNIT *uptr, char *cptr)
{
lps_ccnt = lps_lcnt = 0; /* top of form */
lps_restart (uptr, 0, NULL, NULL); /* restart I/O if hung */
return attach_unit (uptr, cptr);
}

View file

@ -25,6 +25,7 @@
lpt 12845B 2607 line printer
19-Nov-04 JDB Added restart when set online, etc.
29-Sep-04 JDB Added SET OFFLINE/ONLINE, POWEROFF/POWERON
Fixed status returns for error conditions
Fixed TOF handling so form remains on line 0
@ -97,6 +98,7 @@ DEVICE lpt_dev;
int32 lptio (int32 inst, int32 IR, int32 dat);
t_stat lpt_svc (UNIT *uptr);
t_stat lpt_reset (DEVICE *dptr);
t_stat lpt_restart (UNIT *uptr, int32 value, char *cptr, void *desc);
t_stat lpt_attach (UNIT *uptr, char *cptr);
/* LPT data structures
@ -128,9 +130,9 @@ REG lpt_reg[] = {
MTAB lpt_mod[] = {
{ UNIT_POWEROFF, UNIT_POWEROFF, "power off", "POWEROFF", NULL },
{ UNIT_POWEROFF, 0, "power on", "POWERON", NULL },
{ UNIT_POWEROFF, 0, "power on", "POWERON", lpt_restart },
{ UNIT_OFFLINE, UNIT_OFFLINE, "offline", "OFFLINE", NULL },
{ UNIT_OFFLINE, 0, "online", "ONLINE", NULL },
{ UNIT_OFFLINE, 0, "online", "ONLINE", lpt_restart },
{ MTAB_XTD | MTAB_VDV, 0, "DEVNO", "DEVNO",
&hp_setdev, &hp_showdev, &lpt_dev },
{ 0 } };
@ -196,9 +198,13 @@ t_stat lpt_svc (UNIT *uptr)
int32 i, skip, chan, dev;
dev = lpt_dib.devno; /* get dev no */
clrCMD (dev); /* clear cmd */
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (lpt_stopioe, SCPE_UNATT);
else if (uptr->flags & UNIT_OFFLINE) /* offline? */
return IORETURN (lpt_stopioe, STOP_OFFLINE);
else if (uptr->flags & UNIT_POWEROFF) /* powered off? */
return IORETURN (lpt_stopioe, STOP_PWROFF);
clrCMD (dev); /* clear cmd */
setFSR (dev); /* set flag, fbf */
if (uptr->buf & LPT_CTL) { /* control word? */
if (uptr->buf & LPT_CHAN) {
@ -237,10 +243,32 @@ sim_cancel (&lpt_unit); /* deactivate unit */
return SCPE_OK;
}
/* Restart I/O routine
If I/O is started via STC, and the printer is powered off, offline,
or out of paper, the CTL and CMD flip-flops will set, a service event
will be scheduled, and the service routine will be entered. If
STOP_IOE is not set, the I/O operation will "hang" at that point
until the printer is powered on, set online, or paper is supplied
(attached).
If a pending operation is "hung" when this routine is called, it is
restarted, which clears CTL and sets FBF and FLG, completing the
original I/O request.
*/
t_stat lpt_restart (UNIT *uptr, int32 value, char *cptr, void *desc)
{
if (lpt_dib.cmd && lpt_dib.ctl && !sim_is_active (uptr))
sim_activate (uptr, 0); /* reschedule I/O */
return SCPE_OK;
}
/* Attach routine */
t_stat lpt_attach (UNIT *uptr, char *cptr)
{
lpt_lcnt = 0; /* top of form */
lpt_restart (uptr, 0, NULL, NULL); /* restart I/O if hung */
return attach_unit (uptr, cptr);
}

View file

@ -133,7 +133,6 @@
#define STA_LOCAL 0000001 /* local (d) */
#define STA_DYN (STA_PE|STA_SEL|STA_TBSY|STA_WLK|STA_LOCAL)
extern uint16 *M;
extern uint32 PC, SR;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
extern int32 sim_switches;
@ -854,12 +853,13 @@ const uint16 ms_rom[IBL_LNT] = {
t_stat msc_boot (int32 unitno, DEVICE *dptr)
{
int32 dev;
extern uint32 saved_AR;
if (unitno != 0) return SCPE_NOFNC; /* only unit 0 */
dev = msd_dib.devno; /* get data chan dev */
if (ibl_copy (ms_rom, dev)) return SCPE_IERR; /* copy boot to memory */
SR = (SR & IBL_OPT) | IBL_MS | (dev << IBL_V_DEV); /* set SR */
if ((sim_switches & SWMASK ('S')) && AR) SR = SR | 1; /* skip? */
if ((sim_switches & SWMASK ('S')) && saved_AR) SR = SR | 1; /* skip? */
return SCPE_OK;
}

View file

@ -115,7 +115,6 @@
#define CLK_V_ERROR 4 /* clock overrun */
#define CLK_ERROR (1 << CLK_V_ERROR)
extern uint16 *M;
extern uint32 PC, SR;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
extern UNIT cpu_unit;

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
19-Nov-04 JDB Added STOP_OFFLINE, STOP_PWROFF messages
25-Sep-04 JDB Added memory protect device
Fixed display of CCA/CCB/CCE instructions
01-Jun-04 RMS Added latent 13037 support
@ -108,7 +109,9 @@ const char *sim_stop_messages[] = {
"Breakpoint",
"Indirect address loop",
"Indirect address interrupt (should not happen!)",
"No connection on interprocessor link" };
"No connection on interprocessor link",
"Device/unit offline",
"Device/unit powered off" };
/* Binary loader

View file

@ -1,6 +1,6 @@
/* i1401_sys.c: IBM 1401 simulator interface
Copyright (c) 1993-2004, Robert M. Supnik
Copyright (c) 1993-2005, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
04-Jan-05 WVS Added address argument support
14-Nov-04 WVS Added data printout support
16-Mar-03 RMS Fixed mnemonic for MCS
03-Jun-02 RMS Added 1311 support
@ -173,7 +174,7 @@ void fprint_addr (FILE *of, t_value *dig)
int32 addr, xa;
extern int32 hun_table[64], ten_table[64], one_table[64];
addr = hun_table[dig[0]] + ten_table[dig[1]] + one_table[dig[2]];
addr = hun_table[dig[0] & CHAR] + ten_table[dig[1]] + one_table[dig[2]];
xa = (addr >> V_INDEX) & M_INDEX;
if (xa) fprintf (of, " %d,%d", addr & ADDRMASK, ((xa - (X1 >> V_INDEX)) / 5) + 1);
else if (addr >= MAXMEMSIZE) fprintf (of, " %d*", addr & ADDRMASK);
@ -246,8 +247,13 @@ for (ilnt = 1; ilnt < sim_emax; ilnt++) if (val[ilnt] & WM) break;
if ((flags & (NOWM | HNOP)) && (ilnt > 7)) ilnt = 7; /* cs, swm, h, nop? */
else if ((op == OP_B) && (ilnt > 4) && (val[4] == BCD_BLANK)) ilnt = 4;
else if ((ilnt > 8) && (op != OP_NOP)) ilnt = 8; /* cap length */
if (((flags & len_table[ilnt]) == 0) && /* invalid lnt, */
(op != OP_NOP)) return dcw (of, op, val); /* not nop? */
if (ilnt == 3) { /* lnt = 3? */
fprintf (of, "DSA"); /* assume DSA */
fprint_addr (of, val); /* print addr */
return -(ilnt - 1); }
if ((((flags & len_table[ilnt]) == 0) && /* invalid lnt, */
(op != OP_NOP)) || /* not nop? */
(opcode[op] == NULL)) return dcw (of, op, val); /* or undef? */
fprintf (of, "%s",opcode[op]); /* print opcode */
if (ilnt > 2) { /* A address? */
if (((flags & IO) || (op == OP_NOP)) && (val[1] == BCD_PERCNT))

View file

@ -25,6 +25,7 @@
mt M46-494 dual density 9-track magtape controller
07-Dec-04 RMS Added read-only file support
25-Apr-03 RMS Revised for extended file support
28-Mar-03 RMS Added multiformat support
28-Feb-03 RMS Revised for magtape library
@ -117,10 +118,10 @@ t_stat mt_map_err (UNIT *uptr, t_stat st);
DIB mt_dib = { d_MT, 0, v_MT, mt_tplte, &mt, NULL };
UNIT mt_unit[] = {
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) } };
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_ROABLE + UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_ROABLE + UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_ROABLE + UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_ROABLE + UNIT_DISABLE, 0) } };
REG mt_reg[] = {
{ HRDATA (STA, mt_sta, 8) },

View file

@ -1,6 +1,6 @@
/* lgp_cpu.c: LGP CPU simulator
Copyright (c) 2004, Robert M. Supnik
Copyright (c) 2004-2005, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,8 @@
cpu LGP-30 [LGP-21] CPU
04-Jan-05 RMS Modified VM pointer setup
The system state for the LGP-30 [LGP-21] is:
A<0:31> accumulator
@ -167,6 +169,7 @@ uint32 shift_in (uint32 a, uint32 dat, uint32 sh4);
extern t_stat op_p (uint32 dev, uint32 ch);
extern t_stat op_i (uint32 dev, uint32 ch, uint32 sh4);
extern void lgp_vm_init (void);
/* CPU data structures
@ -578,6 +581,7 @@ out_strt = 0;
out_done = 0;
lgp21_sov = 0;
delay = 0;
lgp_vm_init ();
pcq_r = find_reg ("CQ", NULL, dptr);
if (pcq_r) pcq_r->qptr = 0;
else return SCPE_IERR;

View file

@ -1,6 +1,6 @@
/* lgp_sys.c: LGP-30 simulator interface
Copyright (c) 2004, Robert M Supnik
Copyright (c) 2004-2005, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -22,6 +22,8 @@
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
04-Jan-05 RMS Modified VM pointer setup
*/
#include "lgp_defs.h"
@ -41,7 +43,6 @@ extern uint32 ts_flag;
extern int32 sim_switches;
extern int32 flex_to_ascii[128], ascii_to_flex[128];
void (*sim_vm_init) (void) = &lgp_init;
extern void (*sim_vm_fprint_addr) (FILE *st, DEVICE *dptr, t_addr addr);
extern t_addr (*sim_vm_parse_addr) (DEVICE *dptr, char *cptr, char **tptr);
@ -221,7 +222,7 @@ else ea = (t_addr) strtotv (cptr, tptr, dptr->aradix);
return ea;
}
void lgp_init (void)
void lgp_vm_init (void)
{
sim_vm_fprint_addr = &lgp_fprint_addr;
sim_vm_parse_addr = &lgp_parse_addr;

View file

@ -25,6 +25,7 @@
cpu PDP-11 CPU
22-Dec-04 RMS Fixed WAIT to work in all modes (from John Dundas)
02-Oct-04 RMS Added model emulation
25-Jan-04 RMS Removed local debug logging support
29-Dec-03 RMS Formalized 18b Qbus support
@ -785,7 +786,7 @@ case 000:
else setTRAP (TRAP_ILL); /* no, ill inst */
break;
case 1: /* WAIT */
if ((cm == MD_KER) && wait_enable) wait_state = 1;
if (wait_enable) wait_state = 1;
break;
case 3: /* BPT */
setTRAP (TRAP_BPT);

View file

@ -25,6 +25,7 @@
tm TM11/TU10 magtape
07-Dec-04 RMS Added read-only file support
30-Sep-04 RMS Revised Unibus interface
25-Jan-04 RMS Revised for device debug support
29-Dec-03 RMS Added 18b Qbus support
@ -188,14 +189,14 @@ DIB tm_dib = { IOBA_TM, IOLN_TM, &tm_rd, &tm_wr,
1, IVCL (TM), VEC_TM, { NULL } };
UNIT tm_unit[] = {
{ UDATA (&tm_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&tm_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&tm_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&tm_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&tm_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&tm_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&tm_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&tm_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) } };
{ UDATA (&tm_svc, UNIT_ATTABLE + UNIT_ROABLE +UNIT_DISABLE, 0) },
{ UDATA (&tm_svc, UNIT_ATTABLE + UNIT_ROABLE +UNIT_DISABLE, 0) },
{ UDATA (&tm_svc, UNIT_ATTABLE + UNIT_ROABLE +UNIT_DISABLE, 0) },
{ UDATA (&tm_svc, UNIT_ATTABLE + UNIT_ROABLE +UNIT_DISABLE, 0) },
{ UDATA (&tm_svc, UNIT_ATTABLE + UNIT_ROABLE +UNIT_DISABLE, 0) },
{ UDATA (&tm_svc, UNIT_ATTABLE + UNIT_ROABLE +UNIT_DISABLE, 0) },
{ UDATA (&tm_svc, UNIT_ATTABLE + UNIT_ROABLE +UNIT_DISABLE, 0) },
{ UDATA (&tm_svc, UNIT_ATTABLE + UNIT_ROABLE +UNIT_DISABLE, 0) } };
REG tm_reg[] = {
{ ORDATA (MTS, tm_sta, 16) },

View file

@ -25,6 +25,7 @@
ts TS11/TSV05 magtape
07-Dec-04 RMS Added read-only file support
30-Sep-04 RMS Revised Unibus interface
25-Jan-04 RMS Revised for device debug support
19-May-03 RMS Revised for new conditional compilation scheme
@ -301,7 +302,7 @@ int32 ts_map_status (t_stat st);
DIB ts_dib = { IOBA_TS, IOLN_TS, &ts_rd, &ts_wr,
1, IVCL (TS), VEC_TS, { NULL } };
UNIT ts_unit = { UDATA (&ts_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) };
UNIT ts_unit = { UDATA (&ts_svc, UNIT_ATTABLE + UNIT_ROABLE + UNIT_DISABLE, 0) };
REG ts_reg[] = {
{ GRDATA (TSSR, tssr, DEV_RDX, 16, 0) },

View file

@ -25,6 +25,7 @@
mt 7 track magnetic tape
07-Dec-04 RMS Added read-only file support
25-Apr-03 RMS Revised for extended file support
28-Mar-03 RMS Added multiformat support
28-Feb-03 RMS Revised for magtape library
@ -114,14 +115,14 @@ static const char bcd_to_sds[64] = {
DIB mt_dib = { CHAN_W, DEV_MT, XFR_MT0, mt_tplt, &mt };
UNIT mt_unit[] = {
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_DISABLE, 0) } };
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_ROABLE +UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_ROABLE +UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_ROABLE +UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_ROABLE +UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_ROABLE +UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_ROABLE +UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_ROABLE +UNIT_DISABLE, 0) },
{ UDATA (&mt_svc, UNIT_ATTABLE + UNIT_ROABLE +UNIT_DISABLE, 0) } };
REG mt_reg[] = {
{ BRDATA (BUF, mtxb, 8, 8, MT_MAXFR) },

View file

@ -52,7 +52,6 @@
#define VAX780_PLANT (0 << 12) /* plant (Salem NH) */
#define VAX780_SN (1234)
#define CON_HLTPIN 0x0200 /* external CPU halt */
#define CON_PWRUP 0x0300 /* powerup code */
#define CON_HLTINS 0x0600 /* HALT instruction */
#define MCHK_RD_F 0x00 /* read fault */
#define MCHK_RD_A 0xF4 /* read abort */
@ -77,7 +76,7 @@
#define TR_MBA1 9
#define NEXUS_HLVL (IPL_HMAX - IPL_HMIN + 1)
#define SCB_NEXUS 0x100 /* nexus intr base */
#define SBI_FAULTS 0xFC000000 /* SBI fault flags - ni */
#define SBI_FAULTS 0xFC000000 /* SBI fault flags */
/* Internal I/O interrupts - relative except for clock and console */
@ -195,7 +194,6 @@
#define VH_MUXES 4 /* max # of DHQ muxes */
#define MT_MAXFR (1 << 16) /* magtape max rec */
#define AUTO_LNT 34 /* autoconfig ranks */
#define DIB_MAX 100 /* max DIBs */
#define DEV_V_UBUS (DEV_V_UF + 0) /* Unibus */
#define DEV_V_MBUS (DEV_V_UF + 1) /* Massbus */

View file

@ -77,7 +77,7 @@
#define MBASR_NFD 0x00040000 /* nx drive - W1C int */
#define MBASR_MCPE 0x00020000 /* ctl perr - ni W1C int */
#define MBASR_ATA 0x00010000 /* attn - W1C int */
#define MBASR_SPE 0x00004000 /* silo par err - ni W1C int */
#define MBASR_SPE 0x00004000 /* silo perr - ni W1C int */
#define MBASR_DTCMP 0x00002000 /* xfr done - W1C int */
#define MBASR_DTABT 0x00001000 /* abort - W1C int */
#define MBASR_DLT 0x00000800 /* dat late - ni W1C abt */
@ -125,8 +125,6 @@
#define MBACMD_OF 0x7
#define MBAMAX_OF 0x8
/* External registers */
#define MBA_CS1 0x00 /* device CSR1 */
@ -180,7 +178,6 @@ extern void WriteL (uint32 pa, int32 val);
static MBACTX *ctxmap[MBA_NUM] = { &massbus[0], &massbus[1] };
static DEVICE *devmap[MBA_NUM] = { &mba0_dev, &mba1_dev };
static DIB *dibmap[MBA_NUM] = { &mba0_dib, &mba1_dib };
/* Massbus register dispatches */
@ -268,7 +265,6 @@ switch (rtype) { /* case on type */
case MBART_INT: /* internal */
ofs = MBA_INTOFS (pa); /* check range */
if (ofs >= MBAMAX_OF) return SCPE_NXM;
switch (ofs) {
case MBACNF_OF: /* CNF */
*val = (mbp->cnf & MBACNF_RD) | MBACNF_CODE;
@ -337,7 +333,6 @@ switch (rtype) { /* case on type */
case MBART_INT: /* internal */
ofs = MBA_INTOFS (pa); /* check range */
if (ofs >= MBAMAX_OF) return SCPE_NXM;
switch (ofs) {
case MBACNF_OF: /* CNF */
mbp->cnf = mbp->cnf & ~(val & MBACNF_W1C);
@ -498,7 +493,7 @@ for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
}
}
}
return 0;
return i;
}
int32 mba_chbufW (uint32 mb, int32 bc, uint16 *buf)
@ -575,7 +570,7 @@ MBACTX *mbp;
if (mb >= MBA_NUM) return 0;
mbp = ctxmap[mb];
return ((0x10000 - (mbp->bc >> MBABC_V_CNT)) & MBABC_WR);
return (((MBABC_WR + 1) - (mbp->bc >> MBABC_V_CNT)) & MBABC_WR);
}
void mba_set_int (uint32 mb)
@ -621,12 +616,14 @@ return;
t_stat mba_reset (DEVICE *dptr)
{
int32 i, mb;
DIB *dibp;
MBACTX *mbp;
for (mb = 0; mb < MBA_NUM; mb++) {
dibp = (DIB *) dptr->ctxt;
if (dibp == NULL) return SCPE_IERR;
mb = dibp->ba - TR_MBA0;
if ((mb < 0) || (mb >= MBA_NUM)) return SCPE_IERR;
mbp = ctxmap[mb];
if (dptr == devmap[mb]) break;
}
mbp->cnf = 0;
mbp->cr = mbp->cr & MBACR_MNT;
mbp->sr = 0;

View file

@ -53,7 +53,6 @@
#define SBISC_RD 0xFFFF0000 /* SBI silo comp */
#define SBISC_WR 0x7FFF0000
#define SBISC_LOCK 0x80000000 /* lock */
#define SBISC_CNT 0x000F0000 /* count */
#define SBIMT_RD 0xFFFFFF00 /* SBI maint */
#define SBIMT_WR 0xFFFFF900
@ -498,8 +497,7 @@ case MT_SBIFS: /* SBIFS */
sbi_fs = sbi_fs & ~(val & SBIFS_W1C);
break;
case MT_SBISC: /* SBISC */
sbi_sc = (sbi_sc & ~SBISC_WR) | (val & SBISC_WR);
if ((val & SBISC_CNT) != SBISC_CNT) sbi_sc = sbi_sc & ~SBISC_LOCK;
sbi_sc = (sbi_sc & ~(SBISC_LOCK|SBISC_WR)) | (val & SBISC_WR);
break;
case MT_SBIMT: /* SBIMT */
sbi_mt = (sbi_mt & ~SBIMT_WR) | (val & SBIMT_WR);

View file

@ -31,8 +31,8 @@
08-Sep-04 RMS Cloned from vax_stddev.c, vax_sysdev.c, and pdp11_rx.c
The console floppy protocol is a guess, because VMS only uses read and write.
Based on triangulation of the boot and full drivers:
The console floppy protocol is based on the description in the 1982 VAX
Architecture Reference Manual:
TXDB<11:8> = 0 -> normal console output
TXDB<11:8> = 1 -> data output to floppy
@ -122,6 +122,11 @@
#define FL_STADDA 0x040
#define FL_STAERR 0x080
#define FL_CPROT 0x905 /* protocol error */
#define FL_MISC 0xF00 /* misc communications */
#define FL_SWDN 0x1 /* software done */
#define FL_BOOT 0x2 /* reboot */
#define FL_CLWS 0x3 /* clear warm start */
#define FL_CLCS 0x4 /* clear cold start */
#define FL_GETFNC(x) (((x) >> FL_V_FNC) & FL_M_FNC)
#define TRACK u3 /* current track */
@ -340,7 +345,7 @@ int32 rxdb_rd (void)
int32 t = tti_buf; /* char + error */
tti_csr = tti_csr & ~CSR_DONE; /* clr done */
tti_buf = tti_buf & 0xFF; /* clr errors */
tti_buf = tti_buf & BMASK; /* clr errors */
tti_int = 0;
return t;
}
@ -635,7 +640,7 @@ todr_reg = (base * 100) + 0x10000000; /* cvt to VAX form */
return SCPE_OK;
}
/* Console write, txdb<11:8> != 1 (console unit) */
/* Console write, txdb<11:8> != 0 (console unit) */
t_stat fl_wr_txdb (int32 data)
{

View file

@ -64,7 +64,8 @@
#define UBA_USEFIE_SR (UBASR_RDTO|UBASR_RDS|UBASR_CRD|UBASR_CXTER| \
UBASR_CXTO|UBASR_DPPE|UBASR_IVMR|UBASR_MRPF)
#define UBA_SUEFIE_SR (UBASR_UBSTO|UBASR_UBTMO)
#define UBA_CNFIE_CR (UBACNF_ADPDN|UBACNF_ADPUP|UBACNF_UBINIT|UBACNF_UBPDN|UBACNF_UBIC)
#define UBA_CNFIE_CR (UBACNF_ADPDN|UBACNF_ADPUP|UBACNF_UBINIT|\
UBACNF_UBPDN|UBACNF_UBIC)
/* Status register */
@ -129,8 +130,6 @@
#define UBADPR_RD 0xC0FFFFFF
#define UBADPR_W1C 0xC0000000
#define UBAMAX_OF 0x020
/* Map registers */
#define UBAMAP_OF 0x200
@ -285,7 +284,6 @@ if (ofs >= UBAMAP_OF) { /* map range */
idx = ofs - UBAMAP_OF;
*val = uba_map[idx] & UBAMAP_RD;
return SCPE_OK; }
if (ofs >= UBAMAX_OF) return SCPE_NXM; /* check range */
switch (ofs) { /* case on offset */
@ -358,7 +356,7 @@ if (ofs >= UBAMAP_OF) { /* map? */
idx = ofs - UBAMAP_OF;
uba_map[idx] = val & UBAMAP_WR;
return SCPE_OK; }
if (ofs >= UBAMAX_OF) return SCPE_NXM; /* check range */
switch (ofs) { /* case on offset */
case UBACNF_OF: /* CNF */

View file

@ -349,7 +349,7 @@ case MATCHC:
Registers if PSL<fpd> = 1:
R[0] = result
R[1] = table address
R[2] = source string length
R[2] = delta-PC/0/source string length
R[3] = source string address
Condition codes:
@ -578,7 +578,6 @@ case DIVP:
NibbleLshift (&src2, 1, 0); /* shift dividend */
NibbleLshift (&dst, 1, 0); /* shift quotient */
} /* end divide loop */
dst.sign = src1.sign ^ src2.sign; /* calculate sign */
} /* end if */
cc = WriteDstr (op[4], op[5], &dst, 0, acc); /* store result */
R[0] = 0;
@ -982,7 +981,7 @@ case EDITPC:
sign = C_SPACE;
}
fill = C_SPACE;
R[0] = R[4] = op[0] & WMASK; /* src len */
R[0] = R[4] = op[0]; /* src len */
R[1] = op[1]; /* src addr */
R[2] = STR_PACK (0, (sign << ED_V_SIGN) | (fill << ED_V_FILL));
/* delta PC, sign, fill */

View file

@ -157,7 +157,7 @@ case 000: /* 00xxxx */
case 003: /* SWAB */
if (dstreg) src = RdRegW (dstspec);
else src = RdMemMW (ea = GeteaW (dstspec));
dst = ((src & 0xFF) << 8) | ((src >> 8) & 0xFF);
dst = ((src & BMASK) << 8) | ((src >> 8) & BMASK);
if (dstreg) WrRegW (dst, dstspec);
else WrMemW (dst, ea);
CC_IIZZ_B ((dst & BMASK));
@ -216,7 +216,7 @@ case 000: /* 00xxxx */
src = RdRegW (srcspec); /* get src reg */
WrMemW (src, (R[6] - 2) & WMASK); /* -(sp) <- r */
R[6] = (R[6] - 2) & WMASK;
if (srcspec != 7) R[srcspec] = PC; /* r <- PC */
if (srcspec != 7) WrRegW (PC, srcspec); /* r <- PC */
CMODE_JUMP (dst); /* PC <- dst */
}
break; /* end JSR */
@ -562,7 +562,8 @@ case 007: /* EIS */
break;
default:
CMODE_FAULT (CMODE_RSVI); } /* end switch EIS */
CMODE_FAULT (CMODE_RSVI); /* end switch EIS */
}
break; /* end case 007 */
/* Opcode 10: branches, traps, SOPs */
@ -627,7 +628,7 @@ case 010:
/* Opcode 10, continued: SOPs */
case 050: /* CLRB */
if (dstreg) R[dstspec] = R[dstspec] & ~BMASK;
if (dstreg) WrRegB (0, dstspec);
else WrMemB (0, GeteaB (dstspec));
cc = CC_Z;
break;

View file

@ -183,7 +183,7 @@ Notes on memory size:
non-zero data, the simulator asks for confirmation. Data in the truncated
portion of memory is lost.
- If the simulator is running VMS, the operating system may have a SYSGEN
parameter set called PHYSICXAL PAGES (viewable from "MCR SYSGEN SHOW
parameter set called PHYSICAL PAGES (viewable from "MCR SYSGEN SHOW
PHYSICALPAGES"). PHYSICALPAGES limits the maximum number of physical pages
of memory the OS will recognize. If it is set to a lower value than the
new memory size of the machine, then only the first PHYSICALPAGES of

View file

@ -68,8 +68,7 @@ typedef struct ufph UFPH;
#define UH_HRND 0x00004000 /* H round */
#define UH_V_NM 127
int32 op_movh (int32 val);
int32 op_mnegh (int32 val);
int32 op_tsth (int32 val);
int32 op_cmph (int32 *hf1, int32 *hf2);
int32 op_cvtih (int32 val, int32 *hf);
int32 op_cvthi (int32 *hf, int32 *flg, int32 opc);
@ -82,7 +81,7 @@ int32 op_mulh (int32 *opnd, int32 *hf);
int32 op_divh (int32 *opnd, int32 *hf);
int32 op_emodh (int32 *opnd, int32 *hflt, int32 *intgr, int32 *flg);
void op_polyh (int32 *opnd, int32 acc);
void h_write_bwl (int32 spec, int32 va, int32 val, int32 lnt, int32 acc);
void h_write_l (int32 spec, int32 va, int32 val, int32 acc);
void h_write_q (int32 spec, int32 va, int32 vl, int32 vh, int32 acc);
void h_write_o (int32 spec, int32 va, int32 *val, int32 acc);
void vax_hadd (UFPH *a, UFPH *b);
@ -104,14 +103,15 @@ void h_normh (UFPH *a);
int32 h_rpackfd (UFPH *a, int32 *rl);
int32 h_rpackg (UFPH *a, int32 *rl);
int32 h_rpackh (UFPH *a, int32 *hflt);
static int32 z_octa[4] = { 0, 0, 0, 0 };
/* Octaword instructions */
int32 op_octa (int32 *opnd, int32 cc, int32 opc, int32 acc, int32 spec, int32 va)
{
int32 r, rh, temp, flg;
int32 z_octa[4] = { 0, 0, 0, 0 };
int32 r_octa[4] = { 0, 0, 0, 0 };
int32 r, rh, temp, flg, rn;
int32 r_octa[4];
switch (opc) {
@ -135,7 +135,7 @@ case PUSHAO:
*/
case MOVAO:
h_write_bwl (spec, va, opnd[0], L_LONG, acc); /* write operand */
h_write_l (spec, va, opnd[0], acc); /* write operand */
CC_IIZP_L (opnd[0]); /* set cc's */
break;
@ -157,7 +157,7 @@ case CLRO:
*/
case TSTH:
r = op_movh (opnd[0]); /* test for -0 */
r = op_tsth (opnd[0]); /* test for 0 */
CC_IIZZ_FP (r); /* set cc's */
break;
@ -174,16 +174,18 @@ case MOVO:
CC_IIZP_O (opnd[0], opnd[1], opnd[2], opnd[3]); /* set cc's */
break;
case MOVH:
if ((opnd[0] = op_movh (opnd[0])) == 0) /* test for -0 */
opnd[1] = opnd[2] = opnd[3] = 0; /* result is 0 */
h_write_o (spec, va, opnd, acc); /* write result */
CC_IIZP_FP (opnd[0]); /* set cc's */
if (r = op_tsth (opnd[0])) /* test for 0 */
h_write_o (spec, va, opnd, acc); /* nz, write result */
else h_write_o (spec, va, z_octa, acc); /* zero, write 0 */
CC_IIZP_FP (r); /* set cc's */
break;
case MNEGH:
if ((opnd[0] = op_mnegh (opnd[0])) == 0) /* test for -0 */
opnd[1] = opnd[2] = opnd[3] = 0; /* result is 0 */
if (r = op_tsth (opnd[0])) { /* test for 0 */
opnd[0] = opnd[0] ^ FPSIGN; /* nz, invert sign */
h_write_o (spec, va, opnd, acc); /* write result */
CC_IIZZ_FP (opnd[0]); /* set cc's */
}
else h_write_o (spec, va, z_octa, acc); /* zero, write 0 */
CC_IIZZ_FP (r); /* set cc's */
break;
/* CMPH
@ -230,19 +232,25 @@ case CVTLH:
case CVTHB:
r = op_cvthi (opnd, &temp, opc) & BMASK; /* convert */
h_write_bwl (spec, va, r, L_BYTE, acc); /* write result */
if (spec > (GRN | nPC)) Write (va, r, L_BYTE, WA);
else {
rn = spec & 0xF;
R[rn] = (R[rn] & ~BMASK) | r; }
CC_IIZZ_B (r); /* set cc's */
cc = cc | temp; /* or in V */
break;
case CVTHW:
r = op_cvthi (opnd, &temp, opc) & WMASK; /* convert */
h_write_bwl (spec, va, r, L_WORD, acc); /* write result */
if (spec > (GRN | nPC)) Write (va, r, L_WORD, WA);
else {
rn = spec & 0xF;
R[rn] = (R[rn] & ~WMASK) | r; }
CC_IIZZ_W (r); /* set cc's */
cc = cc | temp; /* or in V */
break;
case CVTHL: case CVTRHL:
r = op_cvthi (opnd, &temp, opc) & LMASK; /* convert */
h_write_bwl (spec, va, r, L_LONG, acc); /* write result */
h_write_l (spec, va, r, acc); /* write result */
CC_IIZZ_L (r); /* set cc's */
cc = cc | temp; /* or in V */
break;
@ -290,7 +298,7 @@ case CVTGH:
case CVTHF:
r = op_cvthfd (opnd, NULL); /* convert */
h_write_bwl (spec, va, r, L_LONG, acc); /* write result */
h_write_l (spec, va, r, acc); /* write result */
CC_IIZZ_FP (r); /* set cc's */
break;
case CVTHD:
@ -402,25 +410,18 @@ default:
return cc;
}
/* Move/test/move negated h_floating
/* Test h_floating
Note that only the high 32b is processed.
If the high 32b is not zero, the rest of the fraction is unchanged. */
int32 op_movh (int32 val)
int32 op_tsth (int32 val)
{
if (val & H_EXP) return val; /* non-zero? */
if (val & FPSIGN) RSVD_OPND_FAULT; /* reserved? */
return 0; /* clean 0 */
}
int32 op_mnegh (int32 val)
{
if (val & H_EXP) return (val ^ FPSIGN); /* non-zero? */
if (val & FPSIGN) RSVD_OPND_FAULT; /* reserved? */
return 0; /* clean 0 */
}
/* Compare h_floating */
int32 op_cmph (int32 *hf1, int32 *hf2)
@ -620,7 +621,7 @@ UFPH a, b;
h_unpackh (&opnd[0], &a); /* unpack operands */
h_unpackh (&opnd[5], &b);
a.frac.f3 = a.frac.f3 | opnd[4]; /* extend src1 */
a.frac.f0 = a.frac.f0 | opnd[4]; /* extend src1 */
vax_hmul (&a, &b); /* multiply */
vax_hmod (&a, intgr, flg); /* sep int & frac */
return h_rpackh (&a, hflt); /* round and pack frac */
@ -984,8 +985,8 @@ int32 h_rpackfd (UFPH *r, int32 *rh)
static UQP f_round = { 0, 0, 0, UH_FRND };
static UQP d_round = { 0, 0, UH_DRND, 0 };
if ((r->frac.f0 == 0) && (r->frac.f1 == 0) && /* if fraction = 0 */
(r->frac.f2 == 0) && (r->frac.f3 == 0)) return 0;
if (rh) *rh = 0; /* assume 0 */
if (r->exp == 0) return 0; /* exp = 0? done */
qp_add (&r->frac, rh? &d_round: &f_round);
if ((r->frac.f3 & UH_NM_H) == 0) { /* carry out? */
qp_rsh (&r->frac, 1); /* renormalize */
@ -999,7 +1000,7 @@ if (r->exp <= 0) { /* underflow? */
qp_rsh (&r->frac, FD_GUARD); /* remove guard */
if (rh) *rh = WORDSWAP (r->frac.f2);
return r->sign | (r->exp << FD_V_EXP) |
(WORDSWAP (r->frac.f0) & ~(FD_HB | FPSIGN | FD_EXP));
(WORDSWAP (r->frac.f3) & ~(FD_HB | FPSIGN | FD_EXP));
}
int32 h_rpackg (UFPH *r, int32 *rh)
@ -1007,8 +1008,7 @@ int32 h_rpackg (UFPH *r, int32 *rh)
static UQP g_round = { 0, 0, UH_GRND, 0 };
*rh = 0; /* assume 0 */
if ((r->frac.f0 == 0) && (r->frac.f1 == 0) && /* if fraction = 0 */
(r->frac.f2 == 0) && (r->frac.f3 == 0)) return 0;
if (r->exp == 0) return 0; /* exp = 0? done */
qp_add (&r->frac, &g_round); /* round */
if ((r->frac.f3 & UH_NM_H) == 0) { /* carry out? */
qp_rsh (&r->frac, 1); /* renormalize */
@ -1030,8 +1030,7 @@ int32 h_rpackh (UFPH *r, int32 *hflt)
static UQP h_round = { UH_HRND, 0, 0, 0 };
hflt[0] = hflt[1] = hflt[2] = hflt[3] = 0; /* assume 0 */
if ((r->frac.f0 == 0) && (r->frac.f1 == 0) && /* if fraction = 0 */
(r->frac.f2 == 0) && (r->frac.f3 == 0)) return 0;
if (r->exp == 0) return 0; /* exp = 0? done */
qp_add (&r->frac, &h_round); /* round */
if ((r->frac.f3 & UH_NM_H) == 0) { /* carry out? */
qp_rsh (&r->frac, 1); /* renormalize */
@ -1051,15 +1050,10 @@ hflt[3] = WORDSWAP (r->frac.f0);
return hflt[0];
}
void h_write_bwl (int32 spec, int32 va, int32 val, int32 lnt, int32 acc)
void h_write_l (int32 spec, int32 va, int32 val, int32 acc)
{
int32 rn;
if (spec >= (GRN | nPC)) Write (va, val, lnt, WA);
else { rn = spec & 0xF;
if (lnt == L_BYTE) R[rn] = (R[rn] & ~BMASK) | val;
else if (lnt == L_WORD) R[rn] = (R[rn] & ~WMASK) | val;
else R[rn] = val; }
if (spec > (GRN | nPC)) Write (va, val, L_LONG, WA);
else R[spec & 0xF] = val;
return;
}

View file

@ -226,7 +226,6 @@
#define VH_MUXES 4 /* max # of DHQ muxes */
#define MT_MAXFR (1 << 16) /* magtape max rec */
#define AUTO_LNT 34 /* autoconfig ranks */
#define DIB_MAX 100 /* max DIBs */
#define DEV_V_UBUS (DEV_V_UF + 0) /* Unibus */
#define DEV_V_QBUS (DEV_V_UF + 1) /* Qbus */

10
scp.c
View file

@ -23,6 +23,8 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
26-Dec-04 RMS Qualified SAVE examine, RESTORE deposit with SIM_SW_REST
10-Nov-04 JDB Fixed logging of errors from cmds in "do" file
05-Nov-04 RMS Moved SET/SHOW DEBUG under CONSOLE hierarchy
Renamed unit OFFLINE/ONLINE to DISABLED/ENABLED (from Dave Bryan)
Revised to flush output files after simulation stop (from Dave Bryan)
@ -734,8 +736,10 @@ do { cptr = read_line (cbuf, CBUFSIZE, fpin); /* get cmd line */
if (cmdp = find_cmd (gbuf)) /* lookup command */
stat = cmdp->action (cmdp->arg, cptr); /* if found, exec */
else stat = SCPE_UNK;
if (stat >= SCPE_BASE) /* error? */
if (stat >= SCPE_BASE) { /* error? */
printf ("%s\n", scp_error_messages[stat - SCPE_BASE]);
if (sim_log) fprintf (sim_log, "%s\n",
scp_error_messages[stat - SCPE_BASE]); }
if (sim_vm_post != NULL) (*sim_vm_post) (TRUE);
} while (stat != SCPE_EXIT);
@ -1798,7 +1802,7 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru devices */
zeroflg = TRUE;
for (l = 0; (l < SRBSIZ) && (k < high); l++,
k = k + (dptr->aincr)) { /* check for 0 block */
r = dptr->examine (&val, k, uptr, 0);
r = dptr->examine (&val, k, uptr, SIM_SW_REST);
if (r != SCPE_OK) return r;
if (val) zeroflg = FALSE;
SZ_STORE (sz, val, mbuf, l);
@ -1963,7 +1967,7 @@ for ( ;; ) { /* device loop */
for (j = 0; j < limit; j++, k = k + (dptr->aincr)) {
if (blkcnt < 0) val = 0; /* compressed? */
else SZ_LOAD (sz, val, mbuf, j);/* saved value */
r = dptr->deposit (val, k, uptr, 0);
r = dptr->deposit (val, k, uptr, SIM_SW_REST);
if (r != SCPE_OK) return r;
} /* end for j */
} /* end for k */

View file

@ -1,6 +1,6 @@
/* sim_rev.h: simulator revisions and current rev level
Copyright (c) 1993-2004, Robert M Supnik
Copyright (c) 1993-2005, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -29,13 +29,60 @@
#define SIM_MAJOR 3
#define SIM_MINOR 3
#define SIM_PATCH 0
#define SIM_PATCH 1
/* V3.3 revision history
patch date module(s) and fix(es)
0 tbd scp.c:
1 05-Jan-05 h316_cpu.c: fixed bug in DIV
h316_stddev.c:
- fixed bug in SKS '104 (reported by Philipp Hachtmann)
- fixed bug in SKS '504
- adder reader/punch ASCII file support
- added Teletype reader/punch support
h316_dp.c: fixed bug in skip on !seeking
h316_mt.c: fixed bug in DMA/DMC support
h316_lp.c: fixed bug in DMA/DMC support
hp2100_cpu.c:
- fixed DMA reset to clear alternate CTL flop (from Dave Bryan)
- fixed DMA reset to not clear control words (from Dave Bryan)
- fixed SBS, CBS, TBS to do virtual reads
- separated A/B from M[0/1], for DMA IO (from Dave Bryan)
- added SET CPU 21MX-M, 21MX-E (from Dave Brian)
- disabled TIMER/EXECUTE/DIAG instructions for 21MX-M (from Dave Bryan)
- added post-processor to maintain T/M consistency (from Dave Bryan)
hp2100_ds.c: first release
hp2100_lps.c (all changes from Dave Bryan)
- added restart when set online, etc.
- fixed col count for non-printing chars
hp2100_lpt.c (all changes from Dave Bryan)
- added restart when set online, etc.
hp2100_sys.c (all changes from Dave Bryan):
- added STOP_OFFLINE, STOP_PWROFF messages
i1401_sys.c: added address argument support (from Van Snyder)
id_mt.c: added read-only file support
lgp_cpu.c, lgp_sys.c: modified VM pointer setup
pdp11_cpu.c: fixed WAIT to work in all modes (from John Dundas)
pdp11_tm.c, pdp11_ts.c: added read-only file support
sds_mt.c: added read-only file support
0 23-Nov-04 scp.c:
- added reset_all_p (powerup)
- fixed comma-separated SET options (from Dave Bryan)
- changed ONLINE/OFFLINE to ENABLED/DISABLED (from Dave Bryan)