;-*-MIDAS-*- ;;; Copyright (c) 1999 Massachusetts Institute of Technology ;;; ;;; This program is free software; you can redistribute it and/or ;;; modify it under the terms of the GNU General Public License as ;;; published by the Free Software Foundation; either version 3 of the ;;; License, or (at your option) any later version. ;;; ;;; This program is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;; General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program; if not, write to the Free Software ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. .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 .-- .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 RUGSA ;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 ;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+ ;ADDR OF FIRST TEXT LINE THAT SHOULDN'T BE USED ;(IT'S INCOMPLETE AND CONTAINS THE WHO-LINE). TVCFENC=TVHI-> ;DON'T TRY TO DISPLAY A CHARACTER AFTER THIS POINT TVHI=TVLO+-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==16. ;MAX NUMBER OF TV DISPLAYS 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==21.*60. ;21. 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 #,TT MOV TT,LHFS(U) MOV TT,U DEC B BGT INIT6 CLR LHFS(U) ;END OF LIST CLR BLINK MOV #BLINKS,A MOV #BELCNT,C MOV #-1,T ;SET UP BELL COUNTS MOV #MAXTV-1,B CLR ITSTDP INIT5: CLRB CHNUSE(B) ;EVERY CHANNEL IS FREE. CLRB BLKSWT(B) ;NO TV HAS BLINKING TEMPORARILY INHIBITED. TSTB CHCREG(B) ;HOW MANY CHANNELS ARE WORKING? BLT INIT5A INC ITSTDP INIT5A: CLR (A)+ MOV T,(C)+ 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 (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 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 LECPC(U),TT ;RESUMING COROUTINE? BEQ DPYDP1 ;NO. MOV LESVB(U),B ;YES, RESTORE B AND PC FOR CORETURN FROM THE CLR LECPC(U) ;GETCHC THAT DIDN'T FIND ANY CHARS. BIC #-400,A ;CLEAR EXTRA BITS DUE TO SIGN-EXTENSION PUSH #DPYXIT ;GETCHC'S CALLER'S RETURN ADDR MUST BE DPYXIT. JMP (TT) ;GETCHC ENFORCES THAT. ;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 DPYCRF: SUB #5,A 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) RTSPC ;230 %TDRST (IGNORED) RTSPC ;231 %TDGPH (IGNORED) 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 #MAXTV,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, 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 .--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,#MAXTV 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 #<#-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 #,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, AND MAY RESET ALL ACS ;BUT B TO WHAT THEY HOLD AT DPYCTL. B IS ALWAYS PRESERVED. GETCHC: JSR PC,GETCHR BEQ GETCH2 BIC #-400,A ;CLEAR EXTRA BITS DUE TO SIGN-EXTENSION RTS PC GETCH2: MOV B,LESVB(U) POP LECPC(U) POP B CMP B,#DPYXIT BEQ GETCH3 BPT ;CALLER OF GETCHC HAD WRONG RETURN ADDRESS 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-,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 #,LELCC(U) ADD #,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-,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 #,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 ;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 ; SELECT VIDEO CHANNEL ESCQPY ; CAUSE A HARD COPY TO EXIST ESCFRE ; SAME AS S, BUT TO CONSOLE FREE BUFFER ESCBUZ ; BUZZ 9TH FLOOR DOOR ESCAUD ; SELECT AUDIO INPUT. ESCELE ; CALL THE ELEVATOR CHECK ESCTAB,<*2> BOWXOR ; TOGGLE BLACK ON WHITE BIT ESCCLR ; CLEAR SCREEN UNBEKNOWNST TO TEN. ESCCSR ; CLEAR SCROLL REGISTER ESCRPT ; START REPEATING THE PREV. CHAR TYPED IN. ESCWHO ; WHO LINE CONTROL ESCWHO ; 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]S, WITH IN TT. VSWSL1: BIC #-400,TT ;UNDO SIGN-EXTENSION AT VSWSL0 CMP TT,NF11TY BLO VSWSL2 ; TOO SMALL TO BE TTY # => IT IS VSW INPUT #. CMP TT,#200 BHIS VSWSL4 ; >= 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 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,#MAXTV 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] 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]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]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+,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 -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. ;LEFONT:: CTAB ;FONT FOR WRITING WITH IN THIS L.E. (NOT USED) LECPC:: 0 ;COROUTINE PC SAVED BY GETCHC. LESVB:: 0 ;VALUE OF B SAVED OVER CALL TO GETCHC. LEFREE:: LBCHRS ;FREE CHARACTER COUNT LECHR:: 0 ;POINTS AT FREE CHARACTER IN BUFFER ;LEBLNK:: 0 ;LINE EDITOR BLINKER (NOT USED, THERE IS NO LINE EDITOR) 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. ...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: .=.+ .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: .=.+ .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 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,10,11,12,13,14,15,16,17,-1,-1 ;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 CHECK DPYVSW,MAXTV*2 ;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) .=.+<*4> WHOLIN: 0 ;POINTS TO WHO LINE VARIABLES FOR THIS CHANNEL 0 ;NOT USED .=.+<*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: .=.+ ;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 MAXTV ;ADDRESS OF 1ST BLINKER OF THIS TV'S BLINKER LIST. BLKSWT: .BLKB MAXTV ;NONZERO => DON'T DO ANY BLINKING ON THIS TV NOW. .EVEN ;BELLS PENDING COUNTS. INDEXED BY TV-BUFFER # BELCNT: .BLKW MAXTV ;PER-KEYBOARD INFORMATION. INDEXED BY KBD#. KBDLE: .BLKW MAXKBD ;KEYBOARD/LINE EDITOR ASSOCIATION KBDESC: .BYTE 0 ;NON-ZERO => KEY HAS BEEN TYPED, READING ARG KBDARG: .BYTE 0 ;NUMERIC ARGUMENT FOR .=.+<*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 .=.+<*2> ;CLOCK QUEUE CLOCKF: 0 ;CLOCK QUEUE FREE LIST CLOCKQ: 0 ;FIRST ENTRY ON CLOCK QUEUE CQUEUE: .=.+ ;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==/ .IIF LT NLBUFS-, .ERROR NOT ENOUGH LEBUFS REPORT NLBUFS=,\NLBUFS LEBUFS: .=.+> REPORT HIGHEST USED=,\. .END GO