1
0
mirror of https://github.com/PDP-10/its.git synced 2026-02-05 16:14:50 +00:00

Added support for SYSMSG

This commit is contained in:
Eric Swenson
2016-12-03 15:56:57 -08:00
parent 1f4f688067
commit a305421ff8
7 changed files with 1102 additions and 0 deletions

99
src/_mail_/bboard.info Normal file
View File

@@ -0,0 +1,99 @@

Node: Policy, Previous: (INFO;SYSMSG)Top, Up: (INFO;SYSMSG)Top, Next: (INFO;SYSMSG)Sending
(The above lines make this file accessible through :INFO. Please leave
them alone.)
These guidelines about where to send which system-wide messages are the
consensus of opinion of AI and LCS staff, based on years of experience of
what kinds of messages people send. Since these staff people are the
official MIT users of the computers the messages are sent on, everyone who
sends a system-wide message -- this means YOU -- should follow the
guidelines.
System-wide messages fall into two categories: System Messages (sysmsgs)
and Bulletin Board messages (BBoard). Sysmsgs can be split into further
categories according to which computers should receive them.
The sysmsg addresses are for messages of general interest only. These
include official Lab announcments, listings of Lab seminars, machine
maintenance schedules, announcements about the Dover, questions of GENERAL
interest to computer scientists, and similar things.
All other messages intended for system-wide distribution, including
requests for information, job offers, housing searches, political
pronouncements, and other material of that nature, should go to the BBoard.
Messages relating to "personal profit", such as messages offering household
goods for sale, are frowned upon by the DCA (they run the ARPANET), but if
you can't restrain yourself from sending such a message, it should also go
to the BBoard.
Good relations among users of the Labs' computers rely in part on people
not being inundated with junk mail; system messages which go to
inappropriate addresses are junk mail. Please think before you send your
system-wide messages, and use consideration and discretion in addressing
them.
What follows is a list of addresses with descriptions of which machines
they direct messages to. Send your message to the correct address at any
ITS, e.g. *MAC@ML, to make it go where you want it to. Send to the address
at only ONE ITS (which one doesn't matter -- *MIT@MC = *MIT@AI, and so
forth), or people will see many duplicates of your message, which can only
make them angry at you.
*MAC The right address for reaching all AI and LCS members who
use computers. Use this, not *ITS or *TENS, for things
like Lab seminar info. This list now includes all four
ITSs, OZ, XX, HT-VAX, and the RTS VAX; as the
Labs acquire more machines that can receive mail, they will
be added to *MAC.
*MIT Everywhere at MIT that can hear -- all of *MAC, plus CIPG,
DSPG, EE, Multics, also an address at CMU so that lonely
former MIT people out there can see what's going on. (As
more mail-server machines are added to the ChaosNet, they
will join this list.) Use this address for messages of
general interest to the MIT community, like Dover info
(which even Multics can use).
BBOARD These are the same address; use either. Unless your
*BBOARD message is important to most of the people gathered in one
of the above or below addresses (see the beginning of this
file for specifications of "important"), send it here.
This list includes all the *MIT sites, but users can choose
whether to read these messages.
Unless your message relates to a particular machine or kind of machine (or
program on same), you probably want to use one of the above lists. The
rest, which follow, are more special-purpose; send sysmsgs to them only
when your message clearly should go to only their constituent machines.
* On any ITS, becomes a sysmsg on just that machine.
*AI, *MC Becomes a sysmsg on just that particular ITS. Use these or
*ML, *DM * (above) for a sysmsg affecting only one ITS, like disk
maintenance.
*ITS Goes only to the four ITSs, listed above. Use if your
message relates only to ITSs, for instance a new ITS
version; otherwise you probably want *MAC or *MIT.
*VX Goes just to the RTS VAX.
*HT Goes just to HTVAX.
*XX These are the same address.
Forum@XX They go just to XX, the LCS Twenex.
*EE These are the same address.
Forum@EE They go just to the EECS Dept. Twenex.
*OZ These are the same address. They go just to OZ, the AI Lab
System@OZ Twenex, and are for important (see above) msgs only.
Forum@OZ For BBoard msgs to OZ.
*TENS The most unlikely address. This goes to the four ITSs, XX,
OZ, and EE, but NOT the Vaxen or the RTS 11. Unless your
message relates only to PDP-10s and DEC-20s, you probably
want *MAC or *MIT.

503
src/sysen1/sysmsg.21 Normal file
View File

@@ -0,0 +1,503 @@
TITLE SYSMSG - ITS SYSTEM MESSAGE PRINTER
.INSRT SYSENG;CALRET >
;;; DEFINE MACROS SO THAT SYSTEM VARIABLES ACCESSED
;;; THROUGH ABS PAGES CAN BE REFERENCED IN A NATURAL WAY
DEFINE CONC A,B
A!B!TERMIN
DEFINE ABSREF SYMS
DEFINE ABSTAB
IRPW SYM,,[SYMS]
IFSE [SYM]----, IMMEDS: ;FROM HERE DOWN ARE NOT ADDRESSES
.ELSE [ SQUOZE 0,SYM
CONC ABSRF",\.IRPCNT,ABS
CONC [EXPUNGE ABSRF"]\.IRPCNT,ABS
]
TERMIN
TERMIN
IRPW SYM,,[SYMS]
IFSN [SYM]----, ABSRF. SYM,\.IRPCNT
TERMIN
TERMIN
DEFINE ABSRF. SYM,CT
ABSRF"!CT!ABS==0
IF1,[DEFINE SYM ?MOD
(MOD)[.,,ABSRF"!CT!ABS]TERMIN
]
IF2,[DEFINE SYM ?MOD
(MOD)<ZZZ==ABSRF"!CT!ABS ? ABSRF"!CT!ABS==[.,,ZZZ] ? ZZZ>TERMIN
]
TERMIN
.BEGIN ABSRF ;PLACE TO KEEP NNNABS SYMBOLS
.END
ABSREF [SYSMBF ;SYSTEM MESSAGE BUFFER
TOIP ;TTY OUTPUT PTR
TOBEP ;.., END OF BUFFER
----
TOBL ;TTY OUTPUT BUFFER LENGTH
SYSCON ;SYSTEM TTY NUMBER
SYSMLNG ;LOG 2 OF NUMBER OF 4-WORD BLOCKS
]
DOWTAB: SIXBIT/SUN/
SIXBIT/MON/
SIXBIT/TUE/
SIXBIT/WED/
SIXBIT/THU/
SIXBIT/FRI/
SIXBIT/SAT/
; SYSTEM MESSAGE BUFFER CONTAINS 8-WORD ENTRIES AS FOLLOWS:
; ABCDEF,,ASCIZ
; ARG1
; ...
; ARG6
; TIME
; A..F = FORMAT OF ARG1..ARG6 RESPECTIVELY, CODED:
FMTBL: 0 ;0 END OF MESSAGE
TYPOCT ;1 FULL WORD OCTAL
TYPDEC ;2 FULL WD DECIMAL
TYPHAF ;3 " WITH COMMAS
TYCRLF ;4 DO CR
CPOPJ ;5 ?
TYPSIX ;6 SIXBIT
TYPASZ ;7 ASCIZ
CPOPJ: POPJ P,
CLSCRN: ASCIZ/C/
CRLF: ASCIZ/
/
CMACMA: ASCIZ/,,/
SEP: ASCIZ/-----
/
MEMHOL: ASCIZ\
WARNING: THERE IS A HOLE IN MEMORY
\
TYIC==2 ;TTY INPUT CHANNEL
TYOC==1 ;TTY OUTPUT CHANNEL
TYO=<.IOT TYOC,> ;INSTRUCTION TO OUTPUT A CHAR
;;; MAIN PROGRAM
PROGRAM SYSMSG
REGISTER A,B,C,F,PT,CH,COUNT
.OPEN TYIC, [.UAI,,'TTY] ;JUST SO CAN GET INTERRUPTS ??
.VALUE
.OPEN TYOC, [20+.UAO,,'TTY]
.VALUE
CALL RITUAL ;ASSURANCE OF PURITY
SETZM JCL ;GET JCL (MESSAGE PREFIX)
MOVE A,[JCL,,JCL+1]
BLT A,JCLP-1
.BREAK 12,[5,,JCL]
MOVE A,[440700,,JCL]
MOVEM A,JCLP
JCHACK: ILDB B,A ;MAKE ASCIZ WITH NO LINE TERMINATOR
CAIL B,"a ;ALSO UPPER-CASE IT
SUBI B,40
CAIG B,"Z
DPB B,A
CAIL B,40
JRST JCHACK
MOVEI B,0
DPB B,A
.RDTIME A,
MOVEM A,.M"TIME' ;SYSTEM TIME NUMBER
.RLPDTM A,
LDB B,[320300,,B]
MOVEM B,.M"DOW' ;CORRESPONDING DAY OF WEEK
IDIVI A,86400.
MOVEM B,.M"TOD' ;OFFSET FROM MIDNIGHT IN SECONDS
CALL TYPE,CLSCRN ;CLEAR SCREEN
MOVEI COUNT, 1 ;SET UP COUNT OF MESSAGE SLOTS
LSH COUNT, SYSMLNG ;..
CAILE COUNT,BUFL*8
.LOSE ;SYSTEM BUFFER GOT BIGGER
MOVSI A,SYSMBF ;COPY SYSTEM BUFFER
HRRI A,BUF
BLT A,BUF+BUFL-1
MOVE C,COUNT
SORT: MOVEI CH,-1(COUNT) ;THEN SORT BY TIME
MOVEI PT,BUF
SORT1: MOVE A,7(PT)
CAMG A,7+8(PT)
JRST SORT2
REPEAT 8,[
MOVE A,.RPCNT(PT)
EXCH A,.RPCNT+8(PT)
MOVEM A,.RPCNT(PT) ]
SORT2: ADDI PT,8
SOJG CH,SORT1
SOJG C,SORT
MOVEI PT,BUF ;SET UP POINTER TO BUFFER
LOOP: UNTIL [SOJLE COUNT,][ ;PRINT ALL MESSAGES
SKIPN A, (PT) ;PICK UP HEADER WORD
JRST NXLOOP ;ZERO => NO MSG HERE
HLLZ F,A ;F ARG FORMAT BITS
HRLI A,440700 ;A ASCIZ POINTER
CALL PRINTP,A ;SHOULD THIS MESSAGE BE PRINTED?
JUMPE T,NXLOOP
MOVEI C,1(PT) ;C PNTR TO NEXT ARG
LOOP1: ILDB B,A
JUMPE B,LOOP2
IF [CAILE B,7][PUSHJ P,ARGSOT]
ELSE [TYO B]
JRST LOOP1
LOOP2: WHILE [SKIPN F][ ;DISPLAY THE ARGUMENTS
TYO [40] ;PUT A SPACE BETWEEN ARGS
PUSHJ P,ARGOT
]
TYO [40]
CALL PTIME,7(PT) ;PRINT THE TIME
CALL TYPE,CRLF
NXLOOP: ADDI PT, 8 ;ADVANCE TO NEXT MESSAGE
];END UNTIL LOOP
; Display any lines that are on the system job console
CALL TYPE,SEP
MOVEI C, SYSCON ;-> SYSTEM JOB TTY
MOVE PT, TOIP(C) ;SCAN THROUGH
SYFNDL: PUSHJ P, SYGET ;FIND FIRST FULL LINE
CAIE A, 15
JRST SYFNDL
SYTYPE: PUSHJ P, SYGET ;NOW DISPLAY WHAT'S THERE
CAIN A,175 ;FLUSH OLDE ALTMODES KEEPING TTY WARM
JRST SYTYPE
TYO A
JRST SYTYPE
SYGET0: CAMN PT, TOBEP(C) ;GET CHR FROM TTY BUF
SUBI PT, TOBL ; WITH WRAP-AROUND
ILDB A, PT ;GET CHAR
CAMN PT, TOIP(C) ;KILL RETURN IF DONE
JRST KILL
POPJ P,
SYGET: PUSHJ P, SYGET0 ;ROUTINE TO GET CHR AND DO %TD HACKS
CAIN A,%TDFS
MOVEI A,40
CAIN A,%TDCRL
MOVEI A,15
TRNN A, 200 ;AND DO SPECIAL CHAR PROCESSING
POPJ P, ; NORMAL CHAR JUST RETURN
CAIE A,%TDMV1
CAIN A,%TDMV0
JRST SYGET1
CAIE A,%TDMOV
JRST SYGET ;1-CHAR SEQ IGNORE
PUSHJ P, SYGET0 ;GOBBLE CURSOR MOTION
PUSHJ P, SYGET0 ;ASSUMING INTR LEVEL HAS PROCESSED
SYGET1: PUSHJ P, SYGET0 ;GOBBLE CURSOR MOTION
PUSHJ P, SYGET0 ;ASSUMING INTR LEVEL HAS PROCESSED
CAIE A, 0 ;SKIP IF IS PROBABLY CRLF
SKIPA A, [40] ;OTHERWISE IS PROBABLY SPACE
MOVEI A, 15 ;NOW CHANGE CURSOR MOTION TO CRLF
CPOPJ: POPJ P,
KILL: .BREAK 16, 040000
ARGSOT: PUSH P,A
PUSH P,B
MOVE A,B ;COUNT OF ARGS TO OUTPUT
ARGSO1: PUSHJ P,ARGOT
TYO [40]
SOJG A,ARGSO1
POP P,B
POP P,A
POPJ P,
ARGOT: LDB B,[410300,,F] ;PICK UP ARG TYPE CODE
CALL @FMTBL(B),@C ;DISPLAY THE ARGUMENT
LSH F,3 ;ADVANCE TO NEXT TYPE CODE
AOJA C,CPOPJ ;ADVANCE TO NEXT ARG
.END
PRINTP: PROCEDURE AMBP ;RETURN NON-ZERO IN T IF MSG MATCHES JCL
REGISTER MBP,JBP,MCH,JCH
MOVE MBP,AMBP
MOVE JBP,JCLP
LP: ILDB MCH,MBP
ILDB JCH,JBP
JUMPE JCH,WIN
CAMN JCH,MCH
JRST LP
LOSE: MOVEI T,0
RETURN
WIN: MOVEI T,1
RETURN
.END
;;; TIME PRINTING
PTIME: PROCEDURE TIM
REGISTER A,B,C,D,E
MOVE A,TIM
SUB A,TIME
IDIVI A,30. ;OFFSET IN SECONDS FROM KNOWN TIME
ADD A,TOD ;CONVERT TO OFFSET FROM MIDNIGHT TODAY
IDIVI A,86400. ;A DAYS, B SECONDS
IF [SKIPL B][ ;FIX DIVISION FOR POSITIVE REMAINDER
SUBI A,1
ADDI B,86400. ]
PUSH P,B
ADD A,DOW ;FIND DAY OF WEEK OF THAT DAY
IDIVI A,7
SKIPGE B ;FIX DIVISION FOR POSITIVE REMAINDER
ADDI B,7
CALL TYPSIX,DOWTAB(B)
TYO [40]
POP P,A
IDIVI A,60. ;A MINUTES, B SECONDS
MOVE C,B
IDIVI A,60. ;A HOURS, B MINUTES
CALL TYPDC2,A
TYO [":]
CALL TYPDC2,B
TYO [":]
CALL TYPDC2,C
RETURN
.END
;;; ROUTINE TO TYPE AN ASCIZ STRING
TYPE: PROCEDURE STRING
REGISTER PT,CH
MOVEI PT, STRING ;SET UP B.P. TO STRING
TLOA PT, 440700 ;..
LOOP: TYO CH
ILDB CH, PT ;GET NEXT CHAR
JUMPN CH, LOOP ;AND IF NOT DONE, TYPE IT
RETURN
.END
;;; ROUTINES TO FORMAT DATA IN WONDROUS WAYS
TYPOCT: PROCEDURE DATA
REGISTER LH,RH
HLRZ LH,DATA
HRRZ RH,DATA
IF [JUMPN LH,][
CALL TYPNUM,LH,[8.]
CALL TYPE,CMACMA
]
CALL TYPNUM,RH,[8.]
RETURN
.END
TYPDEC: PROCEDURE DATA
REGISTER DAT
IF [SKIPL DAT, DATA][ ;PUT MINUS SIGN IF NEEDED
TYO ["-]
MOVMS DAT
]
CALL TYPNUM,DAT,[10.]
RETURN
.END
TYPDC2: PROCEDURE DATA
REGISTER DAT
IF [SKIPL DAT, DATA][ ;PUT MINUS SIGN IF NEEDED
TYO ["-]
MOVMS DAT
]
CAIGE DAT,10.
TYO ["0]
CALL TYPNUM,DAT,[10.]
RETURN
.END
TYPNUM: PROCEDURE DATA,RADIX
REGISTER NUM,REM
MOVE NUM, DATA
PUSHJ P, FROB
RETURN
FROB: IDIV NUM, RADIX
HRLM REM, (P)
SKIPE NUM
PUSHJ P, FROB
HLRZ REM, (P)
ADDI REM, "0
TYO REM
POPJ P,
.END
TYPHAF: PROCEDURE DATA
REGISTER DAT,LH
MOVE DAT, DATA
IF [TLNN DAT,-1][ ;IF HAS LEFT HALF
HLRZ LH, DAT
CALL TYPOCT,LH
TYO [",]
TYO [",]
]
HRRZS DAT
CALL TYPOCT,DAT
RETURN
.END
TYCRLF: PROCEDURE IGNORED
CALL TYPE,CRLF
RETURN
.END
TYPSIX: PROCEDURE DATA
REGISTER CH,WRD
MOVE WRD, DATA
6LOOP: SETZ CH,
LSHC CH, 6
ADDI CH, 40
TYO CH
JUMPN WRD, 6LOOP
RETURN
.END
TYPASZ: PROCEDURE PT
REGISTER A
MOVE A,PT ;CAN'T INDIRECT PARAM
CALL TYPE,@A
RETURN
.END
;;; PURIFICATION RITUAL
OITSVRS:0 ;ITS VERSION PURIFIED FOR
OUSRSTG:0 ;EXTRA Check
RITUAL: PROCEDURE
.RSYSID TT,
MOVE T, [SQUOZE 0,USRSTG] ;SEE IF SYSTEM CHANGED
.EVAL T,
JFCL
CAMN TT, OITSVRS
CAME T, OUSRSTG
JRST NOGOOD
RETURN
NOGOOD: CALL PURIFY ;WRONG SYS VERSION OR NOT PURE
RETURN ;YET SO REPURIFY
.END
ABSTB1: ABSTAB
ABSTB2:
PURIFY: PROCEDURE
REGISTER I,L,V,LIM
.VALUE [ASCIZ\:New system version; must repurify.
Take paws off keys and wait.

 p\]
MOVEI LIM, IMMEDS-ABSTB1 ;LIMIT ON REMAPPABLENESS
MOVSI I, <ABSTB1-ABSTB2>/2 ;SCAN ABSTAB
EVLOOP: MOVE V, ABSTB1(I) ;GET SYMBOL
.EVAL V, ;EVALUATE IT
.VALUE ;NOT THERE???
CAIG LIM, (I) ;SKIP FOLLOWING CODE
JRST EVLP00 ; IF IMMEDIATE SYMBOL
CAIGE V, REMAPT ;REMAP LOW CORE
SUBI V, REMAPT ;INTO HIGH CORE
EVLP00: ADDI I, 1
MOVE TT, ABSTB1(I) ;FOLLOW PATCH LIST
PLOOP: JUMPE TT,EVLPNX ;JUMP IF END OF LIST
MOVE L,TT
HLRZ TT,(L) ;LOC TO PATCH
HRRM V,(TT) ;PATCH IT
HRRZ TT,(L) ;LINK TO NEXT
JRST PLOOP ;AND TRY AGAIN
EVLPNX:AOBJN I, EVLOOP ;NEXT SYMBOL
; HAVING PATCHED, SET UP PAGE TABLE
; FOR NOW, WE DON'T ACTUALLY PURIFY ANY PAGES...
.RSYSID V, ;REMEMBER ITS VERSION
MOVEM V, OITSVRS
MOVE V, [SQUOZE 0,USRSTG] ;AND A KLUDGEY MACHINE CHECK
.EVAL V,
.VALUE
MOVEM V, OUSRSTG
SETZM V
MOVEI TT, REMAPT_-10. ;GET ABS PAGES
HRLI TT, <REMAPT-400000>_-10. ;FROM 0 TO 400000
MOVE T, TT
GETMOR: .CALL CORBLK,[#210000,#-1,TT,#400000,T]
JRST .+2 ;ERROR RETURN
JRST GOTIT
.SUSET [.RBCHN,,V] ;FIND OUT WHAT LOST
.CALL STATUS,V,V ;GET ERROR CODE
.VALUE
LDB V, [270600,,V] ;..
CAIE V, 32 ;CAN'T GET THAT ACCESS
.VALUE ;NO - UNCLEAR
ADD TT, [40,,40] ;YES - BITING MD10'S HAVE A 32K HOLE!
MOVE T, TT
JUMPL TT, GETMOR
GOTIT: JUMPE V,GOTIT1
CALL TYPE,MEMHOL
GOTIT1: MOVEI TT, <1000000-REMAPT>_-10. ;DO REMAPPAGE
HRLI TT, -<REMAPT_-10.>
SETZ T,
.CALL CORBLK,[#210000,#-1,TT,#400000,T]
.VALUE
.VALUE [ASCIZ\:PDUMP SYS1;TS SYSMSG
P\]
RETURN
.END PURIFY
BUFL==400
BUF: BLOCK BUFL
JCL: BLOCK 20
JCLP: 440700,,JCL
CONSTANTS
VARIABLES
REMAPT=<.+1777>&776000 ;FIRST NON USED PAGE
END SYSMSG

396
src/syseng/calret.30 Normal file
View File

@@ -0,0 +1,396 @@
;;; CALRET - Call Return routines. DAM.
;;; This facility is based on a similar one by Michael Spier
;;;** NOTE FORMAT OF CERTAIN MACROS HAS BEEN CHANGED SINCE CALRET 8
;;;** Rewritten to make literals etc. work. Max 10 arguments.
;;; This is entirely due to the losiness of IRP wrt brackets.
;;; FORMAT OF STACK FRAME CHANGED - VERSION 16
IF1,[ ;STUFF THAT ONLY NEEDS TO BE DONE ONCE
; MACRO TO TELL WHAT VERSION INSERT FILE THIS IS
DEFINE TELLVERSION
IF1,[
.TYO6 .IFNM1
PRINTX " "
.TYO6 .IFNM2
PRINTX " Included in this assembly.
"
]
TERMIN
TELLVERSION
;;; Registers
;;; Temporary Registers - destroyed by calls, may not be passed as arg.
;;; Note: T0 is not an index register; The order may be relied upon
T0=0
T1=1
T=2
TT=3
;;; Registers Used Internally by the System
P=17 ;PushDown List Pointer
.CF.=16 ;Current Stack Frame Pointer
.PF.=15 ;Previous Stack Frame Pointer
.AP.=14 ;Argument List Pointer
;;; Registers which may be used as variables and passed as arg,
;;; by means of a REGISTER declaration.
.PRSVA=4 ;First Preserved Register
.PRSVZ=13 ;Last Preserved Register
;;; Format of the Stack Frame
;;;
;;; Return Address (Previous Routine's PC)
;;; Previous Routine's Registers, i.e.
;;; .CF. -> .PRSVA - .PRSVZ, .AP., .PF.
;;; User's LOCAL variables + System Generated Locals
;;; Temporaries Pushed
;;; P -> on the Stack
;;; next Frame will begin here
;;; Macro used at start of program to set up environment
DEFINE PROGRAM NAME,SPEC
SPEC ;SET STACK SIZE IF USER SAID TO
IFNDEF STACK, STACK=100 ;DEFAULT TO 100 WORDS
IFNDEF PDL, PDL: BLOCK STACK
NAME: .BEGIN NAME
IF2 .STZZ.==.STSZ.-1 ;final stack size
.STSZ.==1 ;minimum size frame
.REGS.==.PRSVA-1
MOVE .CF., [-STACK,,PDL-1] ;SET UP PDL
MOVE P, [.STZZ.-STACK,,PDL+.STZZ.-1]
IF1 EXPUNGE PDL
TERMIN
;;; Macro to define a Procedure
; NAME: PROCEDURE ARG1,ARG2,...
DEFINE PROCEDURE -PARAMS
.BEGIN ;Name picked from tag
IF2 .STZZ.==.STSZ.-1 ;final stack size
.STSZ.==1 ;minimum size frame
.REGS.==.PRSVA-1
ENTRY PARAMS
TERMIN
DEFINE ENTRY -PARAMZ ;you will lose unless .U"NAME: ENTRY
.PARM.==0
IRPW PARAMS,,[PARAMZ]
IRP PARAM,,[PARAMS] ;declare the formal parameters
.DEF. PARAM,.AP.,\.PARM.,@
.PARM.==.PARM.+1
TERMIN
TERMIN
JSP T, .ENTR. ;invoke entry operator
.STZZ.,,.STZZ. ;on 2nd pass, becomes stack adjustment
TERMIN
DEFINE .DEF. NAME,BASE,OFFS,MOD
DEFINE NAME
MOD!OFFS(BASE)TERMIN
TERMIN
; To end a procedure, just use .END
;;; Macro to declare variables that reside in registers
DEFINE REGISTER -NAMES1
IRPW NAMES,,[NAMES1]
IRPS NAME,,[NAMES]
.REGS.==.REGS.+1
IFG .REGS.-.PRSVZ, INFORM TOO MANY REGISTERS DECLARED - ,NAME
NAME=.REGS.
TERMIN
TERMIN
TERMIN
;;; Macro to declare local variables
;;; for a multiword var, follow name by length in parentheses.
;;; the length must be a number or constant symbol (no A+1, etc.)
DEFINE LOCAL -NAMES1
IRPW NAMES,,[NAMES1]
.ARG.==0 ;FLAG FOR LENGTH FROB
IRPS NAME,DELIM,[NAMES]
IFN .ARG.,[ .STSZ.==.STSZ.+NAME-1 ;LENGTH OF PREV VAR
.ARG.==0
]
.ELSE [ ;NORMAL VAR
IFSE [DELIM](, .ARG.==1 ;LENGTH FOLLOWS
.DEF. NAME,.CF.,\.STSZ.
.STSZ.==.STSZ.+1
]
TERMIN
TERMIN
TERMIN
;;; Macro to generate a call
DEFINE CALL ROUTINE?A,B,C,D,E,F,G,H,I,J
.NARG.==0 ;count arguments
.NFRM.==0 ;count formals passed as arg, which require kludgery
IRP ARG,,[[A],[B],[C],[D],[E],[F],[G],[H],[I],[J]]
IFSE [ARG], .ISTOP
.NARG.==.NARG.+1
.ARG.==<ARG>
IFNDEF .ARG.,.STOP ;undef skip it
.TAG.==<.ARG._-18.>&17
IFN <.TAG.>*<.TAG.-.CF.>,[ ;have to copy it
MOVEI T0, ARG
MOVEM T0, .STSZ.(.CF.)
.STSZ.==.STSZ.+1
.NFRM.==.NFRM.+1
]
TERMIN
IFN .NARG.,[ ;create argument list
MOVEI T1, [ IRP ARG,,[[A],[B],[C],[D],[E],[F],[G],[H],[I],[J]]
IFSE [ARG], .ISTOP
.ARG.==<ARG> ;evaluate the argument's address
IF1 IFNDEF .ARG., .ARG.==. ;PASS 1 UNDEFINED
.TAG.==<.ARG._-18.>&17
.IND.==.ARG.&<@>
.ARG.==.ARG.&777777
IFE .TAG.-.CF., .ARG.==0 .ARG.(.PF.) ;passing local
IFE .TAG.,[
IFE .ARG.&777760, .ARG.==0 .ARG.-.PF.(.CF.) ;reg
.ELSE ;passing a static variable
]
IFN <.TAG.>*<.TAG.-.CF.>,[ ;passing via copy
.IND.==<@>
.ARG.==0 .STSZ.-.NFRM.(.PF.)
.NFRM.==.NFRM.-1
]
.ARG.+.IND. ;now generate the argument pointer
TERMIN
]]
PUSHJ P, ROUTINE
TERMIN
;;; Macro to generate a return
DEFINE RETURN
JRST .RETN.
TERMIN
;;; Error Macro
DEFINE INFORM A,B,C,D,E,F,G,H,I,J
PRINTX\A!B!C!D!E!F!G!H!I!J
\
TERMIN
];END MOBY IF1
;;; Entry Operator
.ENTR.: MOVEI TT, 1(P) ;save registers between frames
HRLI TT, .PRSVA
ADD P, [.PF.-.PRSVA+1,,.PF.-.PRSVA+1] ;protect reg save area
BLT TT, 0(P)
MOVE .AP., T1 ;set called routine's registers
MOVE .PF., .CF.
MOVE .CF., P
ADD P, 0(T) ;adjust stack
JUMPL P, 1(T) ;and go to called routine
.SUSET [.SIPIRQ,,[%PIPDL]]
JRST 1(T)
;;; Return Operator
.RETN.: MOVE P, .CF. ;pop frame off
MOVE .CF., .PF.
MOVSI TT, -<.PF.-.PRSVA>(P) ;restore registers
HRRI TT, .PRSVA
BLT TT, .PF.
SUB P, [.PF.-.PRSVA+1,,.PF.-.PRSVA+1] ;pop regs off
POPJ P, ;and return
CONSTANTS
IF1,[ ;MORE ONCE-ONLY STUFF
;;; Conditional-Jump Generator Used Internally.
;;; COND may be a skip or a JUMP or an AOJ or a SOJ, if condition true.
;;; COND may also be several instructions - the last is looked at
;;; to see whether it is a skip or a jump - all are assembled in.
;;; Generates code to jump to TAG if the condition is false.
DEFINE .COND. COND,TAG
.JUMP.==0 ;condition type flag
.CRGL.==004000,, ;opcode sense inverter
IRPW CND,,[COND]
IRPS CN,,[CND]
.OPCD.==770000000000&<CN>
IFSE CN,AOBJN,[ .JUMP.==1 ? .CRGL.==1000,,]
IFSE CN,AOBJP,[ .JUMP.==1 ? .CRGL.==1000,,]
.ISTOP
TERMIN
.ICNT.==.IRPCNT ;count instructions
TERMIN
IFE .OPCD.-JUMP, .JUMP.==1
IFE .OPCD.-AOJ, .JUMP.==1
IFE .OPCD.-SOJ, .JUMP.==1
IFE .JUMP.,[ ; skip - code it followed by JRST
COND
JRST TAG
]
IFN .JUMP.,[ ; jump - alter sense of last instr (the jump)
IRPW CND,,[COND]
IFN .IRPCNT-.ICNT., CND
.ELSE <<CND>#.CRGL.>+TAG
TERMIN
]
TERMIN
;;; Iteration Macros
DEFINE WHILE COND,BODY\EAT,BTAG,ETAG
DEFINE EXITLOOP
JRST ETAG
TERMIN
BTAG: .COND. [COND]ETAG
BODY
JRST BTAG
ETAG:
.XCREF BTAG,ETAG,EXITLOOP
TERMIN
DEFINE UNTIL COND,BODY\EAT,BTAG,ETAG
DEFINE EXITLOOP
JRST ETAG
TERMIN
BTAG: BODY
.COND. [COND]BTAG
ETAG:
.XCREF BTAG,ETAG,EXITLOOP
TERMIN
;;; If - Then - Else Macros
DEFINE IF COND,THENCLAUSE\EAT,TAG
DEFINE .IFTG.
TAG==.
TERMIN ;remember TAG for redefinition
.COND. [COND]TAG ;if false, skip THEN clause
THENCLAUSE
TAG==.
TERMIN
DEFINE ELSE ELSECLAUSE\EAT,TAG
JRST TAG ;make THEN clause skip ELSE clause
.IFTG. ;redefine tag generated by IF
ELSECLAUSE
TAG:
TERMIN
DEFINE ELSEIF COND,THENCLAUSE
ELSE [IF [COND][THENCLAUSE]]
TERMIN
;;; System-Call Macro.
DEFINE .CALL PROC,IN,OUT,CTLB
;COUNT ARGUMENTS
.CLST.==0
.CLCT. IN
.CLCT. OUT
.CLCT. CTLB
043000,,[SETZ
.1STWD SIXBIT/PROC/
.CLAG. 4000,CTLB
.CLAG. 0,IN
.CLAG. 2000,OUT
IFN .CLST.,INFORM BAD FORMAT SYSTEM CALL - PROC
]
TERMIN
DEFINE .CLCT. ?A,B,C,D,E,F,G,H ;CROCK DUE TO IRP LOSS
IFNB [A] .CLST.==.CLST.+1
IFNB [B] .CLST.==.CLST.+1
IFNB [C] .CLST.==.CLST.+1
IFNB [D] .CLST.==.CLST.+1
IFNB [E] .CLST.==.CLST.+1
IFNB [F] .CLST.==.CLST.+1
IFNB [G] .CLST.==.CLST.+1
IFNB [H] .CLST.==.CLST.+1
TERMIN
;;; ARGUMENT POINTER GENERATOR FOR ABOVE
;;; A # INDICATES AN IMMEDIATE ARGUMENT
DEFINE .CLAG. BITS?A,B,C,D,E,F,G,H
IFNB [A] .CLG1. BITS,A
IFNB [B] .CLG1. BITS,B
IFNB [C] .CLG1. BITS,C
IFNB [D] .CLG1. BITS,D
IFNB [E] .CLG1. BITS,E
IFNB [F] .CLG1. BITS,F
IFNB [G] .CLG1. BITS,G
IFNB [H] .CLG1. BITS,H
TERMIN
DEFINE .CLG1. BITS?ARG
.CLST.==.CLST.-1 ;COUNT ARGS
.CLG2.==0
IRPNC 0,1,-1,CH,REST,[ARG]
IFE "CH-"#,[ <IFE .CLST.,[400000]+BITS+1000>,,0*"CH+REST
.CLG2.==1 ;the 0 times is per order rms
] ;Immediate
IFE "CH-"?,[ <IFE .CLST.,[400000]+3000>,,0*"CH+REST
.CLG2.==1
] ;Error-code argument
IFN "CH-40, .ISTOP ;STOP ON FIRST NON BLANK
TERMIN
IFE .CLG2., <IFE .CLST.,[400000]+BITS>,,ARG
TERMIN
];END MOBY IF1
;;; Interrupt Facilities
DEFINE INTSET ?Z\IB ;arg is one line per interrupt, usual four things
IB: P
IRPW X,,Z
IRP Y,,[X]
ZZ==.IRPCNT
IFN ZZ-4, Y
.ELSE [ 0,,[ PUSHJ P, .INTR. ? Y ] ]
TERMIN
IFN ZZ-4, INFORM ERROR: INTSET - NOT FIVE THINGS - ,[X]
TERMIN
;end interrupt list
ZZ==.
LOC 42
IB-ZZ,,IB
LOC ZZ
; Interrupt Interface Routine - allows Standard Procedures as handlers
.INTR.: PUSH P, T ;save temporary registers
PUSH P, T1
PUSH P, T0
EXCH TT, -3(P) ;saves TT and gets call addr
PUSHJ P, @0(TT) ;invoke handler. Entry seq saves rest of regs
POP P, T0 ;restore regs
POP P, T1
POP P, T
POP P, TT
.CALL DISMISS,P ;and dismiss interrupt
TERMIN
;;; End of CALRET