1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-02-28 17:09:15 +00:00
Files
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

567 lines
15 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TITLE RDREG -- Read and interpret Massbus registers
SUBTTL G.M. Uhler/GMU
;This program asks the user for an RH20 device code, an optional drive
;select unit number, and a CPU number if on a multi-CPU (TOPS-10) system and
;reads and interprets the massbus registers of the specified device.
;The program is assembled with a separate universal file, DEFS, that
;defines macros that give the massbus registers to interpret and the
;definitions of bits and fields in each register. In this manner,
;only the UNIVERSAL file need be changed to change the type of device
;being interpreted. The program is assembled for either TOPS-10 or TOPS-20
;by changing the definition of the parameter TOPS in the universal file
;RDRMAC. This need be done only once when the program is moved to a new
;operating system.
;Copyright (C) 1980,1981,1982,1983 by
;Digital Equipment Corporation, Maynard, Mass.
;
;
;This software is furnished under a license and may be used and copied
;only in accordance with the terms of such license and with the
;inclusion of the above copyright notice. This software or any other
;copies thereof may not be provided or otherwise made available to any
;other person. No title to and ownership of the software is hereby
;transferred.
;
;The information in this software is subject to change without notice
;and should not be construed as a commitment by Digital Equipment
;Corporation.
;
;Digital assumes no responsibility for the use or reliability of its
;software on equipment which is not supplied by Digital.
SUBTTL Assembly directives
SEARCH RDRMAC ;Get the monitor specific definitions
SEARCH DEFS ;Get the Massbus register definitions
IF TOPS-10,<
SEARCH JOBDAT,MACTEN,UUOSYM
.REQUIRE REL:SCAN
>
IF TOPS-20,<
SEARCH MONSYM,MACSYM
>
.DIRECTIVE .XTABM,FLBLST
SALL
RDRVER==1 ;Major version
RDRMIN==0 ;Minor version
RDREDT==6 ;Edit number
RDRWHO==0 ;Who edited
;Define the version number information for TOPS-10 and setup the program
;so that it's running as a sharable high segment.
IF TOPS-10,<
LOC .JBVER
VRSN. (RDR)
RELOC
TWOSEG
RELOC 400000
>
;Define the entry vector for TOPS-20
IF TOPS-20,<
ENTVEC: JRST RDREG ;Start instruction
JRST RDREG ;Restart instruction
FLD(RDRVER,VI%MAJ)!FLD(RDRMIN,VI%MIN)!FLD(RDREDT,VI%EDN)!FLD(RDRWHO,VI%WHO)
;Version number
ENTLEN==.-ENTVEC ;Length of the entry vector
> ;End IF TOPS-20
SUBTTL Parameter definitions
;Miscelaneous definitions
PDLLEN==50 ;Length of stack
DRAES==1B9 ;Disable register access error interrupt
.DXDTR==06B5 ;Drive type register
.FTBIT==1 ;Field type is bit
.FTVAL==2 ;Field type is value
.FTNVL==3 ;Field type is value (negative number)
OPDEF XCONI[700240,,0] ;Because CONI is a macro also
SUBTTL Program initialization
RDREG: JFCL ;No CCL entry
RESET ;Clear the world
MOVE P,[IOWD PDLLEN,PDL] ;Setup a PDL
IF TOPS-10,<
MOVEI T1,0 ;Force .TCHAR in SCAN to
CALL .TYOCH## ; do an OUTCHR
> ;End IF TOPS-10
CALL ASKDVC ;Get the device code
JRST BADDVC ;Bad device code
CAIL N,540 ;Range check the
CAILE N,574 ; RH20 device code for legality
CAIA ;Illegal
TRNE N,3 ;And must be only 7 bits
JRST BADDVC ;Bad device code
LSH N,-2 ;Convert to 7 bit form
DPB N,[POINT 7,DODATO,9] ;Store device code in DATAO
DPB N,[POINT 7,DODATI,9] ;Store device code in DATAI
DPB N,[POINT 7,DOCONI,9] ;Store device code in CONI
MOVEI N,0 ;Assume no unit number required
IFN FTDSEL,<
CALL ASKUNI ;Ask for unit number
JRST BADUNI ;Bad unit number
JUMPL N,BADUNI ;Range check the
CAILE N,7 ; drive select value
JRST BADUNI ;Go if error
> ;End IFN FTDSEL
HRLZM N,DRVSEL ;Save the drive select value
IF TOPS-10,<
MOVX T1,%CNST2 ;GETTAB arg to get CNFST2
GETTAB T1, ;Get it
HALT . ;Can't happen
TXNE T1,ST%LSC ;Low seg cached (i.e. only 1 CPU)?
JRST RDREG0 ;Yes, don't ask about CPU number
MOVEI T1,0 ;No arg for .QSCAN
CALL .QSCAN## ;Initialize input line
HRROI T1,[ASCIZ/CPU number: /]
CALL TSTRG ;Prompt the user
CALL OCTNW ;Get the number
CAIL N,0 ;Range check the CPU number
CAILE N,5 ;...
JRST BADCPU ;If illegal
MOVX T1,SP.CR0 ;Get bit for CPU0
LSH T1,(N) ;Shift by value of CPU
HRLI T1,.STCPU ;Function for SET CPU ONLY CPUn
SETUUO T1, ;Restrict execution to that CPU
JRST NOSCPU ;Failed
RDREG0:
> ;End IF TOPS-10
USRIOT ;Get USRIOT privs from monitor
JRST NOTRPS ;Request failed
CALL CHKDTR ;See if drive type is one we know about
JRST BADDTR ;No, tell him
HRROI T1,[ASCIZ/
Rg Name Contents Text
-- ---- -------------- ----------------------------------------
/]
CALL TSTRG ;Type the header
SUBTTL Register read and print logic
MOVSI P1,-REGTBL ;Get AOBJN pointer to register table
XCT DOCONI ;Get the CONI
JRST RDREG2 ;Skip the rest for the CONI
RDREG1: MOVE T1,DRVSEL ;Get drive select
TXO T1,DRAES ;Set DRAES
HLRZ T2,REGTAB(P1) ;Get register to read from table
DPB T2,[POINT 6,T1,5] ;Store in DATAO word
XCT DODATO ;Setup the preparation register
IMULI T1,1 ;Stall
IMULI T1,1 ;...
XCT DODATI ;Read the value
LDB T3,[POINT 6,T1,5] ;Get register select back
CAIE T3,(T2) ;Same as what we asked for?
JRST RDREG1 ;No, took an interrupt at the wrong time
RDREG2: MOVEM T1,MBRTAB(P1) ;Store in the table
AOBJN P1,RDREG1 ;Loop for all elements in the table
MOVSI P1,-REGTBL ;Build the AOBJN pointer again
HRROI T1,[ASCIZ/ /] ;No register number to print for CONI
CALL TSTRG ; so don't try
JRST RDREG4 ;Join common processing
RDREG3: HLRZ T1,REGTAB(P1) ;Get register back
CALL .TOCT2 ;Type as 2 digit octal number
RDREG4: CALL TSPAC ;Add a space separator
HRRZ P3,REGTAB(P1) ;Get address of block for this register
MOVE T2,0(P3) ;Get SIXBIT name of register
CALL .T6ALL ;Type as full SIXBIT name
CALL TSPAC ;Add a space separator
MOVE T2,MBRTAB(P1) ;Get the octal value
CALL .T12DG ;Type as 12 octal digits
MOVEI C," " ;Make the separator a space
RDREG5: SKIPN T1,1(P3) ;Any more fields left to do?
JRST RDREG9 ;No
SKIPL 2(P3) ;This field valid for all types?
CAMN DTR,2(P3) ;No, is it legal for this one?
CAIA ;Yes, continue
JRST RDREG8 ;No, skip it
LDB T1,T1 ;Get the field from P2
HLRZ T2,3(P3) ;Get the type of field
CAIN T2,.FTBIT ;Is it a bit?
JUMPE T1,RDREG8 ;Yes, don't print if it's off
PUSH P,T1 ;Save the value
MOVE T1,C ;Move the separator to T1
CALL TCHAR ;Type the separator
HRRO T1,3(P3) ;Get the string for this field
CALL TSTRG ;Type it
CAIE T2,.FTVAL ;This a value field?
CAIN T2,.FTNVL ; or a negative value field?
SKIPA T1,["="] ;Yes, get the separator
JRST RDREG7 ;No, continue
CALL TCHAR ;Print it
SKIPE T1,0(P) ;Get the value back but don't negate if 0
CAIE T2,.FTNVL ;Is it a negative value field?
JRST RDREG6 ;No, just print as-is
SETOM T2 ;Get a full mask of ones
LDB T3,[POINT 6,1(P3),11] ;Get the size of the field
LSH T2,(T3) ;Shift the ones mask that much
IOR T1,T2 ;Make it a full 36 bit negative number
MOVNS T1 ;Negate it
RDREG6: CALL TOCTW ;Type in octal
RDREG7: POP P,(P) ;Flush the stack
MOVEI C,"," ;Change the separator
RDREG8: ADDI P3,3 ;Step block pointer by length of field
JRST RDREG5 ; and loop for next field
RDREG9: HRROI T1,[ASCIZ/
/] ;Get a CRLF
CALL TSTRG ;End the line
AOBJN P1,RDREG3 ;Loop for all registers
RESET ;Clear the world
MONRT. ;Exit quietly
JRST RDREG ;Resart if CONTINUE
SUBTTL Error processing
BADDVC: SKIPA T1,[-1,,[ASCIZ/
?Illegal RH20 device code
/]]
NOTRPS: HRROI T1,[ASCIZ/
?Failed to get USRIOT privilegs
/]
CALL TSTRG
EXIT
IF TOPS-10,<
BADCPU: SKIPA T1,[-1,,[ASCIZ/
?Illegal CPU number
/]]
NOSCPU: HRROI T1,[ASCIZ/
?Unable to restrict execution to specified CPU
/]
CALL TSTRG
EXIT
> ;End IF TOPS-10
IFN FTDSEL,<
BADUNI: SKIPA T1,[-1,,[ASCIZ/
?Illegal unit number
/]]
> ;End IFN FTDSEL
BADDTR: HRROI T1,[ASCIZ/
?Drive type register does not match known values
/]
CALL TSTRG
EXIT
SUBTTL Subroutines
;Routine to print a number left-padded to a least size two with spaces.
;Call:
; T1/Number
; CALL .TOCT2
;Return CPOPJ always
.TOCT2: CAILE T1,7 ;One digit?
PJRST TOCTW ;No, print as-is
PUSH P,T1 ;Save the number
CALL TSPAC ;Type a space
POP P,T1 ;Restore the number
PJRST TOCTW ;Type it
;Routine to print all 6 characters of a SIXBIT name.
;Call:
; T2/SIXBIT word
; CALL .T6ALL
;Return CPOPJ always
.T6ALL: MOVEI T3,6 ;Setup loop count
.T6AL1: LSHC T1,^D36 ;Move to T1, clear T2
LSHC T1,-^D30 ;Keep just one character in T1
ADDI T1,"A"-'A' ;Convert to ASCII
CALL TCHAR ;Type it
SOJG T3,.T6AL1 ;Loop for all six
.HELPR::RET ;Return
;Routine to print a number as six octal digits separated by commas.
;Call:
; T2/Number
; CALL .T12DG
;Return CPOPJ always
.T12DG: PUSH P,T2 ;Save the number
CALL .T12D1 ;Type the left half
HRROI T1,[ASCIZ/,,/] ;Separate the two halves
CALL TSTRG ; by commas
POP P,T2 ;Restore the number
HRLZS T2 ;Keep only right half
.T12D1: MOVEI T3,6 ;Get a loop count
.T12D2: LSHC T1,^D36 ;Move number to T1, clear T2
LSHC T1,-^D33 ;Keep only 3 bits
ADDI T1,"0" ;Convert to ASCII
CALL TCHAR ;Type it
SOJG T3,.T12D2 ;Loop for all
RET ;Return
;Routine to read the drive type register from the specified drive
;and check it against the table of the ones we know about.
;Call:
; CALL CHKDTR
;Return CPOPJ if no match
; CPOPJ1 if match with DTR set to the index
CHKDTR: MOVX T1,.DXDTR!DRAES ;Get drive type register
IOR T1,DRVSEL ;Include drive select field
XCT DODATO ;Setup the preparation register
IMULI T1,1 ;Stall
IMULI T1,1 ;...
XCT DODATI ;Read the value
LDB DTR,[POINT 6,T1,5] ;Get the register select field
CAIE DTR,<.DXDTR_-^D30> ;Was it the register we wanted?
JRST CHKDTR ;No, try again
ANDI T1,77 ;Isolate just the drive type
MOVSI DTR,-DTRTBL ;Build AOBJN pointer to table
CHKDT1: CAME T1,DTRTAB(DTR) ;Find a match?
AOBJN DTR,CHKDT1 ;No, loop for all
JUMPGE DTR,.POPJ ;Return error if no match
TLZ DTR,-1 ;Clear the LH
.POPJ1: AOS 0(P) ;Give skip return
.POPJ: RET ;Return
;Define the table of drive types that we know about.
DEFINE DTRTYP(A,B),<
EXP A
.DT'B==.-DTRTAB-1
>
DTRTAB: DRVTYP
DTRTBL==.-DTRTAB
SUBTTL TOPS-10 specific support routines
;The following equivalences define the local routines in terms of routines
;in SCAN for TOPS-10.
IF TOPS-10,<
TCHAR==.TCHAR## ;Type a character
TSTRG==.TSTRG## ;Type a string
OCTNW==.OCTNW## ;Input an octal number
TSPAC==.TSPAC## ;Type a space
TOCTW==.TOCTW## ;Type an octal number
;Routine to ask the user for the RH20 device code.
;Call:
; CALL ASKDVC
;Return CPOPJ if error
; CPOPJ1 with number in N
ASKDVC: MOVEI T1,0 ;No arg for .QSCAN
CALL .QSCAN## ;Initialize input line
HRROI T1,[ASCIZ/
RH20 device code: /]
CALL TSTRG ;Prompt the user
CALL OCTNW ;Get the number
RETSKP ;Give skip return
IFN FTDSEL,<
;Routine to ask the user for the massbus unit number.
;Call:
; CALL ASKUNI
;Return CPOPJ if error
CPOPJ1 with number in N
ASKUNI: MOVEI T1,0 ;No arg for .QSCAN
CALL .QSCAN## ;Initialize input line
HRROI T1,[ASCIZ/Unit number (drive select): /]
CALL TSTRG ;Prompt the user
CALL OCTNW ;Get the number
RETSKP ;Give skip return
> ;End IFN FTDSEL
> ;End IF TOPS-10
SUBTTL TOPS-20 specific support routines
IF TOPS-20,<
;Routine to print a space character.
;Call:
; CALL TSPAC
;Return CPOPJ always
TSPAC: HRROI T1,[ASCIZ/ /] ;Get the space
;; PJRST TSTRG ;Fall into TSTRG
;Routine to print a string.
;Call:
; T1/Byte pointer to string
; CALL TSTRG
;Return CPOPJ always
TSTRG: PSOUT ;Output the string
RET ;Return
;Routine to print a character.
;Call:
; T1/Character to print
; CALL TCHAR
;Return CPOPJ always
;Preserves all but T1
TCHAR: PUSH P,T2 ;Save T2
LSHC T1,-^D36 ;Move character to T2, clear rest of word
LSHC T1,^D36-^D7 ;Left justify character in T2
HRROI T1,T2 ;Get a byte pointer to the character
PSOUT ;Output it
POP P,T2 ;Restore T2
RET ;Return
;Routine to print an octal number.
;Call:
; T1/number to print
; CALL TOCTW
;Return CPOPJ always
;Destroys T1, T2, T3
TOCTW: MOVE T2,T1 ;Copy number to T2
MOVX T1,.PRIOU ;Destination is primary output device
MOVX T3,FLD(^D8,NO%RDX) ;Radix is octal
NOUT ;Output the number
HALT . ;Shouldn't happen
RET ;Return
;Routine to ask the user for the RH20 device code.
;Call:
; CALL ASKDVC
;Return CPOPJ if error
; CPOPJ1 with number in N
ASKDVC: HRROI T1,[ASCIZ/
RH20 device code: /]
PJRST ASKNUM
IFN FTDSEL,<
;Routine to ask the user for the massbus unit number.
;Call:
; CALL ASKUNI
;Return CPOPJ if error
CPOPJ1 with number in N
ASKUNI: HRROI T1,[ASCIZ/Unit number (drive select): /]
PJRST ASKNUM
> ;End IFN FTDSEL
;Routine to ask the user for an octal number.
;Call:
; T1/Byte pointer to prompt string
; CALL ASKNUM
;Return CPOPJ if error
; CPOPJ1 with number in N
ASKNUM: MOVE T3,T1 ;Copy byte pointer to T3 for RDTTY
PSOUT ;Prompt the user
SETZM NUMBUF ;Clear first word of NUMBUF
MOVE T1,[NUMBUF,,NUMBUF+1] ;Setup to clear it all
BLT T1,NUMBUF+NUMBLN-1 ;Clear it all
HRROI T1,NUMBUF ;Get byte pointer to NUMBUF
MOVEI T2,NUMBLN*5 ;Get length of buffer in bytes
RDTTY ;Read the string from the user
RET ;Failed
HRROI T1,NUMBUF ;Get byte pointer to NUMBUF again
MOVEI T3,^D8 ;Radix is octal
NIN ;Read the number
RET ;Failed
MOVE N,T2 ;Return the number in N
ILDB T2,T1 ;Get next byte
JUMPE T2,.POPJ1 ;Give skip return if end of line
RET ;Else error
> ;End IF TOPS-20
SUBTTL Generate the tables from the macros
;Define a macro to generate byte pointers from the mask in the
;FIELDS macro definition. Stupid MACRO chokes on the one in MACTEN
;unless the argument to the POS macro is symbolic.
DEFINE POINTR(LOC,MASK),<
POSN==POS(<MASK>)
SIZ==WID(<MASK>)
POINT SIZ,LOC,POSN
>
;Define the first-level table that gives the registers that we want to
;read and the address of the block describing the fields in that register.
DEFINE XX(A,B),<
XWD A,.'B
>
REGTAB: REGS
REGTBL==.-REGTAB
;Now, for each register defined in the REGTAB table, define another
;table giving its SIXBIT mnemonic and the fields that we want to
;interpret in the register.
DEFINE XX(A,B),<
.'B: SIXBIT/B/
B
EXP 0
>
DEFINE FIELDS(A,B,C,D),<
IFIDN <C>,<BIT>,<..XX==.FTBIT>
IFIDN <C>,<VAL>,<..XX==.FTVAL>
IFIDN <C>,<NVAL>,<..XX==.FTNVL>
IFIDN <D>,<ALL>,<..YY==-1>
IFDIF <D>,<ALL>,<..YY==.DT'D>
POINTR MBRTAB(P1),A
EXP ..YY
XWD ..XX,[ASCIZ\B\]
>
REGS
SUBTTL Low segment data locations
XLIST ;Literals under XLIST
LIT
LIST
IF TOPS-10,<
RELOC
>
DODATO: DATAO 0,T1 ;Device code patched in
DODATI: DATAI 0,T1 ;Ditto
DOCONI: XCONI 0,T1 ;Ditto
DRVSEL: BLOCK 1 ;Drive select value in bits 15-17
MBRTAB: BLOCK REGTBL ;Registers stored here
PDL: BLOCK PDLLEN ;Push down list
IF TOPS-20,<
NUMBUF: BLOCK 2 ;Storage for numbers read in
NUMBLN==.-NUMBUF ;Length of buffer
> ;End IF TOPS-20
IF TOPS-10,<
END RDREG
> ;End IF TOPS-10
IF TOPS-20,<
END <ENTLEN,,ENTVEC>
> ;End IF TOPS-20