.SBTTL INTRODUCTION .TITLE VT ;VT01 DEVICE HANDLER .IDENT 'V002A' ; ; VIDEO TUBE (VT01) DEVICE HANDLER FOR RSX11D ; ; THIS HANDLER IS AN RSX11D PRIVILEGED TASK WHICH SUPPORTS OUTPUT OF ; ALPHANUMERIC TEXT (128 CHARACTER SET, EXTENDED ASCII), AS WELL AS ; GRAPHICS OPERATION (POINTS, LINES, AND A BLINKING CURSOR; STORAGE ; AND NON-STORAGE MODES) ON A VT01 SCOPE. ADDITIONAL FEATURES ; SUPPORTED INCLUDE VARIABLE TEXT SIZES, POSITIONING OF TEXT AT ARBITRARY ; X AND Y COORDINATES, AUTOMATIC SWITCHING TO NON-STORAGE MODE WHEN ; AN INTERVAL ELAPSES WITHOUT ANY I/O ACTIVITY, AND USE OF THE "FAST" ; DEFLECTION (IMPLEMENTED IN THE BISON DISPLAY CONTROLLER ONLY) OPTION ; FOR ALL BUT THE FIRST POINTS OF LINES OR CHARACTERS DRAWN. ALSO, WHEN ; THE SCREEN HAS BEEN FILLED WITH TEXT OR WHEN A FORM FEED (END OF PAGE ; INDICATION) IS ENCOUNTERED, THE HANDLER WILL WAIT (ON LOCAL EVENT FLAG ; 30) FOR OPERATOR INTERVENTION BEFORE CONTINUING. (TO SET FLAG 30, THE ; COMMAND "CON VT...." CAN BE TYPED; OR A SPECIAL TASK CAN BE WRITTEN TO ; SET THE FLAG AND INSTALLED UNDER THE NAME "TTYN00" SO THAT CONTROL-X ; WILL PERFORM THAT FUNCTION). IF FLAG 30 IS SET WHILE THE HANDLER IS ; IDLE, THE MODE WILL BE SWITCHED FROM STORAGE TO NON-STORAGE OR ; VICE-VERSA; THIS ALLOWS THE DISPLAY TO BE CLEARED BEFORE THE NORMAL ; TIMEOUT INTERVAL ELAPSES, OR TO BE RESTORED AFTERWARDS. ; ; THE FOLLOWING QIO FUNCTIONS ARE SUPPORTED: ; ; KILL I/O (12) CANCELS ALL REQUESTS FOR THE ISSUING TASK ; I/O RUNDOWN (22) LIKE KILL I/O, BUT EXECUTIVE REQUEST ; UNLOAD HANDLER(42) WAITS FOR ALL OPERATIONS TO COMPLETE, THEN ; SETS NON-STORAGE MODE AND EXITS ; WRITE (400) OUTPUTS TEXT AND/OR PERFORMS GRAPHICS OPERATIONS ; ACCORDING TO CONTROL CHARACTERS IN USER BUFFER ; ATTACH (1400) ATTACHES THE SCOPE TO THE CALLER & INITIALIZES IT ; DETACH (2000) DETACHES THE SCOPE FROM THE CALLER ; ; THE CONTENTS OF THE BUFFER FOR A "WRITE" FUNCTION IS INTERPRETED AS ; SUCCESSIVE 7-BIT ASCII CHARACTERS (ONE PER BYTE). PRINTING CHARACTERS ; (CODES 041 TO 176 OCTAL) ARE DRAWN ON THE SCREEN STARTING AT THE ; CURRENT SCOPE POSITION (INITIALLY, THE TOP LEFT CORNER OF THE SCREEN), ; AND THE CURRENT POSITION IS UPDATED (X INCREASED BY ONE CHARACTER ; WIDTH). CHARACTER CODES 000 (NUL) AND 177 (DEL) ARE IGNORED. CONTROL ; CHARACTERS (CODES 001 TO 040 OCTAL) CAUSE A SPECIFIC ACTION TO BE TAKEN ; BY THE HANDLER, AS FOLLOWS: ; ; CHARACTER CODE ACTION TAKEN ; SOH 001 SET CURRENT POSITION TO TOP LEFT OF SCREEN (HOME) ; STX 002 SET CURRENT POSITION TO TOP RIGHT OF SCREEN ; ETX 003 STOP DISPLAYING TEXT OR GRAPHICS UNTIL OPERATOR ; SETS FLAG 30 ; EOT 004 INITIALIZE VT01 (AS AT HANDLER LOAD OR ATTACH ; TIME): ERASE SCREEN, POSITION TOP LEFT, STORAGE ; MODE, DEFAULT CHARACTER SIZE, TURN OFF CURSOR, ; SET CURSOR POSITION TO BOTTOM LEFT ; ENQ 005 SET Y POSITION TO TOP OF SCREEN ; ACK 006 TURN ON CURSOR AT CURRENT SCOPE POSITION ; BEL 007 ADD ONE UNIT TO CURRENT TEXT SIZE ; BS 010 SET X POSITION BACK ONE CHARACTER SPACE ; (BACKSPACE) ; HT 011 MOVE X POSITION FORWARD TO NEXT TAB STOP ; (HORIZONTAL TAB) ; LF 012 SET Y POSITION DOWN ONE LINE (LINE FEED) ; VT 013 MOVE Y POSITION DOWN TO NEXT TAB STOP (VERTICAL ; TAB) ; FF 014 WAIT FOR FLAG 30; THEN ERASE SCREEN AND SET Y ; POSITION TO TOP (FORM FEED) ; CR 015 SET X POSITION TO LEFT OF SCREEN (CARRIAGE ; RETURN) ; SO 016 SELECT NON-STORAGE MODE (SHIFT OUT) ; SI 017 SELECT STORAGE MODE (SHIFT IN) ; DLE 020 MOVE Y POSITION UP TO PREVIOUS TAB STOP ; DC1 021 SET Y POSITION UP ONE LINE ; DC2 022 MOVE X POSITION BACKWARD TO PREVIOUS TAB STOP ; DC3 023 SET X POSITION TO RIGHT MARGIN OF SCREEN ; DC4 024 SUBTRACT ONE UNIT FROM CURRENT TEXT SIZE ; NAK 025 TURN OFF CURSOR ; SYN 026 SET Y POSITION TO BOTTOM OF SCREEN ; ETB 027 RESET CURRENT TEXT SIZE TO DEFAULT (4) ; CAN 030 ERASE SCREEN ; EM 031 SET CURRENT POSITION TO BOTTOM RIGHT OF SCREEN ; SUB 032 SET CURRENT POSITION TO BOTTOM LEFT OF SCREEN ; (ORIGIN) ; ESC 033 INTERPRET FOLLOWING CHARACTER AS TEXT (NOT ; CONTROL CHARACTER) ; FS 034 INTERPRET FOLLOWING CHARACTER AS NEW TEXT SIZE ; INDICATOR ; GS 035 DRAW LINE (VECTOR) FROM CURRENT POSITION TO ; POINT INDICATED BY NEXT 4 CHARACTERS (ENDPOINT ; BECOMES NEW CURRENT POSITION) ; RS 036 SET CURRENT POSITION TO POINT INDICATED BY NEXT ; 4 CHARACTERS ; US 037 SET CURRENT CURSOR POSITION TO POINT INDICATED ; BY NEXT 4 CHARACTERS AND TURN ON CURSOR ; SP 040 SET X POSITION FORWARD ONE CHARACTER SPACE ; (SPACE) ; ; THE "ESC" CHARACTER IS FOLLOWED BY ANY 7 BIT ASCII CHARACTER, WHICH ; IS VISUALIZED AS FOLLOWS: CODES 041 TO 176 (OCTAL) AS USUAL (UPPER AND ; LOWER CASE ASCII); CODE 040 IS A TRIANGLE; CODE 177 IS A SOLID BOX; ; AND CODES 000 TO 037 GENERATE RUNES FROM THE "ANGERTHAS MORIA" ; (SEE J.R.R. TOLKIEN, "THE LORD OF THE RINGS"). ; ; THE "FS" CHARACTER IS FOLLOWED BY A CODE IN THE RANGE 101 TO 177 (BIT ; 6 MUST BE ON) WHICH SETS THE CURRENT TEXT SIZE TO 1 TO 63 (DECIMAL); ; OR BY CODE 100, WHICH SETS THE TEXT SIZE TO THE DEFAULT (4). ; CHARACTERS ARE ALWAYS CONSTRUCTED FROM A 5 X 7 GRID OF POINTS (THOUGH ; THE SPACING BETWEEN CHARACTERS IS 7 X 9); THE TEXT SIZE IS THE NUMBER ; OF VT01 UNITS BETWEEN EACH POINT OF THE GRID. ; ; THE "GS", "RS", AND "US" CHARACTERS ARE FOLLOWED BY FOUR CHARACTERS ; WITH BIT 6 ON WHICH DEFINE THE X AND Y COORDINATES OF A POINT ON THE ; SCREEN IN VT01 UNITS (WHICH RANGE FROM 0 TO 2047 DECIMAL). THE ; FOLLOWING FORMAT IS USED: ; ; BIT 6 5 4 3 2 1 0 ; CHARACTER 1 1 * X10 X9 X8 X7 X6 ; CHARACTER 2 1 X5 X4 X3 X2 X1 X0 ; CHARACTER 3 1 * Y10 Y9 Y8 Y7 Y6 ; CHARACTER 4 1 Y5 Y4 Y3 Y2 Y1 Y0 ; ; WHERE "1" INDICATES THE BIT MUST BE ON, "*" INDICATES THE BIT IS ; IGNORED, AND X10 - X0 IS THE 11 BIT X COORDINATE, Y10 - Y0 IS THE 11 ; BIT Y COORDINATE. ; ; THE FOLLOWING COMPLETION CODES ARE RETURNED BY THE HANDLER: ; ; IE.IFC -02 INVALID FUNCTION CODE ; IE.SPC -06 IMPROPER USER BUFFER ADDRESS OR LENGTH ; IE.DNA -07 DETACH FAILED -- DEVICE NOT ATTACHED ; IE.DAA -08 ATTACH FAILED -- DEVICE ALREADY ATTACHED ; IE.ABO -15 WRITE FUNCTION ABORTED BY KILL I/O OR I/O RUNDOWN ; IE.PRI -16 PRIVILEGE VIOLATION ; IS.SUC +01 SUCCESFUL COMPLETION ; ; THE PUD ENTRY FOR THE VT DEVICE MUST CONTAIN THE FOLLOWING INFORMATION: ; ; DEVICE NAME U.DN "VT" ; UNIT NUMBER U.UN 0 (BYTE) ; CHARACTERISTICS 1 U.C1 UC.REC!UC.CCL = 3 (RECORD ORIENTED, ; CARRIAGE CONTROL DEVICE) ; CHARACTERISTICS 2 U.C2 CURSOR BLINK INTERVAL IN CLOCK TICKS ; (50 DECIMAL RECOMMENDED) ; CHARACTERISTICS 3 U.C3 HANDLER TIME-OUT IN MINUTES (TIME BEFORE ; AUTOMATIC CHANGE TO NON-STORAGE MODE TO ; PROLONG SCREEN LIFE) = 5 ; CHARACTERISTICS 4 U.C4 STANDARD BUFFER SIZE OR LINE LENGTH (73 ; DECIMAL RECOMMENDED) ; INTERRUPT VECTOR U.TV INTERRUPT VECTOR ADDRESS (140 OCTAL) ; INTERRUPT PSW U.IP 200 OCTAL (PRIORITY 4) ; DEVICE ADDRESS U.DA CSR ADDRESS (176756 OCTAL) ; ; NOTE THAT THE HANDLER SUPPORTS ALL CARRIAGE CONTROL CHARACTERS (NULL, ; SPACE, +, 1, 0, AND $). ALSO NOTE THAT THE USER'S BUFFER FOR A WRITE ; CAN BE ANY LENGTH IN THE RANGE 1 TO 8128 BYTES, BUT THAT ONLY 72 ; CHARACTERS OF STANDARD SIZE WILL FIT ON ONE LINE. ; ; TASK ATTRIBUTES: /-AB /-CP /DS /-FP /-FX /HD /-MU /-PI /PR /-TA /-TR ; ; TASKNAME: VT.... ; PARTITION: GEN ; POOL LIMIT: 40 ; PRIORITY: 80 (SO AS NOT TO INTERFERE WITH OUTPUT DESPOOLER) ; STACK: 43 ; UIC: [1,1] ; UNITS: 0 ; .SBTTL SYMBOL DEFINITIONS ; ; MACRO CALLS: ; RSXMAC: .MCALL DIR$,EXIT$S,ASTX$S,SPRA$,SETF$,CMKT$,MRKT$,CLEF$,WTLO$ ; ; DEFINITIONS: ; PS = 177776 ;PDP11 PROCESSOR STATUS WORD PR7 = 340 ;PRIORITY 7 MASK ; NREFM1 = 1 ;NORMAL REQUEST FLAG MASK WORD 1 XREFM1 = 2 ;EXPRESS REQUEST FLAG MASK WORD 1 VTEFM1 = 4 ;INTERRUPT (VT01 READY) FLAG MASK WORD 1 EREF = 4 ;ERASE INTERVAL EVENT FLAG NUMBER EREFM1 = 10 ;ERASE INTERVAL FLAG MASK WORD 1 TOEF = 5 ;HANDLER TIME-OUT EVENT FLAG NUMBER TOEFM1 = 20 ;HANDLER TIME-OUT FLAG MASK WORD 1 OPEF = 30. ;OPERATOR ACTION EVENT FLAG NUMBER OPEFM2 = 20000 ;OPERATOR ACTION FLAG MASK WORD 1 ; MAX = 2*<4096.-32.> ;MAXIMUM WRITE BUFFER LENGTH WRT = 1 ;TRANSFER DIRECTION FOR WRITE ASROFF = 60000 ;ASR 3 VIRTUAL ADDRESS OFFSET PDESC = 77402 ;PAGE DESCRIPTOR FOR ACCESS TO USER BUF ; VTNAM = "VT ;HANDLER NAME VTUNIT = 0 ;DEVICE UNIT NUMBER ; XREG = 2 ;OFFSET OF X REGISTER FROM CSR YREG = 4 ;OFFSET OF Y REGISTER FROM CSR ; INTN = 1 ;INTENSIFY BIT IN CSR ERAS = 2 ;ERASE BIT IN CSR STOR = 4 ;STORAGE MODE BIT IN CSR INTR = 100 ;INTERRUPT ENABLE BIT IN CSR FAST = 400 ;FAST DEFLECTION MODE BIT IN CSR ; DEFSIZ = 4 ;DEFAULT TEXT GRID SIZE IN VT01 UNITS CWID = 5 ;CHARACTER GRID WIDTH CXSPAC = 7 ;CHARACTER X SPACING CYSPAC = 9. ;CHARACTER Y SPACING TABX = 8. ;NO. OF SPACES PER HORIZONTAL TAB TABY = 6 ;NO. OF SPACES PER VERTICAL TAB SCRSZX = 2048. ;SCREEN SIZE IN X DIRECTION SCRSZY = 2048. ;SCREEN SIZE IN Y DIRECTION ; LF = 12 ;ASCII CODE FOR LINE FEED FF = 14 ;ASCII CODE FOR FORM FEED CR = 15 ;ASCII CODE FOR CARRIAGE RETURN SPA = 40 ;ASCII CODE FOR SPACE DEL = 177 ;ASCII CODE FOR DELETE (RUBOUT) ; .PSECT VT01RW ; .SBTTL INITIALIZATION AND MAINLINE CODE ; VTSTRT: MOV #VTUIT,R0 ;SET ADDRESS OF UIT MOV #VTNAM,R2 ;SET HANDLER NAME MOV #UF.RH,R3 ;HANDLER RESIDENT FLAG JSR PC,@#..DSUT ;DECLARE HANDLER RESIDENT BCS EXIT ;GO AWAY IF IT FAILS DIR$ #PFDPB ;SET UP POWER FAIL AST BCS NONRES ;QUIT IF DOESN'T WORK MOV PUDPTR,R5 ;GET PUD ADDRESS MOV U.TV(R5),R0 ;GET INTERRUPT VECTOR ADDRESS MOV #VTINT,R1 ;INTERRUPT SERVICE ROUTINE CLR R2 ;BASE ADDRESS CLR R3 ;GET... BISB U.IP(R5),R3 ;...INTERRUPT PSW JSR PC,@#..CINT ;CONNECT TO INTERRUPT BCS NONRES ;FAILED, GIVE UP DIR$ #STEDPB ;SET ERASE INTERVAL FLAG BCS DISCON ;ON ERROR, DISCONNECT & EXIT CLRB EXITFL ;CLEAR HANDLER EXIT FLAG CLRB INTRON ;CLEAR INTERRUPT ENABLED FLAG JSR PC,INIT ;INITIALIZE VT01 MOV PC,SP ;INCREASE STACK SIZE START: CLR COUNTR ;NO CHARACTERS LEFT IN BUFFER NEXT: JSR PC,GETCHR ;GET A CHARACTER FROM BUFFER CMP R0,#DEL ;IS IT A RUBOUT? BEQ NEXT ;YES, IGNORE IT CMP R0,#SPA ;IS IT A CONTROL CHARACTER? BGT 1$ ;NO, IT'S PRINTABLE ASL R0 ;MAKE IT A WORD OFFSET JSR PC,@CNTRLS(R0) ;DISPATCH TO SUBROUTINE FROM TABLE BR NEXT 1$: JSR PC,TEXT ;OUTPUT TEXT CHARACTER BR NEXT ; .SBTTL SUBROUTINE GETCHR -- GET NEXT CHARACTER FOR OUTPUT ; ; THIS ROUTINE RETURNS WITH R0 = CHARACTER CODE (MASKED TO 7 BITS) ; GETCHR: MOV R1,-(SP) ;SAVE REGISTERS MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV R5,-(SP) TST NRNA ;OUTPUT BUFFER EXIST YET? BEQ IDLE ;NO, GO GET ONE JMP NXTCHR ;YES, GET NEXT CHARACTER IDLE: TSTB EXITFL ;HANDLER WANT TO EXIT? BEQ CURCHK ;NO TST NRNA ;DOING SOMETHING NOW THOUGH? BNE CURCHK ;YES, CAN'T EXIT YET MOV #START,SP ;NO, RESTORE STACK DISCON: DIR$ #CMTDPB ;CANCEL ANY PENDING MARK TIMES MOV PUDPTR,R0 ;GET PUT ADDRESS CLR @U.DA(R0) ;CLEAR VT01 CSR (SAVE PHOSPHOR) MOV U.TV(R0),R0 ;GET INTERRUPT VECTOR ADDRESS JSR PC,@#..DINT ;DISCONNECT FROM INTERRUPT NONRES: MOV #VTUIT,R0 ;GET UIT ADDRESS JSR PC,@#..DNRC ;DECLARE NONRESIDENT... EXIT: EXIT$S ;...AND BECOME NONRESIDENT ; CURCHK: MOV PUDPTR,R0 ;GET PUD ADDRESS TST CURFLG ;IS CURSOR ON? BEQ 1$ ;NO MOV U.C2(R0),CRSDPB+M.KTMG;YES, GET BLINK TIME FROM PUD DIR$ #CRSDPB ;START CURSOR BLINKING (VIA AST) 1$: MOV U.C3(R0),TIMDPB+M.KTMG;GET HANDLER TIME-OUT FROM PUD DIR$ #TIMDPB ;START TIME-OUT CLOCK DIR$ #CLFDPB ;CLEAR OPERATOR ACTION FLAG DIR$ #IDLDPB ;WAIT FOR SOMETHING TO HAPPEN DIR$ #CANDPB ;CANCEL CURSOR BLINKING DIR$ #CTODPB ;CANCEL HANDLER TIME-OUT CLOCK CHECK: MOV @#.CRTSK,R1 ;GET OUR ATL ADDRESS MOV @#PS,-(SP) ;SAVE PRIORITY BIS #PR7,@#PS ;INHIBIT INTERRUPTS MOV A.EF(R1),R5 ;GET HANDLER EVENT FLAGS MOV A.EF+2(R1),R4 ;(TWO WORDS) MOV (SP)+,@#PS ;RE-ENABLE INTERRUPTS BIT #XREFM1,R5 ;ANY EXPRESS REQUESTS? BEQ 1$ ;NO JSR PC,XPRESS ;YES, GO PROCESS THEM 1$: BIT #NREFM1,R5 ;ANY NORMAL REQUESTS? BEQ 2$ ;NO MOV #VTUIT,R0 ;YES, GET UIT ADDRESS JSR PC,@#..DQRN ;AND DEQUEUE REQUEST BCC 4$ ;GOT ONE! 2$: MOV PUDPTR,R0 ;GET PUD ADDRESS MOV U.DA(R0),R0 ;ADDRESS OF VT01 CSR BIT #TOEFM1,R5 ;HANDLER TIME OUT? BEQ 3$ ;NO CLR CURFLG ;YES, TURN OFF CURSOR CLR (R0) ;TURN OFF VT01 3$: BIT #OPEFM2,R4 ;IS OPERATOR ACTION FLAG ON? BEQ IDLE ;NO, GO BACK TO SLEEP MOV #STOR,R1 ;YES, GET STORAGE MODE BIT MASK XOR R1,(R0) ;FLIP MODE BR IDLE ;WAIT FOR THINGS TO HAPPEN 4$: MOVB R.FC+1(R1),R3 ;GET I/O REQUEST FUNCTION CODE BEQ UNRFN ;ZERO IS INVALID FOR NORMAL REQUEST CMP R3,#NFUNS ;SEE IF TOO BIG FOR DISPATCH TABLE BHIS UNRFN ;YES, IT'S ILLEGAL JSR PC,@#..VACC ;VERIFY ACCESS RIGHTS BCS NOPRIV ;NOT ENOUGH PRIVILEGES JMP @#..DISP ;OK, DISPATCH USING FUNCTION TABLE ; ATTACH: JSR PC,@#..ATUN ;ATTACH UNIT BCS ATFAIL ;FAILED (ALREADY ATTACHED) JSR PC,INIT ;INITIALIZE VT01 FOR THE ATTACHER BR IOSUCC ;DONE ; DETACH: JSR PC,@#..DTUN ;DETACH UNIT BCS DTFAIL ;DIDN'T WORK (NOT ATTACHED) BR IOSUCC ;DONE ; UNRFN: MOV #IE.IFC,R3 ;ILLEGAL FUNCTION CODE BR IOVER ; ILLMRQ: MOV #IE.SPC,R3 ;INVALID BUFFER SPECIFICATION BR IOVER ; DTFAIL: MOV #IE.DNA,R3 ;DEVICE NOT ATTACHED BR IOVER ; ATFAIL: MOV #IE.DAA,R3 ;DEVICE ALREADY ATTACHED BR IOVER ; NOPRIV: MOV #IE.PRI,R3 ;PRIVILEGE VIOLATION BR IOVER ; IOSUCC: MOV #IS.SUC,R3 ;I/O FUNCTION SUCCEEDED IOVER: CLR R4 ;ZERO BYTES TRANSFERED BR IOFIN ;DO I/O COMPLETION ; WRITE: MOV R.PB+2(R1),R3 ;GET NO. OF BYTES TO WRITE BLE ILLMRQ ;ZERO OR NEGATIVE IS ILLEGAL CMP R3,#MAX ;TOO MANY FOR ONE ASR? BGT ILLMRQ ;YES MOV R.PB(R1),R2 ;GET VIRTUAL BUFFER ADDRESS MOV #WRT,R5 ;WRITE (TRANSFER DIRECTION) JSR PC,@#..VXFR ;VERIFY TRANSFER LEGALITY BCS ILLMRQ ;BAD USER BUFFER MOV R3,COUNTR ;SET CHARACTER COUNT ASH #-4,R4 ;GET HI ORDER 2 BITS OF PHYSICAL ADDR. ASHC #12,R4 ;SET R4 = ASR ADDRESS... ASH #-12,R5 ;...AND R5 = ASR OFFSET BIC #177700,R5 ;64. BYTES MAXIMUM ADD #ASROFF,R5 ;MAKE IT ASR3 RELATIVE ADDRESS MOV R5,POINTR ;SAVE BUFFER POINTER MOV R5,BUFBEG ;ALSO SET ADDRESS OF START OF BUFFER MOV #PDESC,-(SP) ;SET ASR3 PAGE DESCRIPTOR... MOV R4,-(SP) ;...AND SEGMENT ADDRESS JSR PC,@#..SPD3 ;SWAP ASR3 WITH STACK CMP (SP)+,(SP)+ ;DON'T NEED OLD ASR VALUE CLRB LFFLAG ;CLEAR LINE FEED FLAG CLRB CRFLAG ;AND CARRIAGE RETURN FLAG MOVB R.PB+4(R1),R5 ;GET CARRIAGE CONTROL BYTE MOV #CARCTL,R4 ;START OF CARRIAGE CONTROL TABLE MOV #NCARCT,R3 ;NO. OF CHARACTERS RECOGNIZED 1$: CMPB R5,(R4)+ ;IS IT THIS ONE? BEQ 2$ ;YES SOB R3,1$ ;NO, TRY THEM ALL 2$: ASL R3 ;CONVERT INDEX TO WORD OFFSET ADD R3,PC ;DISPATCH TO PROPER PLACE BR LFCR ;SPACE OR OTHER BR FFCR ;"1" BR L2CR ;"0" BR XXCR ;"+" BR LFXX ;"$" BR XXXX ;NULL L2CR: INCB LFFLAG ;SET "EXTRA LINEFEED NEEDED" FLAG INC COUNTR ;INCLUDE IT IN CHARACTER COUNT LFCR: MOVB #LF,R0 ;BEGIN WITH A LINE FEED BR SETCR FFCR: MOVB #FF,R0 ;BEGIN WITH A FORM FEED SETCR: INCB CRFLAG ;SET "CARRIAGE RETURN AT END" FLAG BR UPCNT LFXX: MOVB #LF,R0 ;BEGIN WITH A LINE FEED UPCNT: INC COUNTR ;INCLUDE STARTING CHARACTER IN COUNT BR XIT XXCR: INCB CRFLAG ;SET "CARRIAGE RETURN AT END" FLAG XXXX: BR NEWCHR ;NO CARRIAGE CONTROLS ; NXTCHR: DEC COUNTR ;COUNT ANOTHER CHARACTER DONE BGT NEWCHR ;STILL MORE TO DO, GET NEW ONE BLT 2$ ;DONE COMPLETE BUFFER TSTB CRFLAG ;NEED TO APPEND CARRIAGE RETURN AT END? BEQ 2$ ;NO MOVB #CR,R0 ;YES, SO GET CARRIAGE RETURN BR XIT 2$: MOV POINTR,R4 ;GET BUFFER ADDRESS NOW... SUB BUFBEG,R4 ;...MINUS STARTING ADDRESS MOV #IS.SUC,R3 ;WRITE FUNCTION SUCCESFULLY COMPLETED IOFIN: MOV NRNA,R1 ;GET NORMAL REQUEST NODE ADDRESS JSR PC,IOCOMP ;DO I/O COMPLETION PROCESSING JMP IDLE ;LOOK FOR MORE TO DO ; NEWCHR: TSTB LFFLAG ;NEED A SECOND LINE FEED? BEQ 1$ ;NO CLRB LFFLAG ;YES, RESET FLAG MOVB #LF,R0 ;DELIVER A LINE FEED BR XIT 1$: MOVB @POINTR,R0 ;GET NEXT CHARACTER FROM BUFFER INC POINTR ;ADVANCE BUFFER POINTER ; XIT: BIC #177600,R0 ;MASK DOWN TO 7 BITS MOV @#.CRTSK,R1 ;GET OUR ATL ADDRESS BIT #XREFM1,A.EF(R1);ANY EXPRESS REQUESTS PENDING? BEQ 1$ ;NO JSR PC,XPRESS ;YES, DO THEM NOW 1$: MOV (SP)+,R5 ;RESTORE REGISTERS MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 RTS PC ;RETURN ; .SBTTL SUBROUTINE XPRESS -- PROCESS EXPRESS REQUESTS (FUNCTION 0) ; XPRESS: MOV R0,-(SP) ;SAVE REGISTERS MOV R1,-(SP) MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV #VTUIT,R0 ;GET UIT ADDRESS JSR PC,@#..DQRE ;DEQUEUE EXPRESS REQUESTS BCS XRDONE ;THERE ARE NONE CLR R4 ;SET ZERO BYTES TRANSFERED TSTB R.FC+1(R1) ;IS FUNCTION CODE ZERO? BNE BADFN ;NO, THAT'S NOT A VALID EXPRESS FUNCTION JSR PC,@#..VACC ;VERIFY ACCESS RIGHTS BCS BADXR ;DON'T HAVE NEEDED PRIVILEGES JMP @#..DISP ;DISPATCH ON TABLE (FORMALITY...) SPECFN: MOV R.FC(R1),R3 ;GET SUBFUNCTION CODE CMP R3,#IO.KIL ;IS IT I/O KILL? BEQ 1$ ;YES TST R.AT(R1) ;DOES REQUEST COME FROM EXECUTIVE? BNE BADFN ;NO, IGNORE IT CMP R3,#IO.RDN ;I/O RUNDOWN? BEQ 2$ ;YES CMP R3,#IO.UNL ;UNLOAD HANDLER? BNE BADFN ;NO, UNRECOGNIZED FUNCTION INCB EXITFL ;YES, SET EXIT FLAG BR 3$ ;GO FINISH UP 1$: MOV R.AT(R1),R3 ;GET ATL ADDRESS OF REQUESTOR MOV R3,R.PB(R1) ;PUT IT IN IORQ NODE PARAMETER 1 MOV A.TD(R3),R.PB+2(R1);PUT STD ADDRESS INTO PARAMETER 2 MOV (R2),R.PB+4(R1) ;PUT PUD ADDRESS INTO PARAMETER 3 2$: JSR PC,@#..FLSH ;FLUSH Q'S OF ALL RQ'S FOR THIS TASK MOV NRNA,R3 ;GET ADDRESS OF CURRENT NORMAL REQUEST BEQ 3$ ;NO ACTIVE REQUESTS, DONE CMP R.AT(R3),R.PB(R1);DOES RQ BELONG TO THE TASK KILLED? BNE 3$ ;NO, LEAVE IT ALONE CLRB R.FN(R3) ;YES, CLEAR REQUEST EVENT FLAG, CLR R.SB(R3) ;I/O STATUS BLOCK ADDRESS, CLR R.AE(R3) ;AND AST ENTRY ADDRESS MOV R1,-(SP) ;SAVE SPECIAL FUNCTION RNA MOV R3,R1 ;GET THE NORMAL RNA MOV #IE.ABO,R3 ;SET I/O ABORTED STATUS JSR PC,IOCOMP ;DO I/O COMPLETION ON NORMAL REQUEST MOV (SP)+,R1 ;RESTORE EXPRESS RNA MOV #IS.SUC,R3 ;EXPRESS REQUEST SUCCEEDED JSR PC,IOCOMP ;DO I/O COMPLETION ON EXPRESS REQUEST MOV #START,SP ;RESET STACK JMP (SP) ;RESTART HANDLER FROM BEGINNING 3$: MOV #IS.SUC,R3 ;SUCCESFUL COMPLETION BR XRFIN BADFN: MOV #IE.IFC,R3 ;INVALID FUNCTION CODE BR XRFIN BADXR: MOV #IE.PRI,R3 ;PRIVILEGE VIOLATION XRFIN: JSR PC,IOCOMP ;DO I/O COMPLETION XRDONE: MOV (SP)+,R4 ;RESTORE REGISTERS MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 RTS PC ;RETURN ; .SBTTL SUBROUTINES WAIT AND IOCOMP ; ; SUBROUTINE WAIT -- WAIT FOR VT01 READY, THEN SET PROPER MODE ; RETURNS WITH R0 = ADDRESS OF VT01 CSR ; WAIT: MOV R1,-(SP) ;SAVE R1 MOV PUDPTR,R0 ;GET PUD ADDRESS MOV U.DA(R0),R0 ;PUT CSR ADDRESS INTO R0 1$: TSTB (R0) ;IS VT01 READY? BMI 2$ ;YES! INCB INTRON ;NO, SET INTERRUPT ON FLAG BIS #INTR,(R0) ;SET INTERRUPT ENABLE BIT DIR$ #VTWDPB ;WAIT FOR VT01 READY MOV @#.CRTSK,R1 ;GET OUR ATL ADDRESS BIC #VTEFM1,A.EF(R1);CLEAR INTERRUPT EVENT FLAG BIT #XREFM1,A.EF(R1);ANY EXPRESS REQUESTS PENDING? BEQ 1$ ;NO, CHECK FOR READY NOW JSR PC,XPRESS ;YES, EXECUTE THEM BR 1$ ;TEST FOR READY AGAIN 2$: MOV MODE,(R0) ;SET UP PROPER MODE (STORE OR NON-STORE) MOV (SP)+,R1 ;RESTORE R1 RTS PC ;RETURN ; ; SUBROUTINE IOCOMP -- DO I/O COMPLETION PROCESSING ; ENTERED WITH R1=REQUEST NODE ADDRESS ; R3=COMPLETION CODE ; R4=NO. OF BYTES TRANSFERED ; IOCOMP: MOV R0,-(SP) ;SAVE R0 MOV R2,-(SP) ;SAVE R2 MOV R.FC(R1),R0 ;GET FUNCTION CODE BIC #177400,R3 ;MASK COMPLETION CODE TO ONE BYTE CLR R2 ;ADJUSTMENT TO UNITY JSR PC,@#..IODN ;SIGNAL I/O DONE TO REQUESTOR BIC #^C,R0 ;MASK OUT ALL BUT EXPRESS BIT CLR NRNA(R0) ;CLEAR PROPER RNA (NORMAL OR EXPRESS) MOV (SP)+,R2 ;RESTORE R2 MOV (SP)+,R0 ;RESTORE R0 RTS PC ;RETURN ; .SBTTL SUBROUTINES TO IMPLEMENT CONTROL CHARACTERS ; ; SUBROUTINE STORE -- SET STORAGE MODE ; STORE: MOV #STOR,MODE ;SET STORE BIT IN MODE RTS PC ; ; SUBROUTINE NONSTR -- SET NON-STORAGE MODE ; NONSTR: CLR MODE ;CLEAR MODE WORD RTS PC ; ; SUBROUTINE RESSIZ -- RESET CHARACTER SIZE TO DEFAULT ; RESSIZ: MOV #DEFSIZ,TXTSIZ ;SET DEFAULT TEXT SIZE RTS PC ; ; SUBROUTINE INCSIZ -- INCREMENT CHARACTER SIZE ; INCSIZ: INC TXTSIZ ;ADD ONE TO TEXT SIZE RTS PC ; ; SUBROUTINE DECSIZ -- DECREMENT CHARACTER SIZE ; DECSIZ: DEC TXTSIZ ;SUBTRACT ONE FROM TEXT SIZE BGT 1$ ;STILL NON-ZERO MOV #1,TXTSIZ ;CAN'T GO BELOW 1 1$: RTS PC ; ; SUBROUTINES TOPLFT (SET POSITION TO TOP LEFT), LEFT (SET X POSITION ; TO LEFT), AND NULL ; NOTE: R1 IS MODIFIED BY ROUTINE TOPLFT. ; TOPLFT: JSR PC,TOP ;SET Y TO TOP OF SCREEN LEFT: CLR XPOS ;SET X TO LEFT MARGIN NULL: RTS PC ;RETURN ; ; SUBROUTINES TOPRGT (SET POSITION TO TOP RIGHT), RIGHT (SET X POSITION ; TO RIGHT), AND DECX (SUBTRACT CHARACTER WIDTH FROM X). ; NOTE: R1 IS MODIFIED BY THESE ROUTINES ; TOPRGT: JSR PC,TOP ;SET Y TO TOP OF SCREEN RIGHT: MOV #SCRSZX,XPOS ;GET SCREEN WIDTH DECX: JSR PC,XSIZE ;SET R1 = CHARACTER WIDTH SUB R1,XPOS ;GO BACK ONE CHARACTER RTS PC ; ; SUBROUTINE BOTLFT -- SET POSITION TO BOTTOM LEFT OF SCREEN ; BOTLFT: CLR XPOS ;SET X TO LEFT MARGIN CLR YPOS ;SET Y TO BOTTOM RTS PC ; ; SUBROUTINES BOTRGT (SET POSITION TO BOTTOM RIGHT) AND BOTTOM (SET ; Y POSITION TO BOTTOM) ; NOTE: R1 IS MODIFIED BY ROUTINE BOTRGT. ; BOTRGT: JSR PC,RIGHT ;SET X TO RIGHT MARGIN BOTTOM: CLR YPOS ;SET Y TO BOTTOM RTS PC ; ; SUBROUTINES TOP (SET Y POSITION TO TOP) AND DECY (SUBTRACT CHARACTER ; HEIGHT FROM Y). ; NOTE: R1 IS MODIFIED BY THESE ROUTINES. ; TOP: MOV #SCRSZY,YPOS ;SET Y TO TOP OF SCREEN DECY: JSR PC,YSIZE ;SET R1 = CHARACTER HEIGHT SUB R1,YPOS ;GO DOWN ONE LINE RTS PC ; ; SUBROUTINE BACKSP -- MOVE X POSITION BACK ONE CHARACTER SPACE ; NOTE: R1 IS MODIFIED BY THIS ROUTINE ; BACKSP: JSR PC,DECX ;SUBTRACT CHARACTER WIDTH FROM X BGE 1$ ;STILL OK CLR XPOS ;TOO SMALL, SET LEFT MARGIN 1$: RTS PC ; ; SUBROUTINES UPLINE (MOVE Y POSITION UP ONE LINE) AND TESTY (RESET Y ; TO TOP IF VALUE EXCEEDS MAXIMUM). ; NOTE: R1 AND R3 ARE MODIFIED BY THESE ROUTINES ; UPLINE: JSR PC,YSIZE ;SET R1 = CHARACTER HEIGHT ADD R1,YPOS ;GO UP ONE LINE TESTY: MOV #SCRSZY,R3 ;GET SCREEN HEIGHT SUB R1,R3 ;MINUS ONE LINE CMP YPOS,R3 ;UP TOO HIGH? BLE 1$ ;NO, OK MOV R3,YPOS ;YES, SET MAXIMUM 1$: RTS PC ; ; SUBROUTINES LINEFD (MOVE Y POSITION DOWN ONE LINE) AND FORMFD (START A ; NEW PAGE) ; NOTE: REGISTERS R0 AND R1 ARE MODIFIED BY THESE ROUTINES. ; LINEFD: JSR PC,DECY ;SUBTRACT CHARACTER HEIGHT FROM Y BGE FFRET ;HAVEN'T REACHED BOTTOM YET FORMFD: JSR PC,OPWAIT ;WAIT FOR OPERATOR ACTION JSR PC,TOP ;GO TO TOP OF SCREEN JSR PC,ERASE ;ERASE SCREEN FFRET: RTS PC ; ; SUBROUTINE OPWAIT -- WAIT FOR OPERATOR ACTION (SETTING EVENT FLAG) ; OPWAIT: DIR$ #CLFDPB ;CLEAR OPERATOR EVENT FLAG DIR$ #OPWDPB ;NOW WAIT FOR IT TO SET RTS PC ; ; SUBROUTINE INIT (INITIALIZE VT01) AND ERASE (ERASE SCREEN) ; NOTE: REGISTER R0 IS MODIFIED BY ROUTINE ERASE. R0 AND R1 ARE ; MODIFIED BY ROUTINE INIT. ; INIT: CLR CXPOS ;SET CURSOR X POSITION TO LEFT CLR CYPOS ;SET CURSOR Y POSITION TO BOTTOM JSR PC,RESSIZ ;RESET CHARACTER SIZE TO DEFAULT JSR PC,TOPLFT ;SET POSITION TO TOP LEFT OF SCREEN JSR PC,STORE ;SET STORAGE MODE CLR CURFLG ;TURN OFF CURSOR ERASE: DIR$ #ERWDPB ;WAIT FOR ERASE INTERVAL OVER ;(DON'T ALLOW SECOND ERASE IMMEDIATELY ;AFTER FIRST) JSR PC,WAIT ;WAIT FOR VT01 READY & SET R0 = CSR ADDR. BIS #ERAS,(R0) ;ERASE SCREEN DIR$ #ERIDPB ;START TIMING ERASE INTERVAL RTS PC ; ; SUBROUTINE TAB -- MOVE X FORWARD TO NEXT TAB STOP ; NOTE: R1, R2, R3, AND R5 ARE MODIFIED BY THIS ROUTINE ; TAB: JSR PC,XSIZE ;SET R1 = CHARACTER WIDTH MOV R1,R5 ;SAVE IT MUL #TABX,R5 ;MULTIPLY BY NO. OF CHARACTERS IN ONE TAB MOV XPOS,R3 ;GET CURRENT X POSITION ADD R5,R3 ;ADD ONE TAB LENGTH CLR R2 ;(HIGH ORDER ZERO) DIV R5,R2 ;DIVIDE BY TAB LENGTH MUL R2,R5 ;TIMES TAB LENGTH AGAIN MOV R5,XPOS ;NEW X POSITION JSR PC,TESTX ;SET TO RIGHT MARGIN IF PAST IT RTS PC ; ; SUBROUTINE VERTAB -- MOVE Y DOWN TO NEXT TAB STOP ; NOTE: REGISTERS R0, R1, R2, AND R3 ARE MODIFIED BY THIS ROUTINE ; VERTAB: JSR PC,YSIZE ;SET R1 = CHARACTER HEIGHT MUL #TABY,R1 ;MULTIPLY BY NO. OF LINES IN ONE TAB MOV YPOS,R3 ;GET CURRENT Y POSITION DEC R3 ;MINUS ONE UNIT CLR R2 ;(HIGH ORDER ZERO) DIV R1,R2 ;DIVIDE BY TAB DISTANCE MUL R2,R1 ;MULTIPLY BY TAB DISTANCE MOV R1,YPOS ;SET NEW Y POSITION BGE 1$ ;STILL ABOVE BOTTOM OF PAGE JSR PC,FORMFD ;START A NEW PAGE 1$: RTS PC ; ; SUBROUTINE BKTAB -- MOVE X BACK TO PREVIOUS TAB STOP ; NOTE: R1, R2, AND R3 ARE MODIFIED BY THIS ROUTINE. ; BKTAB: JSR PC,XSIZE ;SET R1 = CHARACTER WIDTH MUL #TABX,R1 ;MULTIPLY BY NO. OF CHARACTERS IN ONE TAB MOV XPOS,R3 ;GET CURRENT X POSITION DEC R3 ;MINUS ONE UNIT CLR R2 ;(HIGH ORDER ZERO) DIV R1,R2 ;DIVIDE BY TAB LENGTH MUL R2,R1 ;MULTIPLY BY IT AGAIN MOV R1,XPOS ;SET NEW X POSITION BGE 1$ ;NOT AT LEFT MARGIN YET CLR XPOS ;TOO SMALL, SET IT TO LEFT MARGIN 1$: RTS PC ; ; SUBROUTINE UPTAB -- MOVE Y UPWARD TO PREVIOUS TAB STOP ; NOTE: R1, R2, R3, AND R5 ARE MODIFIED BY THIS ROUTINE ; UPTAB: JSR PC,YSIZE ;SET R1 = CHARACTER HEIGHT MOV R1,R5 ;SAVE IT MUL #TABY,R5 ;MULTIPLY BY NO. OF LINES IN ONE TAB MOV YPOS,R3 ;GET CURRENT Y POSITION ADD R5,R3 ;MOVE UP BY TAB DISTANCE CLR R2 ;(HIGH ORDER ZERO) DIV R5,R2 ;DIVIDE BY TAB DISTANCE MUL R2,R5 ;MULTIPLY BY IT AGAIN MOV R5,YPOS ;SET NEW Y POSITION JSR PC,TESTY ;IF TOO BIG, SET TO TOP OF SCREEN RTS PC ; ; SUBROUTINE ESCAPE -- TREAT NEXT CHARACTER AS TEXT TO DISPLAY ; NOTE: ALL REGISTERS ARE MODIFIED BY THIS ROUTINE ; ESCAPE: JSR PC,GETCHR ;GET NEXT CHARACTER INTO R0 JSR PC,TEXT ;DISPLAY IT RTS PC ; ; SUBROUTINE SETSIZ -- SET CHARACTER SIZE TO GIVEN VALUE ; NOTE: R0 IS MODIFIED BY THIS ROUTINE ; SETSIZ: JSR PC,GETCHR ;GET NEXT CHARACTER INTO R0 BITB #100,R0 ;MAKE SURE BIT 6 IS ON BEQ SETSIZ ;IF NOT, IGNORE IT BIC #177700,R0 ;RESTRICT TO RANGE 0 TO 63 BNE 1$ ;NON-ZERO MOV #DEFSIZ,R0 ;ZERO IMPLIES DEFAULT 1$: MOV R0,TXTSIZ ;SET TEXT SIZE RTS PC ; ; SUBROUTINE CURSCU -- TURN ON CURSOR AT CURRENT POSITION ; CURSCU: MOV XPOS,CXPOS ;SET CURSOR X POSITION MOV YPOS,CYPOS ;SET CURSOR Y POSITION JSR PC,CURSON ;TURN ON CURSOR RTS PC ; ; SUBROUTINES CURSOR (SET CURSOR POSITION & TURN ON) AND CURSON (TURN ; ON CURSOR) ; NOTE: R0 AND R5 ARE MODIFIED BY ROUTINE CURSOR ; CURSOR: JSR PC,GET2C ;GET X COORDINATE INTO R5 MOV R5,CXPOS ;SET CURSOR X POSITION JSR PC,GET2C ;GET Y COORDINATE INTO R5 MOV R5,CYPOS ;SET CURSOR Y POSITION CURSON: MOV #1,CURFLG ;TURN ON CURSOR RTS PC ; ; SUBROUTINE CURSOF -- TURN OFF CURSOR ; CURSOF: CLR CURFLG ;TURN OFF CURSOR RTS PC ; ; SUBROUTINE MOVE -- SET NEW CURRENT SCOPE POSITION ; NOTE: R0 AND R5 ARE MODIFIED BY THIS ROUTINE ; MOVE: JSR PC,GET2C ;GET X COORDINATE INTO R5 MOV R5,XPOS ;SET X POSITION JSR PC,GET2C ;GET Y COORDINATE INTO R5 MOV R5,YPOS ;SET Y POSITION RTS PC ; ; SUBROUTINE GET2C -- GET 2 CHARACTERS AND CONVERT THEM TO 11 BIT ; COORDINATE ; R0 IS MODIFIED BY THIS ROUTINE. R5 CONTAINS COORDINATE ON EXIT. ; GET2C: JSR PC,GETCHR ;GET NEXT CHARACTER INTO R0 BITB #100,R0 ;CHECK THAT BIT 6 IS ON BEQ GET2C ;IF NOT, IGNORE IT ASH #6,R0 ;SHIFT LEFT 6 BITS BIC #174077,R0 ;MASK OUT HIGH ORDER 5 BITS MOV R0,R5 ;SAVE IT 1$: JSR PC,GETCHR ;GET ANOTHER CHARACTER INTO R0 BITB #100,R0 ;CHECK BIT 6 BEQ 1$ ;IF ZERO, TRY AGAIN BIC #177700,R0 ;MASK OUT LOW ORDER 6 BITS BIS R0,R5 ;COMBINE WITH HIGH ORDER RTS PC ; ; SUBROUTINE XSIZE -- GET CHARACTER WIDTH IN VT01 UNITS ; RETURNS WITH RESULT IN R1. ; XSIZE: MOV TXTSIZ,R1 ;GET TEXT SIZE MUL #CXSPAC,R1 ;TIMES CHARACTER X SPACING RTS PC ; ; SUBROUTINE YSIZE -- GET CHARACTER HEIGHT IN VT01 UNITS ; RETURNS WITH RESULT IN R1 ; YSIZE: MOV TXTSIZ,R1 ;GET TEXT SIZE MUL #CYSPAC,R1 ;TIMES CHARACTER Y SPACING RTS PC ; .SBTTL SUBROUTINES TEXT, SPACE, AND TESTX ; ; SUBROUTINE TEXT DISPLAYS THE CHARACTER WHOSE CODE IS IN R0. (MODIFIES ; ALL REGISTERS). ; SUBROUTINE SPACE MOVES X FORWARD ONE CHARACTER SPACE. (MODIFIES R1 ; AND R3). ; SUBROUTINE TESTX SETS X TO THE RIGHT MARGIN IF IT EXCEEDS IT. ; (MODIFIES R1 AND R3). ; TEXT: MOV R0,R3 ;GET CHARACTER CODE MOV #CWID,R2 ;SET CHARACTER GRID WIDTH MUL R2,R3 ;MULTIPLY CODE BY BYTES IN ONE CHARACTER ADD #CHRTBL,R3 ;ADD START OF CHARACTER TABLE MOV XPOS,R4 ;GET STARTING X POSITION MOV #INTN,R1 ;INTENSIFY BIT CLR -(SP) ;RESERVE SPACE ON STACK JSR PC,WAIT ;WAIT FOR VT01 READY, SET R0 = CSR ADDR. 1$: MOV YPOS,R5 ;SET STARTING (BOTTOM) Y POSITION MOVB (R3)+,(SP) ;GET MASK BYTE FOR THIS X POSITION 2$: BEQ 5$ ;NO MORE POINTS LEFT IN THIS MASK BPL 4$ ;DON'T INTENSIFY THIS POINT 3$: TSTB (R0) ;CHECK VT01 READY BPL 3$ ;IF NOT, WAIT FOR IT MOV R5,YREG(R0) ;SET Y COORDINATE MOV R4,XREG(R0) ;SET X COORDINATE BIS R1,(R0) ;INTENSIFY BIS #FAST,R1 ;USE FAST DEFLECTION FOR LATER POINTS 4$: ADD TXTSIZ,R5 ;GO UP ONE GRID POINT ASLB (SP) ;GET NEXT BIT IN MASK BR 2$ ;LOOP 5$: ADD TXTSIZ,R4 ;GO RIGHT ONE GRID POINT SOB R2,1$ ;DO ALL HORIZONTAL POSITIONS TST (SP)+ ;CLEAN UP STACK SPACE: JSR PC,XSIZE ;SET R1 = CHARACTER WIDTH ADD R1,XPOS ;MOVE RIGHT ONE SPACE TESTX: MOV #SCRSZX,R3 ;GET SCREEN WIDTH SUB R1,R3 ;MINUS ONE CHARACTER WIDTH CMP XPOS,R3 ;PAST RIGHT MARGIN? BLE 1$ ;NO, OK MOV R3,XPOS ;YES, SET TO RIGHT MARGIN 1$: RTS PC ; .SBTTL SUBROUTINE VECTOR -- DRAW VECTOR BETWEEN TWO POINTS ; ; THIS ROUTINE DRAWS A LINE FROM THE CURRENT POSITION TO A SPECIFIED ; POINT (WHICH BECOMES THE NEW CURRENT POSITION). THE CODE IS OPTIMIZED ; FOR THE SPECIAL CASES OF A POINT, A HORIZONTAL OR VERTICAL LINE, OR ; A DIAGONAL LINE. ; ; ALL REGISTERS ARE MODIFIED BY THIS ROUTINE. ; VECTOR: JSR PC,GET2C ;GET X COORDINATE OF ENDPOINT MOV R5,R4 ;PUT IT IN R4 JSR PC,GET2C ;GET Y COORDINATE OF ENDPOINT JSR PC,WAIT ;WAIT FOR VT01 READY, SET R0 = CSR ADDR. MOV #INTN,R1 ;GET INTENSIFY BIT ( = 1) MOV R4,R2 ;GET FINAL X MOV R5,R3 ;ALSO FINAL Y SUB XPOS,R2 ;FIND DELTA X BNE 4$ ;NON-ZERO MOV R4,XREG(R0) ;VERTICAL LINE: SET X POSITION MOV YPOS,R2 ;GET STARTING Y POSITION SUB R2,R3 ;CALCULATE DELTA Y BNE 1$ ;NON-ZERO MOV R5,YREG(R0) ;IT'S A POINT: SET Y REGISTER BIS R1,(R0) ;INTENSIFY BR 7$ ;ALL DONE 1$: BGT 2$ ;FINAL Y BIGGER THAN INITIAL NEG R3 ;OTHER WAY AROUND: NEGATE DELTA Y MOV R5,R2 ;START AT FINAL Y POSITION 2$: INC R3 ;ADD ONE FOR LOOP COUNT 3$: TSTB (R0) ;CHECK VT01 READY BPL 3$ ;WAIT FOR IT MOV R2,YREG(R0) ;SET Y POSITION BIS R1,(R0) ;INTENSIFY BIS #FAST,R1 ;SET FAST DEFLECTION FOR LATER POINTS INC R2 ;GO TO NEXT Y SOB R3,3$ ;DO ALL BR 7$ ;ALL DONE 4$: SUB YPOS,R3 ;CALCULATE DELTA Y BNE ANGLED ;NON-ZERO (ANGLED LINE) MOV R5,YREG(R0) ;HORIZONTAL LINE: SET Y POSITION MOV XPOS,R3 ;GET STARTING X POSITION TST R2 ;IS FINAL X BIGGER THAN INITIAL? BGT 5$ ;YES NEG R2 ;NO, NEGATE DELTA X MOV R4,R3 ;START AT FINAL X POSITION 5$: INC R2 ;ADD ONE FOR LOOP COUNT 6$: TSTB (R0) ;SEE IF VT01 IS READY BPL 6$ ;IF NOT, WAIT MOV R3,XREG(R0) ;SET X POSITION BIS R1,(R0) ;INTENSIFY BIS #FAST,R1 ;USE FAST DEFLECTION FOR SUCCESIVE POINTS INC R3 ;GO TO NEXT X POSITION SOB R2,6$ ;DO ALL OF THEM 7$: BR VECEND ;DONE ANGLED: MOV R4,-(SP) ;PUSH FINAL X MOV R5,-(SP) ;PUSH FINAL Y MOV R2,R4 ;GET DELTA X SXT R2 ;NOW R2=-1 IF NEGATIVE, 0 IF POSITIVE BPL 1$ ;FINAL X IS BIGGER THAN INITIAL NEG R4 ;OTHER WAY, NEGATE DELTA X 1$: MOV R3,R5 ;GET DELTA Y SXT R3 ;NOW R3=-1 IF NEGATIVE, 0 IF POSITIVE BPL 2$ ;FINAL Y IS BIGGER THAN INITIAL NEG R5 ;OTHER WAY, NEGATE DELTA Y 2$: BIS R1,R2 ;NOW R2=+1 OR -1 (SIGN OF DELTA X) BIS R1,R3 ;NOW R3=+1 OR -1 (SIGN OF DELTA Y) CMP R4,R5 ;IS ABS(DELTA X) .GT. ABS(DELTA Y)? BGT XLONG ;YES (X IS LONGER) MOV R0,-(SP) ;NO: PUSH ADDRESS... ADD #YREG,(SP) ;...OF Y REGISTER MOV R0,-(SP) ;PUSH ADDRESS... ADD #XREG,(SP) ;...OF X REGISTER MOV R3,-(SP) ;PUSH SIGN OF DELTA Y TST R2 ;IS DELTA X POSITIVE? BGT 3$ ;YES NEG (SP) ;NO, NEGATE DELTA Y MOV 10(SP),R2 ;STARTING X = FINAL X MOV 6(SP),R3 ;STARTING Y = FINAL Y BR 4$ 3$: MOV XPOS,R2 ;STARTING X = INITIAL X MOV YPOS,R3 ;STARTING Y = INITIAL Y 4$: CMP R4,R5 ;DOES ABS(DELTA X) = ABS(DELTA Y)? BNE YLONG ;NO (Y IS LONGER) MOV (SP)+,R4 ;YES (DIAGONAL): POP SIGN OF DELTA Y INC R5 ;SET UP LOOP COUNT 5$: TSTB (R0) ;CHECK VT01 READY BIT BPL 5$ ;WAIT IF NOT READY MOV R2,XREG(R0) ;SET X POSITION MOV R3,YREG(R0) ;SET Y POSITION BIS R1,(R0) ;INTENSIFY BIS #FAST,R1 ;SET UP FOR FAST DEFLECTION LATER INC R2 ;NEXT X POSITION ADD R4,R3 ;UPDATE Y IN PROPER DIRECTION SOB R5,5$ ;DO WHOLE LINE BR POPNEW ;FINISH UP XLONG: MOV R0,-(SP) ;PUSH ADDRESS... ADD #XREG,(SP) ;...OF X REGISTER MOV R0,-(SP) ;PUSH ADDRESS... ADD #YREG,(SP) ;...OF Y REGISTER MOV R2,-(SP) ;PUSH SIGN OF DELTA X TST R3 ;IS DELTA Y POSITIVE? BGT 1$ ;YES NEG (SP) ;NO, NEGATE DELTA X MOV 10(SP),R3 ;STARTING X = FINAL X MOV 6(SP),R2 ;STARTING Y = FINAL Y BR 2$ 1$: MOV XPOS,R3 ;STARTING X = INITIAL X MOV YPOS,R2 ;STARTING Y = INITIAL Y 2$: MOV R4,-(SP) ;SAVE ABS (DELTA X) MOV R4,-(SP) ;TWICE MOV R5,R4 ;GET ABS (DELTA Y) BR GENRAL ;GO TO GENERAL LINE DRAWER YLONG: MOV R5,-(SP) ;SAVE ABS (DELTA Y) MOV R5,-(SP) ;TWICE ; ; AT THIS POINT, REGISTERS ARE SET AS FOLLOWS (WHERE S=SHORT LEG, ; L=LONG LEG COORDINATE): ; R0 = CSR ADDRESS ; R1 = INTENSIFY BIT ; R2 = STARTING S VALUE ; R3 = STARTING L VALUE ; R4 = ABS(DELTA S) ; (SP) = ABS(DELTA L) ; 2(SP) = ABS(DELTA L) ; 4(SP) = SIGN OF DELTA L (+1 OR -1) ; 6(SP) = S REGISTER ADDRESS ; 10(SP) = L REGISTER ADDRESS ; GENRAL: ASL (SP) ;MULTIPLY ABS(DELTA L) BY 2 (AVOID ;DIVIDE OVERFLOW) CLR R5 ;LOW ORDER PART OF ABS(DELTA S) IS ZERO DIV (SP)+,R4 ;DIVIDE 65536*ABS(DELTA S) BY ;2*ABS(DELTA L) ASL R4 ;MULTIPLY BY 2 GIVING 65536 * ;ABS(DELTA S) / ABS(DELTA L) MOV (SP)+,R5 ;GET ABS(DELTA L) MOV R4,-(SP) ;PUSH RESULT OF DIVIDE (LOW ORDER S ;INCREMENT) CLR R4 ;CLEAR LOW ORDER S VALUE INC R5 ;ADD ONE FOR LOOP COUNT ; ; REGISTERS NOW ARE SET AS FOLLOWS: ; R0 = CSR ADDRESS ; R1 = INTENSIFY BIT ; R2 = HIGH ORDER S VALUE ; R3 = L VALUE ; R4 = LOW ORDER S VALUE ; R5 = LOOP COUNT ; (SP) = LOW ORDER S INCREMENT ; 2(SP) = L INCREMENT (+1 OR -1) ; 4(SP) = S REGISTER ADDRESS ; 6(SP) = L REGISTER ADDRESS ; 1$: TSTB (R0) ;CHECK FOR READY STATUS BPL 1$ ;IF NOT, WAIT FOR IT MOV R2,@4(SP) ;PUT S VALUE INTO S REGISTER MOV R3,@6(SP) ;PUT L VALUE INTO L REGISTER BIS R1,(R0) ;INTENSIFY BIS #FAST,R1 ;SET FAST DEFLECTION FOR LATER POINTS ADD 2(SP),R3 ;UPDATE L VALUE TST R4 ;WAS LOW ORDER S .GT. 32767? BPL 2$ ;NO DEC R2 ;YES, UNDO THE ROUND-UP DONE LAST TIME 2$: ADD (SP),R4 ;UPDATE LOW ORDER S BPL 3$ ;LESS THAN 32767 INC R2 ;GREATER, ROUND UP HIGH ORDER S 3$: ADC R2 ;ADD CARRY TO HIGH ORDER ALSO SOB R5,1$ ;LOOP OVER ALL POINTS CMP (SP)+,(SP)+ ;REMOVE INCREMENTS FROM STACK POPNEW: CMP (SP)+,(SP)+ ;REMOVE X,Y REGISTER ADDRESSES FROM STACK MOV (SP)+,R5 ;RESTORE FINAL Y VALUE MOV (SP)+,R4 ;RESTORE FINAL X VECEND: MOV R4,XPOS ;SET NEW X POSITION MOV R5,YPOS ;SET NEW Y POSITION RTS PC ;DONE ; .SBTTL POWER-UP & CURSOR DISPLAY AST, INTERRUPT SERVICE ROUTINE ; PWRUP: MOV R0,-(SP) ;SAVE R0 MOV PUDPTR,R0 ;GET PUD ADDRESS MOV U.DA(R0),R0 ;NOW VT01 CSR ADDRESS MOV MODE,(R0) ;SET PROPER MODE TSTB INTRON ;IS INTERRUPT SUPPOSED TO BE ON? BEQ 1$ ;NO BIS #INTR,(R0) ;YES, SET INTERRUPT ENABLE BIT TOO 1$: MOV (SP)+,R0 ;RESTORE R0 ASTX$S ;AST EXIT ; CURDSP: MOV R0,(SP) ;SAVE R0 (DON'T NEED EVENT FLAG NO.) MOV PUDPTR,R0 ;GET PUD ADDRESS MOV U.C2(R0),CRSDPB+M.KTMG;SET CURSOR BLINK TIME (FROM PUD) MOV U.DA(R0),R0 ;GET VT01 CSR ADDRESS TSTB (R0) ;IS VT01 READY? BPL 1$ ;NO, DON'T DRAW CURSOR THIS TIME MOV CXPOS,XREG(R0) ;SET X POSITION REGISTER MOV CYPOS,YREG(R0) ;ALSO Y REGISTER MOV MODE,(R0) ;SET PROPER MODE BIS #INTN,(R0) ;INTENSIFY 1$: TST CURFLG ;IS CURSOR STILL TURNED ON? BEQ 2$ ;NO DIR$ #CRSDPB ;YES, MARK TIME FOR ANOTHER BLINK 2$: MOV (SP)+,R0 ;RESTORE R0 ASTX$S ;EXIT AST ; VTINT: MOV R0,-(SP) ;SAVE REGISTERS MOV R1,-(SP) MOV PUDPTR,R0 ;GET PUD ADDRESS CLRB INTRON ;CLEAR "INTERRUPT ON" FLAG BIC #INTR,@U.DA(R0) ;TURN OFF INTERRUPT MOV #VTEFM1,R1 ;VT01 READY EVENT FLAG MASK WORD 1 JSR PC,@#..STEF ;SET EVENT FLAG MOV (SP)+,R1 ;RESTORE REGISTERS MOV (SP)+,R0 JMP @#..INTX ;TAKE INTERRUPT EXIT ; .SBTTL DISPATCH TABLE FOR CONTROL CHARS; CARRIAGE CONTROL TABLE ; CNTRLS: .WORD NULL ;(000) NUL .WORD TOPLFT ;(001) SOH .WORD TOPRGT ;(002) STX .WORD OPWAIT ;(003) ETX .WORD INIT ;(004) EOT .WORD TOP ;(005) ENQ .WORD CURSCU ;(006) ACK .WORD INCSIZ ;(007) BEL .WORD BACKSP ;(010) BS .WORD TAB ;(011) HT .WORD LINEFD ;(012) LF .WORD VERTAB ;(013) VT .WORD FORMFD ;(014) FF .WORD LEFT ;(015) CR .WORD NONSTR ;(016) SO .WORD STORE ;(017) SI .WORD UPTAB ;(020) DLE .WORD UPLINE ;(021) DC1 .WORD BKTAB ;(022) DC2 .WORD RIGHT ;(023) DC3 .WORD DECSIZ ;(024) DC4 .WORD CURSOF ;(025) NAK .WORD BOTTOM ;(026) SYN .WORD RESSIZ ;(027) ETB .WORD ERASE ;(030) CAN .WORD BOTRGT ;(031) EM .WORD BOTLFT ;(032) SUB .WORD ESCAPE ;(033) ESC .WORD SETSIZ ;(034) FS .WORD VECTOR ;(035) GS .WORD MOVE ;(036) RS .WORD CURSOR ;(037) US .WORD SPACE ;(040) SP ; ; TABLE OF CARRIAGE CONTROL CHARACTERS: ; CARCTL: .BYTE 0 ;NO CARRIAGE CONTROL .ASCII '$+01' ;STANDARD CARRIAGE CONTROLS NCARCT = .-CARCTL ;NO. OF CARRAIGE CONTROLS RECOGNIZED .EVEN ; .SBTTL CHARACTER GENERATOR MASK TABLE ; ; CODES 000 TO 037 (NORMALLY CONTROL CHARACTERS) ARE VISUALIZED AS RUNES ; FROM THE "ANGERTHAS MORIA". ; CHRTBL: .BYTE 376,004,010,360,000 ;(000) SHORT "A" RUNE .BYTE 376,024,050,360,000 ;(001) LONG "A" RUNE .BYTE 376,042,124,210,000 ;(002) "B" RUNE .BYTE 376,020,040,100,200 ;(003) "CH" RUNE .BYTE 376,024,050,120,040 ;(004) "D" RUNE .BYTE 376,010,020,040,376 ;(005) SHORT "E" RUNE .BYTE 000,010,024,376,000 ;(006) "F" RUNE .BYTE 376,024,022,010,006 ;(007) "G" RUNE .BYTE 202,104,050,020,000 ;(010) "H" RUNE .BYTE 104,104,174,104,104 ;(011) "I" RUNE .BYTE 376,030,024,042,300 ;(012) "J" RUNE .BYTE 376,020,020,010,006 ;(013) "K" RUNE .BYTE 300,040,376,010,006 ;(014) "L" RUNE .BYTE 376,124,050,000,000 ;(015) "M" RUNE .BYTE 016,020,376,020,016 ;(016) "N" RUNE .BYTE 360,010,004,010,360 ;(017) SHORT "O" RUNE .BYTE 376,024,010,000,000 ;(020) "P" RUNE .BYTE 376,004,010,004,002 ;(021) "KW" RUNE .BYTE 010,004,376,004,010 ;(022) "R" RUNE .BYTE 200,100,076,100,200 ;(023) "S" RUNE .BYTE 376,004,010,020,040 ;(024) "T" RUNE .BYTE 210,124,042,124,210 ;(025) SHORT "U" RUNE .BYTE 210,124,042,376,000 ;(026) "V" RUNE .BYTE 010,024,342,024,010 ;(027) "W" RUNE .BYTE 006,010,020,000,376 ;(030) "KH" RUNE .BYTE 174,010,020,040,174 ;(031) "Y" RUNE .BYTE 200,100,376,100,200 ;(032) "Z" RUNE .BYTE 376,024,050,120,376 ;(033) LONG "E" RUNE .BYTE 360,010,374,010,360 ;(034) SPECIAL "O" RUNE ; (AS IN AUGHT, LOG) .BYTE 040,020,010,004,376 ;(035) "TH" RUNE .BYTE 020,252,104,252,020 ;(036) LONG "U" RUNE ; (AS IN RULE, TOOL) .BYTE 210,124,342,124,210 ;(037) SPECIAL "U" RUNE ; (AS IN BOOK) ; ; CODE 040 IS VISUALIZED AS A TRIANGLE, CODES 041 TO 077 AS SPECIAL ; ASCII CHARACTERS ; .BYTE 100,120,104,120,100 ;(040) TRIANGLE .BYTE 000,000,276,000,000 ;(041) ! .BYTE 000,016,000,016,000 ;(042) " .BYTE 050,376,050,376,050 ;(043) # .BYTE 110,124,376,124,044 ;(044) $ .BYTE 306,046,020,310,306 ;(045) % .BYTE 154,222,254,100,240 ;(046) & .BYTE 010,014,006,002,000 ;(047) CLOSING SINGLE QUOTE .BYTE 000,070,104,202,000 ;(050) ( .BYTE 000,202,104,070,000 ;(051) ) .BYTE 050,020,174,020,050 ;(052) * .BYTE 020,020,174,020,020 ;(053) + .BYTE 000,000,240,140,000 ;(054) , .BYTE 020,020,020,020,020 ;(055) - .BYTE 000,000,300,300,000 ;(056) . .BYTE 300,040,020,010,006 ;(057) / .BYTE 174,242,222,212,174 ;(060) 0 .BYTE 000,204,376,200,000 ;(061) 1 .BYTE 344,222,222,222,214 ;(062) 2 .BYTE 104,202,222,222,154 ;(063) 3 .BYTE 060,050,044,376,040 ;(064) 4 .BYTE 116,212,212,212,162 ;(065) 5 .BYTE 170,224,222,222,140 ;(066) 6 .BYTE 002,342,022,012,006 ;(067) 7 .BYTE 154,222,222,222,154 ;(070) 8 .BYTE 014,222,222,122,074 ;(071) 9 .BYTE 000,000,154,154,000 ;(072) : .BYTE 000,000,254,154,000 ;(073) ; .BYTE 020,050,104,202,000 ;(074) < .BYTE 050,050,050,050,050 ;(075) = .BYTE 000,202,104,050,020 ;(076) > .BYTE 000,004,002,262,014 ;(077) ? ; ; CODES 100 TO 137 ARE UPPER CASE LETTERS ; .BYTE 174,202,272,252,074 ;(100) @ .BYTE 370,044,042,044,370 ;(101) A .BYTE 376,222,222,222,154 ;(102) B .BYTE 174,202,202,202,104 ;(103) C .BYTE 202,376,202,202,174 ;(104) D .BYTE 376,222,222,202,202 ;(105) E .BYTE 376,022,022,002,002 ;(106) F .BYTE 174,202,202,222,362 ;(107) G .BYTE 376,020,020,020,376 ;(110) H .BYTE 000,202,376,202,000 ;(111) I .BYTE 100,200,200,200,176 ;(112) J .BYTE 376,020,050,104,202 ;(113) K .BYTE 376,200,200,200,200 ;(114) L .BYTE 376,004,030,004,376 ;(115) M .BYTE 376,004,010,020,376 ;(116) N .BYTE 376,202,202,202,376 ;(117) O .BYTE 376,022,022,022,014 ;(120) P .BYTE 174,202,242,102,274 ;(121) Q .BYTE 376,022,062,122,214 ;(122) R .BYTE 104,212,222,242,104 ;(123) S .BYTE 002,002,376,002,002 ;(124) T .BYTE 176,200,200,200,176 ;(125) U .BYTE 016,060,300,060,016 ;(126) V .BYTE 376,100,040,100,376 ;(127) W .BYTE 306,050,020,050,306 ;(130) X .BYTE 006,010,360,010,006 ;(131) Y .BYTE 302,242,222,212,206 ;(132) Z .BYTE 000,376,202,202,000 ;(133) [ .BYTE 006,010,020,040,300 ;(134) \ .BYTE 000,202,202,376,000 ;(135) ] .BYTE 040,020,010,020,040 ;(136) CARROT .BYTE 200,200,200,200,200 ;(137) UNDERSCORE ; ; CODES 140 TO 176 ARE LOWER CASE LETTERS; CODE 177 IS VISUALIZED ; AS A SOLID BOX ; .BYTE 000,002,006,014,010 ;(140) OPENING SINGLE QUOTE .BYTE 100,250,250,250,120 ;(141) SMALL "A" .BYTE 000,366,210,210,160 ;(142) SMALL "B" .BYTE 000,160,210,210,220 ;(143) SMALL "C" .BYTE 000,160,210,210,366 ;(144) SMALL "D" .BYTE 000,160,250,250,260 ;(145) SMALL "E" .BYTE 010,374,012,002,004 ;(146) SMALL "F" .BYTE 020,250,250,250,324 ;(147) SMALL "G" .BYTE 000,366,010,010,360 ;(150) SMALL "H" .BYTE 000,220,364,200,000 ;(151) SMALL "I" .BYTE 000,100,200,200,172 ;(152) SMALL "J" .BYTE 376,040,060,110,200 ;(153) SMALL "K" .BYTE 000,202,376,200,000 ;(154) SMALL "L" .BYTE 370,010,360,010,360 ;(155) SMALL "M" .BYTE 000,370,010,010,360 ;(156) SMALL "N" .BYTE 160,210,210,210,160 ;(157) SMALL "O" .BYTE 000,330,050,050,020 ;(160) SMALL "P" .BYTE 010,024,024,170,200 ;(161) SMALL "Q" .BYTE 010,360,010,010,020 ;(162) SMALL "R" .BYTE 020,250,250,250,100 ;(163) SMALL "S" .BYTE 010,376,210,200,100 ;(164) SMALL "T" .BYTE 000,170,200,200,370 ;(165) SMALL "U" .BYTE 070,100,200,100,070 ;(166) SMALL "V" .BYTE 370,100,040,100,370 ;(167) SMALL "W" .BYTE 210,120,040,120,210 ;(170) SMALL "X" .BYTE 030,240,240,240,130 ;(171) SMALL "Y" .BYTE 210,310,250,230,210 ;(172) SMALL "Z" .BYTE 020,020,154,202,202 ;(173) OPENING BRACES .BYTE 000,000,376,000,000 ;(174) VERTICAL BAR .BYTE 202,202,154,020,020 ;(175) CLOSING BRACES .BYTE 060,010,020,040,030 ;(176) TILDA (SQUIGGLE) .BYTE 376,376,376,376,376 ;(177) BLACK BOX ; .SBTTL UNIT ID TABLE (UIT) AND FUNCTION DISPATCH TABLE (FDT) ; VTUIT: .WORD VTFDT ;POINTER TO FUNCTION DISPATCH TABLE .BYTE 1,0 ;NO. OF UNITS = 1 .WORD 0,0,0 ;RESERVED PUDPTR: .WORD VTUNIT ;UNIT NO. (BECOMES ADDRESS OF PUD) NRNA: .WORD 0 ;NORMAL REQUEST NODE ADDRESS .WORD 0 ;EXPRESS REQUEST NODE ADDRESS ; .MACRO FD L,H,ADDR ;FDT TABLE ENTRIES .BYTE L,H .WORD ADDR .ENDM ; VTFDT = .-4 ;NO SEND/RECV; OVERLAY LAST 2 UIT WORDS FUN0: FD 000,000,SPECFN ;SPECIAL FUNCTIONS (0) FUNSZ = .-FUN0 ;FDT ENTRY LENGTH FD 010,162,WRITE ;WRITE LOGICAL (1) FD 010,161,UNRFN ;READ LOGICAL (2) FD 020,160,ATTACH ;ATTACH (3) FD 020,160,DETACH ;DETACH (4) FD 010,000,UNRFN ;CONTROL (5) FD 140,160,UNRFN ;(6) FD 140,160,UNRFN ;(7) FD 140,160,UNRFN ;(10) FD 140,160,UNRFN ;FIND FILE (11) FD 140,160,UNRFN ;(12) FD 140,160,UNRFN ;REMOVE FILE (13) FD 140,160,UNRFN ;ENTER FILE (14) FD 140,161,IOSUCC ;ACCESS FOR READ (15) FD 140,163,IOSUCC ;ACCESS FOR WRITE (16) FD 140,167,IOSUCC ;ACCESS FOR EXTEND (17) FD 100,160,IOSUCC ;DEACCESS (20) FD 100,161,UNRFN ;READ VIRTUAL (21) FD 100,162,WRITE ;WRITE VIRTUAL (22) NFUNS = <.-FUN0>/FUNSZ ;NUMBER OF FUNCTIONS ; .SBTTL DIRECTIVE PARAMETER BLOCKS AND VARIABLES ; PFDPB: SPRA$ PWRUP ;SET UP POWER FAIL AST STEDPB: SETF$ EREF ;SET ERASE INTERVAL DONE FLAG CMTDPB: CMKT$ ;CANCEL ALL PENDING MARK TIMES CRSDPB: MRKT$ ,0,1,CURDSP ;MARK TIME WITH AST FOR BLINKING CURSOR TIMDPB: MRKT$ TOEF,0,3 ;MARK TIME FOR HANDLER TIMEOUT CLFDPB: CLEF$ OPEF ;CLEAR OPERATOR ACTION EVENT FLAG IDLDPB: WTLO$ 4,;WAIT FOR SOME FLAGS CANDPB: CMKT$ ,CURDSP ;CANCEL CURSOR BLINK MARK TIME CTODPB: CMKT$ TOEF ;CANCEL HANDLER TIMEOUT MARK TIME VTWDPB: WTLO$ 0,XREFM1!VTEFM1 ;WAIT FOR VT01 READY (OR EXPRESS REQUEST) OPWDPB: WTLO$ 4,;WAIT FOR OPERATOR ACTION FLAG ;(OR EXPRESS REQUEST) ERWDPB: WTLO$ 0,XREFM1!EREFM1 ;WAIT FOR ERASE INTERVAL OVER ;(OR EXPRESS REQUEST) ; ; (NOTE: THE PURPOSE OF THE ERASE INTERVAL WAIT IS TO PREVENT A ; SECOND ERASE FROM FOLLOWING AN ORIGINAL ERASE PRIOR TO TWICE THE ; ERASE TIME (SINCE THE ERASE TIMER HARDWARE IN THE VT01 IS NOT ; DEADTIMELESS AND IS INSENSITIVE FOR 1/2 SECOND MORE THAN THE ERASE ; TIME ALONE). ; ERIDPB: MRKT$ EREF,2,2 ;MARK TIME FOR 2 SECONDS AFTER AN ERASE ; ; VARIABLES: ; EXITFL: .BYTE 0 ;HANDLER AWAITING EXIT INTRON: .BYTE 0 ;INTERRUPT ENABLE IS ON COUNTR: .WORD 0 ;CHARACTER COUNTER CURFLG: .WORD 0 ;CURSOR ON FLAG POINTR: .WORD 0 ;BUFFER POINTER BUFBEG: .WORD 0 ;ADDRESS OF START OF BUFFER LFFLAG: .BYTE 0 ;SECOND LINEFEED NEEDED FLAG CRFLAG: .BYTE 0 ;FINAL CARRIAGE RETURN NEEDED FLAG MODE: .WORD 0 ;VT01 MODE (STORAGE/NON-STORAGE) TXTSIZ: .WORD 0 ;TEXT GRID SIZE IN VT01 UNITS XPOS: .WORD 0 ;CURRENT X POSITION YPOS: .WORD 0 ;CURRENT Y POSITION CXPOS: .WORD 0 ;CURSOR X POSITION CYPOS: .WORD 0 ;CURSOR Y POSITION ; .END VTSTRT