1
0
mirror of https://github.com/PDP-10/its.git synced 2026-01-24 11:22:36 +00:00
Lars Brinkhoff 5e218aadc8 Newer version of PDP-11 code for TV system.
Includes SUPDUP graphics.  Timestamp 1982-05-31.
2018-02-20 05:58:22 +01:00

6634 lines
140 KiB
Plaintext
Raw 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.

;-*-MIDAS-*-
.SBTTL MACROS AND CONDITIONAL ASSEMBLY
;AI PDP-11 TV CONSOLE PROGRAM
; USER WHO-LINE VARIABLES CODE ADDED 7/28/75 BY GLS
; AUDIO SWITCH CODE REWRITTEN 7/12/76 BY ED
; TV IS PDP-11 NUMBER 0 TO THE 10-11 INTERFACE.
; ELEVATOR CODE 2/13/79 BY DANNY & HIC
; REGION-SCROLLING 11/3/79 MOON
FONTSW==1 ;COMPILE FONTS
FONTMS==0 ;USE MACROS TO COMPILE FONTS
;REGISTER ASSIGNMENTS
A=%0 ;ASCII CHARACTER
B=%1 ;META BITS
C=%2 ;C, T, AND TT ARE TEMPORARIES
T=%3
TT=%4
U=%5 ;LINE EDITOR OR PAGE PRINTER
SP=%6
PC=%7
.XCREF A,B,C,T,TT,U,SP,PC,...,....
.IIF E FONTSW,.TITLE TV NOFONTS
.IF NE FONTSW
.TITLE TV
.IF NE FONTMS
.NLIST ;WE'RE ONLY INTERESTED IN FONTS
.IF1
.PRINT /THIS ASSEMBLY WILL TAKE FOREVER!
/
.ENDC ;.IF1
.ENDC ;.IF NE FONTMS
.ENDC ;.IF NE FONTSW
.MACRO PUSH A
.NLIST
MOV A,-(SP)
.LIST
.ENDM
.MACRO POP A
.NLIST
MOV (SP)+,A
.LIST
.ENDM
.MACRO REPORT TEXT,NUM
.NLIST
.IF2
.LIST
.PRINT /TEXT'NUM
/
.NLIST
.ENDC
.LIST
.ENDM
.MACRO CHROFF
.NLIST
MOVB PS,-(SP)
MOVB #LKLVL,PS
.LIST
.ENDM
.MACRO CHRON
.NLIST
MOVB (SP)+,PS
.LIST
.ENDM
.MACRO BLKOFF A
.NLIST
INCB BLKSWT(A)
.LIST
.ENDM
.MACRO BLKON A
.NLIST
DECB BLKSWT(A)
BGE .+4
BPT
.LIST
.ENDM
.MACRO TENWRD
.NLIST
.IIF NE .&3,.=<.&177774>+4
.LIST
.ENDM
.MACRO CHECK TAG,LENGTH
.NLIST
.IF NE .-<TAG>-<LENGTH>
.ERROR TAG WRONG LENGTH
.ENDC
.EVEN
.LIST
.ENDM
.MACRO TYPOUT A
.NLIST
JSR PC,OUTSTR
.ASCIZ A
.EVEN
.LIST
.ENDM
.MACRO DECTYPE NUM
.NLIST
MOV NUM,A
JSR PC,DECPNT
.LIST
.ENDM
.MACRO OCTYPE NUM
.NLIST
MOV NUM,A
JSR PC,OCTPNT
.LIST
.ENDM
.MACRO ZAPFLG FLAG
.NLIST
%COMPAT==0
MOV PC,FLAG
%COMPAT==1
.LIST
.ENDM
.MACRO CONC A,B,C,D,E,F,G,H,I
A'B'C'D'E'F'G'H'I
.ENDM
.IF NE 0 ;PROGRAM MAP:
0, TO PDLORG ;TRAP VECTORS
PDLORG, TO KBDBUF ;PUSH DOWN LIST
KBDBUF, TO GO ;KBD BUFFER
GO, TO XTAB ;PROGRAM
XTAB, TO FNTORG ;KEYBOARD TRANSLATION TABLE
FNTORG, TO VARORG ;FONT DEFINITION
VARORG, TO MISORG ;LINE EDITOR/PAGE PRINTER VARIABLES
MISORG, TO PATCH ;MISCELLANEOUS TABLES AND VARIABLES
PATCH, TO LEBUFS ;PATCH AREA
LEBUFS, TO TVLO ;FREE STORAGE
.ENDC
.SBTTL HOW IT WORKS
.REPT 0
channel header pointer (location 40, read only)
ADDRESS(channel header area)
ADDRESS(pointer area)
I/O version number
source file version number
0 always 0
INITED non-zero indicates PDP-11 is running ok(can be cleared by PDP-10)
0 always 0
GDOWN used as flag by PDP-10 to acknowledge clear of INITED
channel header area (aligned on PDP-10 word)
KBD channel:
KBDFLG cleared by 10/set by 11 (chain of activated KBD buffers)
0 allows PDP-10 to do SKIPN for activation test
DPY channel: (1 per console)
DPYCHN buffer assigned to channel, if zero then DPY channel is closed
DPYKBD .BYTE KBD#, DPY# (377 for either implies not assigned)
KBD flags: (1 per console)
ECOFLG Set by PDP-10. Next time DPYBUF is empty clear ECOFLG
and put flag on KBD ring to signal this condition
CHNCLS if -1, log this guy out!!!!
If non-negative, has keyboard number (377 if none).
WHO flags: (1 per console)
WHOLIN who line variables for this console
WHOUSR -1=>user who line, 0=>system who line
format of KBD buffer (aligned on PDP-10 word)
KBDSTS negative=>-(data byte count), 0=>free
0
KBDRNG next KBD buffer associated with this KBD
KBDLST next buffer on activated list (0=>end of chain)
KBDCHN keyboard channel
0 not used
KBDATA key board data area (1 PDP-11 word/character)
format of DPY buffer (aligned on PDP-10 word)
(actually, this is the beginning of the "line editor vars" or "channel vars" block).
DPY10B word PDP-10 is hacking (used only for initailization)
This always points at DPYATA for this buffer these days.
DPY11B word PDP-11 is hacking
0
DPYLGL last legal address in this buffer
DPYSIZ size of data area in bytes
0 not used
DPYATA display data area (1 PDP-11 byte/character)
format of pointer area (aligned on PDP-10 word)
ADDRESS(system who line variables)
ADDRESS(PDP-10/PDP-11 communication area)
TENWHO -1=>PDP-10 should update who lines
TENWH1 pads TENWHO
SYMTAB BEGINNING OF TABLE OF SWITCHES WHICH 10 ACCESSES.
Notes:
1. All addresses and pointers are in PDP-11 address space.
2. KBD buffers are ringed two per channel. While the PDP-10 is
emptying one, the PDP-11 can fill the other.
3. There is only one DPY buffer per channel. When the buffer is filled
with negative ones, it is free. When the PDP-10 writes a character
in the current word: then the PDP-11 processes the data in that
word, sets that word to negative one, and advances to the next word.
(Formerly any negative number would do, but now that the byte size is
8 rather than 16, -1 [377] must be used since valid characters > 200 exist.)
WHO LINE VARIABLES
SYSTEM WHO LINE (ALIGNED ON PDP-10 WORD)
ITSTDP # total # dpy's (read only for PDP-10)
ITSFDP # free dpys (read only for PDP-10)
ITSVER ITS version #
ITSJOB total jobs
ITSCOR total core
ITSRU runnable users
ITSWBJ # jobs swap blocked
ITSJWP # jobs waiting for pages
ITSTRC total runable core
ITSCFU core available for users
ITSDAT date [byte (7) year (4) month (5) day]
ITSDBG system debug flag
ITSTIM time of day (# half seconds since midnight) aligned on PDP-10 word
ITSTI1 low order of time
ITSUSR total number of users
ITSFSH fair share
USER WHO LINE (ALIGNED ON PDP-10 WORD)
WHJOB job #, -1=>who line not in use
WHJOB1 if negative then clear who line
WHMODE mode 0=>follow keyboard
1=>freeze
2=>next higher (when PDP-10 sees this state, it searches
user variables for next higher job index number with same
uname. When it finds it, it stores the number in job #
and changes mode to 1
3=>next lower
WHMOD1 pads WHMODE
WHUNAM uname in sixbit (left 18 bits in first two words, right in next two)
WHUNM1
WHUNM2
WHUNM3
WHJNAM jname in sixbit
WHJNM1
WHJNM2
WHJNM3
WHSNAM sname in sixbit
WHSNM1
WHSNM2
WHSNM3
WHSTAT status in sixbit, 0=>job does not exist
WHSTA1
WHSTA2
WHSTA3
WHJ%RT job % run time
WHJTRT job total run time (in tenth's of seconds)
WHRPAG job real memory pages (swapped in)
WHTPAG job total pages
NOTE: The PDP-11 will not update who lines until it sees that ITSTIM
has changed.
PDP-10/PDP-11 COMMAND CHANNEL
CMDFLG aligned on PDP-10
0=>buffer is free (PDP-10 can write CMDBUF)
positive=>command # from PDP-10 (PDP-11 can write CMDBUF)
negative=>affirmative reply from PDP-11 (0=>command failed)
PDP-10 can read CMDBUF, then must zero CMDFLG
CMDFL1 always 0
CMDBUF each arg takes 4 bytes (1 PDP-10 word)
PDP-10/PDP-11 COMMANDS
1 video switch
arg1: video switch input # (set by PDP-10)
arg2: video switch output # ( " " " " )
2 reserve DPY
arg1: DPY reserved (set by PDP-11)
3 free DPY
arg1: DPY to free (set by PDP-10)
4 read video switch
arg1: < 0 for default setting, > 0 for current setting (set by PDP-10)
1=>tty chnl, 2=>KBD, 3=>video switch output
arg2: # described by arg1 (set by PDP-10)
arg3: input (set by PDP-11)
arg4: input (set by PDP-11)
arg5: output(set by PDP-11)
5 audio switch
arg1: audio switch input # (set by PDP-10)
arg2: audio switch output # (set by PDP-10)
6 read audio switch (for this to be useful, 11 must maintain table, since
the audio switch is read-only.
arg1: < 0 for default setting, > 0 for current setting (set by PDP-10)
1=>tty chnl, 2=>KBD, 3=>audio switch output
arg2: # described by arg1 (set by PDP-10)
arg3: input (set by PDP-11)
arg4: output(set by PDP-11)
;other 10-11 commuincation issues ..
;go down resetting video switch vs not
;PDP-11 indicates it has reset video switch
;(PDP-10 then detaches all jobs with tv ttys)
;console scroll register 6/23/74
CSA==157776 ;selects where video scan starts in video buffer
__|_____|_____|_____|_____|_____|
15 1211 |
| 3 |1| 12 |
|_____|_|_______________________|
| | |
| | |----------------->scroll offset (start video scan at n*4 PDP-11 words from TVLO)
| |
| |------------------------------->black on white bit (1=>black on white)
|
|----------------------------------->not used
;console register 6/24/74
CREG==164044 ;selects video buffer memory
__|_____|_____|_____|_____|_____|
15 7 |
| 8 | 8 |
|_______________|_______________|
| |
| |-------------->console # (TVLO-TVHI on unibus is video bit map)
|
|------------------------------>ALU function
video switch 4/17/74
VSW==164060 ;sets video switch
__|_____|_____|_____|_____|_____|
15 12 10 7 3 |
| 3 | 2 | 3 | 4 | 4 |
|_____|___|_____|_______|_______|
| | | | |
| | | | |---------->video source
| | | |
| | | |------------------>not used
| | |
| | |------------------------->| |card section
| | |switch output|
| |------------------------------>| |card select
|
|----------------------------------->switch section number
audio switch 7/12/76
ASW==170670 ;SETS AUDIO SWITCH. (this is a write-only memory.)
__|_____|_____|_____|_____|_____|
15 13 10 7 3 |
| 2 | 3 | 3 | 4 | 4 |
|___|_____|_____|_______|_______|
| | | | |
| | | | |---------->audio source
| | | |
| | | |------------------>not used
| | |
| | |------------------------->| |card section (complemented)
| | |switch output|
| |------------------------------->| |card select
|
|------------------------------------>not used
ASWXOR==1617 ;complemented fields of ASW.
keyboard multiplexor 3/15/74
KBDPC==340 ;interrupt vector
KBDLVL==5_7 ;interrupts on level 5
KMS==164050 ;keyboard status
__|_____|_____|_____|_____|_____|
151413121110 9 8 7 6 5 4 1 |
|1|1|1|1|1|1|1|1|1|1|1| 3 | 2 |
|_|_|_|_|_|_|_|_|_|_|_|_____|___|
| | | | | | | | | | | | |
| | | | | | | | | | | | |------>KMA extension (bits 17 and 16)
| | | | | | | | | | | |
| | | | | | | | | | | |----------->not used
| | | | | | | | | | |
| | | | | | | | | | |--------------->interrupt enable
| | | | | | | | | |
| | | | | | | | | |----------------->direct memory access enable
| | | | | | | | |
| | | | | | | | |------------------->waiting to hack memory
| | | | | | | |
| | | | | | | |--------------------->8th floor elevator
| | | | | | |----------------------->9th floor elevator
| | | | | |
| | | | | |------------------------>extra OC output, pin BBF1.
| | | | |
| | | | |--------------------------->buzz the 9th floor door (dip relay)
| | | |
| | | |----------------------------->generate copy from second source(currently not
| | | enabled)
| | |------------------------------->generate copy from first source
| |
| |--------------------------------->ready line
|
|----------------------------------->waiting to interrupt
KMA==165052 ;keyboard memory address register
__|_____|_____|_____|_____|_____|
15 7 1 |
| 9 | 5 | 2 |
|_________________|_________|___|
| | |
| | |----->always 0
| |
| |------------>binary counter (overflow lost)
|
|------------------------->buffer origin
;keyboard multiplexor 3/15/74
;format of data written into memory (each record is two words)
;first word
__|_____|_____|_____|_____|_____|
151413 11 9 7 5 |
|1|1| 2 | 2 | 2 | 2 | 6 |
|_|_|___|___|___|___|___________|
| | | | | | |
| | | | | | |--------->key struck
| | | | | |
| | | | | |----------------->shift (7-left, 6-right)
| | | | |
| | | | |--------------------->top (9-left, 8-right)
| | | |
| | | |------------------------->control (11-left, 10-right)
| | |
| | |----------------------------->meta (13-left, 12-right)
| |
| |-------------------------------->shift lock
|
|---------------------------------->always 1
;second word
__|_____|_____|_____|_____|_____|
15 13 7 |
| 2 | 6 | 8 |
|___|___________|_______________|
| | |
| | |----------->high order bits of character (ignored)
| |
| |------------------------->console number
|
|--------------------------------->always 0
.ENDR
;CHARACTER FORMAT WRITTEN BY KBD MULTIPLEXOR
RCHAR==177700 ;6 BITS FOR KEY STRUCK
RSHBIT==300 ;SHIFT BITS
RTPBIT==1400 ;TOP BITS
RCLBIT==6000 ;CONTROL BITS
RMTBIT==30000 ;META BITS
RSLBIT==40000 ;SHIFT LOCK
RXTRA==100000 ;UNUSED BITS
;XTAB BITS USED FOR XTAB LOOK UP
XTPBIT==400 ;TOP
XSLBIT==200 ;SHIFT LOCK
XSHBIT==100 ;SHIFT
;POSITION OF META BITS, ASCII COMPATIBLE
ACTBIT==SNB ;CAUSES CHARACTER TO ACT AS ACTIVATOR
ACLBIT==200 ;CONTROL
AMTBIT==400 ;META
ASHBIT==XSHBIT_3 ;SHIFT
ASLBIT==XSLBIT_3 ;SHIFT LOCK
ATPBIT==XTPBIT_3 ;TOP
ACMBIT==AMTBIT+ACLBIT ;CONTROL AND META TOGETHER
.SBTTL ASSIGNMENTS
;GEOMETRY
BITPL==1100 ;BITS PER LINE
NLINS==706 ;LINES ON SCREEN
BYTPL==BITPL/10 ;BYTES PER LINE
WRDPL==BYTPL/2 ;WORDS PER LINE
CHRWD==6 ;CHARACTER WIDTH ON TEXT LINE
GRIDWD==5 ;WIDTH OF CHARACTER GRID
CHRHT==12 ;CHARACTER HEIGHT
CHRVSP==2 ;BLANK RASTER LINES BETWEEN CHARACTER LINES
LINHT==CHRHT+CHRVSP ;CHRACTER LINE HEIGHT
CHRPL==BITPL/CHRWD ;CHARACTERS PER LINE
CHRLN==NLINS/LINHT ;CHARACTER LINES ON SCREEN
NLINS1==CHRLN*LINHT ;# ROWS OF DOTS NOT INCL. WHOLINE.
;MEMORY MAP
NXMPC== 4 ;BUS ERROR VECTOR
NXMPSW== 6
RESPC== 10 ;RESERVED INTRUCTION VECTOR
RESPSW== 12
BPTPC== 14 ;BREAK POINT VECTOR
BPTPSW== 16
IOTPC== 20 ;IOT VECTOR
IOTPSW== 22
PWRPC== 24 ;POWER FAIL TRAP VECTOR
PWRPSW== 26
EMTPC== 30 ;EMULATE TRAP VECTOR
EMTPSW== 32
TRPPC== 34 ;TRAP INSTRUCTION VECTOR
TRPPSW== 36
TYIPC== 60 ;TTY INPUT INTERRUPT VECTOR
TYIPSW== 62
LKPC== 100 ;LINE CLOCK INTERRUPT VECTOR
LKPSW== 102
KLIPC== 320 ;KL11 INPUT INTERRUPT VECTOR
KLIPSW==322
KBDPC== 340 ;KEYBOARD MULTIPLEXOR INTERRUPT VECTOR
KBDPSW==342
PDLORG==400 ;ORIGIN OF PUSH DOWN LIST
TVLO=60000 ;ORIGIN OF DISPLAY MEMORY
TVFENCE=TVLO+<CHRLN*LINHT*BYTPL> ;ADDR OF FIRST TEXT LINE THAT SHOULDN'T BE USED
;(IT'S INCOMPLETE AND CONTAINS THE WHO-LINE).
TVCFENC=TVHI-<BYTPL*<CHRHT-1>> ;DON'T TRY TO DISPLAY A CHARACTER AFTER THIS POINT
TVHI=TVLO+<BYTPL*NLINS>-2 ;HIGHEST LEGAL DISPLAY ADDRESS
CSA=157776 ;DISPLAY REFRESH STARTING ADDRESS (STARTS AT 0)
CREG== 164044 ;UNIBUS CONSOLE REGISTER ADDRESS
CALU== 164045 ;CONSOLE REGISTER LOGICAL FUNCTION ADDR
KMS== 164050 ;KEYBOARD MULTIPLEXOR STATUS
KMA== 164052 ;KEYBOARD MULTIPLEXOR MEMORY ADDRESS
VSW== 164060 ;VIDEO SWITCH
ASW== 170670 ;AUDIO SWITCH
KLIS== 174000 ;KL11 INPUT STATUS
KLIB== 174002 ;KL11 INPUT BUFFER
KLOS== 174004 ;KL11 OUTPUT STATUS
KLOB== 174006 ;KL11 OUTPUT BUFFER
.EXPUNGE DIV,MUL,ASH ;THESE ARE PREDEFINED AS 11/45 INSTRUCTIONS.
DIV== 177300 ;EAE GOODIES
AC== 177302
MQ== 177304
MUL== 177306
SC== 177310
SR== 177311
NOR== 177312
LSH== 177314
ASH== 177316
LKS== 177546 ;LINE CLOCK STATUS
TKS== 177560 ;TTY KEYBOARD STATUS
TKB== 177562 ;TTY KEYBOARD BUFFER
TPS== 177564 ;TTY PRINTER STATUS
TPB== 177566 ;TTY PRINTER BUFFER
CSR== 177570 ;CONSOLE SWITCH REGISTER
PS== 177776 ;PROCESSOR STATUS REGISTER
...==0
....==0
;TEN/11 COMMUNICATIONS AREA
CHAP==40 ;CHANNEL HEADER AREA POINTER
POINTP==42 ;POINTER TO POINTER AREA
CIOVER==44 ;HOLDS I/O VERSION FOR PDP-10 TO LOOK AT
CVERSE==46 ;ASSEMBLY VERSION FOR PDP-10
;50 ;ALWAYS 0
INITED==52 ;INITED FLAG, SET BY 11 CLEARED BY 10
;54 ;ALWAYS 0
GDOWN==56 ;INTERLOCKS WITH INITED, CLEARED BY 11 SET BY 10
;CONSOLE REGISTER FUNCTIONS
CSETC==0
CNOR==1
CANDC==2
CSETZ==3
CNAND==4
CCOMP==5
CXOR==6
CANCSD==7
CEQV==11
CORCSD==10
CSAME==12
CAND==13
CORSCD==13
CSETO==14
CIOR==16
CSET==17
;INTERRUPT LEVELS
KBDLVL==5_5 ;KEYBOARD MULTIPLEXOR INT. PRIORITY (BUT HANDLER RUNS AT LKLVL).
LKLVL==6_5 ;LINE CLOCK
ERRLVL==7_5 ;PROCESSOR ERRORS
;MISCELLANEOUS ASSIGNMENTS
IOVER==3 ;I/O VERSION FOR ITS
PDL==400 ;PUSH DOWN LIST SIZE
MAXKBD==64. ;MAXIMUM # OF KEYBOARDS
MAXTV==14. ;MAX NUMBER OF CHANNELS; SIZE OF TABLES INDEXED BY CHANNEL.
MAXCRG==20 ;SIZE OF TABLES INDEXED BY CREG VALUE (BIT BUFFER NUMBER).
MAXBLK==MAXTV ;MAXIMUM # OF BLINKERS
MAXASI==20 ;AUDIO SWITCH INPUTS
MAXASO==100 ;AUDIO SWITCH OUTPUTS
ASWXOR==3400 ;XOR THIS INTO EACH CONTROL WORD TO BE SENT TO THE ASW.
MAXVSI==20 ;VIDEO SWITCH INPUTS
MAXVSO==40 ;VIDEO SWITCH OUTPUTS
VSWSEC==2 ;# VIDEO SWITCH SECTIONS
VSWINC==MAXVSO_10 ;INCREMENTS VIDEO SWITCH SECTION NUMBER
QPYVSW==27 ;VIDEO SWITCH OUTPUT FOR TEKTRONIX VIDEO HARD COPY UNIT
QPTIME==28.*60. ;28. SECONDS BETWEEN COPIES
QPYKMS==20000 ;GENERATE COPY FROM FIRST SOURCE (IN KEYBOARD STATUS, NATURALLY)
QPYKM2==10000 ;GENERATE COPY FROM SECOND SOURCE.
BUZKMS==4000 ;BUZZ DOOR (ALSO IN KEYBOARD STATUS)
BUZTIM==3*60. ;LEAVE THE DOOR BUZZING FOR 3 SECONDS
ELKMS8==1 ;8TH FLOOR ELEVATOR BIT, SWAPPED (IT LIVES IN BYTE 1 OR WORD)
ELKMS9==2 ;9TH FLOOR ELEVATOR BIT, SWAPPED.
ELEKMS==1400 ;ALL ELEVATOR BITS
ELETIM==20 ;PUSH THE BUTTON FOR 1/3 OF A SEC
KBDTIM==10. ;TIME UNTIL KEYBOARD GETS RESET (IN SEMI-SLOW CLOCK TICKS)
MAXBEL==4 ;MAXIMUM # OF BELLS ALLOWED
GLITIM==60.*60.*2 ;# CLOCK TICKS BETWEEN GLITCHES ON CONSOLE FREE DPY
NCQSLT==100 ;# CLOCK QUEUE SLOTS
KBDBFL==200 ;SIZE OF KEYBOARD BUFFER
LBLEN==100 ;PDP-10 INPUT BUFFER SIZE (BETTER BE DIVISIBLE BY 4)
LBCHRS==LBLEN/2 ;# CHARACTERS IN INPUT BUFFER
DPSIZE==600 ;PDP-10 OUTPUT BUFFER SIZE
BOWBIT==10000 ;CSA BLACK ON WHITE BIT
SAMSK==BOWBIT-1 ;MASK FOR SCROLL REGISTER
CSAMSK==170000 ;COMPLEMENT OF SAMSK
BLKTIM==15. ;CLOCK TICKS BETWEEN BLINKS
SNB==100000 ;SIGN BIT
PATL==400 ;SIZE OF PATCH AREA
CMDARG==10 ;# ARGUMENTS WHICH WILL FIT INTO PDP-10/PDP-11 COMMAND BUFFER
RUGSA==57100 ;STARTING ADDRESS OF RUG
TYMSLC==2 ;MAX # 60THS OF A SECOND, MINUS 1, TO CONCENTRATE ON ONE TV
.SBTTL GO CODE, PDL, AND KBD BUFFER
.ABS
;PUSH DOWN LIST AND KEYBOARD BUFFER
.=PDLORG+PDL
.IIF NE .&177,.=<.&177600>+200 ;ALIGN ON 200 BYTE BOUNDARY
PDBUF==.
KBDBUF:
.=.+KBDBFL
KBDEND==.
REPORT GO=,\GO
GO: RESET ;IN THE PRIVACY OF YOUR OWN HOME
CLR PS
MOV #PDBUF,SP ;SET UP PUSH DOWN POINTER
MOV #ERRLVL,C ;ALL PROCESSOR TRAPS GO ON 7
MOV #NXMPC,B
MOV #NXMBRK,(B)+ ;BUS TIME OUT
MOV C,(B)+
MOV #RESBRK,(B)+ ;RESERVED INSTRUCTION
MOV C,(B)+
MOV (B),T ;BREAK POINT
BNE .+6
MOV #BPTBRK,T
MOV T,(B)+
MOV C,(B)+
MOV #IOTBRK,(B)+ ;IOT TRAP
MOV C,(B)+
MOV #PWRBRK,(B)+ ;POWER FAILURE
MOV C,(B)+
MOV #EMTBRK,(B)+ ;EMT
MOV C,(B)+
MOV #TRPBRK,(B)+ ;"TRAP" TRAP (LEV 7)
MOV C,(B)+
MOV #CHA,(B)+ ;CHANNEL HEADER AREA
MOV #POINTA,(B)+ ;POINTER AREA POINTER
MOV #IOVER,(B)+ ;I/O VERSION
MOV VERSE,(B)+ ;ASSEMBLY VERSION
CLR (B)+ ;INITED
CLR (B)+
MOV C,(B)+ ;NON-ZERO SUFFICES
MOV C,(B)+ ;GDOWN
MOV #CLKBRK,LKPC ;CLOCK
MOV #LKLVL,LKPSW
MOV #KBDBRK,KBDPC ;KBD
MOV #LKLVL,KBDPSW
MOV #BPT,0 ;CATCH JUMPS TO ZERO.
;FALLS THROUGH
;INITIALIZE VARIBLES FALLS THROUGH
JSR PC,INIT
;ENABLE INTERRUPTS
MOV #100,LKS ;CLOCK
MOV #KBDBUF,KMA
MOV #KBDBUF,OLDKMA
MOV #140,KMS ;KEYBOARD MULTIPLEXOR
MOV #-1,INITED
;THE MAIN LOOP
MAIN: MOV #MAXTV-1,U ;CHANNEL
CMP WHOTIM,ITSTI1 ;TIME FOR WHO LINES?
BEQ MAIN1
ZAPFLG WHOFLG ;TRIGGER WHO LINES
MAIN1: TST INITED
BEQ GO ;RESET THE WORLD
TST CSR
BLT GO2RUG ;SWITCH 15 => GO TO RUG
MAIN3: JSR PC,DPYDPY
MOV CMDFLG,A ;PDP-10 GIVING COMMAND?
BLE MAIN2
PUSH U
JSR PC,TENCMD ;PROCESS THE COMMAND
POP U
MAIN2: DEC U
BGE MAIN1 ;CYCLED THROUGH ALL CHANNELS?
CLR WHOFLG ;TURN OFF WHO LINES
BR MAIN
GO2RUG: BPT
BR MAIN3
;HERE TO RESTART, NOTIFY THE PDP-10
GODOWN: RESET
CLR PS
MOV #INITED-2,B
CLR (B)+
CLR (B)+ ;INITED
CLR (B)+
CLR (B)+ ;GDOWN
TST GDOWN ;WAIT FOR THE PDP-10 TO REPLY
BEQ .-4
JMP GO
.SBTTL INITIALIZATION
INIT: CLR TICKS
CLR TICKS1
;******* TEMPORARY CODE FOR FONT CHECKSUM *******
MOV #FNTORG,T
MOV T,CKSPNT
CLR CKSSUM
CLR TT
1$: ADD (T)+,TT
CMP T,#FNTEND
BLO 1$
MOV TT,CKSSMG
;******* END OF TEMPORARY CODE *******
CLR KBDFLG
CLR KBDFLG+2
CLR KBDACT
CLR KBDLAST
CLR KBDTSW
CLR CMDFLG
CLR CMDFLG+2
CLR WHOTIM
CLR ITSTI1
CLR WHOFLG
CLR TENWHO
CLR QPYSWT
CLR BUZSWT
CLR ELESWT
CLR SSCC
JSR PC,REASW ;FEED EVERY SPEAKER SILENCE.
MOV #LEBUFS,U ;INITIALIZE FREE LIST OF 11-TO-10 INPUT BUFFERS.
MOV U,FSP
MOV #NLBUFS-1,B
INIT6: MOV U,TT
ADD #<LHLEN+LBLEN>,TT
MOV TT,LHFS(U)
MOV TT,U
DEC B
BGT INIT6
CLR LHFS(U) ;END OF LIST
CLR BLINK
;SET UP TABLES INDEXED BY BIT-BUFFER NUMBER.
MOV #BLINKS,A
MOV #BELCNT,C
MOV #MAXCRG-1,B
1$: CLR (A)+
CLRB BLKSWT(B) ;NO TV HAS BLINKING TEMPORARILY INHIBITED.
MOV #-1,(C)+
DEC B
BGE 1$
;SET UP TABLES INDEXED BY TV NUMBER.
MOV #MAXTV-1,B
CLR ITSTDP
INIT5: CLRB CHNUSE(B) ;EVERY CHANNEL IS FREE.
TSTB CHCREG(B) ;HOW MANY CHANNELS ARE WORKING?
BLT INIT5A
INC ITSTDP
INIT5A: DEC B
BGE INIT5
MOV ITSTDP,ITSFDP ;# FREE DPY'S
MOV #MAXBLK,B ;PUT ALL BLINKER BLOCKS ON THE FREE BLINKERS LIST.
MOV #BLKVAR,U
MOV U,FBLINK
INIT7: MOV U,TT
ADD #BLLEN,TT
MOV TT,BLNEXT(U)
CLRB BLON(U)
MOV TT,U
DEC B
BGT INIT7
CLR <BLNEXT-BLLEN>(U)
MOV #MAXTV-1,A
CLR T
MOV #WHVARS,C
INIT2: MOV DPYCHN(T),U
JSR PC,CHCLR ;SET UP THAT CHANNEL
MOV #-1,DPYKBD(T)
MOV #-1,CHNCLS(T)
CLR ECOFLG(T)
MOV C,WHOLIN(T)
MOV #-1,(C) .SEE WHJOB
ADD #WHLEN,C
CMP (T)+,(T)+
DEC A
BGE INIT2 ;MORE DPY CHANNELS TO SET UP?
MOV #-1,C
JSR PC,CHCONS ;GET A CHANNEL FOR THE FREE SCREENS.
TST T
BEQ .+4 ;THIS SHOULD ALWAYS GIVE US CHANNEL 0.
BPT
MOV WHOLIN,TT ;WANT SYSTEM WHO LINE ON CONSOLE FREE DPY
MOV #NWHCMD,WHMODE(TT)
MOVB CHCREG,TT ;TT GETS WHICH VIDEO BUFFER IT IS.
MOV TT,DPYFRE ;REMEMBER # OF DPY USED FOR FREE SCREENS.
MOVB TT,CREG ;SET UP CONSOLE REGISTER FOR PRINT
CLR CSA
TYPOUT </TV's ready, but not in operation
/>
MOVB LECREG(U),C ;DPY
ASL C
MOV #MAXVSO-1,B ;SWITCH TO ALL OUTPUTS
INIT1: MOV DPYVSW(C),TT ;VIDEO SWITCH INPUT
MOV B,T ;SWITCH OUTPUT
JSR PC,VSWIT
DEC B
BGE INIT1
MOV #MAXKBD,A ;CLEAR KBDLE
CLR B
INIT8: CLR KBDLE(B)
CLR KBDESC(B)
MOV #-1,KBDDEF(B)
TST (B)+
DEC A
BGT INIT8
MOV #NCQSLT-1,C ;INITIALIZE CLOCK QUEUE
CLR CLOCKQ
MOV #CQUEUE,A
MOV A,CLOCKF
INIT9: MOV A,B
ADD #CQLEN,B
MOV B,(A)
MOV B,A
DEC C
BGT INIT9
CLR (A)
MOVB #CSET,CALU
MOV CREG,T ;SEED QUEUE WITH GLITCH CONSOLE FREE
JSR TT,ADQUE
GLITIM
MSGLIT
RTS PC
.SBTTL MAIN PROGRAM LEVEL ROUTINES
;HERE TO GET CHARACTER FROM OPEN CHANNEL
;LOOPS UNTIL NO MORE CHARACTERS AVAILABLE
DPYDPY: TSTB CHNUSE(U)
BLE DPYD5 ;IGNORE FREE DISPLAYS.
PUSH U ;DPY CHANNEL NUMBER
ASL U
ASL U
PUSH U
MOV DPYCHN(U),U ;U GETS CHANNEL VAR BLOCK ADDR
JSR PC,GETCHR ;ANY OUTPUT FOR THIS CHANNEL?
BEQ DPYDON ;NO, GO CHECK FOR WHO LINES, ETC.
MOV #TYMSLC,TYMSHR ;MAX TIME BEFORE CHECKING OTHER CHANNELS
MOVB LECREG(U),T ;SET UP CONSOLE REGISTER
MOVB T,CREG
PUSH T
BLKOFF T ;TURN OFF ALL BLINKERS ON THIS SCREEN
JSR PC,CLBLIN ;AND CLEAR THEM
PUSH U ;SAVE PAGE PRINTER FOR DPYTVO+5
MOVB #CIOR,CALU ;ALU FUNCTION FOR DRAWING CHARACTERS
MOV LESTKP(U),B ;JUMP IF NOT RESUMING A COROUTINE.
BEQ DPYDP1
PUSH #DPYXIT ;UNDER WHAT'S IN LESTK, PUT A RETURN TO DPYXIT.
MOV #LESTK,TT
ADD U,TT
2$: MOV -(B),T
PUSH T ;COPY USED PART OF LESTK BACK ONTO STACK.
CMP B,TT
BNE 2$
MOV LESVB(U),B ;RESTORE COROUTINED ACS.
MOV LESVC(U),C
MOV LESVT(U),T
MOV LESVTT(U),TT
CLR LESTKP(U) ;SAY WE ARE NOT STOPPED IN A COROUTINE NOW.
BIC #-400,A ;CLEAR EXTRA BITS DUE TO SIGN-EXTENSION
RTS PC ;RETURN TO THE CO-CALL
;FAST CHARACTER OUTPUT LOOP
DPYDP1: MOV (SP),U ;GET PP POINTER
MOVB A,A ;FLUSH HIGH BITS FROM CHAR
BLT DPYCTL ;BRANCH IF NON-PRINTING CONTROL FUNCTION
DPYTVO: MOV LEPHS(U),C ;SET UP TO DRAW CHARACTER
MOV LECC(U),TT ;THIS IS OPEN-CODED FOR SPEED
ASL A ;COPIED FROM CODE AT GENCHR
MOV CTAB(A),T
JSR PC,GENCH1 ;GENERATE CHARACTER, CLOBBER ALL ACS
MOV (SP),U ;RESTORE PP POINTER, CLOBBERED BY GENCH1
JSR PC,LEDADC ;ADVANCE CURSOR
DPYXIT: TST TYMSHR ;TIME UP?
BMI DPYDX2 ;YES, LEAVE THIS TV FOR A WHILE
MOV (SP),U
JSR PC,GETCHR ;NO, GET NEXT CHARACTER
BNE DPYDP1 ;AND LOOP BACK TO PROCESS IT
DPYDX2: POP U
POP T ;DONE WITH THIS DPY FOR NOW
BLKON T ;ALLOW BLINKERS TO BLINK AGAIN
BR DPYDON
;HERE IF NO CHARACTER AVAILABLE. TWO WORDS STILL ON THE STACK:
;(SP) IS 4 TIMES CHANNEL NUMBER, 2(SP) IS CHANNEL NUMBER (TO BE POPPED INTO U).
DPYDON: POP B
TST CHNCLS(B)
BLT DPYFLS ;FLUSH DPY CHANNEL?
TST ECOFLG(B)
BEQ DPYD2 ;CAUSE PSEUDO ACTIVATION?
MOV U,T
ADD #LEZER0,T
CHROFF
MOV KBDACT,LELIST(TT) ;PUT LINE EDITOR ON ACTIVE RING
MOV T,KBDACT
TST KBDFLG
BNE DPYD0
MOV T,KBDFLG
CLR KBDACT
CLR KBDLAST
DPYD0: CHRON
DPYD1: CLR ECOFLG(B)
DPYD2: TST WHOFLG ;DO WHO LINES?
BEQ DPYD3
MOV WHOLIN(B),T
TST WHMODE(T)
BMI DPYD4 ;DON'T DO WHO LINE, BUT MIGHT WANT TO CLEAR IT
TST WHO1(T)
BMI DPYD4 ;USER WHO MODE VAR CAN ALSO DISABLE WHO LINE
JSR PC,DOWHO ;DO THE WHO LINE FOR THIS GUY
DPYD3: POP U
DPYD5: RTS PC
;HERE IF NO WHO LINE IS TO BE DONE, WE MIGHT WANT TO CLEAR IT
DPYD4: MOV WHOLIN(B),T
TST 2(T) ;IF NEGATIVE, THEN CLEAR IT
BGE DPYD3
CLR 2(T) ;ZAP THE SWITCH
JSR PC,ZAPWHL ;CLEAR THE LINE
BR DPYD3
;HERE TO FLUSH DPY CHANNEL
DPYFLS: MOV (SP),T
TSTB CHNUSE(T) ;ALREADY FREED?
BEQ DPYD3 ;YES, THIS MEANS MAIN LOOP SHOULD SIMPLY IGNORE THIS DPY.
CHROFF
JSR PC,CHRETN
CHRON
BR DPYD3
;HERE IF CONTROL CODE FOUND
DPYCTL: BIC #177600,A ;DISPATCH ON CONTROL CODE
CMP #ILLCTL,A
BLOS DPYTVO ;BRANCH IF ILLEGAL CODE
ASL A
PUSH #DPYXIT ;MAKE THE RETURN ADDR BE "DPYXIT"
JMP @CTLTAB(A) ;SO GETCHC COROUTINING WILL WORK.
;CONTROL FUNCTION ROUTINES CALLED WITH PP INDEX IN U.
;MAY CLOBBER ALL ACS BUT MUST LEAVE CIOR IN CALU. MANY ARE ALSO
;CALLED FROM ELSEWHERE AND EXPECTED TO PRESERVE U.
CTLTAB: SETCUR ;200 %TDMOV (FOLLOWED BY TWO IGNORED CHARS, THEN VPOS, HPOS).
SETCR1 ;201 %TDMV1 (FOLLOWED BY NEW VPOS AND NEW HPOS)
CLEOF ;202 %TDEOF (CLEAR TO END OF SCREEN)
CLEOL ;203 %TDEOL (CLEAR TO END OF LINE)
CLRCHR ;204 %TDDLF (DELETE FORWARD)
RTSPC ;205 %TDMTF (MOTOR OFF - IGNORED)
RTSPC ;206 %TDMTN (MOTOR ON - IGNORED)
CRLF ;207 %TDCRL (CRLF AND CLEAR EOL, BUT SCROLL AT END OF SCREEN)
RTSPC ;210 %TDNOP (NO-OP)
DPYBS ;211 %TDBS (BACKSPACE)
LF ;212 %TDLF (LF)
CR ;213 %TDRCR (RAW CR)
RTSPC ;214 %TDORS (OUTPUT RESET - WE CAN'T DO ANYTHING USEFUL)
RTSPC ;215 %TDQOT (DEVICE DEPENDENT DATA FOLLOWS - WELL, THIS DEVICE
;SAYS IT DOESN'T REALLY DEPEND)
LEDADC ;216 %TDFS
SETCR1 ;217 %TDMV0 (SAME AS %TDMV1 FOR OUR PURPOSES)
DPYCLR ;220 %TDCLR (HOME UP AND CLEAR SCREEN)
BELL ;221 %TDBEL (FLASH THE SCREEN)
RTSPC ;222 %TDINI (REINITIALIZE INTELLIGENT TERMINAL (NOT APPLICABLE))
LINS ;223 %TDILP (INSERT LINE POSITION (FOLLOW BY # LINES TO INSERT))
LDEL ;224 %TDDLP (DELETE LINE POSITION (FOLLOW BY # LINES TO DELETE))
CINS ;225 %TDICP (INSERT CHARACTER POSITION (FOLLOW BY # CHARS))
CDEL ;226 %TDDCP (DELETE CHARACTER POSITION (FOLLOW BY # CHARS))
RTSPC ;227 %TDBOW (IGNORED)
GRFRST ;230 %TDRST (RESET MODES. FOR NOW ONLY GRAPHICS MODES EXIST).
GRFLP ;231 %TDGPH (START GRAPHICS COMMANDS)
RGSCUP ;232 %TDRSU (REGION SCROLL UPWARDS)
RGSCDN ;233 %TDRSD (REGION SCROLL DOWN)
ILLCTL==<.-CTLTAB>/2
.SBTTL WHO LINE ROUTINES
;PRINTS WHO LINE, TAKES 10/11 CHANNEL IN B
DOWHO: PUSH B ;SAVE 10/11 CHANNEL
MOV ITSTI1,WHOTIM ;TIME WE DID WHO LINE
MOV #WHOPP,TT ;SET DEFAULTS FOR WHO PAGE PRINTER
MOV #LEDFLT,T
MOV #LELEN,U
JSR PC,CALCPY ;ZAP
MOV #WHOPP,U ;SET UP PAGE PRINTER INDEX
CLR A ;CHARACTER X
MOV #CHRLN,B ;CHARACTER Y, PAST LAST LINE
JSR PC,SETXY0
MOV (SP),B ;RESTORE 10/11 CHANNEL INDEX
MOV WHOLIN(B),A
TST WHO1(A) ;SIGN OF .WHO1 VARIABLE INHIBITS ALL HACKERY
BPL .+4 ;ASSUME USER HAS STUFF THERE AND SHOULDN'T CLOBBER IT.
RTS PC
JSR PC,ZAPWHL ;CLEAR OUT THE WHO LINE
WHINIT: MOV (SP),B ;10/11 CHANNEL INDEX
MOV WHOLIN(B),TT
CMP #NWHCMD-1,WHMODE(TT)
BHI DATIME ;NO VERSION NUMBER FOR USER WHO LINE
TYPOUT /ITS /
DECTYP ITSVER ;TYPE VERSION NUMBER
JSR PC,SPACE
TST ITSDBG
BEQ DATIME
TYPOUT /BEING DEBUGGED /
;TYPES DAY TIME AND DATE
DATIME: MOV ITSDAT,A ;PRINT PACKED DATE FIRST
JSR PC,DATTYP ; 7 BITS YEAR, 4 MONTH, 5 DAY
JSR PC,SPACE
MOV #MQ,B
MOV ITSTI1,(B)
MOV ITSTIM,-(B)
JSR PC,TIMTY1 ;TYPE DAY TIME NEXT
JSR PC,SPACE
POP B ;10/11 CHANNEL
MOV WHOLIN(B),TT
CMP #NWHCMD-1,WHMODE(TT)
BHI UWHLDO ;DO USER WHO LINE?
;SYSTEM WHO LINE
;ITS XXX {BEING DEBUGGED} MM/DD/YY HH:MM:SS ITSFDP/ITSTDP USR RU/JOB SHARE SWBJ JWP TRC/COR CFU
SWLDO: TYPOUT /TVS: /
DECTYP ITSFDP ;# FREE DPYS
JSR PC,SLASH
DECTYP ITSTDP ;TOTAL DPYS
TYPOUT / USERS: /
DECTYP ITSUSR ;# SYSTEM USERS
JSR PC,SPACE
DECTYP ITSRU ;RUNABLE JOBS/
JSR PC,SLASH
DECTYP ITSJOB ;# SYSTEM JOBS
JSR PC,SPACE
DECTYP ITSFSH ;FAIR SHARE IN %
TYPOUT /% SB=/
DECTYP ITSWBJ ;SWAP BLOCKED JOBS
TYPOUT / PG=/
DECTYP ITSJWP ;JOBS WAITING FOR PAGES
TYPOUT / CORE: /
DECTYP ITSTRC ;RUNABLE CORE
JSR PC,SLASH
DECTYP ITSCOR ;TOTAL CORE
JSR PC,SPACE
DECTYP ITSCFU ;CORE FOR USERS
RTS PC
;USER WHO LINE
;MM/DD/YY HH:MM:SS JOB UNAME JNAME SNAME STATUS J%RT HH:MM:SS.S JCORE {USER VARS}
WHNOJB: TYPOUT / JOB SLOT VACANT/ ;HERE IF JOB SLOT VACANT
RTS PC
UWHLDO: OCTYPE WHJOB(TT) ;JOB #
TST WHSTAT(TT)
BEQ WHNOJB ;VACANT JOB SLOT?
JSR PC,SPACE
MOV #WHUNAM,T
ADD TT,T
JSR PC,SIXPNT ;UNAME
JSR PC,SPACE
JSR PC,SIXPNT ;JNAME
JSR PC,SPACE
JSR PC,SIXPNT ;SNAME
JSR PC,SPACE
JSR PC,SIXPNT ;STATUS
JSR PC,SPACE
DECTYP WHJ%RT(TT) ;JOB % RUN TIME
JSR PC,SLASH
DECTYP ITSFSH ;OUT OF FAIR SHARE
JSR PC,PERCNT
JSR PC,SPACE
MOV WHJTRT(TT),A ;JOB RUNTIME IN .1-SEC TICKS
JSR PC,TIMTEN
JSR PC,SPACE
DECTYP WHRPAG(TT) ;# PAGES REAL CORE
JSR PC,SLASH
DECTYP WHTPAG(TT) ;# PAGES OF VIRTUAL CORE
MOV #'K,A
JSR PC,TVO
JSR PC,SPACE
MOV WHO1(TT),A ;PRINT FIRST USER WHO VAR
MOV #WHO2,T
JSR PC,UWVDO
MOV WHO1A(TT),A ;MAYBE PRINT SPACE
BMI UWHLD1
JSR PC,SPACE
MOV WHO1A(TT),A
UWHLD1: MOV #WHO3,T ;NOW SECOND USER WHO VAR
;TAKE CONTROL WORD IN A, OFFSET (OFF TT) TO FOUR WORDS IN T, PRINT USER WHO VAR
;CONTROL WORD:
; 15 USED ELSEWHERE - IGNORE HERE
; 14 SUPPRESS SPACE BETWEEN TWO HALVES
; 13-11 MODE FOR FIRST HALF
; 10-08 MODE FOR SECOND HALF
; 07 DOUBLE 06-00
; 06-00 CHARACTER TO PRINT AFTER FIRST HALF, BEFORE SPACE
UWVDO: PUSH A ;SAVE CONTROL WORD
ADD TT,T ;T POINT TO VAR
MOVB 1(SP),A
ASR A ;GET FIRST MODE
ASR A
ASR A
JSR PC,UWVDO4 ;PRINT FIRST HALF
MOVB (SP),A
BEQ UWVDO1
BIT #200,A
BEQ UWVDO3
JSR PC,TVOMSK ;SEPARATOR CHAR(S)
UWVDO3: JSR PC,TVOMSK
UWVDO1: BITB #100,1(SP)
BNE UWVDO2
JSR PC,SPACE ;INTERVENING SPACE
UWVDO2: MOVB 1(SP),A ;GET SECOND MODE
TST (SP)+ ;POP CONTROL WORD, THEN DO SECOND HALF
UWVDO4: BIC #177770,A
ASL A
JMP @UWVDTB(A)
UWVDTB: RTSPC ;0 DON'T PRINT
UWVDAT ;1 PACKED DATE AS MM/DD/YY
UWVTEN ;2 TIME IN .025 SECONDS AS HH:MM:SS.T
UWVHAK ;3 TIME IN .5 SECONDS AS HH:MM:SS
UWVHAK ;4 OCTAL (18. BITS)
UWVHAK ;5 DECIMAL (18. BITS)
SIXPN1 ;6 THREE SIXBIT CHARS
RTSPC ;7 RESERVED FOR EXPANSION
;USER-CONTROLLED WHO-LINE FIELD PRINT-OUT ROUTINES.
UWVHAK: MOV #MQ,B
TST (T)+
MOV (T),(B)
MOV -(T),-(B)
CMP (T)+,(T)+
MOV #-14.,LSH
JMP @UWVDT1-6(A)
UWVDT1: TIMTY1
UWVOCT
UWVDEC
UWVOCT: MOV #10,B
BR UWVDC1
UWVDEC: MOV #10.,B
UWVDC1: PUSH RADIX
MOV B,RADIX
JSR PC,DECPN9
POP RADIX
RTS PC
UWVTEN: MOV (T)+,A
TST (T)+
JMP TIMTEN
UWVDAT: MOV (T)+,A
TST (T)+
JMP DATTYP
;SOME WHO LINE UTILITY ROUTINES
PERCNT: MOV #'%,A
JMPTVO: JMP TVO
SPACE: MOV #40,A
BR JMPTVO
SLASH: MOV #'/,A
BR JMPTVO
;TAKES POINTER TO SIXBIT IN T AND TYPES IT (ADVANCING T)
SIXPNT: JSR PC,SIXPN1 ;DO TWO SETS OF THREE CHARS
SIXPN1: MOV #MUL,B ;DO ONE SET OF THREE CHARS
MOV #LSH,C
CMP (T)+,(T)+ ;BAG BITING EAE HAS TO LOADED IN JUST THE RIGHT ORDER
MOV -(T),-(B) ;LOW ORDER FIRST
MOV -(T),-(B)
CMP (T)+,(T)+
MOV #-10.,(C) ;FIRST CHARCTER IN AC, THE REST IN MQ
JSR PC,SIXPN2 ;PRINT FIRST CHAR
JSR PC,SIXPN2 ;PRINT SECOND, FALL IN FOR THIRD
SIXPN2: MOV (B)+,A ;SIXBIT
ADD #40,A ;ASCII
PUSH (B)+
JSR PC,TVO
POP -(B)
CLR -(B) ;CLEAR AC
MOV #6,(C) ;NEXT CHARACTER INTO AC
RTS PC
;TAKES TENTHS OF SECONDS IN A AND PRINTS AS HH:MM:SS.T
TIMTEN: MOV #MQ,T
MOV A,(T)
CLR -(T)
MOV #10.,-(T) ;DO DIVIDE
TST (T)+
PUSH (T)+ ;TENTH'S OF SECONDS
MOV (T),A
ASL A ;# HALF SECONDS JOB HAS BEEN RUNNING
JSR PC,TIMTYP ;TYPE TIME
MOV #'.,A
JSR PC,TVO
POP A ;TENTH'S OF SECONDS
JMP DECPNT
;TAKES # HALF SECONDS IN A AND TYPES TIME IN HH:MM:SS FORMAT
TIMTYP: MOV #MQ,B
MOV A,(B)
CLR -(B)
;TAKE # HALF SECONDS IN EAE AC-MQ AND TYPE AS HH:MM:SS
TIMTY1: MOV #120.,-(B) ;MINUTES SINCE MIDNIGHT
TST (B)+
PUSH (B) ;REMAINDER IS SS*2
ASR (SP)
CLR (B) ;CLEAR AC
MOV #60.,-(B) ;HOURS SINCE MIDNIGHT
TST (B)+
PUSH (B)+ ;REMAINDER IS MM
MOV (B),A ;HH
JSR PC,DECPNT
MOV #':,C ;COLON SEPARATES GOODIES
POP A
JSR PC,MSDPNT ;PRINTS COLON AND PADS WITH LEADING ZERO IF NECESSARY
POP A
MSDPNT: PUSH A
MOV C,A ;PRINT SEPARATING CHARACTER
JSR PC,TVO
CMP #10.,(SP)
BLE MSDPN1 ;PAD WITH LEADING ZERO?
MOV #'0,A
JSR PC,TVO
MSDPN1: POP A
JMP DECPNT ;PRINT NUMBER
;TAKE DATE PACKED AS 7 BITS YEAR, 4 MONTH, 5 DAY AND PRINT AS MM/DD/YY
DATTYP: MOV #MQ,B
MOV A,(B)
CLR -(B) ;CLEAR AC
MOV #LSH,C
MOV #7,(C) ;YEAR
PUSH (B)
CLR (B)
MOV #4,(C) ;MONTH
MOV (B),A
CLR (B)
MOV #5,(C) ;DAY
PUSH (B)
JSR PC,DECPNT ;PRINT MONTH
MOV #'/,C ;USE SLASH AS SEPARATOR
POP A
JSR PC,MSDPNT ;PRINT DAY
POP A
JMP MSDPNT ;PRINT YEAR
.SBTTL PDP-10 COMMAND PROCESSOR SWITCH VIDEO SWITCH, ETC.
TENCMD: CMP #MAXCMD,A ;LEGAL COMMAND?
BLOS TENCFL ;NO, COMMAND FAILS
ASL A ;BYTES FOR DISPATCH
JMP @TENDSP(A)
;PDP-10 COMMAND DISPATCH
TENDSP: TENCFL ;0 ILLEGAL
TENVSW ;1 VIDEO SWITCH
TENDPC ;2 CONS DPY FOR PDP-10
TENDPR ;3 RETURN DPY
TENRVS ;4 READ VIDEO SWITCH
TENASW ;5 AUDIO SWITCH
TENRAS ;6 READ AUDIO SWITCH
MAXCMD==<.-TENDSP>/2
;HERE TO SWITCH VIDEO SWITCH
TENVSW: MOV CMDBUF,TT ;SWITCH INPUT
MOV CMDBUF+4,T ;SWITCH OUTPUT
CHROFF ;INHIBIT INTERRUPTS WHILE WE DO THIS
JSR PC,VSWCMD ;CHECKS FOR LEGAL BEFORE SWITCHING
BHIS TENCF1 ;JUMP IF THEY WERE ILLEGAL.
TENCS1: CHRON
TENCSD: MOV #-1,CMDFLG ;COMMAND SUCCEEDS
RTS PC
;SWITCH AUDIO SWITCH UPON COMMAND FROM PDP-10
TENASW: MOV CMDBUF,TT ;SWITCH INPUT
MOV CMDBUF+4,T ;SWITCH OUTPUT
CHROFF
JSR PC,ASWCMD ;SWITCH SWITCH, TESTING LEGALITY.
BHIS TENCF1 ;JUMP IF THEY WERE ILLEGAL, TO SAY COMMAND FAILED.
BR TENCS1
;HERE TO CONS UP DPY FOR PDP-10
TENDPC: CHROFF ;INHIBIT INTERRUPTS AGAIN
MOV CMDBUF,C ;ARG IS KEYBOARD TO USE, OR -1 FOR NO KEYBOARD.
CMP C,#MAXKBD ;BUT BARF IF ILLEGAL KEYBOARD NUMBER.
BGE TENCF1
JSR PC,CHCONS ;GET A CHANNEL, CONNECT IT TO THAT KEYBOARD.
TST T
BLT TENCF1 ;CAN'T => COMMAND FAILS.
MOVB LECREG(U),CMDBUF ;ELSE RETURN THE VIDEO BUFFER NUMBER
CLRB CMDBUF+1
MOV T,CMDBUF+4 ;AND THE 10-11 CHANNEL NUMBER (TTY NUMBER MINUS 52).
BR TENCS1
TENCF1: CHRON
TENCFL: CLR CMDFLG ;REPORT FAILURE OF A COMMAND TO THE TEN.
RTS PC
;HERE TO RETURN DPY ON COMMAND
TENDPR: MOV CMDBUF,TT ;THE DPY TO RETURN
MOV #MAXTV-1,T
TENDR0: CMPB CHCREG(T),TT ;WHICH CHANNEL DOES IT BELONG TO? GET # IN T.
BEQ TENDR1
DEC T
BGE TENDR0
BR TENCSD
TENDR1: TST CHNUSE(T) ;DO NOTHING IF THE CHANNEL IS FREE.
BEQ TENCSD
CHROFF ;OTHERWISE, FREE THAT CHANNEL.
JSR PC,CHRETN
BR TENCS1
;HERE RETURN STATE OF VIDEO SWITCH
TENRVS: JSR PC,SWTARG ;SET UP 10-11 CHANNEL ARGUMENT
BLOS TENCFL ;ILLEGAL ARG MAKES COMMAND FAIL
JMP @RVSDSP(T)
RVSDSP: TENCFL ;0 IS ILLEGAL
RVSCHN ;1 10/11 CHANNEL #
RVSKBD ;2 KBD #
RVSOUT ;3 VIDEO SWITCH OUTPUT #
NSWTRG==<.-RVSDSP>/2
RVSKBD: JSR PC,CHKKBD ;HERE GIVEN KBD #; TEST IT.
BHI RVSCH1 ;IF LEGAL, FALL INTO MAIN LINE CODE
BR TENCFL ;ILLEGAL, TELL HIM SO
RVSOUT: MOV CMDBUF+4,TT ;HERE GIVEN VIDEO SWITCH OUTPUT #.
MOV #-1,T ;ILLEGAL KBD #
CMP #MAXVSO,TT ;CHECK FOR LEGAL
BHI RVSCH2 ;FALL INTO MAIN LINE CODE
BR TENCFL ;HERE IF ILLEGAL
RVSCHN: JSR PC,CHNKBD ;HERE GIVEN 10-11 CHANNEL #; GET KBD # IN T
BLOS TENCFL
RVSCH1: MOVB KBDVSW(T),TT ;GET VIDEO SWITCH OUTPUT INTO TT
RVSCH2: MOV TT,CMDBUF+<4*4> ;PUT VIDEO SWITCH OUTPUT INTO COMMAND BUFFER
MOV TT,CMDBUF+<3*4>
TST CMDBUF
BMI RVSDF ;BRANCH IF HE WANTS DEFAULT INPUT OF THIS OUTPUT.
MOVB VSWTAB(TT),TT ;GET CURRENT INPUT OF THIS OUTPUT AND STORE.
BR RVSCH3
RVSDF: ASL T ;MAKE IT BYTE INDEX
BMI RVSNL ;NEGATIVE IF NOT LOGGED IN
MOV KBDLE(T),U
BEQ RVSNL ;KBD NOT LOGGED IN, ITS THE DEFAULT
RVSDF1: MOVB LECREG(U),TT ;THE REGISTER HE HACKS
CMP #MAXCRG,TT
BLOS TENCFL ;BRANCH IF ILLEGAL CONSOLE #
ASL TT ;MAKE IT A BYTE INDEX
MOV DPYVSW(TT),TT ;VIDEO SWITCH INPUT
RVSCH3: MOV TT,CMDBUF+<2*4> ;STORE SWITCH INPUT INTO COMMAND BUFFER
BR TENCSD
RVSNL: MOV DPYCHN,U ;CHANNEL 0 IS CONSOLE FREE CHANNEL
BR RVSDF1 ;AND BACK INTO MAIN STREAM
;GIVEN 10/11 CHANNEL # AND RETURNS KBD IN T
CHNKBD: MOV CMDBUF+4,T ;PICK UP CHANNEL #
CMP #MAXTV,T
BLOS CHNKB2
ASL T ;MAKE CHANNEL # INTO INDEX INTO CHANNEL TABLES
ASL T
TST CHNCLS(T) ;MAKE SURE CHANNEL IS OPEN
BLT CHNKB3
MOVB DPYKBD(T),T ;PICK UP KBD #
CHNKB1: CMP #MAXKBD,T ;FIX CONDITION CODES FOR SUCCESSFUL RETURN
CHNKB2: RTS PC
CHNKB3: MOV #MAXKBD+1,T ;HERE IF CHANNEL CLOSED
BR CHNKB1 ;CONS UP ILLEGAL KBD #
CHKKBD: MOV CMDBUF+4,T ;CHECK FOR REASONABLE KBD #
BR CHNKB1
;HERE TO SET UP SWITCH ARG FOR 10-11 COMMAND RETURN IN CONDITION CODES
;IS THE RESULT OF CMP #NCHARG,<argument type> TO CHECK FOR LEGALITY
SWTARG: MOV CMDBUF,T ;ARGUMENT TYPE
BPL .+4 ;MAKE SURE WE HAVE A POSITIVE #
NEG T
ASL T ;MAKE IT INTO A BYTE INDEX
CMP #NSWTRG*2,T ;TEST FOR LEGAL
RTS PC
;HERE RETURN STATE OF AUDEO SWITCH
TENRAS: JSR PC,SWTARG ;SET UP 10-11 CHANNEL ARGUMENT
BLOS RASLOS ;ILLEGAL ARG MAKES COMMAND FAIL
JMP @RASDSP(T)
RASDSP: TENCFL ;0 IS ILLEGAL
RASCHN ;1 10/11 CHANNEL #
RASKBD ;2 KBD #
RASOUT ;3 AUDEO SWITCH OUTPUT #
.IIF NZ .-<NSWTRG*2>-RASDSP,.ERROR RASDSP AND RVSDSP DIFFER.
RASCHN: JSR PC,CHNKBD ;GIVEN A 10-11 CHANNEL #; GET KBD # IN T
BLOS RASLOS
RASCH1: MOVB KBDASW(T),TT ;GET AUDEO SWITCH OUTPUT INTO TT
RASCH2: MOV TT,CMDBUF+<3*4> ;PUT OUTPUT NUMBER IN AS RETURN VALUE.
CLR CMDBUF+<2*4> ;IF HE WANTS DEFAULT INPUT OF THIS OUTPUT, IT'S 0.
TST CMDBUF
BMI RASCH3 ;BRANCH IF HE WANTS DEFAULT INPUT OF THIS OUTPUT.
MOVB ASWTAB(TT),CMDBUF+<2*4> ;GET CURRENT INPUT OF THIS OUTPUT AND STORE.
RASCH3: JMP TENCSD
RASKBD: JSR PC,CHKKBD ;HERE IF GIVEN KBD #; TEST FOR LEGALITY.
BHI RASCH1 ;IF LEGAL, FALL INTO MAIN LINE CODE
RASLOS: JMP TENCFL ;ILLEGAL, TELL HIM SO
RASOUT: MOV CMDBUF+4,TT ;HERE IS GIVEN AUDEO SWITCH OUTPUT
CMP #MAXASO,TT ;CHECK FOR LEGAL
BHI RASCH2 ;FALL INTO MAIN LINE CODE
BR RASLOS ;HERE IF ILLEGAL
.SBTTL ERROR TRAPS HERE
NXMBRK: BPT
RESBRK: BPT
IOTBRK: BPT
PWRBRK: BPT
EMTBRK: BPT
TRPBRK: BPT
;BPT BREAKS COME HERE IF THERE IS NO RUG.
;DON'T WANT TO HALT THE 11 SINCE 11TEN INTERFACE WOULDN'T BE ABLE TO GET TO BUS.
;WANT TO PUT CONTENTS OF REGISTERS IN CORE WHERE CARPET CAN GET AT THEM.
BPTBRK: .REPT 7 ;SAVE THE ACS
MOV %0+.RPCNT,BPTACS+<2*.RPCNT>
.ENDR
MOV #INITED-2,A ;TELL THE 10 WE'RE DOWN
CLR (A)+
CLR (A)+
CLR (A)+
CLR (A)+
; BELOW LOSES - PREVENTS RESTUFFING UNLESS YOU GO HIT SWITCHES
; WAIT ;PUT 000001 IN LIGHTS (11/05)
BR . ;WAIT FOR RELOAD OR MANUAL INTERVENTION
;BRANCH TO POINT SO STUFF WILL AUTOMATICALLY START IT.
.REPT 7 ;PROCEED
MOV BPTACS+<2*.RPCNT>,%0+.RPCNT
.ENDR
RTI
BPTACS: .BLKW 7
.SBTTL CLOCK ROUTINES CAUSE BLINKING
CLKBRK: DEC TYMSHR ;COUNT DOWN THIS DPY'S QUANTUM
;******* TEMPORARY CODE TO CHECKSUM THE FONT *******
;CHECKSUM IT 100 OCTAL WORDS AT A TIME, SO AS NOT TO SLOW THINGS DOWN
;TOO MUCH. WILL GET CHECKED APPROXIMATELY FOUR TIMES A SECOND.
PUSH T
PUSH TT
MOV CKSPNT,T
MOV T,TT
ADD #100*2,TT
CMP TT,#FNTEND
BLOS 1$
MOV #FNTEND,TT
1$: ADD (T)+,CKSSUM
CMP T,TT
BLO 1$
MOV T,CKSPNT
CMP TT,#FNTEND
BNE 2$
CMP CKSSUM,CKSSMG
BEQ .+4
BPT
CLR CKSSUM
MOV #FNTORG,CKSPNT
2$: POP TT
POP T
;******* END OF TEMPORARY CODE *******
PUSH T
ADD #1,TICKS1 ;INC DOES NOT AFFECT C-BIT (SIGH)
ADC TICKS
TST KBDFLG
BNE CLKBR1 ;HAS PDP-10 HACKED THE LAST BUNCH?
MOV KBDACT,KBDFLG ;YES, GIVE HIM THE NEW BUNCH
CLR KBDFLG+2 ;PARANOIA REIGNS SUPREME
CLR KBDACT
CLR KBDLAST ;POINTS TO END OF ACTIVE CHAIN
;CLOCK QUEUE DISPATCH
CLKBR1: MOV CLOCKQ,T
BEQ CLKBR2 ;ANYTHING ON CLOCK QUEUE?
TST (T)+ ;IGNORE CDR
CMP (T)+,TICKS ;DOUBLE-PRECISION COMPARE TIME NOW
BHI CLKBR2 ;WITH TIME IN QUEUE BLOCK; TO CLKBR2 IF NOT DUE YET.
BLO CLKBR3
CMP (T)+,TICKS1
BHI CLKBR2
CLKBR3: PUSH CLOCKQ ;CDR THE CLOCK QUEUE
MOV @(SP),CLOCKQ
JSR PC,@(T)+ ;CALL CLOCK LEVEL ROUTINE, T POINTS TO ARGUMENT
POP T
MOV CLOCKF,(T) ;PUT OLD SLOT ON FREE LIST
MOV T,CLOCKF
BR CLKBR1 ;CHECK AGAIN IF SOMETHING STILL ON QUEUE
CLKBR2: DEC BLINK
BGE .+10
MOV #BLKTIM,BLINK
CMP BLINK,#MAXCRG
BHIS CLKR1
MOV BLINK,T
TSTB BLKSWT(T)
BNE CLKR1
PUSH U
PUSH CREG
PUSH AC
PUSH MQ
MOVB T,CREG
ASL T
MOV BLINKS(T),T ;BLINK CHAIN FOR THIS DPY
BEQ CLKBR4
CLKLOP: MOV BLCURS(T),U ;CURSOR TO BLINK
JSR PC,XORCHR
COMB BLON(T) ;CHANGE STATE OF BLINK
MOV BLNEXT(T),T
BNE CLKLOP
CLKBR4: POP MQ ;CLOCK RETURN
POP AC
POP CREG
POP U
CLKR1: TST BLINK
BEQ CLKR3
CMP BLINK,#BLKTIM/2
BNE CLKR2
CLKR3: JSR PC,RPT ;AS OFTEN AS WE BLINK, HANDLE THE REPEAT KEY.
CLKR2: INCB SSCC ;INCREMENT SEMI-SLOW CLOCK COUNT
BNE CLKRET ;WRAP-AROUND => SEMI-SLOW CLOCK TICK
BR CLKBRS
;ON ALL CONSOLES IN "REPEAT" MODE, PERFORM ONE REPETITION
;BY SENDING AS INPUT TO THE PDP-10 ANOTHER COPY OF THE CHAR
;MOST RECENTLY SENT. ALSO DECREMENTS ALL FINITE REPEAT COUNTS.
RPT: JSR U,ACSAV
PUSH CREG
MOV #LEUVAR,U
RPT4: TST LERPT(U)
BEQ RPT3
BMI RPT1
DEC LERPT(U)
RPT1: MOV LELSTA(U),A
MOV LELSTB(U),B
JSR PC,PUTCHR
RPT3: ADD #LELEN,U
CMP #LEUEND,U
BGT RPT4
POP CREG
JMP ACRES
;COME HERE EVERY 256./60. = 4.27 SECONDS FOR SEMI-SLOW CLOCK
CLKBRS: PUSH TT
PUSH C
PUSH U
PUSH #69. ;FOR DEBUGGING
TST KBDTSW
BEQ SSCRET
CLR KBDTSW
MOV #KBDDEF+<2*MAXKBD>,T
BR CLKBR5
CLKBR9: INC KBDTSW
CLKBR5: CMP #KBDDEF-2,T
BEQ SSCRET
TST -(T) ;FAST LOOP LOOKING FOR ANY KEYBOARD
BGE CLKB10 ; NEEDING ITS CONSOLE'S VIDSW INPUT RESET
BR CLKBR5
CLKB10: DECB 1(T)
BGE CLKBR9 ;NOT TIME TO RESET THIS SCREEN YET
MOV T,C
SUB #KBDDEF,C ;C HAS 2*KBD NUMBER, FOR VSWDEF.
PUSH T
JSR PC,VSWSGO ;SET UP L.E. INDEX IN U, VSW OUTPUT IN T
BLT CLKBR7 ;VSWSGO IS NEGATIVE IF SOMETHING IS FUNNY.
JSR PC,VSWDEF ;RESET VIDEO SWITCH INPUT
CLKBR7: POP T
BR CLKBR5
SSCRET: CMP (SP)+,#69. ;IS STACK SCREWED?
BEQ SSCRE1
BPT
SSCRE1: POP U
POP C ;SEMI-SLOW CLOCK RETURN
POP TT
CLKRET: POP T
CRTI: RTI
;CLEARS ALL BLINKERS ON THIS DPY
CLBLIN: PUSH U
MOVB CREG,T
BIC #177400,T
ASL T
MOV BLINKS(T),T
BEQ CLBL2
CLBL0: TSTB BLON(T) ;BLINK ON?
BEQ CLBL1
MOV BLCURS(T),U
JSR PC,XORCHR
CLRB BLON(T)
CLBL1: MOV BLNEXT(T),T
BNE CLBL0
CLBL2: POP U
RTS PC
;CLOCK QUEUE ROUTINES
;ADQUE CALLED WITH ARG IN T, THE CALLING SEQUENCE IS:
; JSR TT,ADQUE
; DELTA T
; ROUTINE TO CALL AT CLOCK LEVEL
ADQUE: PUSH T ;ARG FOR ROUTINE
MOV CLOCKF,T ;GET FREE CLOCK QUEUE SLOT
BEQ ADQFL ;IF THERE IS A FREE ONE
TST (T)+ ;IGNORE CDR
MOV TICKS,(T)+ ;MOVE IN CURRENT TIME
MOV TICKS1,(T)
ADD (TT)+,(T)+ ;TIME TO CALL ROUTINE
ADC -4(T)
MOV (TT)+,(T)+ ;ROUTINE TO CALL
MOV (SP)+,(T) ;AND ITS ARG
PUSH TT ;RETURN ADDRESS
MOV CLOCKF,TT ;ADDRESS OF THIS CLOCK QUEUE SLOT
MOV (TT),CLOCKF ;CDR THE FREE LIST
PUSH TT ;ADDRESS OF ONE TO ADD
PUSH #CLOCKQ ;ADDRESS OF PREVIOUS CLOCK QUEUE ENTRY
ADQUE1: MOV @(SP),TT ;CURRENT ENTRY IN QUEUE
BEQ ADQUE2 ;END OF QUEUE?
MOV 2(SP),T ;THE ONE WE WANT TO ADD
CMP (T)+,(TT)+ ;IGNORE CDR'S
CMP (T)+,(TT)+ ;HIGH ORDER OF TIME
BLO ADQUE2 ;GO SPLICE IT IN HERE
BHI ADQUE3
CMP (T)+,(TT)+ ;LOW ORDER
BLOS ADQUE2
ADQUE3: MOV @(SP),(SP) ;CDR THE QUEUE
BR ADQUE1
;HERE TO SPLICE ENTRY INTO CLOCK QUEUE
ADQUE2: MOV @(SP),@2(SP) ;CDR OF QUEUE, GOES TO CDR OF NEW ENTRY
MOV 2(SP),@(SP) ;CURRENT SLOT GOES TO CDR OF PREVIOUS
CMP (SP)+,(SP)+ ;CLEANSE STACK
POP TT
RTS TT
;HERE FOR NO FREE CLOCK QUEUE SLOTS
ADQFL: CMP (TT)+,(TT)+ ;SKIP OVER ARGS
POP T ;CLEANSE STACK
RTS TT
;THIS CAUSES CONSOLE FREE DPY TO GLITCH
MSGLIT: PUSH CREG
MOV (T),T
MOV T,CREG
JSR TT,ADQUE
GLITIM
MSGLIT
MOV CSA,T
PUSH T
BIC #-BOWBIT,T ;CLEAR BOW AND OTHER GARBAGE
ADD #LINHT*BYTPL/10,T ;GLITCH ONE CHARACTER LINE
CMP #LINHT*BYTPL*CHRLN/10,T
BHI .+4 ;WRAP AROUND?
CLR T
BIC #-1#<-BOWBIT>,(SP)
BIS T,(SP)
POP CSA ;ZAP
POP CREG
RTS PC
;HERE TO RING BELL ON DPY
BELL: PUSH T
MOV CREG,T
MOVB T,TT ;DOUBLE TV BUFFER # FOR BYTE INDEX
ASL TT
CHROFF ;INHIBIT INTERRUPTS WHILE WE HACK CLOCK QUEUE, ETC.
INC BELCNT(TT) ;FLASH SCREEN AT LEAST ONCE
BEQ BELL0 ;IF NONE PENDING, FLASH IT NOW
INC BELCNT(TT) ;IF BELLS PENDING THEN FLASH TWICE
CMP BELCNT(TT),#MAXBEL
BLOS BELL0A
DEC BELCNT(TT)
DEC BELCNT(TT)
BR BELL0A
;HERE IF NO BELLS PENDING, FLASH SCREEN RIGHT AWAY, ADD CLOCK QUEUE ENTRY
BELL0: JSR PC,BOWXOR ;FLASH THE SCREEN NOW!
JSR PC,BELL1A ;ADD CLOCK QUEUE ENTRY
BELL0A: CHRON
POP T
RTS PC
;CLOCK LEVEL BELL ROUTINE
BELL1: PUSH CREG
MOV (T),T ;THE DESIRED CONSOLE REGISTER
MOV T,CREG ;N.B. THE ALU MODE WAS SAVED AS "XOR"
MOV #BOWBIT,CSA ;FLASH THE SCREEN
BIC #177400,T ;THE DPY #
ASL T ;BYTE INDEX
DEC BELCNT(T) ;WE JUST DID THAT ONE
BMI BELL1B ;ANY MORE PENDING?
JSR PC,BELL1A ;YES, PUT ANOTHER ON QUEUE
BELL1B: POP CREG
RTS PC
BELL1A: MOV CREG,T ;PUT ANOTHER BELL ON CLOCK QUEUE
JSR TT,ADQUE
BLKTIM
BELL1
RTS PC
.SBTTL KEYBOARD INTERRUPT ROUTINES
;KEYBOARD BREAK ROUTINES THE LINE EDITOR RUNS AT THIS LEVEL
KBDBRK: JSR U,ACSAV ;PUT AC'S ON STACK
PUSH CREG
PUSH AC
PUSH MQ
KBDLOP: MOV OLDKMA,A
CMP #KBDEND,A ;CHECK WRAP AROUND
BHI .+6
MOV #KBDBUF,A
CMP KMA,A
BEQ KBDRET ;NO MORE CHARACTERS
MOV (A)+,B ;RAW CHARACTER
TSTB (A)+ ;GARBAGE
MOVB (A)+,-(SP) ;KEYBOARD #
MOV A,OLDKMA
;GET ASCII REPRESENTATION OF CHARACTER
; ASCII CODE IN A, META BITS IN B
MOV B,C ;TWO COPIES OF RAW CHARACTER
BIC #RCHAR,B ;KEY STRUCK
BIT #RTPBIT,C ;TOP?
BEQ KBDX1
BIS #XTPBIT,B
BR KBDX2
KBDX1: BIT #RSLBIT,C ;SHIFT LOCK?
BEQ .+6
BIS #XSLBIT,B
BIT #RSHBIT,C ;SHIFT?
BEQ KBDX2
BIS #XSHBIT,B
KBDX2: MOVB XTAB(B),A ;ASCII REPRESENTATION
BIC #<<XSLBIT!XSHBIT!XTPBIT>#-1>,B ;FLUSH ALL UNINTERESTING BITS
ASL B ;XTAB TO ASCII REPRESENTATION
ASL B
ASL B
BIT #RMTBIT,C ;META?
BEQ .+6
BIS #AMTBIT,B
BIT #RCLBIT,C ;CONTROL?
BEQ .+6
BIS #ACLBIT,B
MOVB (SP)+,C ;KEYBOARD #
ASL C ;BYTE FOR INDEX INTO KBDLE
TST A
BLT NONASC ;NON-ASCII
KBDUN3: TSTB KBDESC(C)
BNE ESCBRK ;ESCAPE OR BREAK IS IN PROGRESS
TSTB KBDCNT(C) ;IF THIS SCREEN IS SPYING WITH A TIMEOUT,
BLT KBDUN1
JSR PC,VSWUNS ;UN-SPY IT IMMEDIATELY.
KBDUN1: MOV KBDLE(C),U ;ASSOCIATED LINE EDITOR?
BEQ KBDLOP
TST LERPT(U) ;IF THE REPEAT KEY IS IN EFFECT,
BEQ KBDUN2 ;TURN IT OFF, AND FLUSH THIS CHARACTER.
CLR LERPT(U)
BR KBDLOP
KBDUN2: MOVB LECREG(U),CREG ;SET UP CONSOLE REGISTER
BIS #ACTBIT,B ;FEED THIS CHAR TO THE PDP-10
JSR PC,PUTCHR
BR KBDLOP
;KEYBOARD RETURN
KBDRET: POP MQ
POP AC
POP CREG
POP A
POP B
POP C
POP T
POP TT
POP U
RTI
;NON-ASCII CHARACTERS COME HERE
NONASC: NEG A
CMP #MAXNAS,A
BHIS .+4
NONAS1: BPT ;ILLEGAL CHARACTER
CMP #<MAXKBD*2>,C ;C HAS BEEN DOUBLED
BHI .+4
BPT ;GARBAGE KBD #
CLRB KBDESC(C)
ASL A ;BYTES
JSR PC,@NASCTB(A) ;DISPATCH TO ROUTINE
JBDLOP: JMP KBDLOP
;PROCESS ESCAPE AND BREAK COMMANDS
ESCBRK: JSR PC,UPPER ;CONVERT LOWER CASE TO UPPER CASE
MOV #ESCHAR,T
ESCBR1: CMPB (T),A ;MATCH?
BEQ DOESC
TSTB (T)+ ;END OF TABLE?
BNE ESCBR1
ESCBR2: CLRB KBDESC(C) ;NO COMMAND
BR JBDLOP
DOESC: MOV KBDLE(C),U ;IF COMMAND NEEDS LOGGED-IN KBD,
BEQ DOESC2 ; MAKE SURE WE'RE LOGGED IN,
MOVB LECREG(U),CREG ; AND SET UP U AND CREG
DOESC1: SUB #ESCHAR,T
CLRB KBDESC(C)
ASL T ;MAKE A WORD INDEX.
JSR PC,@ESCTAB(T) ;C MUST BE KBD #, SOME ESCAPE ROUTINES RELY ON IT
BR JBDLOP
DOESC2: CMP #ESCSRN,T ;IF NOT LOGGED IN BUT MUST BE,
BLE ESCBR2 ; THEN WE LOSE TOTALLY
MOVB DPYFRE,CREG ;OTHERWISE SET UP CREG FOR THE
BR DOESC1 ; SAKE OF RANDOM BELLS
;NASCTB FOR KEYS SUCH AS BREAK, CLEAR, ETC POINTS HERE
;TO TURN THOSE CHARACTERS INTO TOP-LETTERS STARTING WITH "A".
;A HOLDS TWICE THE NASCTB INDEX.
BRKCLR: ASR A
ADD #4000+'@,A
BRKCLX: TST (SP)+ ;FLUSH RETURN POINTER TO JBDLOP
JMP KBDUN3 ;AND GO GIVE CHARACTER TO TEN.
GAMMA: MOV #4011,A
BR BRKCLX
DELTA: MOV #4012,A
BR BRKCLX
CRCPLS: MOV #4015,A
BR BRKCLX
PLSMNS: MOV #4014,A
BR BRKCLX
.SBTTL 10/11 INPUT/OUTPUT ROUTINES
;HERE TO COMPLEMENT STATE OF BOW BIT WHEN PDP-10 FALLS BEHIND ON KBD
SLOW10: MOVB LECREG(U),CREG
JMP BELL ;RING BELL
;PUT CHARACTER WHICH IS A OR'D WITH B INTO BUFFER. ACTIVATES IF
; 1 FINDS ACTIVATION CHARACTER
; 2 BUFFER FILLS
;A AND B ARE SAVED IN LELSTA AND LELSTB IN CASE THE USER DECIDES
;TO REPEAT THE CHARACTER.
PUTCHR: TST @LEBUF(U)
BGT PUTCH0 ;BUFFER BEING FILLED?
BLT SLOW10 ;HAS PDP-10 FALLEN BEHIND?
MOV #LBCHRS,@LEBUF(U) ;MARK BUFFER BUSY WITH # FREE CHARACTERS
PUTCH0: TST LEFREE(U) ;ANY ROOM LEFT IN BUFFER?
BGT PUTCH2
BEQ SLOW10 ;NOPE, DO SOME ERROR CHECKING
BPT ;LOSE IF LESS THAN NO ROOM
PUTCH2: MOV A,@LECHR(U)
BIS B,@LECHR(U)
MOV A,LELSTA(U)
MOV B,LELSTB(U)
ADD #2,LECHR(U)
DEC LEFREE(U) ;BUFFER FULL?
BGT PUTCH4
BEQ .+4 ;WE MUST ACTIVATE ANYWAY
BPT
MOV LEBUF(U),T
TST LHQUED(T) ;IF ALREADY QUEUED TO ACTIVATE,
BEQ ACTIVA ; DON'T ACTIVATE NOW
RTS PC
PUTCH4: TST B
BGE RTSPC1 ;NOT ACTIVATING
MOV LEBUF(U),T ;ACTIVATION CHAR, MUST ACTIVATE
TST LHQUED(T) ;IF ALREADY QUEUED TO ACTIVATE,
BNE RTSPC1 ; DON'T ACTIVATE NOW
TST @LHNEXT(T) ;TEST NEXT BUFFER IN RING
BMI QBFR ;IF NOT FREE, TRY ACTIVATION ON NEXT CLOCK TICK
;HERE TO ACTIVATE BUFFER
ACTIVA: SUB #LBCHRS,LEFREE(U) ;NEGATIVE OF ACTIVE CHARS
BLT .+4
BPT ;HAD BETTER BE NEGATIVE
MOV LEBUF(U),T ;THE BUFFER TO ACTIVATE
MOV LEFREE(U),LHFLAG(T) ;THAT ACTIVATES IT
CHROFF
CLR LHALST(T) ;PUT THIS ONE AT END CHAIN
PUSH KBDLAST
MOV T,KBDLAST
POP T
BNE ACTIV0 ;EMPTY ACTIVATION LIST?
MOV KBDLAST,KBDACT ;YES, MAKE ACTIVE LIST POINT TO THIS ONE
BR ACTV0A
ACTIV0: MOV KBDLAST,LHALST(T) ;OLD LAST POINTS TO NEW LAST
ACTV0A: MOV KBDLAST,T ;IN ANY EVENT THIS THE ONE JUST ADDED
TST KBDFLG ;DOES THE PDP-10 WANT MORE
BNE ACTIV1
MOV KBDACT,KBDFLG ;ACTIVATE THIS LIST
CLR KBDACT ;AND PREPARE FOR NEXT
CLR KBDLAST
ACTIV1: CHRON
MOV LHNEXT(T),T ;NEXT ON RING
MOV #LHLEN,TT
ADD T,TT ;FIRST FREE CHARACTER
MOV T,LEBUF(U) ;NEW BUFFER
TST (T)+ ;LHFLAG IS SET AT PUTCHR
CLR (T)+ ;LHZERO
; CMP (T)+,(T)+ ;DON'T HACK LHNEXT AND LHALST
MOV TT,LECHR(U) ;FIRST FREE CHARACTER
MOV #LBCHRS,LEFREE(U) ;FREE CHARACTERS IN BUFFER
RTSPC1: RTS PC
;HERE AT CLOCK LEVEL TO ACTIVATE BUFFER
CLKACT: PUSH TT
PUSH U
MOV (T),U ;THE LINE EDITOR
MOV LEBUF(U),T ;THE BUFFER
TST LHFLAG(T)
BGE .+4
BPT ;CAN'T ACTIVATE AN ALREADY ACTIVATED BUFFFER
TST @LHNEXT(T) ;THE NEXT BUFFER
BMI CLKAC1 ;ACTIVATE IF READY
CLR LHQUED(T)
JSR PC,ACTIVA
CLKAC2: POP U
POP TT
RTS PC
CLKAC1: JSR PC,QBFR ;NOT, READY TRY ANOTHER CLOCK TICK
BR CLKAC2
;HERE IF NEXT BUFFER ON RING IS NOT FREE, TRY ACTIVATION AT NEXT CLOCK TICK
QBFR: ZAPFLG LHQUED(T) ;SET FLAG THAT SAYS WE'RE QUEUED
MOV U,T ;ARG
CHROFF ;INHIBIT INTERRUPTS WHILE WE DO THIS
JSR TT,ADQUE ;PUT ON CLOCK QUEUE
1 ;AT NEXT TICK
CLKACT ;CLOCK LEVEL ACTIVATION
CHRON
RTS PC
;SAVE ALL ACS ON STACK
ACSAV: PUSH TT
PUSH T
PUSH C
PUSH B
PUSH A
PUSH U ;RETURN ADDRESS
MOV 14(SP),U ;RESTORE U
RTS PC
;GETS NEXT CHARACTER FROM DPY BUFFER
;DPY CHANNEL POINTER IN U. RETURNS SIGN-EXTENDED CHARACTER IN A, CLOBBERS TT.
;RETURNS 'EQ' IN CONDITION CODES IF NO CHARACTER PRESENT.
GETCHR: MOV DPY11B(U),TT ;GET POINTER FOR EASE IN INCREMENTING
MOVB (TT),A ;GET NEXT CHARACTER
CMP A,#-1 ;HAS TEN PUT GOODIES THERE?
BEQ RTSPC1 ;NO
MOVB #-1,(TT) ;MARK AS TAKEN
DEC DPY11B(U) ;ADVANCE POINTER
ROR TT ;USING PDP10 BYTE ORDER (1, 0, 3, 2)
BCS GETCH1 ;BRANCH IF 1->0 OR 3->2
ADD #4,DPY11B(U) ;0->3 OR 2->1 NEXT WORD
ROR TT
BCC GETCH1 ;BRANCH IF 0->3
MOV DPY11B(U),TT ;OTHERWISE NEXT PDP10 WORD
DEC TT
MOV #-1,-2(TT) ;SO SET PREV ONE TO ALL -1.
MOV #-1,-4(TT) ; IN CASE OF TIMING ERROR
CMP TT,DPYLGL(U) ;PAST END OF BUFFER?
BLOS GETCH1
MOV U,DPY11B(U) ;YES, RESET TO
ADD #DPDATA+1,DPY11B(U) ;FIRST WORD OF DATA AREA, HIGH BYTE
GETCH1: CLZ
RTS PC ;RETURN CONDITION CODE 'NE'
;GET NEXT CHARACTER BUT IF NOT AVAILABLE DO A COROUTINE-RETURN
;FROM THE CHARACTER-READING LOOP, SO THAT WHEN THE NEXT CHARACTER
;IS READ THIS CALL WILL BE RETURNED FROM. ASSUMES THAT U CONTAINS THE
;ADDRESS OF THE CHANNEL VAR BLOCK.
;PRESERVES B AND C AND T AND TT.
GETCHC: PUSH TT
TST TYMSHR ;IF OUR QUANTUM IS UP, LET OTHER LINES RUN FOR A WHILE.
BMI GETCH2
JSR PC,GETCHR
BEQ GETCH2
POP TT
BIC #-400,A ;CLEAR EXTRA BITS DUE TO SIGN-EXTENSION
RTS PC
GETCH2: POP LESVTT(U)
MOV B,LESVB(U)
MOV C,LESVC(U)
MOV T,LESVT(U)
MOV #LESTK,A ;SAVE STACK CONTENTS, BACK TO CALL FROM DPYXIT.
ADD U,A
1$: POP B
MOV B,(A)+
CMP B,#DPYXIT
BNE 1$
TST -(A) ;DON'T INCLURE THE DPYXIT IN "USED PART OF LESTK".
MOV A,LESTKP(U) ;REMEMBER HOW MUCH WE USED OF LESTK.
GETCH3: JMP DPYDX2 ;CEASE TYPING ON THIS TV FOR A WHILE
.SBTTL DISPLAY FUNCTION (%TD, ETC) ROUTINES
TVOMSK: BIC #177600,A ;HERE IF YOU DON'T TRUST THE HIGH BITS
;TYPE CHARACTER IN A AND ADVANCE OVER IT. PRESERVES A.
TVO: JSR PC,GENCHR ;GENERATES CHARACTER AND ADVANCES CURSOR
;LEDADC ADVANCES LINE EDITOR CURSOR
LEDADC: ADD #CHRWD,LEX(U) ;INCREMENT HPOS IN BITS FROM RIGHT MARGIN.
BEQ LEDAD2 ;REACHED MARGIN => WRAP AROUND.
TST LEPHS(U) ;ELSE, INCREMENT THE AUXILIARY VARIABLES.
BGT LEDAD1
ADD #20,LEPHS(U) ;HERE IF WE ARE ADVANCING TO A NEW WORD.
ADD #2,LECC(U)
CMP LECC(U),#TVCFENCE
BLOS LEDAD1
MOV #TVLO,LECC(U)
LEDAD1: SUB #CHRWD,LEPHS(U)
RTS PC
LEDAD2: JMP CR
;RETREATS LINE EDITOR CURSOR
LEDREC: CMP LEX(U),#-BYTPL ;IF AT LEFT MARGIN, DON'T DO ANYTHING. WE COULD WRAP AROUND,
BEQ LEDRE1 ;BUT THAT'S MORE WORK, AND SHOULDN'T EVER HAPPEN ANYWAY.
ADD #CHRWD,LEPHS(U)
SUB #CHRWD,LEX(U)
CMP #<20-CHRWD>,LEPHS(U)
BGE LEDRE1
SUB #20,LEPHS(U) ;BACKUP A WORD IN DISPLAY
SUB #2,LECC(U)
CMP LECC(U),#TVLO
BHIS LEDRE1
BPT ;BACKING UP PAST BEGINNING OF SCREEN?
LEDRE1: RTS PC
;HERE TO CRLF AND CLEAR EOL.
CRLF: JSR PC,CR
CMP #TVFENCE-<BYTPL*LINHT>,LELCC(U) ;IF NOW ON LAST LINE OF SCREEN,
BEQ CRLF1 ;MUST SCROLL.
JSR PC,LF ;ELSE JUST MOVE DOWN AND CLEAR A LINE.
JMP CLEOL
CRLF1: JSR PC,SCROLL ;MOVE EVERYTHING UP 4 LINES,
JMP LF ;THEN MOVE DOWN 1 LINE.
;SCROLL THE TEXT, MOVING THE CURSOR WITH IT, UP 4 LINES.
SCROLL: PUSH LEY(U) ;TO SCROLL, HOME UP AND DELETE 4 LINES AT SCREEN TOP.
PUSH LELCC(U)
PUSH LECC(U)
JSR PC,HU
MOV #4,A
JSR PC,LDEL0
POP LECC(U) ;THEN RESTORE POSITION (TO LAST LINE, USUALLY)
POP LELCC(U)
POP LEY(U)
MOV LELCC(U),A
SUB #4*BYTPL*LINHT,A ;AND MOVE UP 4 LINES (OR TO SCREEN TOP).
CMP A,#TVLO
BHI SCROL1
JMP HU
SCROL1: MOV A,LELCC(U)
SUB #4*BYTPL*LINHT,LECC(U)
SUB #4*LINHT,LEY(U)
SCROLX: RTS PC
;HERE TO BACKSPACE (NO-OP IF AT BEGINNING OF LINE)
DPYBS: CMP LELCC(U),LECC(U)
BEQ SCROLX
JMP LEDREC
;HERE TO HOME UP AND CLEAR SCREEN.
DPYCLR: JSR PC,HU
JMP CLEOF
;HERE FOR LINE FEED, NO FRILLS. WRAP AROUND AT SCREEN BOTTOM.
LF: ADD #<BYTPL*LINHT>,LELCC(U)
ADD #<BYTPL*LINHT>,LECC(U)
ADD #LINHT,LEY(U)
CMP #TVFENCE,LELCC(U)
BHI LF1
SUB #TVFENCE-TVLO,LELCC(U)
SUB #TVFENCE-TVLO,LECC(U)
MOV #-NLINS,LEY(U)
LF1: RTS PC
;HERE TO HOME UP
HU: MOV #TVLO,LELCC(U) ;RESET POINTER TO CURRENT LINE BEGINNING.
MOV #-NLINS,LEY(U) ;AND ITS POSITION ON SCREEN.
;HERE FOR CARRIAGE RETURN
CR: MOV LELCC(U),LECC(U) ;ORIGIN OF THIS LINE
CR1: MOV #20-CHRWD,LEPHS(U) ;PHASE
MOV #-BITPL,LEX(U) ;RESET X
RTS PC
;DELETE LINE(S). MOVE UP THE LINES BELOW THE CURRENT ONE,
;FLUSHING THE CURRENT ONE. BLANK LINES ARE SHIFTED IN AT THE BOTTOM.
LDEL: JSR PC,GETCHC ;READ NUMBER OF LINES TO DELETE IN A.
LDEL0: MOV #TVFENCE,B ;ADDRESS OF "END OF REGION"
LDEL00: MOV A,MQ
BEQ LINSX
CMP A,#50
BHI LINS3
MOV #BYTPL*LINHT,MUL ;GET # LINES * BYTPL*LINHT, = # BYTES TO SHIFT BY.
MOV LELCC(U),TT ;TT GETS ADDR OF THIS LINE.
MOV TT,T
ADD MQ,T ;T GETS ADDR OF LINE TO COPY INTO THIS.
BCS LDEL4 ;CARRY => T IS PAST BOTTOM OF SCREEN ALREADY.
LDEL3: CMP T,B ;NO MORE LINES AT BOTTOM TO COPY UP =>
BHIS LDEL4 ; START CLEARING INSTEAD.
JSR PC,CPYCHL ;COPY THEM, INCREMENTING T AND TT TO NEXT LINES.
BR LDEL3
LDEL4: MOV TT,T
;CLEAR TEXT LINES FROM THE ONE T POINTS TO, TO END OF REGION IN B. PUTS CIOR IN CALU.
LDEL5: CMP T,B
BHIS LINSX ;POPJ, SETTING CALU TO CIOR.
JSR PC,CLRCHL
BR LDEL5
;INSERT LINE(S). MOVE THE CURRENT LINE AND LOWER ONES DOWN ONE OR MORE POSITIONS.
;BLANK LINES SHIFT IN AT THE CURRENT POSITION.
LINS: JSR PC,GETCHC ;HOW MANY LINES TO INSERT (IN A).
MOV A,MQ
BEQ LINSX ;DON'T WASTE TIME IF INSERTING 0 LINES.
CMP A,#50 ;DELETING INFINITE LINES = CLEAREOF
BHI LINS3
MOV #BYTPL*LINHT,MUL
MOV #TVFENCE-<BYTPL*LINHT>,TT ;TT POINTS AT LAST ACTUAL LINE ON SCREEN.
LINS4: MOV TT,T
SUB MQ,T ;T IS LINE TO COPY INTO IT (COPYING DOWNWARD).
BCS LINS3 ;IF T IS ABOVE TOP OF SCREEN, GIVE UP.
LINS1: CMP LELCC(U),T ;STOP AFTER COPYING CURRENT LINE DOWN.
BHI LINS3
JSR PC,CPYCHL ;COPY ONE LINE DOWNWARD.
SUB #2*BYTPL*LINHT,T ;THIS ADVANCES T AND TT TO NEXT LINE DOWN,
SUB #2*BYTPL*LINHT,TT ; WHEN WHAT WE WANT IS NEXT LINE UP.
BR LINS1
LINS3: MOV LELCC(U),T
;CLEAR C(A) LINES OF CHARACTERS, STARTING AT THE LINE T POINTS TO, BUT STOP IF REACH END OF SCREEN.
;SETS CALU TO CIOR.
LINS2: CMP #TVFENCE,T
BLOS LINSX
JSR PC,CLRCHL
DEC A
BNE LINS2
LINSX: MOVB #CIOR,CALU
RTS PC
;REGION SCROLLING
RGSCDN: JSR PC,GETCHC ;NUMBER OF LINES IN REGION
MOV A,B
JSR PC,GETCHC ;NUMBER OF LINES TO MOVE DOWN
MOV B,MQ
MOV #BYTPL*LINHT,MUL
MOV LELCC(U),TT
SUB #BYTPL*LINHT,TT
ADD MQ,TT ;ADDRESS OF LAST LINE IN REGION
BCS LINSX ;IGNORE IF GARBAGE REGION (WRAPPED AROUND ADDRESS)
CMP TT,#TVFENCE
BHIS LINSX ;IGNORE IF GARBAGE REGION
MOV A,MQ ;CONVERT DISTANCE TO MOVE TO BYTES
BEQ LINSX ;EXIT IF NOT MOVING
MOV #BYTPL*LINHT,MUL
BR LINS4 ;GO DO IT, USING INSERT-LINES SUBROUTINE
RGSCUP: JSR PC,GETCHC ;NUMBER OF LINES IN REGION
MOV A,B
JSR PC,GETCHC ;NUMBER OF LINES TO MOVE UP
MOV B,MQ
MOV #BYTPL*LINHT,MUL
MOV LELCC(U),B
ADD MQ,B ;ADDRESS OF FIRST LINE AFTER REGION
BR LDEL00 ;GO DO IT, USING DELETE-LINES SUBROUTINE
;INSERT CHARACTER(S). MOVE THE CURRENT CHARACTER AND FOLLOWING ONES TO THE RIGHT.
;BLANKS ARE SHOFTED IN AT THE CURRENT POSITION.
CINS: JSR PC,GETCHC ;A GETS HOW MANY CHARACTERS TO INSERT.
JSR PC,CINSET ;CHECK A FOR VALIDITY; PUSH A, LELCC(U), LINHT, AND LECC(U).
CINSL: MOV 6(SP),A
MOV (SP),T
MOV 4(SP),C
JSR PC,CINS1L
ADD #BYTPL,(SP)
ADD #BYTPL,4(SP)
DEC 2(SP)
BNE CINSL
ADD #6,SP ;FLUSH ALL BIT # CHAR POSITIONS FROM STACK.
POP B
PUSH LEX(U)
PUSH LEPHS(U)
PUSH LECC(U)
CINSC: JSR PC,CLRCHR ;NOW CLEAR OUT THE CHAR POSITIONS WE INSERTED.
JSR PC,LEDADC ;AND MOVE CURSOR PAST IT.
DEC B ;NOTE CLRCHR SETS CALU TO CIOR.
BNE CINSC
POP LECC(U) ;AND RESTORE THE CURSOR.
POP LEPHS(U)
POP LEX(U)
CINSX: RTS PC
;INSERT C(A) CHARACTER POSITIONS IN ONE RASTER LINE AT PLACE T POINTS AT.
;C POINTS AT FRONT OF RASTER LINE. REQUIRES CALU/ CSET.
CINS1L: MOV A,MQ
MOV #CHRWD,MUL ;COMPUTE # OF BITS TO SHIFT THE LINE BY.
MOV #20,DIV ;COMPUTE # WORDS TO SHIFT IN MQ, # BITS IN AC.
MOV #20-CHRWD,TT
SUB LEPHS(U),TT ;TT GETS # BITS AT FRONT OF 1ST WORD NOT TO CHANGE.
PUSH TT
PUSH (T) ;ALSO SAVE THE WORD CONTAINING THEM.
PUSH T ;AND ITS ADDRESS
PUSH U ;FIT IN WITH WHAT CINS2 WILL POP.
MOV C,A
ADD #BYTPL,A ;A GETS ADDR TO AUTODECREMENT TO LAST WORD OF LINE.
MOV A,B
SUB MQ,B ;SUBTRACT THE # OF BYTES IN THE DESIRED # OF WORDS.
SUB MQ,B ;B GETS ADDR OF LAST WORD NOT SHIFTED INTO BIT BUCKET,
MOV -(B),TT ;TT GETS ITS CONTENTS, TO INIT THE LOOP.
MOV AC,C
NEG C ;C <= SHIFT COUNT, TO GET 1 NEW WORD FROM PAIR OF OLD.
CINS1: CMP B,T ;NOTE T STILL HAS ADDR OF LOWEST (LAST) WORD TO SHIFT
BEQ CINS3
MOV TT,MQ
MOV -(B),TT ;FETCH ANOTHER (LOWER) OLD WORD, FROM WHICH
MOV TT,AC ;(COMBINED WITH PREVIOUS OLD WORD)
MOV C,LSH ;WE MAKE A NEW SHIFTED WORD.
MOV MQ,-(A) ;STORE THE NEXT NEW WORD.
BR CINS1
CINS3: MOV AC,-(A) ;REMAINDER OF LAST FROM-WORD GOES INTO LAST TO-WORD.
BR CINS2
;FOR INSERT/DELETE CHARACTER, CHECK ARG IN A FOR LEGALITY. MAYBE JUMP OFF
;TO CLEAR-TO-END-OF-LINE FOR INSERTING OR DELETING TOO MANY CHARACTERS.
;OTHERWISE, RETURN HAVING PUSHED ON THE STACK THE ARG, LELCC(U), #LINHT, AND LECC(U).
CINSET: POP B ;GET RET ADDR OFF STACK SO WE CAN POPJ OUR CALLER
MOV A,MQ ;OR PUSH ON HIS STACK.
BEQ CINSX ;IF ARG IS 0, OUR CALLER HAS NOTHING TO DO, SO POPJ HIM
MOV #CHRWD,MUL
MOV LEX(U),C ;AT WHAT DOT POSITION DOES REGION INSERTED/DELETED END?
ADD MQ,C
BLT .+6 ;PAST RIGHT MARGIN => THIS OPERATION EQUIVALENT
JMP CLEOL ;TO A CLEAR-TO-END-OF-LINE.
MOVB #CSET,CALU
PUSH A ;SAVE # CHAR POSITIONS TO INSERT.
PUSH LELCC(U) ;SAVE ADDR START OF 1ST RASTER LINE (ADVANCES)
PUSH #LINHT
PUSH LECC(U) ;AND ADDR OF CURSOR IN 1ST RASTER LINE.
JMP (B) ;RETURN TO OUR CALLER, HAVING PUSHED HIS TEMPS.
;DELETE CHARACTERS. DELETE SOME CHARACTERS AFTER THE CURSOR. THE FOLLOWING ONES
;MOVE LEFT. BLANKS ARE SHOFTED IN AT THE RIGHT MARGIN.
CDEL: JSR PC,GETCHC ;A GETS HOW MANY CHARACTERS TO DELETE.
JSR PC,CINSET ;DECODE A. MAYBE POPJ OR JUMP TO CLEOL.
;OTHERWISE, PUSH ON STACK A, LELCC(U), #LINHT, LECC(U).
CDELL: MOV 6(SP),A
MOV (SP),T
MOV 4(SP),C
JSR PC,CDEL1L
ADD #BYTPL,(SP)
ADD #BYTPL,4(SP)
DEC 2(SP)
BNE CDELL
ADD #10,SP
MOVB #CIOR,CALU
CDELX: RTS PC
;DELETE C(A) CHARACTER POSITIONS FROM ONE RASTER LINE
;T POINTS AT WORD CONTAINING CURSOR, IN THAT RASTER LINE.
;C POINTS AT START OF THAT RASTER LINE. ASSUMES CALU/ CSET.
CDEL1L: MOV A,MQ
MOV #CHRWD,MUL ;COMPUTE # OF BITS TO SHIFT THE LINE BY.
MOV #20,DIV ;COMPUTE # WORDS TO SHIFT IN MQ, # BITS IN AC.
MOV #20-CHRWD,TT
SUB LEPHS(U),TT ;TT GETS # BITS AT FRONT OF 1ST WORD NOT TO CHANGE.
PUSH TT
PUSH (T) ;ALSO SAVE THE WORD CONTAINING THEM.
PUSH T ;AND ITS ADDRESS
MOV T,TT ;(WHICH IS ALSO ADDR TO START SHIFTING INTO).
ADD MQ,TT ;AND ADDR TO START SHIFTING FROM, AND 1ST FROM-WORD.
ADD MQ,TT ;MQ HAS # OF WORDS, BUT TT HAS AN ADDRESS.
MOV (TT)+,A
ADD #BYTPL,C ;C GETS ADDR OF 1ST WORD PAST END OF LINE.
PUSH U
MOV AC,U ;U HAS # BITS SHIFTING BY.
;NOW MAKE TO-WORDS 1 BY 1 EACH OUT OF A PAIR OF FROM-WORDS.
;THE LAST FROM-WORD IS IN A. T HAS STORE ADDRESS, TT HAS FETCH ADDRESS.
CDEL1: CMP C,TT ;STOP AFTER GOBBLING ALL OF THIS RASTER LINE.
BLOS CDEL2
MOV (TT)+,B
MOV B,MQ ;CLOBBERS AC, SO RELOAD IT FROM T.
MOV A,AC
MOV U,LSH ;NOW SHIFT THE 2 FROM-WORDS BY # BITS SHIFTING BY,
MOV AC,(T)+ ;WHICH GIVES AC THE RIGHT STUFF FOR NEXT TO-WORD.
MOV B,A ;NOW T GETS THE NEWEST FROM-WORD, AND FETCH ANOTHER.
BR CDEL1
CDEL2: MOV A,MQ ;REMAINDER OF LAST FROM-WORD IS NEXT TO-WORD.
MOV U,LSH
MOV MQ,(T)+
JSR PC,CLRRNG ;CLEAR STARTING WHERE T POINTS, ENDING WHERE C POINTS.
;NOW RESTORE THE FIRST FEW BITS OF THE FIRST WORD (WHICH WEREN'T SUPPOSED
;TO BE INCLUDED IN THE SHIFT).
CINS2: POP U
POP C ;GET ADDRESS OF 1ST TO-WORD
POP A ;GET OLD 1ST TO-WORD CONTENTS
POP T ;AND NUMBER OF BITS AT TOP NOT TO INCLUDE IN SHIFT.
MOV #-1,AC
NEG T
MOV T,LSH ;MQ GETS MASK TO BITS WE WANT SHIFTED INTO.
MOV AC,T
BIC T,A ;FLUSH THOSE IN SAVED CONTENTS.
COM T
BIC T,(C) ;FLUSH THE OTHERS IN SHIFTED CONTENTS.
BIS A,(C) ;MERGE OLD BITS WITH NEW.
RTS PC
CLRRN1: CLR (T)+
CLRRNG: CMP T,C
BNE CLRRN1
RTS PC
;CLEARS TO END OF LINE
CLEOL: PUSH LECC(U)
PUSH LEPHS(U)
PUSH LEX(U)
JSR PC,CLEOL1 ;DO THE DIRTY WORK
CLEOX: POP LEX(U)
POP LEPHS(U)
POP LECC(U)
MOVB #CIOR,CALU ;RESTORE FOR DPYDP1 LOOP
RTS PC
CLEOL1: MOV LEX(U),TT ;ALREADY AT END OF LINE?
BGE CLEOLX
CMP LEPHS(U),#20-CHRWD
BEQ CLEOL2 ;IF AT START OF WORD, START CLEARING WORD-WISE
JSR PC,CLRCHR ;ELSE CLEAR 1 CHAR AT A TIME TILL REACH WORD BOUNDARY.
JSR PC,LEDADC
CMP LEX(U),#-BITPL
BEQ CLEOLX ;CLEARED WHOLE LINE AND WRAPPED AROUND => DONE
BR CLEOL1
CLEOL2: ASR TT
ASR TT
ASR TT
ASR TT ;-(# WORDS TO CLEAR)
PUSH TT
PUSH LECC(U) ;ADDR OF 1ST WORD TO CLEAR,
PUSH #LINHT ;# LINES TO PROCESS
MOVB #CSET,CALU
CLEOL3: MOV 2(SP),T ;START CLEARING HERE
CLEOL4: CLR (T)+
INC TT
BLT CLEOL4
ADD #BYTPL,2(SP)
MOV 4(SP),TT ;-(# WORDS TO CLEAR)
DEC (SP)
BGT CLEOL3
ADD #6,SP ;CLEANSE STACK
MOV T,LECC(U)
JMP CR1 ;RESET X AND PHASE
CLEOLX: MOV LELCC(U),T
ADD #<LINHT*BYTPL>,T ;HERE IF ALREADY AT END OF LINE
MOV T,LECC(U)
JMP CR1
;CLEARS TO END OF SCREEN
CLEOF: MOV LELCC(U),T ;IF AT START OF LINE, DO FAST CLEAR FROM THIS LINE.
CMP #-BYTPL,LEX(U) ;IF NOT AT BEGINNING OF LINE, USE CLEOL TO CLEAR
BEQ CLEOF1 ;ONLY THE REST OF THIS LINE.
JSR PC,CLEOL
MOV LELCC(U),T ;AND START FAST CLEAR WITH NEXT LINE.
ADD #BYTPL*LINHT,T
CLEOF1: MOV #TVFENCE,B
JMP LDEL5
;HERE TO FORWARD SPACE
FS: JMP LEDADC
;HANDLE %TDMOV
SETCUR: JSR PC,GETCHC ;OLD VERTICAL AND HORIZONTAL
JSR PC,GETCHC
;HANDLE %TDMV0, %TDMV1 ABSOLUTE POSITIONING COMMANDS.
SETCR1: JSR PC,GETCHC ;NEW VERTICAL
MOV A,B
JSR PC,GETCHC ;NEW HORIZONTAL
;NOTE GETCHC MAY RETURN AND BE REENTERED,
;RESETTING ALL ACS BUT B.
;HERE TO SET CURSOR GIVEN A COORDINATE PAIR (X,Y) IN CHARACTERS.
;X AND Y ARE IN A AND B RESPECTIVELY, (0,0) IS UPPER LEFTHAND CORNER
;(1,3) IS THE SECOND CHARACTER OF FOURTH LINE
SETXY: CMP #CHRPL,A ;CHECK FOR LEGAL POSITION
BLOS SETXY1
CMP #CHRLN,B
BLOS SETXY1
SETXY0: MOV #MQ,T ;FOR THE MYRIAD MULTIPLIES AND DIVIDES
MOV B,(T)+ ;Y POSITION
MOV #BYTPL*LINHT,(T) ;FIND ORIGIN OF LINE IN MEMORY
MOV -(T),LECC(U)
MOV (T),LELCC(U)
MOV A,(T)+ ;X POSITION
MOV #CHRWD,(T)
MOV -(T),LEX(U) ;BITS FROM LEFT OF SCREEN
CLR -(T) ;CLEAR OUT AC
MOV #20,-(T) ;DIVIDE GIVES WORDS FROM LEFT AND PHASE
TST (T)+
MOV (T)+,LEPHS(U) ;PHASE
ASL (T) ;BYTES FROM BEGIN OF LINE
ADD (T),LECC(U) ;LEAVE T POINTING AT MQ
ADD #-BITPL,LEX(U) ;THAT'S ALL DONE
NEG LEPHS(U)
ADD #20-CHRWD,LEPHS(U) ;PHASE IS SET
MOV B,(T)+ ;Y POSITION AGAIN
MOV #LINHT,(T)
MOV -(T),LEY(U)
ADD #-NLINS,LEY(U) ;LEY SET
ADD #TVLO,LECC(U)
ADD #TVLO,LELCC(U)
BIT #1,LECC(U) ;MAKE SURE IT LINES UP ON WORD BOUNDARY
BEQ .+4
BPT
SETXY1: RTS PC
;Read a character into A.
;If it is a %TD code, go process it.
.macro grfchr
jsr pc,getchc
bit #200,a
beq .+6
jmp grfctl
.endm
;Come here on 200 code seen inside graphics input.
grfctl: pop t ;Discard all our stack,
cmp t,#dpyxit ;including the return to DPYXIT,
bne grfctl ;since DPYCTL will push it again.
jmp dpyctl
grflp: grfchr
mov a,b ;Save %GO command in B so we can test abs vs rel later.
bit #100,a
bne grfdrw
cmp a,#grfmax
bge grflp
asl a
jmp @grfd1(a)
grfd1: grflp
grfmov
grfxor
grflp
grflp
grflp
grflp
grflp
grfclr
grfpsh
grfvir
grflp
grflp
grflmt
grflp
grflp
grflp
grfmov
grfior
grflp
grflp
grflp
grflp
grflp
grflp
grflp
grfphy
grflp
grflp
grflmt
grflp
grflp
grfmax=<.-grfd1>/2
;Here for graphics drawing command (100 bit set)
grfdrw: mov a,t
bic #-20,t
asl t
jmp @grfd2(t)
grfd2: grflp
grflin
grfdpt
grfrec
grfstr
grfscn
grfrun
grflp
grflp
grflp
grflp
grflp
grflp
grflp
grflp
grflp
;Read in the coordinates of a point, either absolute or relative
;depending on the 20 bit of the command we are processing (which should be in B).
grfpnt: bit #20,b
beq 1$
grfchr
mov a,c ;Save low byte
grfchr
swab a ;Read high byte.
asl a ;Sign extend it.
asr a
asr a ;Shift down - next byte is just 7 bits too.
add c,a
mov a,legx(u) ;Combine and set x position.
grfchr
mov a,c
grfchr
swab a
asl a
asr a
asr a
add c,a
mov a,legy(u)
br 2$
;Read relative point address
1$: grfchr
asl a ;sign extend 7 bits to 16.
movb a,a
asr a
add a,legx(u) ;add to current position.
grfchr
asl a
movb a,a
asr a
add a,legy(u)
2$: rts pc
;Get absolute coords (0,0 at top left) from current graphics cursorpos.
grfgp1: tstb legvir(u)
beq 1$
mov legx(u),mq ;scale virtual coords to physical.
clr ac
mov #nlins1,mul ;Use nlins1 for x and y coords
mov #-11.,ash ;since it is the smaller of the two dimensions.
mov mq,t
mov legy(u),mq
clr ac
mov #nlins1,mul
mov #-11.,ash
mov mq,tt
;Get absolute coords from physical ones.
1$: mov legx(u),t
add #bitpl/2,t
mov #nlins1/2,tt
sub legy(u),tt
rts pc
;Get the current graphics cursor pos in T and TT,
;converted to physical coords with the origin at the top left,
;and brought onto the screen if it was off.
grfclp: jsr pc,grfgp1
tst t
bge 1$
clr t
1$: cmp t,#bitpl
blt 2$
mov #bitpl-1,t
2$: tst tt
bge 3$
clr tt
3$: cmp tt,#nlins1
blt 4$
mov #nlins1-1,tt
4$: rts pc
;Get graphics cursor pos in t,tt and return
;with carry flag set if it is off the screen.
grfgtp: jsr pc,grfgp1
tst t
blt 1$
tst tt
blt 1$
cmp t,#bitpl
bge 1$
cmp tt,#nlins1
bge 1$
clc
rts pc
1$: sec
rts pc
;Convert TV coords in T, TT (such as grfclp and grfgpt return)
;to word address in TT and bit within word in T.
grfwrd: mov #bitpl/8,mq
mov tt,mul
mov mq,tt
add #tvlo,tt ;tt has address of start of row.
push t
asr t ;Take xpos, divide by 8 for byte within row.
asr t
asr t
bic #1,t ;Clear low bit for index of word within row.
add t,tt
pop t
bic #-20,t
rts pc
;Non-drawing commands.
grfmov: jsr pc,grfpnt
jmp grflp
grfxor: movb #-1,legxor(u)
jmp grflp
grfior: clrb legxor(u)
jmp grflp
grfvir: movb #-1,legvir(u)
jmp grflp
grfphy: clrb legvir(u)
jmp grflp
grflmt: jsr pc,grfpnt
jsr pc,grfclp
mov t,leglft(u)
mov tt,legtop(u)
jsr pc,grfpnt
jsr pc,grfclp
mov t,legrgt(u)
mov tt,legbot(u)
jmp grflp
;For now, %GOPSH is not implemented.
grfpsh: jmp grflp
;Handle %TDRST.
grfrst: clrb legxor(u)
clrb legvir(u)
clr leglft(u)
clr legtop(u)
mov #bitpl,legrgt(u)
mov #nlins1,legbot(u)
rts pc
;Select ALU function from current command (in B) and state of XOR mode.
grfmod: movb #cior,calu
tstb legxor(u) ;Set up to set, clear or flip bits.
bne 1$
bit #40,b
beq 3$
movb #candc,calu
rts pc
1$: movb #cxor,calu
3$: rts pc
;%GODPA, etc.
grfdpt: jsr pc,grfpnt ;Read coords of point.
jsr pc,grfmod ;Select ALU function.
jsr pc,grfgtp ;Convert to TV coords in T, TT.
bcs 1$ ;Don't display if off screen.
jsr pc,grfwrd ;Get word address in TT, bit within word in T.
asl t
mov bittbl(t),(tt) ;get bit within word, and store.
1$: jmp grflp
;%GODLA, etc.
grflin: jsr pc,grfclp ;Get cursorpos to start from.
jsr pc,grfpnt ;read in ending point (clobbers a).
jsr pc,grfmod ;Select ALU function.
mov t,a ;Move starting point into a, b.
mov tt,b
jsr pc,grfclp ;Get endpoint cursorpos in t,tt.
jsr pc,drwlin
grfx1: jmp grflp
;Output text at the graphics cursor position.
grfstr: jsr pc,grfclp ;Get current cursor addr in T, TT and move on screen.
jsr pc,grfwrd ;Turn into word address in TT, bit within wd in T.
mov #20-chrwd,c
sub t,c ;C gets phase within word of right edge of char.
;C has phase, TT has addr of word to start in.
1$: grfchr ;Read next arg char.
tst a
beq grfx1 ;Zero means exit.
jsr pc,grfmod ;Select ALU function.
asl a ;copied from code at genchr
mov ctab(a),t
push u
push c
push tt
push b
jsr pc,gench1 ;generate character, clobber all acs
pop b
pop tt
pop c
pop u
tst c ;Advance c, tt and legx to next char pos.
bgt 2$
add #20,c
tst (tt)+
cmp tt,#tvcfence
blos 2$
mov #tvlo,tt
2$: sub #chrwd,c
add #chrwd,legx(u)
br 1$
grfscn: ;scan line interpreter
clr c ;C has bits to set
clr tt ;TT has # of bits we got.
grfchr
bit #300,a
bne 1$
swab a ;1st char, if not terminator, has 6 bits.
asl a ;Put in top of word in C.
asl a
mov a,c
add #6,tt
grfchr
bit #300,a ;Next char has 6 more bits.
bne 1$ ;Put it in following bits of C.
asl a
asl a
asl a
asl a
bis a,c
add #6,tt
grfchr
bit #300,a ;Next char has 4 bits. Finish filling up C.
bne 1$
bis a,c
add #4,tt
;Now, B has original %GO command,
;C has accumulated bits, TT has number of bits.
1$: jsr pc,grfmod ;Select ALU function.
push tt ;Save # of bits.
jsr pc,grfgtp ;Get TV coords in T, TT
bcs 2$ ;Don't display if they are off screen.
push #0
cmp t,#bitpl-20
blt 3$
com (sp) ;Top of stack has -1 if within 1 word of right edge.
3$: jsr pc,grfwrd ;Compute word addr in TT, bit within word in T
mov c,mq
clr ac
mov t,lsh ;Divide word in B into bits for this wd and bits for next.
mov ac,(tt)+ ;Store the bits into this word.
tst (sp)+
bne 2$
mov mq,(tt) ;If there is a next word, store in it too.
;Finished displaying the bits (or not).
2$: add (sp)+,legx(u) ;Advance cursor by # bits we got.
bit #300,a
beq grfscn ;Was terminator? If not, read 3 more chars.
bit #200,a
beq grfx2 ;%TD code => go process it.
jmp dpyctl
grfx2: jmp grflp ;Code btw 100 and 200 => ignore it.
;Draw run-length encoded data.
grfrun: grfchr
tst a
beq grfx2
bit #100,a ;If it's a skip command, no output.
beq 6$
bic #100,a
jsr pc,grfgtp ;If off screen, no output.
bcs 6$
push a
add t,a ;Draw a line of the desired width
dec a ;(subtract 1 from end coord, since it is inclusive)
cmp a,#bitpl
blt 1$ ;Bring it onto the screen.
mov #bitpl-1,a
1$: jsr pc,grfmod ;Select ALU function.
jsr pc,drwhln
pop a
6$: add a,legx(u) ;increment x coord of cursor.
br grfrun
grfclr: mov leglft(u),a
mov legtop(u),b
mov legrgt(u),t
mov legbot(u),tt
movb #candc,calu
jsr pc,drwrec
jmp grflp
grfrec: jsr pc,grfclp ;Get cursorpos to start from.
jsr pc,grfpnt ;read in ending point (clobbers a).
jsr pc,grfmod ;select alu function
mov t,a ;Put starting cursorpos in a,b.
mov tt,b
jsr pc,grfclp ;Get endpoint cursorpos in t,tt.
jsr pc,drwrec
jmp grflp
;Draw a line from point (a,b) to point (t,tt).
;The coords are with origin at top left.
;We assume they are valid and on the screen.
drwlin: cmp b,tt ;If VPOS's are the same, draw horiz line is faster.
beq drwhln
mov u,-(sp)
mov c,-(sp)
sub tt,b ;create dy
sub t,a ;create dx
bgt 100$ ;branch if pos
neg a ;dx=abs(dx)
br 110$
100$: add b,tt ;get back the new values !!
add a,t
neg b ;flip dy
110$: mov #0,-(sp) ;dummy delinc
mov #bitpl/16.*2,-(sp) ;assume dy>=0 for ystep.
tst b ;test dy
bge 120$
neg (sp) ;turn ystep around
neg b
120$: mov #bitpl/10,mq
mov tt,mul
mov mq,u
mov t,c ;save c for the starting bit
asr t
asr t
asr t ;Compute word address offset.
bic #1,t
add t,u
add #tvlo,u ;Get word address of word ctning start of line.
bic #-20,c ;get ready to get starting bit
asl c ;indexable
mov bittbl(c),c ;get the starting bit in C.
;a,b is dx,dy; c=starting bit
cmp a,b ;compare dx,dy
bgt 150$
mov b,t ;get greater (delinc) into t
mov a,tt ;put deldec in tt
br 200$
150$: mov a,t
mov b,tt
200$: mov t,2(sp) ;put delinc on stack
sub a,b ;dy-dx, for comparison
mov t,a ;compute initial delta
asr a ;=delinc/2
inc t ;count=delinc+1
; c = bit
; u = pointer into memory
; t = count
; tt = deldec
; a = delta
; b = dy-dx
drwln1:
tst b
bge 100$
10$: mov c,(u) ;x direction
sub tt,a ;delta = delta-deldec
bgt 20$
add 2(sp),a ;up it by delinc
add (sp),u ;and go up (down) the screen
20$: asl c
bne 30$
sub #2,u ;go left
inc c ;and put a bit in the reg
30$: dec t
bne 10$
br ktvvex
100$: mov c,(u)
sub tt,a
bgt 120$
add 2(sp),a
asl c
bne 120$
sub #2,u
inc c
120$: add (sp),u
dec t
bne 100$
ktvvex: tst (sp)+
tst (sp)+
mov (sp)+,c
mov (sp)+,u
rts pc
bittbl: 100000,040000,020000,010000,004000,002000,001000,000400
000200,000100,000040,000020,000010,000004,000002,000001
;Draw a horizontal line from (t,tt) to (a,tt), inclusive.
;Does not refer to or set the graphics cursor position.
;Clobbers A, B, T, TT.
drwhln: cmp a,t
bgt 1$ ;Make sure that t is < a. Swap if not so.
push a
mov t,a
pop t
1$: sub t,a
inc a ;A has # bits to draw.
jsr pc,grfwrd ;Get word addr in TT, bit within word in T.
11$: mov #-1,b
cmp #20,a
ble 12$
mov b,mq ;Get desired # bits in top of B.
mov #20,b
sub a,b
mov b,lsh
mov mq,b
12$: tst t ;If not starting at start of word,
beq 2$
mov b,ac ;shift the bits to where we are starting.
push t
neg (sp)
pop lsh
mov ac,b ;Handle only what's left in current word.
2$: mov b,(tt)+ ;Process one word, and update # bits to be drawn.
sub #20,a ;Subtract 20-t, number of bits left in word,
add t,a ;from number of bits to be processed.
clr t ;We start at the top of the next word.
tst a
bgt 11$ ;Want more bits? Go do them.
rts pc
.if z 0
;Draw a rectangle with horizontal range a to t and vert range b to tt.
;Coords have origin at top left corner.
drwrec: cmp b,tt
bgt 1$
push b ;Make sure b is > tt. Swap if not.
mov tt,b
pop tt
1$: push b
push tt ;Now draw a horiz line with desired endpoints
push a
push t
jsr pc,drwhln ;on each row within the vertical limits.
pop t
pop a
pop tt
pop b
inc tt
cmp tt,b
ble 1$
rts pc
.iff
msktbl: 177777,077777,037777,017777,007777,003777,001777,000777
000377,000177,000077,000037,000017,000007,000003,000001
msktbe::
;Draw a rectablge with horizontal range a to t and vert range b to tt.
;Coords have origin at top left corner.
drwrec: cmp b,tt
bgt 10$
push b
mov tt,b ;make sure b > tt
pop tt
10$: cmp a,t
bgt 20$
push a
mov t,a ;make sure a > t
pop t
20$: sub tt,b ;vertical distance
inc b ;number of lines to hit
sub t,a ;horizontal distance
inc a ;number of columns to hit
push b ;vertical line count
push #<bitpl/8>-2 ;initial wrap around increment
clr -(sp) ;extra bits on left
clr -(sp) ;words in the middle
clr -(sp) ;extra bits on right
;;; ;;; vertical line count
;;; ;;; wrap around increment
;;; ;;; extra bits on left
;;; ;;; number of words to hit in the middle
;;; ;;; sp--* extra bits on right
jsr pc,grfwrd ;convert tt,t to address
tst t ;0 bits extra?
beq 40$
sub #16,a
add t,a ;count bits as done
asl t
mov msktbl(t),4(sp)
sub #2,6(sp) ;one less word to wrap around
40$: tst a
bpl 50$
asl a
bic msktbe(a),4(sp) ;line down middle of word
br 200$ ;finished, go draw
50$: com (sp) ;setup for extra bits on the right
mov a,t
bic #177760,t ;only 4 bits
asl t
bic msktbl(t),(sp) ;don't draw bits too many bits
bic #17,a
asr a
asr a
asr a
sub a,6(sp) ;fix wrap around increment
asr a ;number of words
mov a,2(sp)
200$: mov 4(sp),t ;bits in first word
beq 210$
mov t,(tt)+
210$: mov 2(sp),t ;number of middle words
beq 220$
215$: mov #-1,(tt)+
dec t
bne 215$
220$: mov (sp),(tt)+ ;bits in last word
add 6(sp),tt ;update to beginning of next scan line
dec 10(sp) ;one less scan line to do
bne 200$ ;loop until finished
add #5*2,sp ;pop temps
rts pc
.endc
;OUTSTR TAKES STRING TO PRINT IN B
OUTSTR:
OUTS1: MOVB @(SP),A
INC (SP)
TST A
BEQ OUTSX
CMP #12,A
BEQ OUTSLF
CMP #15,A
BEQ OUTSCR
JSR PC,TVO
BR OUTS1
OUTSLF: JSR PC,LF
BR OUTS1
OUTSCR: JSR PC,CR
BR OUTS1
OUTSX: ASR (SP) ;MAKE SURE WE RETURN TO EVEN ADDRESS
ADC (SP)
ASL (SP)
RTS PC
;TAKES # IN A AND PRINTS AS UNSIGNED INTEGER
OCTPNT: PUSH RADIX
MOV #10,RADIX
OCTPN1: JSR PC,DECPN0
POP RADIX
RTS PC
DECPNT: PUSH RADIX
MOV #10.,RADIX ;FOR DECIMAL PRINTING
BR OCTPN1
DECPN0: MOV A,MQ ;INTO EAE
DECPN9: MOV #AC,A ;FOR FAST ACCESS
DECPN1: MOV RADIX,-(A) ;DIVIDE BY RADIX
TST (A)+ ;POINTS AT AC
MOV (A)+,-(SP) ;REMAINDER
ADD #'0,(SP)
TST (A) ;QUOTIENT IS IN MQ
BEQ DECPN2
CLR -(A) ;FLUSH OUT AC, LEAVING MQ UNTOUCHED
JSR PC,DECPN1 ;RECURSIVE YET!
DECPN2: POP A ;TYPE OUT THAT DIGIT
JMP TVO ;TYPES DIGIT AND ADVANCES CURSOR
.SBTTL CALL, BREAK AND ESCAPE ROUTINES
;LEGAL ESCAPE AND BREAK COMMAND TABLE
ESCHAR: .BYTE '0,'1,'2,'3,'4,'5,'6,'7,'8,'9 ;DON'T DISTURB DIGITS
.BYTE 'S,'Q,'F,'D,'A,'E ;THESE CAN BE DONE ON ANY KBD
ESCSRN: .BYTE 'C,'L,'I,'R,'W,'U ;THESE NEED A SCREEN TO WIN
NESCMD==.-ESCHAR
.BYTE 0 ;MARKS END OF TABLE
.EVEN
;DISPATCH TABLE
ESCTAB: .REPT 10.
.NLIST
ESCDIG ;DIGIT
.LIST
.ENDR
VSWSEL ;<S> SELECT VIDEO CHANNEL
ESCQPY ;<Q> CAUSE A HARD COPY TO EXIST
ESCFRE ;<F> SAME AS S, BUT TO CONSOLE FREE BUFFER
ESCBUZ ;<D> BUZZ 9TH FLOOR DOOR
ESCAUD ;<A> SELECT AUDIO INPUT.
ESCELE ;<E> CALL THE ELEVATOR
CHECK ESCTAB,<<ESCSRN-ESCHAR>*2>
BOWXOR ;<C> TOGGLE BLACK ON WHITE BIT
ESCCLR ;<L> CLEAR SCREEN UNBEKNOWNST TO TEN.
ESCCSR ;<I> CLEAR SCROLL REGISTER
ESCRPT ;<R> START REPEATING THE PREV. CHAR TYPED IN.
ESCWHO ;<W> WHO LINE CONTROL
ESCWHO ;<U> WHO LINE CONTROL
CHECK ESCTAB,NESCMD*2
;HERE FOR ESCAPE
ESCAPE: BIT #ACLBIT+AMTBIT,B
BEQ ESCAP1 ;ESCAPE WITH CONTROL OR META TURNS INTO TOP-A.
JMP BRKCLR
ESCAP1: MOVB A,KBDESC(C) ;SAY FOLLOWING CHARS TO BE INTERPRETED AS AN ESCAPE CMD.
CLRB KBDARG(C) ;DEFAULT ARG TO ZERO
RTSPC4: RTS PC
;ACCUMULATE ARGS FOR ESCAPE AND BREAK
ESCDIG: ASR T ;DIGIT
MOVB KBDARG(C),A ;MULTIPLY ACCUMULATED VALUE BY 8
ASL A
ASL A
ASL A
ADD T,A ;ADD IN NEW DIGIT
MOVB A,KBDARG(C)
INCB KBDESC(C) ;READ NEXT CHAR AS A COMMAND CHAR, NOT AS PDP-10 INPUT.
RTS PC
;TAKES CHARACTER IN A AND CONVERTS IT UPPER CASE
UPPER: TST A ;MAKE SURE ITS LEGAL ASCII
BLE UPPER1
CMP #'a,A ;LOWER CASE?
BGT UPPER1
CMP #'z,A
BLT UPPER1
SUB #'a-'A,A ;MAKE IT UPPER CASE
UPPER1: RTS PC
;HANDLE ESCAPE-R. WITH NO ARG, STARTS INDEFINITE REPETITION OF LAST CHARACTER TYPED.
;WITH ARG, STOPS AFTER THAT MANY REPETITIONS. IN ANY CASE, ANY USER-SUPPLIED
;INPUT STOPS THE REPETITION.
ESCRPT: MOVB KBDARG(C),A
BNE ESCRP1
DEC A
ESCRP1: MOV A,LERPT(U)
RTS PC
;HERE TO SELECT VIDEO SWITCH INPUT.
;C HAS 2*KBD NUMBER; KBDARG(C) HAS VSW INPUT # OR 0 => DEFAULT.
VSWSEL: JSR PC,VSWSGO ;SET UP L.E. IDX IN U, VSW OUTPUT IN T.
BLT RTSPC4
MOV #-1,KBDDEF(C) ;NORMALLY RESET ANY TIME-OUT, BUT
TSTB KBDARG(C) ;IF THERE'S AN ARGUMENT,
BEQ VSWSL0
TST U
BNE VSWSL0
JSR PC,VSWSL3 ;SET UP A TIMEOUT, IF WE ARE A FREE SCREEN.
VSWSL0: MOVB KBDARG(C),TT ;GET ARG
BNE VSWSL1 ;SELECT DEFAULT?
;SELECT THE DEFAULT INPUT FOR A KEYBOARD.
;C HAS 2*KBD #, U HAS L.E. IDX OR 0 IF NONE, T HAS DEFAULT VSW OUTPUT OF THAT KBD.
VSWDEF: MOV #-1,KBDDEF(C) ;SAY THERE'S NO TIMEOUT ON THIS VSW SELECTION.
TST U ;FREE SCREEN => DEFAULT IS THE FREE DPY BUFFER.
BEQ VSWFRE
MOVB LECREG(U),TT ;GET DPY # TO SET DEFAULT
BLT RTSPC4 ;GARBAGE?
;COME HERE WITH DPY BUFFER # IN TT, TO SELECT THAT DPY BUFFER.
VSWDE1: ASL TT
MOV DPYVSW(TT),TT ;DEFAULT VIDEO SWITCH INPUT
JMP VSWIT ;DON'T NEED TO CHECK THIS
;COME HERE FOR [ESC]<N>S, WITH <N> IN TT.
VSWSL1: BIC #-400,TT ;UNDO SIGN-EXTENSION AT VSWSL0
CMP TT,NF11TY
BLO VSWSL2 ;<N> TOO SMALL TO BE TTY # => IT IS VSW INPUT #.
CMP TT,#200
BHIS VSWSL4 ;<N> >= 200 => IT IS DPY BUFFER # PLUS 200.
TST NF11TY ;IF NF11TY ISN'T KNOWN, VSW INPUT #S LOOK LIKE TTY #S
BEQ VSWSL2 ;BUT WE ARE EVEN SMARTER AND KNOW IT'S REALLY VSW INPUT.
SUB NF11TY,TT ;ELSE <N> SHOULD BE TTY NUMBER
CMP TT,#MAXTV
BHIS RTSPC4 ;DO NOTHING IF ARG OUT OF RANGE.
ASL TT
ASL TT
MOVB DPYKBD+1(TT),TT ;GET DPY BUFFER # FOR THIS TV, AND SELECT THAT DPY BUFFER.
BMI RTSPC4
BR VSWDE1
VSWSL4: SUB #200,TT ;TT SUPPOSEDLY HAS 200 PLUS DPY BUFFER NUMBER.
CMP TT,#MAXCRG
BLO VSWDE1
BR RTSPC4
;COME HERE TO HANDLE SET-VSW COMMAND FROM PDP10. T HAS OUTPUT #, TT HAS INPUT #.
;IF THEY ARE ILLEGAL WE DO NOTHING.
;ON RETURN, BLO JUMPS IF THEY WERE LEGAL.
VSWCMD: MOV #-1,KBDDEF(C) ;FLUSH ANY TIME-OUT.
CMP T,#MAXVSO ;CHECK FOR LEGAL OUTPUT
BHIS RTSPC4
;COME HERE WITH VALID OUTPUT # IN T, AND (MAYBE INVALID) INPUT # IN TT.
VSWSL2: CMP TT,#MAXVSI*VSWSEC
BHIS RTSPC4 ;REASONABLE?
JMP VSWIT ;SWITCH THE SWITCH
ESCFRE: JSR PC,VSWSGO ;SET UP U AND T FOR VSWDE1.
BLT RTSPC5
JSR PC,VSWSL3 ;THERE IS A TIMEOUT ON THIS SPYING.
VSWFRE: MOV DPYFRE,TT ;GET DPY # OF FREE CONSOLE SCREEN
BR VSWDE1
;SET UP A TIMEOUT WHEN A SPY IS ABOUT TO BE DONE. C HAS 2*KBD.
VSWSL3: MOVB #KBDTIM,KBDCNT(C) ;SET UP A TIMEOUT ON THIS KEYBOARD.
INC KBDTSW ;TELL CLOCK LEVEL TO START CHECKING TIMEOUTS.
RTS PC
;SET UP U := L.E. IDX, OR 0 IF NONE; T HAS DEFAULT VSW OUTPUT; GIVEN 2*KBD # IN C
;NEGATIVE IF SOMETHING FUNNY IS GOING ON, AND CALLER SHOULDN'T HACK.
VSWSGO: MOV KBDLE(C),U
BLT RTSPC5 ;THIS IF TEN SELECTS NON-EXISTENT VSW OUTPUT.
BEQ VSWSG1
TST LEKBD(U)
BLT RTSPC5
VSWSG1: MOV C,T
ASR T
MOVB KBDVSW(T),T
RTS PC
;DO [ESC]S ON KBD SPEC'D BY 2*KBD IN C.
VSWUNS: JSR PC,VSWSGO
BLT RTSPC5
JMP VSWDEF
;HANDLE [ESC] <ASW INPUT> A.
ESCAUD: MOVB KBDARG(C),TT ;ASW INPUT NUMBER.
MOV C,T
ASR T ;KEYBOARD NUMBER.
MOVB KBDASW(T),T ;OUTPUT NUMBER OF KEYBOARD.
BMI RTSPC5 ;WE DON'T KNOW YET OR IT HAS NO SPEAKER.
JMP ASWIT ;CONNECT THEM.
;CHANGE STATE OF BOW BIT
BOWXOR: MOVB #CXOR,CALU
MOV #BOWBIT,CSA
RTS PC
;HERE TO CLEAR SCREEN
ESCCLR: MOVB CREG,T ;THE SCREEN TO CLEAR
PUSH T
BLKOFF T
JSR PC,CLBLIN ;CLEAR ALL BLINKERS
JSR PC,CLRSCR ;CLEAR THE SCREEN
POP T
BLKON T
RTS PC
;HERE TO RESET SCROLL REGISTER
ESCCSR: MOVB #CSET,CALU
BIC #SAMSK,CSA ;RESET THE SCROLL REGISTER
RTS PC
;HERE TO GENERATE VIDEO HARD COPY
ESCQPY: TST QPYSWT ;IS THE SWITCH LOCKED?
BNE ESCQPB
TST QPYDWN ;IS THE QPY DOWN?
BNE ESCQPB
ESCQP1: MOV KBDLE(C),U
BEQ ESCQP6
TST LEKBD(U)
BLT RTSPC5
ESCQP6: MOV #QPYVSW,T ;THE VIDEO SWITCH OUTPUT FOR THE HARD COPY UNIT
JSR PC,VSWSL0 ;PROCESS THE ARG
CHROFF
ZAPFLG QPYSWT ;LOCK THE SWITCH
BIS #QPYKMS,KMS ;CAUSE THE COPY
JSR TT,ADQUE ;SCHEDULE THE UNCOPY
2
ESCQP2
MOV CREG,T
JSR TT,ADQUE ;SCHEDULE THE SWITCH UNLOCK
QPTIME
ESCQP3
RTSON: CHRON
RTSPC5: RTS PC
ESCQPB: JMP BELL ;SOME ONE ELSE IS COPYING, GIVE HIM A BELL
ESCQP2: BIC #QPYKMS,KMS ;UNCAUSE THE COPY
RTS PC
ESCQP3: JSR PC,CLKBEL ;BELL WHEN COPY DONE
CLR QPYSWT
RTS PC
;HERE TO BUZZ 9TH FLOOR DOOR
ESCBUZ: TST BUZSWT ;IS THE SWITCH LOCKED?
BEQ ESCBZ1
JMP BELL
ESCBZ1: CHROFF
ZAPFLG BUZSWT ;LOCK SWITCH
BIS #BUZKMS,KMS ;BUZZ THE DOOR
MOV CREG,T
JSR TT,ADQUE ;SCHEDULE THE UNBUZZ
BUZTIM
ESCBZ2
BR RTSON
ESCBZ2: JSR PC,CLKBEL ;BELL WHEN BUZZ DONE
BIC #BUZKMS,KMS ;UNBUZZ THE DOOR
CLR BUZSWT ;UNLOCK THE SWITCH
RTS PC
;HERE TO CALL THE ELEVATOR
; C HAS 2*KBD NUMBER
ESCELE: TST ELESWT ;IS THE SWITCH LOCKED?
BEQ ESCEL1
JMP BELL
ESCEL1: CHROFF
ZAPFLG ELESWT ;LOCK SWITCH
MOV C,T
ASR T ;DEVIDE BY 2
CMP T,#MAXVSO ;IS IT IN RANGE?
BHIS RTSON
MOVB ELETAB(T),TT ;WHICH FLOOR IS IT ON?
SWAB TT ;GET CONSTANT INTO THE LEFT HALF WORD
BIS TT,KMS ;FROB THE CORRECT BIT
MOV CREG,T
JSR TT,ADQUE ;SCHEDULE THE UNPUSH
ELETIM
ESCEL2
BR RTSON
ESCEL2: JSR PC,CLKBEL ;BELL WHEN DONE
BIC #ELEKMS,KMS ;UNPRESS
CLR ELESWT ;UNLOCK THE SWITCH
RTS PC
CLKBEL: PUSH CREG ;FOR USE BY CLOCK QUEUED ROUTINES
MOV (T),CREG ;T POINTS TO DESIRED CREG
PUSH TT ;DON'T CLOBBER AT PI LEVEL!!
JSR PC,BELL
POP TT
POP CREG
RTS PC
;HERE TO CONTROL WHO LINE
; [ESC]<N>W WHMODE
; N=0 TURN OFF WHO LINE -1
; 1 FOLLOW KEYBORAD 0
; 2 FREEZE 1
; 3 NEXT HIGHER 2
; 4 NEXT LOWER 3
;ALL OTHERS SYSTEM WHO LINE
; [ESC]<N>U
;FREEZES WHOLINE ON JOB WHOSE USER INDEX IS N*L (L IS THE ITS SYMBOL).
NWHCMD==5 ;NUMBER OF WHO COMMANDS
ESCWHO: MOV LECHN(U),TT ;10/11 CHANNEL
ASL TT ;MAKE IT CHANNEL INDEX
ASL TT
MOV WHOLIN(TT),TT ;WHO LINE VARIABLES
CMPB A,#'U
BEQ ESCWHU
MOVB KBDARG(C),T ;ARGUMENT
DEC T ;HACK
BMI ESCWH2 ;TURN IT OFF?
MOV T,WHMODE(TT) ;SET THE MODE WE WANT
ESCWU1: CLR WHMOD1(TT) ;JUST TO BE SURE
MOV #-1,TENWHO ;TELL PDP-10 TO UPDATE WHO LINES
RTS PC
;TURNS OFF WHO LINE
ESCWH2: ;CLEAR WHO LINE AT MAIN PROGRAM LEVEL TOO
MOV T,2(TT) ;(T HAS -1 IN IT)
MOV T,WHMODE(TT) ;AND TURN IT OFF
BR CLRWHL
ZAPWHL: MOV DPYCHN(B),A ;SET UP CREG
MOVB LECREG(A),CREG
CLRWHL: MOV #TVLO+<LINHT*CHRLN*BYTPL>,T
MOV #CHRHT-1,TT
JMP CLRCL0
ESCWHU: MOV #1,WHMODE(TT)
MOVB KBDARG(C),WHJOB(TT)
CLR WHJOB1(TT)
BR ESCWU1
;COME HERE FOR CALL KEY
CALL: PUSH B
TSTB KBDCNT(C)
BLT CALL1
JSR PC,VSWUNS ;IF DOING A SPY WITH A TIMEOUT, UNDO IT.
CALL1: MOV KBDLE(C),U ;LINE EDITOR VARIABLES
BNE UPTREE ;GET FRESH LINE EDITOR?
ASR C
JSR PC,CHCONS ;ALLOCATE A CHANNEL.
;T HAS CHANNEL NUMBER. U HAS LINE EDITOR ADDR. A HAS WHOLINE VAR BLOCK ADDR.
TST T ;-1 RETURNED AS CHANNEL # => NONE AVAILABLE.
BLT CALLLS
MOVB LECREG(U),CREG
CLR CSA ;CLRSCR SETS UP CALU
;HERE IF CALL AND LINE EDITOR EXISTS.
UPTREE: POP B
CLR LERPT(U)
MOV #32,A ;CONTROL-Z (SIGH)
BIS #ACTBIT,B ;ACTIVATES BUFFER
JMP PUTCHR ;SEND THAT CHARACTER TO PDP-10
CALLLS: POP B
RTSPC2: RTS PC
;HERE TO ALLOCATE A DISPLAY CHANNEL.
;CALLED WITH KEYBOARD NUMBER IN C, OR -1 IF NOT ALLOCATING THIS DPY FOR A KEYBOARD.
;RETURNS THE CHANNEL NUMBER (TTY NUMBER MINUS NF11TY) IN T,
;THE LINE EDITOR BLOCK ADDR IN U,
;AND THE ADDRESS OF THE WHOLINE VARIABLE BLOCK IN A. SETS WHMODE TO 0.
;IF NO CHANNEL IS AVAILABLE, OR THE KEYBOARD CAN'T BE USED FOR SOME REASON,
;WE RETURN -1 IN T TO INDICATE THAT.
CHCONS: MOV C,T ;IF A KEYBOARD IS SPECIFIED,
BLT CHCON4
TSTB KBDVSW(C) ;DON'T ALLOW IT IF KEYBOARD HAS NO SCREEN
BLT CHCNFL
ASL T
TST KBDLE(T) ;OR IS ALREADY IN USE.
BNE CHCNFL
CHCON4: CLR T ;NOW FIND A FREE CHANNEL
CHCON1: TSTB CHCREG(T) ;DON'T ALLOCATE CHANNELS THAT DON'T HAVE BUFFERS.
BLT CHCON0
TSTB CHNUSE(T)
BEQ CHCON2
CHCON0: INC T
CMP T,#MAXTV
BLT CHCON1
CHCNFL: MOV #-1,T
RTS PC ;NO FREE CHANNEL
CHCON2: INCB CHNUSE(T) ;FOUND A CHANNEL. MARK IT IN USE.
DEC ITSFDP ;DECREASE COUNT OF FREE CHANNELS.
MOVB CHCREG(T),A
PUSH A ;SAVE VIDEO BUFFER NUMBER FOR POPPING INTO LECREG
MOVB A,CREG ;SELECT THAT BUFFER
PUSH T ;PROTECT T, SMASHED BY CLRSCR (TT ALSO SMASHED)
JSR PC,CLRSCR ;AND CLEAR IT (SLOW, BUT NECESSARY BEFORE SWITCHING VSW)
POP T
MOV T,A
ASL A
ASL A
MOV DPYCHN(A),U ;GET THE ADDR OF CHANNEL'S VAR BLOCK.
JSR PC,CHCLR ;PUT -1'S IN THE 10-TO-11 BUFFER, RESET POINTERS.
JSR PC,LECON2 ;INITIALIZE THE LINE EDITOR BLOCK.
MOVB (SP),DPYKBD+1(A) ;TELL THE 10 WHICH TV BUFFER.
POP LECREG(U) ;TELL THE LINE EDITOR WHICH TV BUFFER IT IS.
MOV C,LEKBD(U) ;AND WHICH KEYBOARD IT IS.
BLT CHCON3
MOV C,CHNCLS(A) ;TELL THE 10 ABOUT THE KEYBOARD.
CLRB CHNCLS+1(A) ;MAKE SURE CHNCLS IS NON-NEGATIVE EVEN IF KBD WAS -1
MOVB C,DPYKBD(A)
MOV T,LECHN(U) ;TELL LE WHICH DPY CHANNEL NUMBER IT IS
PUSH T ;SHOW OUR DPY BUFFER ON THE KBD'S SCREEN.
MOVB KBDVSW(C),T ;VIDEO SWITCH OUTPUT
MOVB LECREG(U),B
ASL B
MOV DPYVSW(B),TT ;GET OUR DPY'S VIDEO INPUT NUMBER.
JSR PC,VSWIT ;SWITCH THE SWITCH
MOV FBLINK,T ;CONS UP A BLINKER FOR THE CURSOR
BNE .+4 ;ARE THERE FREE BLINKERS?
BPT
MOV BLNEXT(T),FBLINK
MOV BLINKS(B),BLNEXT(T)
MOV T,BLINKS(B) ;THE BLINKER
MOV U,BLCURS(T) ;FOLLOW PAGE PRINTER
CLRB BLON(T) ;BLON
POP T
ASL C ;MAKE THE KEYBOARD AND THIS LINE EDITOR POINT AT EACH OTHER.
MOV U,KBDLE(C)
CHCON3: PUSH WHOLIN(A)
PUSH T
MOV T,TT
MOV LEBUF(U),T
JSR PC,CLRING ;CLEAR THE 11-TO-10 INPUT BUFFER RING.
POP T
POP A
MOV #0,WHMODE(A)
RTS PC
;CLEAR OUT THE 10-TO-11 BUFFER WHICH U POINTS AT.
CHCLR: MOV DPY10B(U),TT ;POINTER TO START OF BUFFER
MOV TT,DPY11B(U) ;RESET OUR POINTER INTO THE CHANNEL'S BUFFER.
INC DPY11B(U) ;MAKE POINT AT 1ST BYTE IN PDP10 ORDER!
CHCLR1: MOV #-1,(TT)+
CMP TT,DPYLGL(U)
BLOS CHCLR1
RTS PC
;HERE TO INITIALIZE MOST OF THE WORDS OF A LINE EDITOR BLOCK,
;AND GET A RING OF KEYBOARD BUFFERS FOR IT.
LECON2: PUSH T
PUSH U
MOV U,TT ;SET DEFAULTS
ADD #DPSIZE+DPDATA,TT
MOV #LEDFLT+DPSIZE+DPDATA,T
MOV #LELEN-DPSIZE-DPDATA,U
JSR PC,CALCPY ;DEFAULT IS FOR FREE VARIABLES
POP U
MOV FSP,T ;FIRST FREE BUFFER
BEQ LECON3
MOV LHFS(T),TT ;NEXT BUFFER
BEQ LECON3
MOV LHFS(TT),FSP ;TAKE THOSE TWO
MOV T,LHNEXT(TT)
MOV TT,LHNEXT(T) ;ALL NICE AND COZY
MOV T,LEBUF(U) ;POINTER TO RING
ADD #LHLEN,T
MOV T,LECHR(U) ;BUFFER ACCESS POINTER
POP T
RTS PC
LECON3: BPT ;NO 11-TO-10 BUFFERS AVAILABLE FOR A RING?
;CLEARS HEADERS OF BUFFER RING, CALLED WITH RING IN T, CHN# IN TT
CLRING: PUSH T
CLRNG1: CLR (T)+ .SEE LHFLAG
CLR (T)+ .SEE LHZERO
TST (T)+ .SEE LHNEXT
CLR (T)+ .SEE LHALST
CLR 2(T) .SEE LHFS
CLR 4(T) .SEE LHQUED
MOV TT,(T) .SEE LHCHN
TST -(T) .SEE LHALST
MOV -(T),T ;.SEE LHNEXT COMMENT THIS OUT DUE TO PALX BRAIN DAMAGE
CMP (SP),T
BNE CLRNG1
POP T
RTS PC
;HERE TO COPY A BLOCK OF CORE
: T SOURCE
; TT DESTINATION
; U BYTE COUNT (ONLY EVEN NUMBERS WILL WORK)
CALCPY: INC U ;MAKE A WORD COUNT
ASR U
CALCP1: MOV (T)+,(TT)+
DEC U
BGT CALCP1
RTS PC
;HERE TO RETURN DPY CHANNEL. T HAS CHANNEL NUMBER.
CHRETN: TST T ;DON'T RETURN CHANNEL 0.
BEQ CHRET0
DECB CHNUSE(T) ;MARK THE CHANNEL AS NOT IN USE
BGE .+4
BPT
INC ITSFDP ;AND INCLUDE IT IN THE COUNT OF FREE CHANNELS.
BR CHRET1
CHRET0: MOV #377,CHNCLS ;IF FREEING THE FREE TV DISPLAY, DON'T REALLY FREE IT
CHRET1: ASL T
ASL T
MOV DPYCHN(T),U
JSR PC,CHCLR ;RESET THE 10-TO-11 BUFFER AND POINTERS.
TST T
BEQ CHRETX ;DON'T RETURN CHANNEL 0 (FREE CONSOLE DISPLAY)
MOV #-1,DPYKBD(T) ;TELL THE PDP-10 WE'RE LOGGING OUT
MOV WHOLIN(T),TT
MOV #-1,WHMODE(TT) ;TURN OFF WHO-LINE GENERATION ON THIS CHANNEL.
;HERE TO FREE THE 11-TO-10 INPUT BUFFERS, AND MARK THE KEYBOARD AND CHANNEL
;AS DISCONNECTED. ALSO FREE THE BLINKERS.
LERETN: CLR LERPT(U)
MOV LEBUF(U),T ;RETURN BUFERS IN RING
BEQ LERT2A ;BUFFERS TO RETURN?
PUSH T
LERET1: MOV LHNEXT(T),LHFS(T)
CMP LHFS(T),(SP)
BEQ LERET2
MOV LHFS(T),T
BR LERET1
LERET2: MOV FSP,LHFS(T) ;CUT RING, PATCH ON TO FREE LIST
POP FSP
CLR LEBUF(U) ;MARK AS FREE
LERT2A: MOV LEKBD(U),T
BLT LERT2B ;A KEYBOARD?
ASL T ;BYTES
CLR KBDLE(T)
ASR T
MOVB KBDVSW(T),T ;VSW THE OUTPUT
BLT LERT2B
MOV DPYFRE,TT ;MESSAGE DPY
ASL TT ;BYTES
MOV DPYVSW(TT),TT
JSR PC,VSWIT ;GIVE HIM THE CONSOLE FREE MESSAGE
LERT2B: MOVB LECREG(U),T ;RETURN ALL THE BLINKERS
BLT LERET5 ;A DPY?
MOVB #-1,LECREG(U) ;INVALIDATE DPY #
ASL T
TST BELCNT(T) ;ANY BELLS PENDING?
BMI LERET6
CLR BELCNT(T) ;THE NEXT FLASH WILL BE THE LAST
LERET6: MOV BLINKS(T),TT ;RETURN THIS DISPLAY'S BLINKERS TO FREE LIST.
BEQ LERET5
LERET3: TST BLNEXT(TT)
BEQ LERET4
MOV BLNEXT(TT),TT
BR LERET3
LERET4: MOV FBLINK,BLNEXT(TT)
MOV BLINKS(T),FBLINK
CLR BLINKS(T)
LERET5: MOV #-1,LEKBD(U)
CLRUJ: CLR U ;SEARCH FAILED
CHRETX: RTS PC
.SBTTL VIDEO AND AUDIO SWITCH ROUTINES
;VIDEO SWITCH TABLES (ONE INPUT CAN DRIVE MANY OUTPUTS)
;THE SWITCH IS COMPOSED OF SEVERAL IDENTICAL SECTIONS, THE CORRESPONDING
;OUTPUTS OF EACH SECTION ARE MIXED TOGETHER TO FORM THE FINAL VIDEO THAT IS
;SENT TO THE MONITOR. INPUT 0 OF EACH SECTION OF THE SWITCH IS THE NULL INPUT,
;HENCE WE USUALLY USE THAT INPUT WHEN USING A MONITOR AS A DISPLAY.
;VSWTAB, INDEXED BY OUTPUT NUMBER, IS A BYTE GIVING THE NONNULL INPUT FEEDING THAT OUTPUT.
;THE INPUT NUMBER IS RELATIVE TO THE WHOLE SWITCH, NOT JUST THE SECTION.
;0 MEANS THAT ONLY NULL INPUTS ARE FEEDING AN OUTPUT.
VSWTAB: .BLKB MAXVSO
;HERE TO SWITCH VIDEO SWITCH (OUTPUT IN T, INPUT IN TT).
;CLOBBERS NO ACS.
VSWIT: PUSH TT
JSR PC,VSWNUL ;FLUSH ALL OTHER INPUTS TO THAT OUTPUT.
POP TT
VSWIT1: PUSH B
PUSH C
MOVB TT,VSWTAB(T) ;UPDATE OUR OWN INTERNAL TABLE.
MOV TT,MQ
MOV #MAXVSI,DIV ;DIVIDE TO TURN INPUT NUMBER
MOV MQ,C ;INTO SECTION NUMBER
MOV AC,B ;AND NUMBER WITHIN SECTION.
TST A ;CLEAR C BIT
ROR C
ROR C
ROR C
ROR C ;GET SECTION NUMBER INTO TOP THREE BITS OF WORD.
BIS C,B
MOV T,C
SWAB C
BIS C,B ;CREATE ARGUMENT FOR VIDEO SWITCH.
MOV B,VSW ;SWITCH IT!
POP C
POP B
RTS PC
;HERE SEND NULL VIDEO TO OUTPUT SPECIFIED IN T
;CLOBBERS TT
VSWNUL: PUSH #VSWSEC ;# SECTIONS
CLR TT ;INPUT 0 IN SECTION 0.
VSWN1: JSR PC,VSWIT1 ;SWITCH IT
ADD #MAXVSI,TT ;ADVANCE TO INPUT 0 IN NEXT SECTION
DEC (SP)
BGT VSWN1 ;MORE
TST (SP)+ ;CLEANSE STACK
CLRB VSWTAB(T) ;MAKE SURE INTERNAL TABLE SAYS NOTHING FEEDING THIS OUTPUT.
RTS PC
;AUDEO SWITCH TABLES (ONE INPUT CAN DRIVE MANY OUTPUTS)
;INPUT 0 IS SILENCE. RIGHT NOW, THAT IS THE NORMAL SETTING FOR ANY OUTPUT.
;ASWTAB, INDEXED BY OUTPUT NUMBER, IS A BYTE GIVING THE INPUT FEEDING THAT OUTPUT.
ASWTAB: .BLKB MAXASO
;GIVEN ASW OUTPUT IN T AND INPUT IN TT, CONNECT THEM IF THEY ARE LEGAL.
;ON RETURN, BLO JUMPS IF THEY WERE LEGAL.
ASWCMD: CMP T,#MAXASO
BHIS ASWITX
CMP TT,#MAXASI
BHIS ASWITX
;HERE TO SWITCH AUDEO SWITCH (OUTPUT IN T, INPUT IN TT).
;CLOBBERS NO ACS.
ASWIT: PUSH C
MOV T,C
SWAB C
BIS TT,C ;CONSTRUCT OUTPUT,,INPUT AND GIVE TO SWITCH AS COMMAND.
PUSH B
MOV C,B ;NOW COMPLEMENT SOME OF C (WHAT'S IN ASWXOR).
BIC #<-1>#ASWXOR,B
BIS #ASWXOR,C
BIC B,C
POP B
MOV C,ASW
MOVB TT,ASWTAB(T) ;UPDATE OUR OWN INTERNAL TABLE.
POP C
ASWITX: RTS PC
;RESET THE AUDEO SWITCH (ALL OUTPUTS RECEIVING SILENCE).
REASW: MOV #MAXASO-1,T
CLR TT
REASW1: JSR PC,ASWIT
DEC T
BGE REASW1
RTS PC
.SBTTL CHARACTER GENERATOR ROUTINES
;CLEARS CHARACTER AT LINE EDITOR CURSOR
CLRCHR: JSR U,ACSAV
MOVB #CANDC,CALU
CLCHR1: MOV #BLOB,T ;BLOB MASKS ENTIRE CHARACTER
CLCHR2: MOV LEPHS(U),C
MOV LECC(U),TT
JSR PC,GENCH1
MOVB #CIOR,CALU ;RESTORE FOR DPYDP1 LOOP
BR ACRES
;BLINK CHARACTER AT CURSOR
XORCHR: JSR U,ACSAV
MOVB #CXOR,CALU
MOV #BLOB,T
BR CLCHR2
;GENERATE A CHARACTER
;CALL WITH CHARACTER IN A AND PAGE PRINTER IN U
;PRESERVES ALL ACS
GENCHR: JSR U,ACSAV
MOV LEPHS(U),C
MOV LECC(U),TT
MOVB #CIOR,CALU
ASL A ;MAKE IT A BYTE OFFSET
MOV CTAB(A),T ;POINTS AT FONT DESCRIPTION
JSR PC,GENCH1
ACRES: POP A
POP B
POP C
POP T
POP TT
POP U
RTS PC
;The lowest level character generator
;Initial AC settings
;A LSH address of EAE shift counter
;B MQ address of EAE regiseter
;C number of desired shifts
;T points into font description
;TT points into display memory
;U number of bytes per line of display memory
;initial memory settings
;AC 0, EAE register
;CREG CIOR,,console number, console register
;;NOTE THAT MQ=AC+2
;THIS ROUTINE CLOBBERS -ALL- ACS
GENCH1: MOV #LSH,A
TST C
BLT OVRLAP
EZCASE: MOV #BYTPL,U
MOV #AC,B
CLR (B)+ ;CLEAR AC
.REPT CHRHT
.NLIST
MOVB (T)+,(B) ;5.2 ;CHARACTER RASTER LINE INTO MQ
MOV C,(A) ;3.7 ;INITIATE SHIFT
MOV (B),(TT) ;5.2 ;OUT OF MQ INTO DISPLAY MEMORY
ADD U,TT ;2.3 ;GET TO NEXT RASTER LINE
; TOTAL 16.4 MICRO-SECONDS
.LIST
.ENDR
RTS PC
;initial settings same as EZCASE with one exception
;U <number of bytes per line of display memory>-2
OVRLAP: MOV #BYTPL-2,U
MOV #MQ+2,B
.REPT CHRHT
.NLIST
CLR -(B) ;3.7 ;CLEAR MQ
CLRB -(B) ;2.3 ;CLEAR HIGH ORDER OF AC
MOVB (T)+,-(B) ;5.2 ;LOAD AC WITH CHARACTER LINE
MOV C,(A) ;3.7 ;INIATE SHIFT
MOV (B)+,(TT)+ ;5.2 ;AC TO DISPLAY MEMORY
MOV (B)+,(TT) ;5.2 ;MQ TO DISPLAY MEMORY
ADD U,TT ;2.3 ;SET TO NEXT RASTER LINE
;TOTAL 27.6 MICRO-SECONDS
.LIST
.ENDR
RTSPC: RTS PC
;SOME LOW LEVEL GOODIES
;CLEARS ONE RASTER LINE
CLRRST: MOVB #CSET,CALU
CLRRS1: .REPT WRDPL
.NLIST
CLR (T)+
.LIST
.ENDR
RTS PC
;CLEARS ONE CHARACTER LINE
CLRCHL: MOV #LINHT-1,TT
CLRCL0: JSR PC,CLRRST
CLRCH1: JSR PC,CLRRS1
DEC TT
BGT CLRCH1
RTS PC
;CLEAR ENTIRE SCREEN
CLRSCR: MOV #TVLO,T
JSR PC,CLRRST
MOV #NLINS-1,TT
CLRSC1: JSR PC,CLRRS1
DEC TT
BGT CLRSC1
RTS PC
;COPIES ONE RASTER LINE
CPYRST: MOVB #CSET,CALU
CPYRS1: .REPT WRDPL
.NLIST
MOV (T)+,(TT)+
.LIST
.ENDR
RTS PC
;COPIES ONE CHARACTER LINE
CPYCHL: PUSH A
MOV #LINHT-1,A
JSR PC,CPYRST
CPYCH1: JSR PC,CPYRS1
DEC A
BGT CPYCH1
POP A
RTS PC
.SBTTL KEYBOARD TABLES
.MACRO KBDKEY N,PLAIN,SH,SL,SLSH,TOP
.XLIST
.=XTAB+N
.BYTE PLAIN
.=XTAB+N+100
.BYTE SH
.=XTAB+N+200
.BYTE SL
.=XTAB+N+300
.BYTE SLSH
.=XTAB+N+400
.BYTE TOP
.LIST
.ENDM
;WHAT FOLLOWS IS THE GRAND CHARACTER CONVERSION TABLE
;AN 8 BIT QUANTITY IS USED TO INDEX INTO THE XTAB
; 0-5 KEYBOARD KEY NUMBER
; 6 SHIFT
; 7 SHIFT LOCK
; 8 TOP (6 AND 7 GUARANTEED TO BE ZERO)
;IF THE BYTE PICKED IS NEGATIVE, YOU HAVE STRUCK A KEY THAT DOES NOT
;HAVE AN ASCII CODE. THESE CODES ARE ASSIGNED AS FOLLOWS:
NASCTB: NONAS1 ; 0 ILLEGAL
ESCAPE ; -1 ESCAPE
BRKCLR ; -2 BREAK
BRKCLR ; -3 CLEAR
PLSMNS ; -4 PLUS-MINUS
CRCPLS ; -5 CIRCLE-PLUS
DELTA ; -6 DELTA
GAMMA ; -7 GAMMA
BRKCLR ; -10 HELP
RTSPC ; -11 BACK -- not really used
RTSPC ; -12 NEXT -- not really used
CALL ; -13 CALL
MAXNAS==<<.-NASCTB>/2>-1 ;MAXIMUM # NON-ASCII CHARACTERS
.EVEN
; CHAR NORMAL SHIFT LOCK SHIFT&LOCK TOP
XTAB:
KBDKEY 0, -2, -2, -2, -2, -2 ;BREAK
KBDKEY 1, -1, -1, -1, -1, -1 ;ESCAPE
KBDKEY 2, '1, '!, '1, '!, '!
KBDKEY 3, '2, '", '2, '", '"
KBDKEY 4, '3, '#, '3, '#, '#
KBDKEY 5, '4, '$, '4, '$, '$
KBDKEY 6, '5, '%, '5, '%, '%
KBDKEY 7, '6, '&, '6, '&, '&
KBDKEY 10, '7, '', '7, '', ''
KBDKEY 11, '8, '(, '8, '(, '(
KBDKEY 12, '9, '), '9, '), ')
KBDKEY 13, '0, '_, '0, '_, '_
KBDKEY 14, '-, '=, '-, '=, '=
KBDKEY 15, '@, '`, '@, '`, '`
KBDKEY 16, '^, '~, '^, '~, '~
KBDKEY 17, 10, 10, 10, 10, 10 ;BACK SPACE
KBDKEY 20, -13, -13, -13, -13, -13 ;CALL
KBDKEY 21, -3, -3, -3, -3, -3 ;CLEAR
KBDKEY 22, 11, 11, 11, 11, 11 ;TAB
KBDKEY 23, 33, 33, 33, 33, 33 ;ALT-MODE
KBDKEY 24, 'q, 'Q, 'Q, 'Q, 4, ;and
KBDKEY 25, 'w, 'W, 'W, 'W, 37 ;or
KBDKEY 26, 'e, 'E, 'E, 'E, 22 ;intersection
KBDKEY 27, 'r, 'R, 'R, 'R, 23 ;union
KBDKEY 30, 't, 'T, 'T, 'T, 20 ;subset
KBDKEY 31, 'y, 'Y, 'Y, 'Y, 21 ;superset
KBDKEY 32, 'u, 'U, 'U, 'U, 5 ;not
KBDKEY 33, 'i, 'I, 'I, 'I, 26 ;xor
KBDKEY 34, 'o, 'O, 'O, 'O, 1 ;down arrow
KBDKEY 35, 'p, 'P, 'P, 'P, 13 ;up arrow
KBDKEY 36, '[, '{, '[, '{, '{
KBDKEY 37, '], '}, '], '}, '}
KBDKEY 40, '\, '|, '\, '|, '|
KBDKEY 41, '/, 16, '/, 16, 16 ;infinity
KBDKEY 42, -4, -6, -4, -6, -6 ;plus-minus, delta
KBDKEY 43, -5, -7, -5, -7, -7 ;circle-plus, gamma
KBDKEY 44, 14, 14, 14, 14, 14 ;form
KBDKEY 45, 13, 13, 13, 13, 13 ;vertical tab
KBDKEY 46, 177, 177, 177, 177, 177 ;rubout
KBDKEY 47, 'a, 'A, 'A, 'A, 34 ;.leq.
KBDKEY 50, 's, 'S, 'S, 'S, 35 ;.geq
KBDKEY 51, 'd, 'D, 'D, 'D, 36 ;equivalence
KBDKEY 52, 'f, 'F, 'F, 'F, 17 ;delta (partial derivative)
KBDKEY 53, 'g, 'G, 'G, 'G, 32 ;not equals
KBDKEY 54, 'h, 'H, 'H, 'H, -10 ;HELP!!!!!
KBDKEY 55, 'j, 'J, 'J, 'J, 30 ;back arrow
KBDKEY 56, 'k, 'K, 'K, 'K, 31 ;forward arrow
KBDKEY 57, 'l, 'L, 'L, 'L, 27 ;both ways arrow
KBDKEY 60,<';>, '+,<';>, '+, '+
KBDKEY 61, ':, '*, ':, '*, '*
KBDKEY 62, 15, 15, 15, 15, 15 ;carriage return
KBDKEY 63, 12, 12, 12, 12, 12 ;line feed
KBDKEY 64, 37, 37, 37, 37, 37 ;next, back gives ^_
;KBDKEY 64, -12, -11, -12, -11, -11 ;next, back
KBDKEY 65, 'z, 'Z, 'Z, 'Z, 2 ;alpha
KBDKEY 66, 'x, 'X, 'X, 'X, 3 ;beta
KBDKEY 67, 'c, 'C, 'C, 'C, 6 ;epsilon
KBDKEY 70, 'v, 'V, 'V, 'V, 10 ;lambda
KBDKEY 71, 'b, 'B, 'B, 'B, 7 ;pi
KBDKEY 72, 'n, 'N, 'N, 'N, 24 ;for all
KBDKEY 73, 'm, 'M, 'M, 'M, 25 ;there exists
KBDKEY 74,<',>, '<,<',>, '<, '<
KBDKEY 75, '., '>, '., '>, '>
KBDKEY 76, '/, '?, '/, '?, '?
KBDKEY 77, 40, 40, 40, 40, 40 ;space
.SBTTL FONT MACROS AND DEFINITION
.IIF E FONTSW,CTAB==0
.IF NE FONTSW
FNTORG==.
.MACRO CTBENT A
.XCREF ...'A
...'A
.ENDM
CTAB: .REPT 200
.NLIST
CTBENT \.RPCNT
.LIST
.ENDR
...200 ;THIS CHAR IS A BLOB FOR CURSORS.
.MACRO FONT A
.NLIST
....==0
...==1_GRIDWD
.IRPC CHR,A
...==..._<-1>
.IF NB CHR
....==....!...
.ENDC
.ENDM
.IF NE ...-1
ERROR \CURCHR
.ENDC
;...FOO==%XLIST
;.REPT ...FOO
;.LIST
;.ENDR
.BYTE ....
;.XLIST
;%XLIST=...FOO
.LIST
.ENDM
.MACRO CDEF A
.NLIST
CURCHR==''A
CDEF1 \CURCHR
.LIST
.ENDM
.MACRO CDEF1 A
.NLIST
.XCREF ...'A
CURCHR==A
;...FOO==%XLIST
;.REPT ...FOO
;.LIST
;.ENDR
...'A==.
;.XLIST
;%XLIST=...FOO
.LIST
.ENDM
.MACRO ERROR NUM
.IF1
.ERROR ;FONT LOSSAGE NUM
.ENDC
.ENDM
.ENDC
.XLIST
.IF NE FONTSW
.IF NE FONTMS
.XCREF CURCHR,FONT,CDEF1,CDEF
CDEF1 0
FONT < >
FONT < >
FONT < >
FONT < *** >
FONT < *** >
FONT < *** >
FONT < >
FONT < >
FONT < >
FONT < >
CDEF1 1
FONT < >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT <* * *>
FONT < *** >
FONT < * >
FONT < >
FONT < >
CDEF1 2
FONT < >
FONT < >
FONT < >
FONT < ** *>
FONT <* * >
FONT <* * >
FONT <* * >
FONT < ** *>
FONT < >
FONT < >
CDEF1 3
FONT < >
FONT < >
FONT < >
FONT < *** >
FONT <* *>
FONT <**** >
FONT <* *>
FONT <**** >
FONT <* >
FONT <* >
CDEF1 4
FONT < >
FONT < >
FONT < >
FONT < * >
FONT < * * >
FONT <* *>
FONT < >
FONT < >
FONT < >
FONT < >
CDEF1 5
FONT < >
FONT < >
FONT < >
FONT < >
FONT <*****>
FONT < *>
FONT < *>
FONT < >
FONT < >
FONT < >
CDEF1 6
FONT < >
FONT < >
FONT < >
FONT < ** >
FONT < * >
FONT < *** >
FONT < * >
FONT < ** >
FONT < >
FONT < >
CDEF1 7
FONT < >
FONT < >
FONT < >
FONT <*****>
FONT < * * >
FONT < * * >
FONT < * * >
FONT < * * >
FONT < >
FONT < >
CDEF1 10
FONT < >
FONT < >
FONT <* >
FONT <* >
FONT < * >
FONT < * >
FONT < * * >
FONT <* *>
FONT < >
FONT < >
CDEF1 11
FONT < >
FONT <* *>
FONT < * * >
FONT < * >
FONT < * * >
FONT <* *>
FONT <* *>
FONT < *** >
FONT < >
FONT < >
CDEF1 12
FONT < >
FONT < *** >
FONT < *>
FONT < * >
FONT < * >
FONT < * * >
FONT <* *>
FONT < *** >
FONT < >
FONT < >
CDEF1 13
FONT < >
FONT < * >
FONT < *** >
FONT <* * *>
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < >
FONT < >
CDEF1 14
FONT < >
FONT < * >
FONT < * >
FONT <*****>
FONT < * >
FONT < * >
FONT <*****>
FONT < >
FONT < >
FONT < >
CDEF1 15
FONT < >
FONT < >
FONT < *** >
FONT <* * *>
FONT <*****>
FONT <* * *>
FONT < *** >
FONT < >
FONT < >
FONT < >
CDEF1 16
FONT < >
FONT < >
FONT < >
FONT < * * >
FONT <* * *>
FONT <* * *>
FONT < * * >
FONT < >
FONT < >
FONT < >
CDEF1 17
FONT < >
FONT < ** >
FONT < * >
FONT < *>
FONT < ****>
FONT <* *>
FONT <* *>
FONT < *** >
FONT < >
FONT < >
CDEF1 20
FONT < >
FONT < >
FONT < ****>
FONT <* >
FONT <* >
FONT <* >
FONT < ****>
FONT < >
FONT < >
FONT < >
CDEF1 21
FONT < >
FONT < >
FONT <**** >
FONT < *>
FONT < *>
FONT < *>
FONT <**** >
FONT < >
FONT < >
FONT < >
CDEF1 22
FONT < >
FONT < >
FONT < *** >
FONT <* *>
FONT <* *>
FONT <* *>
FONT < >
FONT < >
FONT < >
FONT < >
CDEF1 23
FONT < >
FONT < >
FONT <* *>
FONT <* *>
FONT <* *>
FONT < *** >
FONT < >
FONT < >
FONT < >
FONT < >
CDEF1 24
FONT < >
FONT <* *>
FONT <* *>
FONT <*****>
FONT <* *>
FONT < * * >
FONT < * * >
FONT < * >
FONT < >
FONT < >
CDEF1 25
FONT < >
FONT <*****>
FONT < *>
FONT < *>
FONT < ****>
FONT < *>
FONT < *>
FONT <*****>
FONT < >
FONT < >
CDEF1 26
FONT < >
FONT < >
FONT < *** >
FONT <** **>
FONT <* * *>
FONT <** **>
FONT < *** >
FONT < >
FONT < >
FONT < >
CDEF1 27
FONT < >
FONT < * >
FONT < * >
FONT <*****>
FONT < * >
FONT < * >
FONT < * >
FONT <*****>
FONT < * >
FONT < * >
CDEF1 30
FONT < >
FONT < >
FONT < * >
FONT < * >
FONT <*****>
FONT < * >
FONT < * >
FONT < >
FONT < >
FONT < >
CDEF1 31
FONT < >
FONT < >
FONT < * >
FONT < * >
FONT <*****>
FONT < * >
FONT < * >
FONT < >
FONT < >
FONT < >
CDEF1 32
FONT < >
FONT < *>
FONT < * >
FONT <*****>
FONT < * >
FONT <*****>
FONT < * >
FONT <* >
FONT < >
FONT < >
CDEF1 33
FONT < >
FONT < * >
FONT < * >
FONT < * * >
FONT <* *>
FONT < * * >
FONT < * >
FONT < * >
FONT < >
FONT < >
CDEF1 34
FONT < >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < >
FONT < *** >
FONT < >
FONT < >
CDEF1 35
FONT < >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < >
FONT < *** >
FONT < >
FONT < >
CDEF1 36
FONT < >
FONT < >
FONT <*****>
FONT < >
FONT <*****>
FONT < >
FONT <*****>
FONT < >
FONT < >
FONT < >
CDEF1 37
FONT < >
FONT < >
FONT < >
FONT <* *>
FONT < * * >
FONT < * >
FONT < >
FONT < >
FONT < >
FONT < >
CDEF < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
CDEF <!>
FONT < >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < >
FONT < * >
FONT < >
FONT < >
CDEF <">
FONT < * * >
FONT < * * >
FONT < * * >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
CDEF <#>
FONT < >
FONT < >
FONT < * * >
FONT <*****>
FONT < * * >
FONT < * * >
FONT <*****>
FONT < * * >
FONT < >
FONT < >
CDEF <$>
FONT < * >
FONT < *** >
FONT <* * *>
FONT <* * >
FONT < *** >
FONT < * *>
FONT <* * *>
FONT < *** >
FONT < * >
FONT < >
CDEF <%>
FONT < >
FONT <*****>
FONT <** *>
FONT < * >
FONT < * >
FONT < * >
FONT <* **>
FONT <* **>
FONT < >
FONT < >
CDEF <&>
FONT < >
FONT < * >
FONT <* * >
FONT <* * >
FONT < * >
FONT <* * *>
FONT <* * >
FONT < ** *>
FONT < >
FONT < >
CDEF <'>
FONT < ** >
FONT < ** >
FONT <** >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
CDEF <(>
FONT < >
FONT < *>
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < *>
FONT < >
FONT < >
CDEF <)>
FONT < >
FONT <* >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT <* >
FONT < >
FONT < >
CDEF <*>
FONT < >
FONT < * >
FONT <* * *>
FONT < *** >
FONT < * >
FONT < *** >
FONT <* * *>
FONT < * >
FONT < >
FONT < >
CDEF <+>
FONT < >
FONT < >
FONT < * >
FONT < * >
FONT <*****>
FONT < * >
FONT < * >
FONT < >
FONT < >
FONT < >
CDEF <,>
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < ** >
FONT < ** >
FONT <** >
FONT < >
CDEF <->
FONT < >
FONT < >
FONT < >
FONT < >
FONT <*****>
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
CDEF <.>
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < ** >
FONT < ** >
FONT < >
FONT < >
CDEF </>
FONT < >
FONT < >
FONT < *>
FONT < * >
FONT < * >
FONT < * >
FONT <* >
FONT < >
FONT < >
FONT < >
CDEF 0
FONT < >
FONT < *** >
FONT <* *>
FONT <* **>
FONT <* * *>
FONT <** *>
FONT <* *>
FONT < *** >
FONT < >
FONT < >
CDEF 1
FONT < >
FONT < * >
FONT < ** >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < *** >
FONT < >
FONT < >
CDEF 2
FONT < >
FONT < *** >
FONT <* *>
FONT < *>
FONT < * >
FONT < * >
FONT < * >
FONT <*****>
FONT < >
FONT < >
CDEF 3
FONT < >
FONT < *** >
FONT <* *>
FONT < *>
FONT < ** >
FONT < *>
FONT <* *>
FONT < *** >
FONT < >
FONT < >
CDEF 4
FONT < >
FONT < * >
FONT < ** >
FONT < * * >
FONT <* * >
FONT <*****>
FONT < * >
FONT < * >
FONT < >
FONT < >
CDEF 5
FONT < >
FONT <*****>
FONT <* >
FONT <**** >
FONT < *>
FONT < *>
FONT <* *>
FONT < *** >
FONT < >
FONT < >
CDEF 6
FONT < >
FONT < ** >
FONT < * >
FONT <* >
FONT <**** >
FONT <* *>
FONT <* *>
FONT < *** >
FONT < >
FONT < >
CDEF 7
FONT < >
FONT <*****>
FONT < *>
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < >
FONT < >
CDEF 8
FONT < >
FONT < *** >
FONT <* *>
FONT <* *>
FONT < *** >
FONT <* *>
FONT <* *>
FONT < *** >
FONT < >
FONT < >
CDEF 9
FONT < >
FONT < *** >
FONT <* *>
FONT <* *>
FONT < ****>
FONT < *>
FONT < * >
FONT < ** >
FONT < >
FONT < >
CDEF <:>
FONT < >
FONT < >
FONT < >
FONT < ** >
FONT < ** >
FONT < >
FONT < ** >
FONT < ** >
FONT < >
FONT < >
CDEF <;>
FONT < >
FONT < >
FONT < >
FONT < ** >
FONT < ** >
FONT < >
FONT < ** >
FONT < ** >
FONT <** >
FONT < >
CDEF1 74
FONT < >
FONT < >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < >
FONT < >
FONT < >
CDEF <=>
FONT < >
FONT < >
FONT < >
FONT <*****>
FONT < >
FONT <*****>
FONT < >
FONT < >
FONT < >
FONT < >
CDEF1 76
FONT < >
FONT < >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < >
FONT < >
FONT < >
CDEF <?>
FONT < >
FONT < *** >
FONT <* *>
FONT < * >
FONT < * >
FONT < * >
FONT < >
FONT < * >
FONT < >
FONT < >
CDEF <@>
FONT < >
FONT < *** >
FONT <* *>
FONT <* ***>
FONT <* * *>
FONT <* ***>
FONT <* >
FONT < *** >
FONT < >
FONT < >
CDEF A
FONT < >
FONT < *** >
FONT <* *>
FONT <* *>
FONT <*****>
FONT <* *>
FONT <* *>
FONT <* *>
FONT < >
FONT < >
CDEF B
FONT < >
FONT <**** >
FONT <* *>
FONT <* *>
FONT <**** >
FONT <* *>
FONT <* *>
FONT <**** >
FONT < >
FONT < >
CDEF C
FONT < >
FONT < *** >
FONT <* *>
FONT <* >
FONT <* >
FONT <* >
FONT <* *>
FONT < *** >
FONT < >
FONT < >
CDEF D
FONT < >
FONT <**** >
FONT < * *>
FONT < * *>
FONT < * *>
FONT < * *>
FONT < * *>
FONT <**** >
FONT < >
FONT < >
CDEF E
FONT < >
FONT <*****>
FONT <* >
FONT <* >
FONT <**** >
FONT <* >
FONT <* >
FONT <*****>
FONT < >
FONT < >
CDEF F
FONT < >
FONT <*****>
FONT <* >
FONT <* >
FONT <**** >
FONT <* >
FONT <* >
FONT <* >
FONT < >
FONT < >
CDEF G
FONT < >
FONT < *** >
FONT <* *>
FONT <* >
FONT <* >
FONT <* **>
FONT <* *>
FONT < *** >
FONT < >
FONT < >
CDEF H
FONT < >
FONT <* *>
FONT <* *>
FONT <* *>
FONT <*****>
FONT <* *>
FONT <* *>
FONT <* *>
FONT < >
FONT < >
CDEF I
FONT < >
FONT < *** >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < *** >
FONT < >
FONT < >
CDEF J
FONT < >
FONT < *>
FONT < *>
FONT < *>
FONT < *>
FONT < *>
FONT <* *>
FONT < *** >
FONT < >
FONT < >
CDEF K
FONT < >
FONT <* *>
FONT <* * >
FONT <* * >
FONT <** >
FONT <* * >
FONT <* * >
FONT <* *>
FONT < >
FONT < >
CDEF L
FONT < >
FONT <* >
FONT <* >
FONT <* >
FONT <* >
FONT <* >
FONT <* >
FONT <*****>
FONT < >
FONT < >
CDEF M
FONT < >
FONT <* *>
FONT <** **>
FONT <* * *>
FONT <* *>
FONT <* *>
FONT <* *>
FONT <* *>
FONT < >
FONT < >
CDEF N
FONT < >
FONT <* *>
FONT <* *>
FONT <** *>
FONT <* * *>
FONT <* **>
FONT <* *>
FONT <* *>
FONT < >
FONT < >
CDEF O
FONT < >
FONT < *** >
FONT <* *>
FONT <* *>
FONT <* *>
FONT <* *>
FONT <* *>
FONT < *** >
FONT < >
FONT < >
CDEF P
FONT < >
FONT <**** >
FONT <* *>
FONT <* *>
FONT <**** >
FONT <* >
FONT <* >
FONT <* >
FONT < >
FONT < >
CDEF Q
FONT < >
FONT < *** >
FONT <* *>
FONT <* *>
FONT <* *>
FONT <* * *>
FONT <* * >
FONT < ** *>
FONT < >
FONT < >
CDEF R
FONT < >
FONT <**** >
FONT <* *>
FONT <* *>
FONT <**** >
FONT <* * >
FONT <* * >
FONT <* *>
FONT < >
FONT < >
CDEF S
FONT < >
FONT < *** >
FONT <* *>
FONT <* >
FONT < *** >
FONT < *>
FONT <* *>
FONT < *** >
FONT < >
FONT < >
CDEF T
FONT < >
FONT <*****>
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < >
FONT < >
CDEF U
FONT < >
FONT <* *>
FONT <* *>
FONT <* *>
FONT <* *>
FONT <* *>
FONT <* *>
FONT < *** >
FONT < >
FONT < >
CDEF V
FONT < >
FONT <* *>
FONT <* *>
FONT <* *>
FONT <* *>
FONT < * * >
FONT < * * >
FONT < * >
FONT < >
FONT < >
CDEF W
FONT < >
FONT <* *>
FONT <* *>
FONT <* *>
FONT <* *>
FONT <* * *>
FONT <** **>
FONT <* *>
FONT < >
FONT < >
CDEF X
FONT < >
FONT <* *>
FONT <* *>
FONT < * * >
FONT < * >
FONT < * * >
FONT <* *>
FONT <* *>
FONT < >
FONT < >
CDEF Y
FONT < >
FONT <* *>
FONT <* *>
FONT < * * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < >
FONT < >
CDEF Z
FONT < >
FONT <*****>
FONT < *>
FONT < * >
FONT <*****>
FONT < * >
FONT <* >
FONT <*****>
FONT < >
FONT < >
CDEF <[>
FONT < ***>
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < ***>
FONT < >
CDEF <\>
FONT < >
FONT < >
FONT <* >
FONT < * >
FONT < * >
FONT < * >
FONT < *>
FONT < >
FONT < >
FONT < >
CDEF <]>
FONT <*** >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT <*** >
FONT < >
CDEF <^>
FONT < * >
FONT < * * >
FONT <* *>
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
CDEF <_>
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT <*****>
CDEF <`>
FONT < ** >
FONT < ** >
FONT < **>
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
CDEF a
FONT < >
FONT < >
FONT < >
FONT < *** >
FONT < *>
FONT < ****>
FONT <* *>
FONT < ****>
FONT < >
FONT < >
CDEF b
FONT < >
FONT <* >
FONT <* >
FONT <**** >
FONT <* *>
FONT <* *>
FONT <* *>
FONT <**** >
FONT < >
FONT < >
CDEF c
FONT < >
FONT < >
FONT < >
FONT < *** >
FONT <* *>
FONT <* >
FONT <* >
FONT < ****>
FONT < >
FONT < >
CDEF d
FONT < >
FONT < *>
FONT < *>
FONT < ****>
FONT <* *>
FONT <* *>
FONT <* *>
FONT < ****>
FONT < >
FONT < >
CDEF e
FONT < >
FONT < >
FONT < >
FONT < *** >
FONT <* *>
FONT <**** >
FONT <* >
FONT < *** >
FONT < >
FONT < >
CDEF f
FONT < >
FONT < ** >
FONT < * *>
FONT < * >
FONT <*** >
FONT < * >
FONT < * >
FONT < * >
FONT < >
FONT < >
CDEF g
FONT < >
FONT < >
FONT < >
FONT < *** >
FONT <* *>
FONT <* *>
FONT <* *>
FONT < ****>
FONT < *>
FONT < *** >
CDEF h
FONT < >
FONT <* >
FONT <* >
FONT <**** >
FONT <* *>
FONT <* *>
FONT <* *>
FONT <* *>
FONT < >
FONT < >
CDEF i
FONT < >
FONT < >
FONT < * >
FONT < >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < >
FONT < >
CDEF j
FONT < >
FONT < >
FONT < *>
FONT < >
FONT < *>
FONT < *>
FONT < *>
FONT < *>
FONT <* *>
FONT < *** >
CDEF k
FONT < >
FONT <* >
FONT <* >
FONT <* *>
FONT <* * >
FONT <*** >
FONT <* * >
FONT <* *>
FONT < >
FONT < >
CDEF l
FONT < >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < >
FONT < >
CDEF m
FONT < >
FONT < >
FONT < >
FONT <** * >
FONT <* * *>
FONT <* * *>
FONT <* * *>
FONT <* * *>
FONT < >
FONT < >
CDEF n
FONT < >
FONT < >
FONT < >
FONT <* ** >
FONT <** *>
FONT <* *>
FONT <* *>
FONT <* *>
FONT < >
FONT < >
CDEF o
FONT < >
FONT < >
FONT < >
FONT < *** >
FONT <* *>
FONT <* *>
FONT <* *>
FONT < *** >
FONT < >
FONT < >
CDEF p
FONT < >
FONT < >
FONT < >
FONT <**** >
FONT <* *>
FONT <* *>
FONT <* *>
FONT <**** >
FONT <* >
FONT <* >
CDEF q
FONT < >
FONT < >
FONT < >
FONT < *** >
FONT <* *>
FONT <* *>
FONT <* *>
FONT < ****>
FONT < *>
FONT < *>
CDEF r
FONT < >
FONT < >
FONT < >
FONT <* ** >
FONT <** *>
FONT <* >
FONT <* >
FONT <* >
FONT < >
FONT < >
CDEF s
FONT < >
FONT < >
FONT < >
FONT < ****>
FONT <* >
FONT < *** >
FONT < *>
FONT <**** >
FONT < >
FONT < >
CDEF t
FONT < >
FONT < * >
FONT < * >
FONT <*****>
FONT < * >
FONT < * >
FONT < * >
FONT < **>
FONT < >
FONT < >
CDEF u
FONT < >
FONT < >
FONT < >
FONT <* *>
FONT <* *>
FONT <* *>
FONT <* *>
FONT < *** >
FONT < >
FONT < >
CDEF v
FONT < >
FONT < >
FONT < >
FONT <* *>
FONT <* *>
FONT <* *>
FONT < * * >
FONT < * >
FONT < >
FONT < >
CDEF w
FONT < >
FONT < >
FONT < >
FONT <* *>
FONT <* *>
FONT <* * *>
FONT <* * *>
FONT < * * >
FONT < >
FONT < >
CDEF x
FONT < >
FONT < >
FONT < >
FONT <* *>
FONT < * * >
FONT < * >
FONT < * * >
FONT <* *>
FONT < >
FONT < >
CDEF y
FONT < >
FONT < >
FONT < >
FONT <* *>
FONT <* *>
FONT <* *>
FONT < * * >
FONT < * >
FONT < * >
FONT <* >
CDEF z
FONT < >
FONT < >
FONT < >
FONT <*****>
FONT < * >
FONT < *** >
FONT < * >
FONT <*****>
FONT < >
FONT < >
CDEF1 173
FONT < *>
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < *>
FONT < >
CDEF1 174
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
CDEF1 175
FONT <* >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT <* >
FONT < >
CDEF1 176
FONT < ** *>
FONT <* ** >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
FONT < >
CDEF1 177
FONT < * >
FONT < * *>
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT < * >
FONT <* * >
FONT < * >
FONT < >
CDEF1 200 ;BLOB CHARACTER FOR CURSORS
FONT <*****>
FONT <*****>
FONT <*****>
FONT <*****>
FONT <*****>
FONT <*****>
FONT <*****>
FONT <*****>
FONT <*****>
FONT <*****>
.ENDC ;.IF NE FONTMS
.IF E FONTMS
...0==.
.BYTE 000,000,000,016,016,016,000,000,000,000
...1==.
.BYTE 000,004,004,004,004,025,016,004,000,000
...2==.
.BYTE 000,000,000,015,022,022,022,015,000,000
...3==.
.BYTE 000,000,000,016,021,036,021,036,020,020
...4==.
.BYTE 000,000,000,004,012,021,000,000,000,000
...5==.
.BYTE 000,000,000,000,037,001,001,000,000,000
...6==.
.BYTE 000,000,000,006,010,016,010,006,000,000
...7==.
.BYTE 000,000,000,037,012,012,012,012,000,000
...10==.
.BYTE 000,000,020,020,010,004,012,021,000,000
...11==.
.BYTE 000,021,012,004,012,021,021,016,000,000
...12==.
.BYTE 000,016,001,002,004,012,021,016,000,000
...13==.
.BYTE 000,004,016,025,004,004,004,004,000,000
...14==.
.BYTE 000,004,004,037,004,004,037,000,000,000
...15==.
.BYTE 000,000,016,025,037,025,016,000,000,000
...16==.
.BYTE 000,000,000,012,025,025,012,000,000,000
...17==.
.BYTE 000,014,002,001,017,021,021,016,000,000
...20==.
.BYTE 000,000,017,020,020,020,017,000,000,000
...21==.
.BYTE 000,000,036,001,001,001,036,000,000,000
...22==.
.BYTE 000,000,016,021,021,021,000,000,000,000
...23==.
.BYTE 000,000,021,021,021,016,000,000,000,000
...24==.
.BYTE 000,021,021,037,021,012,012,004,000,000
...25==.
.BYTE 000,037,001,001,017,001,001,037,000,000
...26==.
.BYTE 000,000,016,033,025,033,016,000,000,000
...27==.
.BYTE 000,004,002,037,002,004,010,037,010,004
...30==.
.BYTE 000,000,004,010,037,010,004,000,000,000
...31==.
.BYTE 000,000,004,002,037,002,004,000,000,000
...32==.
.BYTE 000,001,002,037,004,037,010,020,000,000
...33==.
.BYTE 000,004,004,012,021,012,004,004,000,000
...34==.
.BYTE 000,002,004,010,004,002,000,016,000,000
...35==.
.BYTE 000,010,004,002,004,010,000,016,000,000
...36==.
.BYTE 000,000,037,000,037,000,037,000,000,000
...37==.
.BYTE 000,000,000,021,012,004,000,000,000,000
...40==.
.BYTE 000,000,000,000,000,000,000,000,000,000
...41==.
.BYTE 000,004,004,004,004,004,000,004,000,000
...42==.
.BYTE 012,012,012,000,000,000,000,000,000,000
...43==.
.BYTE 000,000,012,037,012,012,037,012,000,000
...44==.
.BYTE 004,016,025,024,016,005,025,016,004,000
...45==.
.BYTE 000,037,031,002,004,010,023,023,000,000
...46==.
.BYTE 000,010,024,024,010,025,022,015,000,000
...47==.
.BYTE 014,014,030,000,000,000,000,000,000,000
...50==.
.BYTE 000,001,002,004,004,004,002,001,000,000
...51==.
.BYTE 000,020,010,004,004,004,010,020,000,000
...52==.
.BYTE 000,004,025,016,004,016,025,004,000,000
...53==.
.BYTE 000,000,004,004,037,004,004,000,000,000
...54==.
.BYTE 000,000,000,000,000,000,014,014,030,000
...55==.
.BYTE 000,000,000,000,037,000,000,000,000,000
...56==.
.BYTE 000,000,000,000,000,000,014,014,000,000
...57==.
.BYTE 000,000,001,002,004,010,020,000,000,000
...60==.
.BYTE 000,016,021,023,025,031,021,016,000,000
...61==.
.BYTE 000,004,014,004,004,004,004,016,000,000
...62==.
.BYTE 000,016,021,001,002,004,010,037,000,000
...63==.
.BYTE 000,016,021,001,006,001,021,016,000,000
...64==.
.BYTE 000,002,006,012,022,037,002,002,000,000
...65==.
.BYTE 000,037,020,036,001,001,021,016,000,000
...66==.
.BYTE 000,006,010,020,036,021,021,016,000,000
...67==.
.BYTE 000,037,001,002,002,004,004,004,000,000
...70==.
.BYTE 000,016,021,021,016,021,021,016,000,000
...71==.
.BYTE 000,016,021,021,017,001,002,014,000,000
...72==.
.BYTE 000,000,000,014,014,000,014,014,000,000
...73==.
.BYTE 000,000,000,014,014,000,014,014,030,000
...74==.
.BYTE 000,000,002,004,010,004,002,000,000,000
...75==.
.BYTE 000,000,000,037,000,037,000,000,000,000
...76==.
.BYTE 000,000,010,004,002,004,010,000,000,000
...77==.
.BYTE 000,016,021,002,004,004,000,004,000,000
...100==.
.BYTE 000,016,021,027,025,027,020,016,000,000
...101==.
.BYTE 000,016,021,021,037,021,021,021,000,000
...102==.
.BYTE 000,036,021,021,036,021,021,036,000,000
...103==.
.BYTE 000,016,021,020,020,020,021,016,000,000
...104==.
.BYTE 000,036,011,011,011,011,011,036,000,000
...105==.
.BYTE 000,037,020,020,036,020,020,037,000,000
...106==.
.BYTE 000,037,020,020,036,020,020,020,000,000
...107==.
.BYTE 000,016,021,020,020,023,021,016,000,000
...110==.
.BYTE 000,021,021,021,037,021,021,021,000,000
...111==.
.BYTE 000,016,004,004,004,004,004,016,000,000
...112==.
.BYTE 000,001,001,001,001,001,021,016,000,000
...113==.
.BYTE 000,021,022,024,030,024,022,021,000,000
...114==.
.BYTE 000,020,020,020,020,020,020,037,000,000
...115==.
.BYTE 000,021,033,025,021,021,021,021,000,000
...116==.
.BYTE 000,021,021,031,025,023,021,021,000,000
...117==.
.BYTE 000,016,021,021,021,021,021,016,000,000
...120==.
.BYTE 000,036,021,021,036,020,020,020,000,000
...121==.
.BYTE 000,016,021,021,021,025,022,015,000,000
...122==.
.BYTE 000,036,021,021,036,024,022,021,000,000
...123==.
.BYTE 000,016,021,020,016,001,021,016,000,000
...124==.
.BYTE 000,037,004,004,004,004,004,004,000,000
...125==.
.BYTE 000,021,021,021,021,021,021,016,000,000
...126==.
.BYTE 000,021,021,021,021,012,012,004,000,000
...127==.
.BYTE 000,021,021,021,021,025,033,021,000,000
...130==.
.BYTE 000,021,021,012,004,012,021,021,000,000
...131==.
.BYTE 000,021,021,012,004,004,004,004,000,000
...132==.
.BYTE 000,037,001,002,037,010,020,037,000,000
...133==.
.BYTE 007,004,004,004,004,004,004,004,007,000
...134==.
.BYTE 000,000,020,010,004,002,001,000,000,000
...135==.
.BYTE 034,004,004,004,004,004,004,004,034,000
...136==.
.BYTE 004,012,021,000,000,000,000,000,000,000
...137==.
.BYTE 000,000,000,000,000,000,000,000,000,037
...140==.
.BYTE 006,006,003,000,000,000,000,000,000,000
...141==.
.BYTE 000,000,000,016,001,017,021,017,000,000
...142==.
.BYTE 000,020,020,036,021,021,021,036,000,000
...143==.
.BYTE 000,000,000,016,021,020,020,017,000,000
...144==.
.BYTE 000,001,001,017,021,021,021,017,000,000
...145==.
.BYTE 000,000,000,016,021,036,020,016,000,000
...146==.
.BYTE 000,006,011,010,034,010,010,010,000,000
...147==.
.BYTE 000,000,000,016,021,021,021,017,001,016
...150==.
.BYTE 000,020,020,036,021,021,021,021,000,000
...151==.
.BYTE 000,000,004,000,004,004,004,004,000,000
...152==.
.BYTE 000,000,001,000,001,001,001,001,021,016
...153==.
.BYTE 000,020,020,021,022,034,022,021,000,000
...154==.
.BYTE 000,004,004,004,004,004,004,004,000,000
...155==.
.BYTE 000,000,000,032,025,025,025,025,000,000
...156==.
.BYTE 000,000,000,026,031,021,021,021,000,000
...157==.
.BYTE 000,000,000,016,021,021,021,016,000,000
...160==.
.BYTE 000,000,000,036,021,021,021,036,020,020
...161==.
.BYTE 000,000,000,016,021,021,021,017,001,001
...162==.
.BYTE 000,000,000,026,031,020,020,020,000,000
...163==.
.BYTE 000,000,000,017,020,016,001,036,000,000
...164==.
.BYTE 000,004,004,037,004,004,004,003,000,000
...165==.
.BYTE 000,000,000,021,021,021,021,016,000,000
...166==.
.BYTE 000,000,000,021,021,021,012,004,000,000
...167==.
.BYTE 000,000,000,021,021,025,025,012,000,000
...170==.
.BYTE 000,000,000,021,012,004,012,021,000,000
...171==.
.BYTE 000,000,000,021,021,021,012,004,010,020
...172==.
.BYTE 000,000,000,037,002,016,010,037,000,000
...173==.
.BYTE 001,002,002,002,004,002,002,002,001,000
...174==.
.BYTE 004,004,004,004,004,004,004,004,004,004
...175==.
.BYTE 020,010,010,010,004,010,010,010,020,000
...176==.
.BYTE 015,026,000,000,000,000,000,000,000,000
...177==.
.BYTE 002,005,004,004,004,004,004,024,010,000
...200==.
.BYTE 037,037,037,037,037,037,037,037,037,037
.ENDC ;.IF E FONTMS
.LIST
BLOB=...200 ;BLOB IS THE CHAR THAT COVERS ENTIRE CHARACTER AREA.
.IIF E FONTSW,.=.+3000 ;APPROXIMATE SIZE OF FONT
REPORT FONT SIZE=,\.-FNTORG
FNTEND==.
.NLIST
.ENDC ;.IF NE FONTSW
.LIST
.SBTTL LINE EDITOR AND PAGE PRINTER VARIABLES
VARORG==.
.MACRO ...TEN
.=<.+3>&<-4>
.ENDM
;LINE EDITOR VARIABLE BLOCK FORMAT:
;THIS DOESN'T REALLY HAVE ANYTHING TO WITH LINE-EDITING. THIS BLOCK
;CONTAINS MOST OF THE VARIABLES FOR EACH TV-CHANNEL (OR VIRTUAL TTY),
;COMBINING THE OLD IDEAS OF DPY BUFFER, LINE EDITOR, AND PAGE PRINTER.
;THERE IS ALSO A TV-BUFFER NUMBER, WHICH GOES IN THE CREG, AND INDEXES
;SOME ARRAYS ON THE LAST PAGE, A DPY CHANNEL # WHICH = A PDP10 TTY # MINUS NF11TY
;AND INDEXES SOME 11-10 SHARED ARRAYS, AND A KBD# WHICH IS A HARDWARE KEYBOARD
;NUMBER AND INDEXES SOME ARRAYS ON THE LAST PAGE.
LEDFLT: .OFFSET -.
;FIRST COMES THE 10-TO-11 DPY OUTPUT BUFFER. NOTE THAT THE "DEFAULT VALUES
;FOR THIS PART ARE NOT USED IN INITIALIZATION.
DPY10B:: .=.+2 ;WORD PDP-10 IS HACKING (USED FOR INITIALIZATION ONLY)
DPY11B:: .=.+2 ;WORD PDP-11 IS HACKING
DPYFS1:: .=.+2 ;WASTED WORD.
DPYLGL:: .=.+2 ;HIGHEST LEGAL BUFFER CELL
DPYSIZ:: .=.+2 ;SIZE OF DATA AREA
DPYFS:: .=.+2 ;NOT USED
...TEN
DPDATA:: .BLKB DPSIZE ;DATA AREA OF BUFFER.
LECC:: TVLO ;ADDRESS OF CURSOR
LEPHS:: 20-CHRWD ;PHASE OF CURSOR
LEX:: -BITPL ;X POSITON OF LE CURSOR
LECREG:: .BYTE -1 ;CONSOLE REGISTER FOR THIS LE DISPLAY
.BYTE 0 ;UNUSED
...TEN
LEZER0:: 0 ;FAKE LINE BUFFER HEADER (SENT TO PDP10 IN RESPONSE TO ECOFLG)
LEZER1:: 0
LEBUF:: 0 ;CURRENT TEXT BUFFER
LELIST:: 0 ;KEYBOARD BUFFER CHAIN
LECHN:: -1 ;DPY CHANNEL NUMBER, SET UP AT INIT TIME.
LEKBD:: -1 ;KEYBOARD DRIVING THIS LINE EDITOR
LEY:: -NLINS ;Y COORDINATE OF LINE EDITOR DISPLAY
LELCC:: TVLO ;ADDRESS OF START OF CURRENT CHARACTER LINE, IN VIDEO BUFFER.
LESTK: .BLKW 3 ;SAVE STACK WHEN BLOCKING INSIDE GETCHC.
LESTKP: 0 ;POINTS AFTER LAST USED WORD IN LESTK,
;OR 0 IF NOT SAVING STATE FOR A GETCHC WHICH BLOCKED.
LESVB: 0 ;SAVE THESE ACS WHEN BLOCKING INSIDE GETCHC.
LESVC: 0
LESVT: 0
LESVTT: 0
LEFREE:: LBCHRS ;FREE CHARACTER COUNT
LECHR:: 0 ;POINTS AT FREE CHARACTER IN BUFFER
LERPT:: 0 ;0 NORMAL, -1 => INDEFINITE REPEAT, ELSE REPEAT COUNT.
;REPEAT REFERS TO REPEAT-ACTION ON AN INPUT CHARACTER.
LELSTA:: 0 ;A AND B AT MOST RECENT CALL TO PUTCHR.
LELSTB:: 0 ;FOR THE SAKE OF REPEAT-ACTION ON INPUT.
LEGX: 0 ;X-COORD FOR SUPDUP GRAPHICS.
LEGY: 0 ;Y-COORD FOR SUPDUP GRAPHICS.
LEGXOR: .BYTE 0 ;-1 FOR GRAPHICS XOR MODE
LEGVIR: .BYTE 0 ;-1 FOR VIRTUAL COORDS.
LEGLFT: 0 ;LEFT EDGE OF GRAPHICS REGION.
LEGTOP: 0
LEGRGT: 0
LEGBOT: 0
...TEN
LELEN:: .OFFSET 0
;LINE EDITOR VARIABLE AREAS.
TENWRD
;HERE WE ASSEMBLE IN THE "DPY BUFFERS".
LEUVAR: .REPT MAXTV
.+DPDATA
.-2+DPDATA
0
.-6+DPDATA+DPSIZE-2
DPSIZE
0
.BLKB LELEN-DPDATA
.ENDR
LEUEND==.
;THE WHO-LINE LINE EDITOR IS DIFFERENT AND APART FROM ALL THE REST
WHOPP: .=.+LELEN
;CLOCK QUEUE ENTRY
.OFFSET -. ;CLOCK QUEUE ENTRY
CQNEXT:: .=.+2 ;CDR OF QUEUE
CQTIME:: .=.+2 ;HIGH ORDER OF TIME
CQTIM1:: .=.+2 ;LOW ORDER
CQROUT:: .=.+2 ;ROUTINE TO CALL AT CLOCK LEVEL
CQARG:: .=.+2 ;ARGUMENT FOR CLOCK LEVEL ROUTINE
CQLEN:: .OFFSET 0
.OFFSET -. ;LINE BUFFER HEADER AREA
;DON'T ADD NEW VARS WITHOUT CHANGING PDP10 CODE
;IN TT11IN.
LHFLAG:: .=.+2 ;0=>FREE, POS=>BUSY, NEG=>ACTIVE.
LHZERO:: .=.+2 ;BETTER BE ZERO SO THAT PDP-10 CAN TEST LHFLAG
LHNEXT:: .=.+2 ;NEXT BUFFER ON RING OF TWO FOR THIS TTY
LHALST:: .=.+2 ;NEXT BUFFER ON LIST OF ACTIVE BUFFERS.
LHCHN:: .=.+2 ;PDP-10 LINE NUMBER (TTY NUMBER MINUS NF11TY).
LHFS:: .=.+2 ;CHAINS FREE STORAGE BLOCKS
LHQUED:: .=.+2 ;NON-ZERO => THIS BUFFER CLOCK QUEUED FOR ACTIVATION (SEE QBFR)
...TEN
LHLEN:: .OFFSET 0
.OFFSET -. ;BLINKER VARIABLES
BLNEXT:: 0 ;NEXT BLINKER ON LIST
BLCURS:: 0 ;POINTS AT CURSOR VARIABLES
BLON:: .BYTE 0 ;PHASE; 0=INVISIBLE, 377=VISIBLE
BLCHAR:: .BYTE 177 ;UNUSED
BLLEN:: .OFFSET 0
BLKVAR: .=.+<MAXBLK*BLLEN>
.EVEN
.OFFSET -. ;USER WHO LINE
WHJOB:: .=.+2 ;job #
WHJOB1:: .=.+2 ;if negative then clear who line
WHMODE:: .=.+2 ;mode
;-1=>who line is off
; 0=>follow keyboard
; 1=>freeze
; 2=>next higher (when PDP-10 sees this state, it searches
; user variables for next higher job index number with same
; uname. When it finds it, it stores the number in job #
; and changes mode to 1
; 3=>next lower
;any other=>system who line
WHMOD1:: .=.+2 ;pads WHMODE
WHUNAM:: .=.+2 ;uname in sixbit (left 18 bits in first two words, right in next two)
WHUNM1:: .=.+2
WHUNM2:: .=.+2
WHUNM3:: .=.+2
WHJNAM:: .=.+2 ;jname in sixbit
WHJNM1:: .=.+2
WHJNM2:: .=.+2
WHJNM3:: .=.+2
WHSNAM:: .=.+2 ;sname in sixbit
WHSNM1:: .=.+2
WHSNM2:: .=.+2
WHSNM3:: .=.+2
WHSTAT:: .=.+2 ;status in sixbit, 0=>job does not exist
WHSTA1:: .=.+2
WHSTA2:: .=.+2
WHSTA3:: .=.+2
WHJ%RT:: .=.+2 ;job % run time
WHJTRT:: .=.+2 ;job total run time (in tenth's of seconds)
WHRPAG:: .=.+2 ;job real pages (swapped in)
WHTPAG:: .=.+2 ;job total pages
WHO1:: .=.+2 ;user who mode control word
WHO1A:: .=.+2
WHO2:: .=.+2 ;first user who line var
WHO2A:: .=.+2
WHO2B:: .=.+2
WHO2C:: .=.+2
WHO3:: .=.+2 ;second user who line var
WHO3A:: .=.+2
WHO3B:: .=.+2
WHO3C:: .=.+2
...TEN
.=.+30 ;EXTRA SPACE SO NEW HACKS CAN SAFELY BE PUT IN PDP10.
WHLEN:: .OFFSET 0
;USER WHO LINE VARIABLES
TENWRD
WHVARS: .=.+<WHLEN*MAXTV>
.SBTTL MISCELLANEOUS TABLES
MISORG==.
;KEYBOARD/VIDEO SWITCH DEFAULTS
;INDEXED BY KBD #, GIVES NEAREST VIDEO SWITCH OUTPUT, -1=>NO DEFAULT
KBDVSW: .BYTE 0 ; 0 809 FAHLMAN, HOLLOWAY, KNIGHT
.BYTE 23 ; 1 810 LAVIN, KUIPERS, MILLER
.BYTE 24 ; 2 919 Very Small Data Bases NORTH (FAR END)
.BYTE 20 ; 3 812 YVONNE
.BYTE 6 ; 4 813 HEWITT
.BYTE 7 ; 5 814 SUSSMAN
.BYTE 3 ; 6 808 FREILING, ULLMAN
.BYTE -1 ; 7
.BYTE 4 ;10 817 JABARI
.BYTE -1 ;11
.BYTE -1 ;12
.BYTE 10 ;13 819 GOLDSTEIN
.BYTE 1 ;14 820 MINSKY
.BYTE -1 ;15
.BYTE -1 ;16
.BYTE 11 ;17 821A MARR
.BYTE -1 ;20
.BYTE 2 ;21 824 RICH, DEKLEER
.BYTE 5 ;22 825 Sjoberg
.BYTE 26 ;23 826 Fredkin
.BYTE 31 ;24 815 Horn
.BYTE -1 ;25
.BYTE -1 ;26
.BYTE -1 ;27
.BYTE 15 ;30 925 MOON'S REFRIGERATOR
.BYTE 16 ;31 902 TAENZER, MASON
.BYTE 17 ;32 919 Very Small Data losers
.BYTE 14 ;33 334 EDWARDS, LEBEL
.BYTE 13 ;34 913 BAISLEY, GREENBLATT
.BYTE 12 ;35 914 COHEN, GOSPER, ETC.
.BYTE 21 ;36 912 9TH FLOOR LOUNGE
.BYTE 22 ;37 907 CHESS, LISP MACHINES
.BYTE -1 ;40 906 Lisp Machines
.BYTE 37 ;41 3rd Floor #1
.BYTE 36 ;42 3rd Floor #2
.BYTE 35 ;43 3rd Floor #3
.BYTE 34 ;44 3rd Floor #4
.BYTE 33 ;45 3rd Floor #5
.BYTE 30 ;46 3rd Floor #6
.BYTE -1 ;47 NOT CONNECTED
.BYTE -1 ;50 NOT CONNECTED
.BYTE -1 ;51 NOT CONNECTED
.BYTE -1 ;52 NOT CONNECTED
.BYTE -1 ;53 NOT CONNECTED
.BYTE -1 ;54 NOT CONNECTED
.BYTE -1 ;55 NOT CONNECTED
.BYTE -1 ;56 NOT CONNECTED
.BYTE -1 ;57 NOT CONNECTED
.BYTE -1 ;60 NOT CONNECTED
.BYTE -1 ;61 NOT CONNECTED
.BYTE -1 ;62 NOT CONNECTED
.BYTE -1 ;63 NOT CONNECTED
.BYTE -1 ;64 NOT CONNECTED
.BYTE -1 ;65 NOT CONNECTED
.BYTE -1 ;66 NOT CONNECTED
.BYTE -1 ;67 NOT CONNECTED
.BYTE -1 ;70 NOT CONNECTED
.BYTE -1 ;71 NOT CONNECTED
.BYTE -1 ;72 NOT CONNECTED
.BYTE -1 ;73 NOT CONNECTED
.BYTE -1 ;74 NOT CONNECTED
.BYTE -1 ;75 NOT CONNECTED
.BYTE -1 ;76 NOT CONNECTED
.BYTE -1 ;77 NOT CONNECTED
CHECK KBDVSW,MAXKBD
;THIS TABLE SAYS WHICH FLOOR TO CALL THE ELEVATOR TO FOR <ESC>E
ELETAB: .BYTE ELKMS8 ; 0 809 FAHLMAN, HOLLOWAY, KNIGHT
.BYTE ELKMS8 ; 1 810 LAVIN, KUIPERS, MILLER
.BYTE ELKMS9 ; 2 919 Very Small Data Bases NORTH (FAR END)
.BYTE ELKMS8 ; 3 812 YVONNE
.BYTE ELKMS8 ; 4 813 HEWITT
.BYTE ELKMS8 ; 5 814 SUSSMAN
.BYTE ELKMS8 ; 6 808 FREILING, ULLMAN
.BYTE 0 ; 7
.BYTE ELKMS8 ;10 817 JABARI
.BYTE 0 ;11
.BYTE 0 ;12
.BYTE ELKMS8 ;13 819 GOLDSTEIN
.BYTE ELKMS8 ;14 820 MINSKY
.BYTE 0 ;15
.BYTE 0 ;16
.BYTE ELKMS8 ;17 821A MARR
.BYTE 0 ;20
.BYTE ELKMS8 ;21 824 RICH, DEKLEER
.BYTE ELKMS8 ;22 825 Sjoberg
.BYTE ELKMS8 ;23 826 Fredkin
.BYTE ELKMS8 ;24 815 Horn
.BYTE 0 ;25
.BYTE 0 ;26
.BYTE 0 ;27
.BYTE ELKMS9 ;30 925 MOON'S REFRIGERATOR
.BYTE ELKMS9 ;31 902 TAENZER, MASON
.BYTE ELKMS9 ;32 919 Very Small Data losers
.BYTE 0 ;33 334 EDWARDS, LEBEL
.BYTE ELKMS9 ;34 913 BAISLEY, GREENBLATT
.BYTE ELKMS9 ;35 914 COHEN, GOSPER, ETC.
.BYTE ELKMS9 ;36 912 9TH FLOOR LOUNGE
.BYTE ELKMS9 ;37 907 CHESS, LISP MACHINES
.BYTE ELKMS9 ;40 906 Lisp Machines
.BYTE 0 ;41 NOT CONNECTED
.BYTE 0 ;42 NOT CONNECTED
.BYTE 0 ;43 NOT CONNECTED
.BYTE 0 ;44 NOT CONNECTED
.BYTE 0 ;45 NOT CONNECTED
.BYTE 0 ;46 NOT CONNECTED
.BYTE 0 ;47 NOT CONNECTED
.BYTE 0 ;50 NOT CONNECTED
.BYTE 0 ;51 NOT CONNECTED
.BYTE 0 ;52 NOT CONNECTED
.BYTE 0 ;53 NOT CONNECTED
.BYTE 0 ;54 NOT CONNECTED
.BYTE 0 ;55 NOT CONNECTED
.BYTE 0 ;56 NOT CONNECTED
.BYTE 0 ;57 NOT CONNECTED
.BYTE 0 ;60 NOT CONNECTED
.BYTE 0 ;61 NOT CONNECTED
.BYTE 0 ;62 NOT CONNECTED
.BYTE 0 ;63 NOT CONNECTED
.BYTE 0 ;64 NOT CONNECTED
.BYTE 0 ;65 NOT CONNECTED
.BYTE 0 ;66 NOT CONNECTED
.BYTE 0 ;67 NOT CONNECTED
.BYTE 0 ;70 NOT CONNECTED
.BYTE 0 ;71 NOT CONNECTED
.BYTE 0 ;72 NOT CONNECTED
.BYTE 0 ;73 NOT CONNECTED
.BYTE 0 ;74 NOT CONNECTED
.BYTE 0 ;75 NOT CONNECTED
.BYTE 0 ;76 NOT CONNECTED
.BYTE 0 ;77 NOT CONNECTED
CHECK ELETAB,MAXKBD
;CHCREG TABLE, INDEXED BY CHANNEL NUMBER, GIVES TV BUFFER NUMBER.
;NON-WORKING TV BUFFERS SHOULD NOT BE IN THE LIST.
;IF THERE ARE MORE CHANNELS THAN BUFFERS, PUT -1 IN FOR SOME CHANNELS.
CHCREG: .BYTE 0,1,4,5,6,7,-1,11,12,13,14,-1,16,17
;15 is pretty broken
;VIDEO SWITCH INPUT INDEXED BY DPY #, HIGH ORDER BYTE GIVES SWITCH SECTION
DPYVSW: 1 ; 0
2 ; 1
3 ; 2
4 ; 3
5 ; 4
6 ; 5
7 ; 6
10 ; 7
21 ;10 THESE INPUTS ARE IN SECOND SECTION
22 ;11
23 ;12
24 ;13
11 ;14 1ST SECTION AGAIN
12 ;15
13 ;16
14 ;17
;AUDIO SWITCH TABLES (INDEXED BY KBD #, GIVES AUDIO SWITCH OUTPUT #)
KBDASW: .BYTE 00 ; 0
.BYTE 01 ; 1
.BYTE 02 ; 2
.BYTE 03 ; 3
.BYTE 04 ; 4
.BYTE 05 ; 5
.BYTE 06 ; 6
.BYTE 07 ; 7
.BYTE 10 ;10
.BYTE 11 ;11
.BYTE 12 ;12
.BYTE 13 ;13
.BYTE 14 ;14
.BYTE 15 ;15
.BYTE 16 ;16
.BYTE 17 ;17
.BYTE 20 ;20
.BYTE 21 ;21
.BYTE 22 ;22
.BYTE 23 ;23
.BYTE 24 ;24
.BYTE 25 ;25
.BYTE 26 ;26
.BYTE 27 ;27
.BYTE 30 ;30
.BYTE 31 ;31
.BYTE 32 ;32
.BYTE 33 ;33
.BYTE 34 ;34
.BYTE 35 ;35
.BYTE 36 ;36
.BYTE 37 ;37
.BYTE -1 ;40
.BYTE -1 ;41
.BYTE -1 ;42
.BYTE -1 ;43
.BYTE -1 ;44
.BYTE -1 ;45
.BYTE -1 ;46
.BYTE -1 ;47
.BYTE -1 ;50
.BYTE -1 ;51
.BYTE -1 ;52
.BYTE -1 ;53
.BYTE -1 ;54
.BYTE -1 ;55
.BYTE -1 ;56
.BYTE -1 ;57
.BYTE -1 ;60
.BYTE -1 ;61
.BYTE -1 ;62
.BYTE -1 ;63
.BYTE -1 ;64
.BYTE -1 ;65
.BYTE -1 ;66
.BYTE -1 ;67
.BYTE -1 ;70
.BYTE -1 ;71
.BYTE -1 ;72
.BYTE -1 ;73
.BYTE -1 ;74
.BYTE -1 ;75
.BYTE -1 ;76
.BYTE -1 ;77
CHECK KBDASW,MAXKBD
;POINTER AREA
TENWRD
POINTA: ITSWHO
CMDFLG
TENWHO: 0 ;-1=>PDP-10 SHOULD UPDATE WHO LINES
TENWH1: 0 ;FILLS OUT TENWHO
MAXTV ;PUT # OF PDP-10 CHANNELS HERE FOR ITS.
0
NF11TY: 0 ;PDP-10 PUTS TTY # OF FIRST CHANNEL HERE.
0
QPYDWN: 0 ;THIS NEEDS TO BE READ BY THE 10 FOR LOCK TVQPY CMD.
0
.=.+10 ;LEAVE A LITTLE ROOM FOR GROWTH
;10/11 CHANNEL HEADER AREA
TENWRD
CHA==.
KBDFLG: 0 ;KEYBOARD ACTIVATED LIST (SET BY 11 CLEARED BY 10)
0 ;ALWAYS ZERO
DPYCHN: LEUVAR ;THE CHANNEL VARS BLOCK ADDR
DPYKBD: 0 ;.BYTE KBD #,DPY #, OR -1 FOR FREE CHANNEL.
.REPT MAXTV-1
LEUVAR+<<.RPCNT+1>*LELEN>
0
.ENDR
ECOFLG: 0
CHNCLS: 0 ;FLAGS DPY CHANNEL AS OPEN (SET TO -1 BY TEN)
.=.+<<MAXTV-1>*4>
WHOLIN: 0 ;POINTS TO WHO LINE VARIABLES FOR THIS CHANNEL
0 ;NOT USED
.=.+<<MAXTV-1>*4>
;PDP-10/PDP-10 COMMAND BUFFER
TENWRD
CMDFLG: 0 ;0=>TEN CAN WRITE, POSITIVE=>ELEVEN CAN WRITE, NEGATVE=>TEN WON
0 ;FULL PDP-10 WORD BOUNDARY
CMDBUF: .=.+<CMDARG*4> ;EACH ARG IN COMMAND BUFFER IS PDP-10 WORD
;SYSTEM WHO LINE
TENWRD
ITSWHO==.
ITSTDP: 0 ;# total # dpy's (read only for PDP-10)
ITSFDP: 0 ;# free dpys (read only for PDP-10)
ITSVER: 0 ;ITS version #
ITSJOB: 0 ;total jobs
ITSCOR: 0 ;total core
ITSRU: 0 ;runnable users
ITSWBJ: 0 ;# jobs swap blocked
ITSJWP: 0 ;# jobs waiting for pages
ITSTRC: 0 ;total runable core
ITSCFU: 0 ;core available for users
ITSDAT: 0 ;date [byte (7) year (4) month (5) day]
ITSDBG: 0 ;system debug flag
ITSTIM: 0 ;time of day (# half seconds since midnight) aligned on PDP-10 word
ITSTI1: 0 ;low order of time
ITSUSR: 0 ;total number of users
ITSFSH: 0 ;fair share in %
.SBTTL MISCELLANEOUS VARIABLES AND FREE STORAGE
;CHANNEL USE FLAGS NON-ZERO MEANS CHANNEL IN USE
CHNUSE: .BLKB MAXTV ;BYTES INDEXED BY DPY CHANNEL #
.EVEN
;BLINKERS. INDEXED BY TV-BUFFER # (CREG)
BLINKS: .BLKW MAXCRG ;ADDRESS OF 1ST BLINKER OF THIS TV'S BLINKER LIST.
BLKSWT: .BLKB MAXCRG ;NONZERO => DON'T DO ANY BLINKING ON THIS TV NOW.
.EVEN
;BELLS PENDING COUNTS. INDEXED BY TV-BUFFER #
BELCNT: .BLKW MAXCRG
;PER-KEYBOARD INFORMATION. INDEXED BY KBD#.
KBDLE: .BLKW MAXKBD ;KEYBOARD/LINE EDITOR ASSOCIATION
KBDESC: .BYTE 0 ;NON-ZERO => <ESC> KEY HAS BEEN TYPED, READING ARG
KBDARG: .BYTE 0 ;NUMERIC ARGUMENT FOR <ESC>
.=.+<<MAXKBD-1>*2> ;THE ABOVE TWO BYTE ARRAYS ARE INTERLEAVED.
0 ;THIS ZERO WORD NEEDED - SEE CLKBR5
KBDDEF: .BYTE 0 ;DEFAULT VIDEO SOURCE FOR THIS KBD WHEN LOOKING AT ANOTHER
KBDCNT: .BYTE 0 ;COUNTDOWN UNTIL RESET TO DEFAULT VIDEO SOURCE, OR -1
.=.+<<MAXKBD-1>*2>
;CLOCK QUEUE
CLOCKF: 0 ;CLOCK QUEUE FREE LIST
CLOCKQ: 0 ;FIRST ENTRY ON CLOCK QUEUE
CQUEUE: .=.+<CQLEN*NCQSLT>
;MISCELLANEOUS VARIBLES
FSP: 0 ;POINTS TO LEBUFS FREE SPACE
OLDKMA: 0 ;LAST KMA
BLINK: 0 ;TV-BUFFER # OF NEXT GUY TO BLINK. ALSO, COUNTS CLOCK TICKS
; UNTIL NEXT BLINK. IT'S PRETTY KLUDGEY, SEE CODE AT CLKLOP.
FBLINK: BLKVAR ;LIST OF FREE BLINKERS
TICKS: 0 ;HIGH ORDER OF TIME
TICKS1: 0 ;LOW ORDER OF TIME
SSCC: .BYTE 0 ;SEMI-SLOW CLOCK COUNTER (WRAPS AROUND EVERY 256./60. SEC)
.BYTE 0 ;UNUSED
QPYSWT: 0 ;INTER LOCK TO SAVE COPY PAPER
BUZSWT: 0 ;INTERLOCK FOR BUZZING 9TH FLOOR DOOR
ELESWT: 0 ;INTERLOCKING THE ELEVATOR
RADIX: 0 ;HOLDS OUTPUT RADIX
VERSE: %FNAM2 ;SOURCE FILE VERSION #
KBDACT: 0 ;KEYBOARD ACTIVE LIST (NOT YET SEEN BY PDP-10)
KBDLAST:0 ;POINTS TO LAST BUFFER ON ACTIVE LIST
KBDTSW: 0 ;NON-ZERO => EXAMINE KBDCNT ARRAY AT SSC LEVEL.
WHOTIM: 0 ;LAST TIME WE DID WHO LINES
WHOFLG: 0 ;DO WHO LINES FLAG
DPYFRE: 0 ;DPY # OF FREE-CONSOLE CHANNEL.
TYMSHR: 0 ;# CLOCK TICKS TO GO BEFORE CHECKING NEXT DPY CHANNEL
;PATCH AREA
PATCH: .=.+PATL
;******* TEMPORARY VARIABLES FOR FONT CHECKSUMS *******
CKSPNT: 0 ;RUNNING POINTER
CKSSUM: 0 ;RUNNING CHECKSUM
CKSSMG: 0 ;GOOD CHECKSUM OF [FNTORG,FNTEND)
;LINE EDITOR BUFFER RINGS
TENWRD
NLBUFS==MAXTV*2-2
LEBUFS: .=.+<NLBUFS*<LHLEN+LBLEN>>
REPORT HIGHEST USED=,\.
.IIF LT TVLO-.-40, .ERROR PROGRAM TOO BIG.
.END GO