mirror of
https://github.com/PDP-10/stacken.git
synced 2026-02-01 14:22:04 +00:00
2265 lines
68 KiB
Plaintext
2265 lines
68 KiB
Plaintext
TITLE DPY MODULE TO MAKE CRT DISPLAYS EASY
|
||
SUBTTL DEFINITIONS
|
||
|
||
|
||
|
||
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
|
||
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
|
||
;
|
||
;COPYRIGHT (C) 1976,1977,1978,1979 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
|
||
|
||
|
||
|
||
;THIS MODULE IS USED TO PRODUCE A CONSTANTLY UPDATING DISPLAY.
|
||
;COMMUNICATION BETWEEN IT AND THE CALLING PROGRAM IS BY LUUOS. THIS
|
||
;MODULE CAN RUN ON VARIOUS KINDS OF TERMINALS. THE FILE DPYDEF.MAC
|
||
;CONTAINS ALL OF THE NECESSARY DEFINITIONS.
|
||
|
||
|
||
|
||
TWOSEG 400000 ;ALWAYS MAKE PROGRAM TWO SEGMENTS
|
||
SALL ;MAKE GOOD LOOKING MACROS
|
||
ENTRY DPYUUO ;DEFINE ENTRY POINT
|
||
INTERN DPYTAB ;AND THE TABLE
|
||
SEARCH DPYDEF ;GET BIT DEFINITIONS
|
||
|
||
|
||
|
||
VERSION==3 ;THIRD VERSION OF DPY
|
||
EDIT==170 ;EDIT NUMBER
|
||
|
||
|
||
IFNDEF FTDEC20,<FTDEC20==0> ;ON FOR TOPS-20, OFF FOR TOPS-10
|
||
|
||
|
||
|
||
DEFINE IF10,<IFE FTDEC20> ;SHORTHAND CONDITIONALS
|
||
DEFINE IF20,<IFN FTDEC20>
|
||
|
||
|
||
|
||
IF10,< SEARCH UUOSYM > ;IF TOPS-10, GET SYMBOLS
|
||
IF20,< SEARCH MONSYM > ;IF TOPS-20, GET SYMBOLS
|
||
|
||
SUBTTL ACCUMULATORS AND FLAGS
|
||
|
||
|
||
|
||
|
||
;ACCUMULATORS. THE USER AC'S ARE ALWAYS PRESERVED. AC "U" IS ASSUMED
|
||
;TO BE THE LAST NON-STACK AC ALWAYS. IF ANOTHER AC IS EVER DEFINED,
|
||
;THEN ALSO CHANGE THE AC SAVING AREAS AT THE END OF THE PROGRAM.
|
||
|
||
|
||
F=0 ;FLAG BITS
|
||
T1=1 ;TEMPORARY USE
|
||
T2=2
|
||
T3=3
|
||
T4=4
|
||
X=5 ;INDEX TO DATA TABLE
|
||
C=6 ;CHARACTER HOLDING
|
||
A=7 ;USER'S LUUO AND ADDRESS TO GET WORDS FROM
|
||
L=10 ;PRESENT LINE NUMBER BEING OUTPUT TO
|
||
N=11 ;PRESENT COLUMN NUMBER BEING OUTPUT TO
|
||
B=12 ;BYTE POINTER INTO SCREEN ARRAY
|
||
U=13 ;ADDRESS OF TERMINAL BLOCK
|
||
P=17 ;STACK POINTER
|
||
|
||
|
||
|
||
;FLAGS IN RIGHT HALF OF AC F. ALL OF THESE BITS ARE TERMINAL
|
||
;CHARACTERISTIC FLAGS, SET WHEN INITIALIZING THE TERMINAL TYPE.
|
||
|
||
|
||
FR.XBY==1 ;IN ADDRESSING, X COORDINATE GOES BEFORE Y
|
||
FR.TAB==2 ;TERMINAL HAS NORMAL TAB STOPS
|
||
FR.ELC==4 ;TERMINAL DOES CRLF WHEN LAST COLUMN IS REACHED
|
||
FR.RAI==10 ;LOWER CASE IS SAME AS UPPER CASE
|
||
FR.ANS==20 ;THIS IS AN ANSI STANDARD TERMINAL
|
||
FR.TTY==40 ;THIS IS A NON-VIDEO TERMINAL
|
||
|
||
|
||
;FLAGS IN THE LEFT HALF OF AC F. THESE BITS ARE STATUS BITS.
|
||
|
||
|
||
FL.OUT==1 ;THERE HAS BEEN OUTPUT IN CURRENT WINDOW
|
||
FL.PNT==2 ;TERMINAL NEEDS TO HAVE OUTPUT FORCED LATER
|
||
FL.ACR==4 ;WE ARE IN AUTO-CARRIAGE RETURN MODE
|
||
FL.AC2==10 ;SAME AS FL.ACR, BUT TEMPORARY
|
||
FL.INI==20 ;INI$ FUNCTION HAS BEEN DONE
|
||
FL.OKU==40 ;IT IS OK TO UPDATE THE SAME LOCATION TWICE
|
||
FL.NZP==100 ;DON'T CLEAR REST OF WINDOWS
|
||
FL.NOS==200 ;DON'T SAVE USER ACS WHEN GIVING CHARS TO HIM
|
||
|
||
;USEFUL CHARACTER DEFINITIONS:
|
||
|
||
|
||
LF==12 ;LINE FEED
|
||
CR==15 ;CARRIAGE RETURN
|
||
TAB==11 ;TAB
|
||
ALT==33 ;STANDARD ALTMODE
|
||
SP==40 ;SPACE
|
||
RUB==177 ;RUBOUT
|
||
NUL==0 ;NULL
|
||
|
||
|
||
|
||
;OTHER DEFINITIONS:
|
||
|
||
|
||
|
||
DEFINE CL(CHAR),<"CHAR"-100> ;TO DEFINE CONTROL CHARACTERS
|
||
OPDEF PJRST [JRST] ;USUAL
|
||
|
||
|
||
TTYLEN==^D20 ;SIZE OF TERMINAL BUFFER
|
||
UPDATE==200 ;FLAG MEANING CHARACTER NEEDS UPDATING
|
||
PRETTY==3 ;NUMBER OF CHARS EXTRA FOR GOOD LOOKS
|
||
DFTTRM==.ASR33 ;DEFAULT TERMINAL TYPE
|
||
|
||
SUBTTL MACRO USED TO DEFINE TERMINAL TYPES
|
||
|
||
|
||
|
||
;THE FOLLOWING MACRO IS USED TO DEFINE THE PARAMETERS OF EACH TERMINAL
|
||
;WHICH WE CAN RUN ON. IT EXPANDS INTO A BLOCK OF WORDS WHICH CONTAIN
|
||
;THE CONSTANTS APPLICABLE TO EACH PARTICULAR TERMINAL.
|
||
|
||
|
||
DEFINE TTY(NAME,TYP10,TYP20,LENGTH,WIDTH,FLAGS,MAXCHR,EATCHR,LFTSEQ,
|
||
RHTSEQ,UPSEQ,DWNSEQ,CRSEQ,HOMSEQ,CLRSEQ,EOLSEQ,EOFSEQ,ADRSEQ,AD2SEQ,
|
||
AD3SEQ,XOFFV,YOFFV),<
|
||
|
||
|
||
.'NAME: ADDR==. ;;DEFINE DATA BLOCK ADDRESS
|
||
|
||
XX TYP,<TYPNUM TYP10,TYP20> ;;TERMINAL TYPE NUMBER
|
||
XX FLAG,<FLG <FLAGS>> ;;FLAGS
|
||
XX LEN,<DFT ^D<LENGTH-1>,^D23> ;;LENGTH OF SCREEN
|
||
|
||
IFG <VAL+1-MAXLEN>,<MAXLEN==VAL+1> ;;REMEMBER NEW MAX
|
||
VAL2==VAL+1 ;;REMEMBER VALUE
|
||
|
||
XX WID,<DFT ^D<WIDTH-1>,^D79> ;;WIDTH OF SCREEN
|
||
|
||
VAL==<VAL+4>/4 ;;GET WORDS PER LINE
|
||
|
||
XX WRDS,<EXP VAL> ;;NUMBER OF WORDS PER LINE
|
||
|
||
IFG <VAL-MAXWID>,<MAXWID==VAL> ;;REMEMBER NEW MAX
|
||
VAL==VAL*VAL2 ;;COMPUTE STORAGE NEEDED
|
||
IFG <VAL-MAXARE>,<MAXARE==VAL> ;REMEMBER NEW MAX
|
||
|
||
XX MAXC,<DFT MAXCHR,176> ;;HIGHEST PRINTING CHARACTER
|
||
XX EATC,<DFT EATCHR," "> ;;CHAR WHICH EATS
|
||
XX LEFT,SEQ <LFTSEQ> ;;SEQUENCE TO MOVE LEFT
|
||
XX RHT,SEQ <RHTSEQ> ;;SEQUENCE TO MOVE RIGHT
|
||
XX UP,SEQ <UPSEQ> ;;SEQUENCE TO MOVE UP
|
||
XX DOWN,SEQ <DWNSEQ> ;;SEQUENCE TO MOVE DOWN
|
||
XX CR,SEQ <CRSEQ> ;;SEQ TO DO A CARRIAGE RETURN
|
||
XX HOM,SEQ <HOMSEQ> ;;SEQUENCE TO HOME UP
|
||
XX CLR,SEQ <CLRSEQ> ;;SEQUENCE TO HOME UP AND CLEAR
|
||
XX EOL,SEQ <EOLSEQ> ;;SEQUENCE TO ERASE END OF LINE
|
||
XX EOF,SEQ <EOFSEQ> ;;SEQUENCE TO ERASE END OF FORM
|
||
XX ADR,SEQ <ADRSEQ> ;;SEQUENCE TO START ADDRESSING
|
||
XX ADR2,SEQ <AD2SEQ> ;;SEQUENCE FOR FILLS BETWEEN X AND Y
|
||
XX ADR3,SEQ <AD3SEQ> ;;SEQUENCE FOR FILLS AFTER ADDRESSING
|
||
XX XOFF,<DFT XOFFV,40> ;;OFFSET FOR X COORDINATE
|
||
XX YOFF,<DFT YOFFV,40> ;;OFFSET FOR Y COORDINATE
|
||
|
||
APPEND < XWD [ASCIZ/NAME/],.'NAME
|
||
> ;;ADD THIS TERMINAL TO CONCATENATED TEXT
|
||
>
|
||
|
||
;DEFINITION OF EMBEDDED XX MACRO. FIRST ARGUMENT DEFINES THE
|
||
;OFFSET INTO THE BLOCK. SECOND ARGUMENT DEFINES THE DATA FOR
|
||
;THIS LOCATION.
|
||
|
||
|
||
DEFINE XX(OFFSET,DATA),<
|
||
|
||
T.'OFFSET==.-ADDR ;;DEFINE OFFSET INTO BLOCK
|
||
DATA ;;THEN STORE THE DATA
|
||
>
|
||
|
||
|
||
;NOW DEFINE THE IMBEDDED DFT MACRO, TO GENERATE AN OCTAL WORD.
|
||
;THE FIRST ARGUMENT IS THE SYMBOL NAME, THE SECOND ARGUMENT IS
|
||
;THE DEFAULT VALUE IF NO SYMBOL WAS GIVEN. THE SYMBOL VAL IS
|
||
;DEFINED AS THE RESULT OF THE MACRO.
|
||
|
||
|
||
|
||
DEFINE DFT(SYMBOL,VALUE),<
|
||
|
||
VAL==VALUE ;;FIRST USE THE DEFAULT VALUE
|
||
|
||
IFNB <SYMBOL>,< ;;IF A SYMBOL WAS GIVEN
|
||
VAL==SYMBOL ;;THEN USE IT INSTEAD
|
||
>
|
||
EXP VAL ;;THEN DUMP THE VALUE
|
||
>
|
||
|
||
;NOW DEFINE THE IMBEDDED FLG MACRO, TO GENERATE THE FLAG BITS
|
||
;FOR THE TERMINAL. IT TAKES ONE ARGUMENT, MADE UP OF A SEQUENCE
|
||
;OF FLAGS.
|
||
|
||
|
||
DEFINE FLG(BITS),<
|
||
|
||
BIT==0 ;;INITIALIZE BITS
|
||
|
||
IRP <BITS>,< ;;LOOP OVER ALL BITS
|
||
BIT==BIT!FR.'BITS ;;ADD IN NEW BIT TO PREVIOUS ONES
|
||
>
|
||
EXP BIT ;;DUMP THE FINAL RESULT
|
||
>
|
||
|
||
|
||
|
||
|
||
;NOW DEFINE THE TYPNUM MACRO, USED TO GENERATE THE PROPER TTY TYPE.
|
||
;THE FIRST ARGUMENT IS USED IF WE ARE RUNNING ON TOPS-10, THE SECOND
|
||
;ONE IF WE ARE RUNNING ON TOPS-20.
|
||
|
||
|
||
|
||
DEFINE TYPNUM(VAL10,VAL20),<
|
||
|
||
IF10,< EXP SIXBIT/VAL10/> ;IF TOPS-10, GENERATE THIS
|
||
IF20,< DFT VAL20,377777> ;;IF TOPS-20, GENERATE THIS
|
||
>
|
||
|
||
;NOW DEFINE THE IMBEDDED SEQ MACRO. IT TAKES ONE ARGUMENT,
|
||
;MADE UP OF A SEQUENCE OF CHARACTERS. A WORD IS GENERATED IN THE
|
||
;FORM ADDR,,N WHERE N IS THE NUMBER OF CHARACTERS, AND ADDRESS IS
|
||
;THE ADDRESS OF THE STRING OF CHARACTERS.
|
||
|
||
|
||
DEFINE SEQ(CHARS),<
|
||
|
||
CNT==0 ;;START COUNT AT ZERO
|
||
IRP <CHARS>,<CNT==CNT+1> ;;LOOP OVER CHARS COUNTING THEM
|
||
|
||
IFE CNT,< ;;IF NO CHARACTERS
|
||
EXP 0 ;;THEN PRODUCE JUST A ZERO WORD
|
||
>
|
||
|
||
IFN CNT,< ;;IF ANY CHARACTERS
|
||
XWD [ ;;START LITERAL
|
||
WORD==0 ;;INITIALIZE WORD TO ZERO
|
||
SHIFT==^D29 ;;INITIALIZE SHIFT VALUE
|
||
|
||
IRP <CHARS>,< ;;LOOP OVER ALL CHARS AGAIN
|
||
WORD==WORD+<<CHARS>_SHIFT> ;;ADD NEW CHAR INTO WORD
|
||
SHIFT==SHIFT-7 ;;LESSEN SHIFT BY A CHAR
|
||
|
||
IFL SHIFT,< ;;IF THE WORD IS FULL
|
||
EXP WORD ;;DUMP COMPLETED WORD OF CHARS
|
||
WORD==0 ;;RESET THE WORD
|
||
SHIFT==^D29 ;;AND THE SHIFT VALUE
|
||
>
|
||
> ;;END OF LOOP OVER CHARS
|
||
|
||
IFN <SHIFT-^D29>,< ;;SEE IF ANY PARTIAL WORD LEFT
|
||
EXP WORD ;;IF SO, DUMP IT TOO
|
||
>
|
||
],CNT ;;END LITERAL AND STORE COUNT
|
||
> ;;END OF IFN CNT CONDITIONAL
|
||
>
|
||
|
||
;THE FOLLOWING MACRO IS USED TO APPEND STRINGS TOGETHER. THE USE OF
|
||
;THIS IS IN GENERATING THE TTYTYP TABLE AFTER EACH TERMINAL HAS BEEN
|
||
;DEFINED.
|
||
|
||
|
||
|
||
DEFINE CONCAT(TEXT),< ;;MACRO TO APPEND NEW TEXT TO OLD
|
||
|
||
DEFINE APPEND(NEWTXT),< ;;REDEFINE OTHER MACRO
|
||
CONCAT (<TEXT''NEWTXT>) ;;WHICH DOES THE WORK
|
||
>
|
||
|
||
DEFINE STRING,< ;;AND DEFINE MACRO FOR WHOLE TEXT
|
||
TEXT
|
||
>
|
||
>
|
||
|
||
|
||
CONCAT ;INITIALIZE CONCATENATION MACROS
|
||
|
||
|
||
|
||
|
||
|
||
|
||
;FINALLY, INITIALIZE THE MAXIMUM VALUES OF THE WIDTH, LENGTH, AND AREA
|
||
;USED FOR ANY SCREEN. NEEDED TO ALLOCATE DATA FOR WORST CASE.
|
||
|
||
|
||
MAXLEN==0 ;INITIALIZE MAXIMUM LENGTH
|
||
MAXWID==0 ;INITIALIZE MAXIMUM WIDTH
|
||
MAXARE==0 ;INITIALIZE MAXIMUM AREA
|
||
|
||
;NOW DEFINE ALL THE TERMINALS WHICH WE CAN RUN ON. THE FOLLOWING TERMINAL
|
||
;NAMES MUST BE IN ALPHABETICAL ORDER!!!
|
||
|
||
|
||
|
||
|
||
TTY(ADM3A,,,24,80,,176,SP,CL(H),CL(L),CL(K),LF,CR,CL(^),CL(Z),,,
|
||
<ALT,"=">,,,SP,SP)
|
||
|
||
|
||
TTY(ASR33,ASR33,.TT33,25,71,TTY,176,SP,,SP,,LF,CR,
|
||
<CR,LF,LF>,<CR,LF,LF>,,,,,)
|
||
|
||
|
||
TTY(ASR35,ASR35,.TT35,25,71,<TAB,TTY>,176,SP,,SP,,LF,CR,
|
||
<CR,LF,LF>,<CR,LF,LF>,,,,,)
|
||
|
||
|
||
TTY(VT05,VT05,.TTV05,20,72,<TAB,RAI>,176,SP,CL(H),CL(X),
|
||
<CL(Z),RUB,RUB,RUB,RUB>,<LF,RUB,RUB,RUB,RUB>,CR,<CL(]),RUB,RUB,RUB,RUB>,
|
||
<CL(]),RUB,RUB,RUB,RUB,CL(_),RUB,RUB,RUB,RUB>,<CL(^),RUB,RUB,RUB,RUB>,
|
||
<CL(_),RUB,RUB,RUB,RUB>,CL(N),<NUL,NUL,NUL,NUL>,,SP,SP)
|
||
|
||
|
||
TTY(VT06,VT06,,25,72,RAI,176,SP,CL(H),CL(X),CL(Z),LF,CR,CL(]),
|
||
<CL(]),CL(_)>,CL(^),CL(_),,,,SP,SP)
|
||
|
||
|
||
TTY(VT100,VT100,.TT100,24,80,<TAB,ANSI>,176,SP,CL(H),<ALT,"[","C">,
|
||
<ALT,"[","A">,LF,CR,<ALT,"[","H">,<ALT,"[","H",ALT,"[","J">,
|
||
<ALT,"[","K">,<ALT,"[","J">,<ALT,"[">,,,,)
|
||
|
||
|
||
TTY(VT50,VT50,.TTV50,12,80,<TAB,RAI>,176,SP,CL(H),<ALT,"C">,<ALT,"A">,
|
||
LF,CR,<ALT,"H">,<ALT,"H",ALT,"J">,<ALT,"K">,<ALT,"J">,,,,SP,SP)
|
||
|
||
|
||
TTY(VT52,VT52,.TTV52,24,80,TAB,176,SP,CL(H),<ALT,"C">,<ALT,"A">,LF,CR,
|
||
<ALT,"H">,<ALT,"H",ALT,"J">,<ALT,"K">,<ALT,"J">,<ALT,"Y">,,,SP,SP)
|
||
|
||
|
||
TTY(VT61,VT61,.TTV61,24,80,TAB,176,SP,CL(H),<ALT,"C">,<ALT,"A">,LF,CR,
|
||
<ALT,"H">,<ALT,"H",ALT,"J">,<ALT,"K">,<ALT,"J">,<ALT,"Y">,,,SP,SP)
|
||
|
||
;NOW DEFINE THE TERMINAL TYPE TABLE, WHICH POINTS OFF TO EACH OF THE
|
||
;TERMINAL BLOCKS. THIS DATA TABLE IS IN THE FORMAT NEEDED FOR
|
||
;THE TBLUK JSYS.
|
||
|
||
|
||
|
||
XALL ;SHOW THE EXPANSION
|
||
|
||
|
||
TTYTYP: XWD TYPMAX,TYPMAX ;HEADER WORD FOR TABLE
|
||
STRING ;THE TERMINAL TYPES
|
||
|
||
|
||
TYPMAX==.-TTYTYP-1 ;NUMBER OF TERMINAL TYPES
|
||
|
||
|
||
SALL ;RETURN TO NORMAL LISTING
|
||
|
||
;THE FOLLOWING SIMPLE MACROS ARE USED TO DEFINE THE ERROR HANDLING
|
||
;INSTRUCTIONS. THE AC FIELD OF THE XCT INSTRUCTION IS THE ERROR
|
||
;CODE. THE INSTRUCTION XCT'D IS A SUBROUTINE CALLING INSTRUCTION.
|
||
|
||
|
||
DEFINE DIE(CODE),<
|
||
XCT <E..'CODE-ERRTAB>,DIEBIG ;;GO TO ERROR ROUTINE
|
||
>
|
||
|
||
|
||
|
||
DEFINE ERR(CODE,TEXT),<
|
||
E..'CODE: [ASCIZ/TEXT/] ;;THE MESSAGE FOR THE ERROR
|
||
>
|
||
|
||
SUBTTL DISPATCH ROUTINE
|
||
|
||
|
||
;HERE ON AN LUUO, TO SAVE THE AC'S, DISPATCH TO THE PROPER ROUTINE,
|
||
;RESTORE THE AC'S, AND GO BACK TO THE USER.
|
||
|
||
|
||
|
||
DPYUUO: MOVEM P,SAVEP ;SAVE PUSH-DOWN AC IN CASE OF ERRORS
|
||
MOVEM F,SAVEF ;SAVE AN AC
|
||
MOVE F,[T1,,SAVET1] ;SET UP FOR BLT
|
||
BLT F,SAVEU ;SAVE REST OF AC'S WE USE
|
||
MOVE A,.JBUUO## ;GRAB HIS UUO
|
||
LDB T1,[POINT 4,A,12] ;GRAB THE AC FIELD
|
||
CAILE T1,MAXUUO ;SEE IF LEGAL LUUO WAS GIVEN
|
||
DIE ILR ;NO, DIE
|
||
JUMPE T1,DOUUO ;IF INITIALIZATION, SKIP ON
|
||
MOVE X,@DP+$DPADR ;GET POINTER TO DATA AREA
|
||
DMOVE L,OURLN(X) ;RESTORE AC'S L AND N
|
||
DMOVE B,OURBU(X) ;RESTORE AC'S B AND U
|
||
MOVE F,OURF(X) ;GET OUR FLAGS
|
||
TLNN F,FL.INI ;HAVE WE BEEN INITIALIZED?
|
||
DIE ING ;NO, LOSE
|
||
DOUUO: PUSHJ P,@DSPTAB(T1) ;CALL SUBROUTINE
|
||
SKIPE OUTADR(X) ;PROGRAM INTERCEPTING OUTPUT?
|
||
PUSHJ P,USRLST ;YES, INDICATE THIS IS END OF IT
|
||
TLZE F,FL.PNT ;NEED TO FORCE OUTPUT?
|
||
PUSHJ P,PUNT ;YES, SEND OUT REMAINING STUFF
|
||
|
||
RETURN: MOVEM F,OURF(X) ;SAVE FLAGS
|
||
DMOVEM L,OURLN(X) ;SAVE AC'S L AND N
|
||
DMOVEM B,OURBU(X) ;SAVE AC'S B AND U
|
||
MOVSI U,SAVEF ;SET UP FOR BLT
|
||
BLT U,U ;RESTORE HIS AC'S
|
||
CPOPJ: POPJ P, ;RETURN
|
||
|
||
;TABLE OF FUNCTION CODES. THESE FUNCTIONS ARE DETERMINED BY THE
|
||
;AC FIELD OF THE LUUO.
|
||
|
||
|
||
DSPTAB: EXP FUNINI ;(0) INITIALIZE
|
||
EXP FUNSTR ;(1) STRING OUTPUT
|
||
EXP FUNCHR ;(2) CHARACTER OUTPUT
|
||
EXP FUNCHI ;(3) IMMEDIATE CHARACTER OUTPUT
|
||
EXP FUNSIZ ;(4) SET WINDOW SIZE
|
||
EXP FUNTAB ;(5) SET TABS
|
||
EXP FUNREF ;(6) REFRESH SCREEN
|
||
EXP FUNDPY ;(7) UPDATE SCREEN
|
||
EXP FUNSET ;(10) SET VARIOUS PARAMETERS
|
||
EXP FUNTTY ;(11) OUTPUT THINGS TO TTY
|
||
EXP FUNLOC ;(12) RETURN LOCATION OF NEXT OUTPUT
|
||
EXP FUNADR ;(13) MOVE TO GIVEN POSITION ON SCREEN
|
||
|
||
MAXUUO==.-DSPTAB-1 ;MAXIMUM LUUO ALLOWED
|
||
|
||
SUBTTL FUNCTION TO INITIALIZE
|
||
|
||
|
||
;FUNCTION WHICH SETS UP EVERYTHING SO THAT ON THE NEXT CALL TO OUR
|
||
;DPY ROUTINES, WE DO CORRECT THINGS. I.E., WE CLEAR ALL FLAGS, SET
|
||
;UP DEFAULT TABS, CLEAR THE STORED SCREEN, AND MAYBE ERASE SCREEN.
|
||
;CALL TO INITIALIZE IS:
|
||
;
|
||
; INI$ [FLAGS,,COUNT
|
||
; ARGS] ;INITIALIZE DPY
|
||
|
||
|
||
|
||
FUNINI: MOVSI F,FL.INI ;SET INITIALIZATION FLAG
|
||
PUSHJ P,INIUSR ;READ USER ARGUMENTS AND PROCESS THEM
|
||
HRR F,T.FLAG(U) ;SET UP FLAGS FOR TERMINAL
|
||
MOVE T1,T.LEN(U) ;GET LENGTH OF SCREEN
|
||
MOVEM T1,@DP+$DPLEN ;SAVE IT
|
||
MOVE T1,T.WID(U) ;GET WIDTH OF SCREEN
|
||
MOVEM T1,@DP+$DPWID ;SAVE IT TOO
|
||
MOVE T1,[POINT 7,TTYBUF(X)] ;GET TERMINAL POINTER
|
||
MOVEM T1,BUFPTR(X) ;INITIALIZE IT
|
||
SETZM BUFCNT(X) ;CLEAR COUNT OF CHARACTERS
|
||
PUSHJ P,DFTTAB ;SET UP DEFAULT TAB STOPS
|
||
PUSHJ P,SIZINI ;SET UP THE DEFAULT WINDOW
|
||
SETZM ZERBLK(X) ;GET SET
|
||
HRLI T1,ZERBLK(X) ;MAKE BLT POINTER...
|
||
HRRI T1,ZERBLK+1(X) ;TO CLEAR ALL PARAMETERS
|
||
BLT T1,ZEREND(X) ;DO IT
|
||
MOVE T1,[BYTE (9)SP,SP,SP,SP] ;SET UP SPACES
|
||
MOVEM T1,SCREEN(X) ;STORE IN SCREEN
|
||
HRRZM T1,TTYN(X) ;SET CURSER WAY OFF OF SCREEN
|
||
HRRZM T1,TTYL(X) ;SO IF NOT CLEARED, WILL ADDRESS OR HOME
|
||
HRLI T1,SCREEN(X) ;SET UP...
|
||
HRRI T1,SCREEN+1(X) ;BLT POINTER
|
||
BLT T1,SCREEN+MAXARE-1(X) ;MAKE WHOLE SCREEN SPACES
|
||
MOVE A,INIFLG ;GET BACK USER FLAGS
|
||
TRNN A,IN$NCL ;SHOULD WE CLEAR THE SCREEN?
|
||
JRST DOCLR ;YES, GO DO IT
|
||
POPJ P, ;NO, JUST RETURN
|
||
|
||
SUBTTL ROUTINE TO PROCESS USER ARGUMENTS FOR INI$ FUNCTION
|
||
|
||
|
||
|
||
|
||
;CALLED TO LOOK AT THE USER'S ARGUMENTS FOR THE INI$ FUNCTION, AND
|
||
;PROCESS THEM. THE MOST IMPORTANT FUNCTION DONE IS SETTING WHICH
|
||
;TERMINAL TYPE WE ARE RUNNING ON.
|
||
|
||
|
||
|
||
INIUSR: TRNN A,-1 ;WERE ARGUMENTS SUPPLIED?
|
||
MOVEI A,ZERO ;NO, THEN POINT TO DEFAULT ONE
|
||
MOVSI B,-ININUM ;GET READY FOR LOOP
|
||
|
||
INILP1: PUSHJ P,GETWRD ;READ ARGUMENT FOR NEXT ROUTINE
|
||
INILP2: PUSHJ P,@INITAB(B) ;THEN CALL ROUTINE
|
||
AOBJP B,CPOPJ ;RETURN IF DONE
|
||
SOSL INICNT ;USER HAVE ANY MORE ARGS?
|
||
JRST INILP1 ;YES, GET READ IT AND PROCESS IT
|
||
SETZ T1, ;NO, THEN DEFAULT TO ZERO
|
||
JRST INILP2 ;GO BACK FOR NEXT ROUTINE
|
||
|
||
|
||
|
||
INITAB: EXP INIHDR ;(0) THE HEADER WORD
|
||
EXP INIADR ;(1) THE ADDRESS OF THE RELOCATABLE DATA
|
||
EXP INIERR ;(2) ROUTINE TO GO TO ON ERROR
|
||
EXP INITTY ;(3) TERMINAL STRING
|
||
EXP INIJFN ;(4) THE JFN OR CHANNEL FOR OUTPUT
|
||
|
||
ININUM==.-INITAB ;NUMBER OF ARGUMENTS TOTAL
|
||
|
||
;HERE TO PROCESS THE HEADER WORD. THIS CONTAINS FLAGS AND THE COUNT
|
||
;OF REMAINING ARGUMENTS TO BE PROCESSED.
|
||
|
||
|
||
INIHDR: HLRZM T1,INIFLG ;SAVE THE FLAGS
|
||
HRRZM T1,INICNT ;AND THE COUNT OF ARGUMENTS
|
||
POPJ P, ;DONE
|
||
|
||
|
||
|
||
|
||
;HERE TO PROCESS THE ADDRESS OF THE RELOCATABLE DATA. THE USER CAN
|
||
;TELL US WHERE IN CORE TO STORE OUR DATA.
|
||
|
||
|
||
INIADR: SKIPN X,T1 ;DID HE GIVE AN ADDRESS?
|
||
MOVEI X,DATBEG ;NO, THEN USE OUR OWN
|
||
MOVEM X,DATADR ;REMEMBER THE LOCATION FOR LATER
|
||
POPJ P, ;DONE
|
||
|
||
|
||
|
||
|
||
;HERE TO PROCESS THE ERROR ADDRESS. THIS IS SO THAT IF THE INI$
|
||
;FUNCTION FAILS SOMEHOW, THE CALLER CAN RECOVER FROM THE ERROR.
|
||
|
||
|
||
INIERR: MOVEM T1,ERRADR(X) ;REMEMBER THE ERROR ADDRESS
|
||
POPJ P, ;DONE
|
||
|
||
|
||
|
||
|
||
|
||
;HERE TO PROCESS THE JFN (OR BUFFER,,CHANNEL) FOR OUTPUT. IF ZERO,
|
||
;WE HAVE TO ALLOCATE OUR OWN JFN (OR USE IONEOU). OTHERWISE, WE ARE
|
||
;TO USE THE SPECIFIED JFN FOR OUTPUT.
|
||
|
||
|
||
INIJFN: MOVEM T1,TTYJFN(X) ;SET UP JFN
|
||
POPJ P, ;RETURN
|
||
|
||
;HERE TO INITIALIZE THE TERMINAL TYPE. ZERO MEANS USE OUR CURRENT
|
||
;TERMINAL TYPE. FOR TOPS-20, 5B2 MEANS TERMINAL TYPE IS IN RIGHT HALF,
|
||
;OTHERWISE WE HAVE A POINTER TO AN ASCIZ STRING. FOR TOPS-10, THE
|
||
;SIXBIT TERMINAL NAME IS SUPPLIED IF NONZERO.
|
||
|
||
|
||
|
||
INITTY: IF20,<
|
||
|
||
JUMPE T1,FNDTYP ;ASK MONITOR FOR TYPE IF NOTHING GIVEN
|
||
HRRZ T2,T1 ;GET RIGHT HALF BY ITSELF
|
||
HLRZ T1,T1 ;AND LEFT HALF BY ITSELF TOO
|
||
CAIN T1,(5B2) ;IS THIS A TERMINAL TYPE NUMBER?
|
||
JRST FNDTTY ;YES, GO USE IT
|
||
CAIE T1,0 ;IS THIS AN ADDRESS?
|
||
CAIN T1,-1 ;OR THE DEFAULT POINTER?
|
||
TLOA T2,(POINT 7,) ;YES, GET STANDARD POINTER
|
||
HRL T2,T1 ;OTHERWISE RESTORE POINTER
|
||
MOVEI T1,TTYTYP ;POINT TO TABLE
|
||
TBLUK ;SEARCH FOR GIVEN STRING
|
||
TLNN T2,(TL%ABR!TL%EXM) ;FIND UNIQUE MATCH?
|
||
SKIPA U,[DFTTRM] ;NO, USE DEFAULT TERMINAL TYPE
|
||
HRRZ U,(T1) ;YES, SET UP POINTER FOR THIS TERMINAL
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
FNDTYP: MOVEI T1,.PRIOU ;WANT TO FIND OUTPUT TERMINAL TYPE
|
||
GTTYP ;READ IT
|
||
;THEN FALL INTO SEARCH CODE
|
||
>
|
||
|
||
IF10,< SKIPE T2,T1 ;SEE IF WE WERE GIVEN A NAME
|
||
JRST FNDTTY ;YES, GO SEARCH FOR IT
|
||
MOVE T2,[2,,T3] ;GET READY
|
||
MOVEI T3,.TOTRM ;TO READ TERMINAL TYPE
|
||
SETO T4, ;FOR OUR CONTROLLING TTY
|
||
TRMOP. T2, ;READ TYPE
|
||
JRST USEDFT ;FAILED, GO USE DEFAULT TERMINAL
|
||
>
|
||
|
||
|
||
|
||
;HERE WHEN T2 CONTAINS THE TERMINAL TYPE FOR TOPS-20, OR THE TERMINAL
|
||
;NAME FOR TOPS-10, TO SEARCH OUR TERMINAL DATA FOR THE RIGHT BLOCK.
|
||
|
||
|
||
FNDTTY: MOVSI T1,-TYPMAX ;GET READY FOR LOOP
|
||
HRRZ T3,TTYTYP+1(T1) ;GET ADDRESS OF NEXT TTY BLOCK
|
||
CAME T2,T.TYP(T3) ;FOUND THE RIGHT TYPE?
|
||
AOBJN T1,.-2 ;NO, KEEP LOOKING
|
||
SKIPL T1 ;FOUND IT?
|
||
USEDFT: SKIPA U,[DFTTRM] ;NO, GET DEFAULT TERMINAL BLOCK
|
||
HRRZ U,TTYTYP+1(T1) ;YES, THEN USE THAT BLOCK
|
||
POPJ P, ;RETURN
|
||
|
||
SUBTTL THE CHARACTER STORING ROUTINES
|
||
|
||
|
||
|
||
;THE FOLLOWING THREE CALLS ARE USED TO GIVE DPY THE CHARACTERS THE
|
||
;USER PROGRAM WANTS TO DISPLAY. STR$ PROCESSES A STRING, CHR$ PROCESSES
|
||
;A CHARACTER, AND CHI$ PROCESSES AN IMMEDIATE CHARACTER.
|
||
|
||
|
||
|
||
|
||
FUNSTR: ANDI A,-1 ;KEEP ONLY ADDRESS OF STRING
|
||
CAIG A,U ;REFERENCING THE STORED AC'S?
|
||
ADDI A,SAVEF ;YES, RELOCATE TO THEM
|
||
STRUNS: TLOA A,(POINT 7,) ;MAKE BYTE POINTER AND SKIP INTO LOOP
|
||
STRLOP: PUSHJ P,STORE1 ;STORE THIS CHARACTER
|
||
ILDB C,A ;GRAB THE NEXT CHARACTER
|
||
JUMPN C,STRLOP ;LOOP OVER WHOLE STRING
|
||
CAME A,[POINT 7,ZERO,6] ;WENT OFF THE SAVED AC'S?
|
||
POPJ P, ;NO, THEN ALL DONE
|
||
MOVEI A,U+1 ;YES, POINT TO UNSAVED AC'S
|
||
JRST STRUNS ;AND PROCEED
|
||
|
||
|
||
|
||
FUNCHR: PUSHJ P,GETWRD ;GO GET THE DESIRED WORD
|
||
SKIPA C,T1 ;AND FALL INTO OTHER ROUTINE
|
||
|
||
FUNCHI: MOVEI C,(A) ;GRAB THE CHARACTER
|
||
ANDI C,177 ;REMOVE ALL JUNK
|
||
; PJRST STORE ;AND FALL INTO STORE ROUTINE
|
||
|
||
;HERE WHEN HAVE THE CHARACTER IN AC C. NULLS ARE IGNORED, AS ARE ALL
|
||
;NON-USEFUL CONTROL CHARACTERS, AND CHARACTERS HIGHER THAN THE TERMINAL
|
||
;CAN TYPE. THE ONLY CONTROL CHARACTERS THAT ARE HANDLED ARE TAB
|
||
;AND LINE FEED.
|
||
|
||
|
||
|
||
STORE: JUMPE C,CPOPJ ;QUIT NOW IF HAVE A NULL
|
||
STORE1: TLO F,FL.OUT ;REMEMBER THAT WE HAVE OUTPUT IN THIS WINDOW
|
||
CAMLE L,MAXL(X) ;IS OUR LINE OFF OF THE BOTTOM?
|
||
JRST OVERFL ;YES, GO SEE IF WE MOVE WINDOWS
|
||
CAIL C,SP ;IS THIS A CONTROL CHAR?
|
||
CAMLE C,T.MAXC(U) ;OR IS CHAR BEYOND PRINTING RANGE?
|
||
JRST CONTRL ;YES, HANDLE SPECIAL
|
||
SKIPLE EATNUM(X) ;EATING UP CERTAIN NUMBER OF LINES?
|
||
POPJ P, ;YES, JUST RETURN
|
||
CAMLE N,MAXN(X) ;ARE WE OFF RIGHT SIDE OF WINDOW?
|
||
JRST OFFRHT ;YES
|
||
TRNN F,FR.RAI ;LOWER CASE ACTS LIKE UPPER CASE?
|
||
JRST NORAIS ;NOPE, SKIP ON
|
||
CAIL C,"A"+40 ;IS THIS A LOWER CASE CHARACTER?
|
||
CAILE C,176 ;WELL?
|
||
JRST NORAIS ;NO, DON'T CHANGE IT
|
||
SUBI C,40 ;YES, CONVERT TO UPPER CASE
|
||
NORAIS: ILDB T1,B ;GRAB THE OLD CHARACTER AT THIS LOCATION
|
||
TRZE T1,UPDATE ;IS IT ALREADY TO BE UPDATED?
|
||
PUSHJ P,CKOKUP ;YES, SEE IF IT IS LEGAL TO DO SO
|
||
CAMN T1,C ;IS NEW CHAR SAME AS OLD ONE?
|
||
AOJA N,CPOPJ ;YES, THEN COUNT POSITION AND RETURN
|
||
TRNE F,FR.ELC ;DOES TERMINAL DO CRLFS AT LAST CHAR?
|
||
CAME N,T.WID(U) ;AND ARE WE AT LAST COLUMN?
|
||
JRST NOKLG ;NO, GO ON
|
||
CAMN L,T.LEN(U) ;ARE WE AT LAST LINE ALSO?
|
||
AOJA N,CPOPJ ;YES, NEVER DIDDLE THE LAST CHAR THEN
|
||
NOKLG: MOVEI T1,UPDATE(C) ;NO, GET CHAR WITH "MUST UPDATE" BIT
|
||
DPB T1,B ;STORE IT AWAY
|
||
MOVEI T1,LINCHG(X) ;GET ADDRESS WE WANT...
|
||
ADD T1,L ;TO SET TO -1
|
||
SETOM (T1) ;REMEMBER THAT CHANGES HAVE BEEN DONE
|
||
AOJA N,CPOPJ ;THEN COUNT POSITION AND RETURN
|
||
|
||
|
||
|
||
;ROUTINE TO SEE IF UPDATING THE SAME PLACE ON THE SCREEN TWICE IS
|
||
;OK. WE RETURN IF SO, GIVE AN ERROR IF NOT.
|
||
|
||
|
||
CKOKUP: TLNN F,FL.OKU ;DID USER TELL US IT'S OK?
|
||
DIE USL ;NO, THEN GIVE THE ERROR
|
||
POPJ P, ;IT'S OK, JUST IGNORE IT
|
||
|
||
;HERE TO PROCESS A CONTROL CHARACTER. THE ONLY CONTROL CHARACTERS WE
|
||
;WILL ALLOW ARE <TAB> OR <LF>. ALL OTHER CHARACTERS ARE EATEN, FOR WE
|
||
;DON'T KNOW WHAT THE TERMINAL MAY DO WITH THEM.
|
||
|
||
|
||
CONTRL: CAIE C,LF ;IS A LINEFEED?
|
||
JRST CHKCTL ;NO, GO LOOK FOR A TAB
|
||
SOSL EATNUM(X) ;DECREMENT NUMBER OF LINES TO EAT
|
||
POPJ P, ;STILL HAVE TO EAT MORE, RETURN
|
||
MOVEI T1,SP+UPDATE ;GET A "MUST UPDATE HERE" SPACE
|
||
MOVEI T2,LINCHG(L) ;GET OFFSET OF FLAG WORD FOR THIS LINE
|
||
ADD T2,X ;RELOCATE IT
|
||
|
||
ZAPLIN: CAMLE N,MAXN(X) ;REACHED THE RIGHT LIMIT YET?
|
||
JRST NEWLIN ;YES, GO MOVE TO NEXT LINE NOW
|
||
ILDB T3,B ;NO, THEN GRAB OLD CHARACTER
|
||
TRZE T3,UPDATE ;HAVE THE "MUST UPDATE" BIT ON?
|
||
PUSHJ P,CKOKUP ;YES, SEE IF IT'S OK FOR THAT TO HAPPEN
|
||
CAIN T3,SP ;IS CHAR A SPACE?
|
||
AOJA N,ZAPLIN ;YES, LOOK AT NEXT CHAR
|
||
DPB T1,B ;NO, PUT IN A "MUST UPDATE" SPACE
|
||
SETOM (T2) ;REMEMBER CHANGES HAVE BEEN DONE
|
||
AOJA N,ZAPLIN ;AND LOOP TO FINISH OFF LINE
|
||
|
||
|
||
|
||
;HERE TO PROCESS A TAB, IF THAT IS WHAT WE HAVE. IF NOT A TAB HERE,
|
||
;WE EAT IT, FOR IT IS A RANDOM CONTROL CHARACTER (INCLUDING CR)
|
||
|
||
|
||
CHKCTL: CAIN C,TAB ;IS IT A TAB?
|
||
SKIPLE EATNUM(X) ;AND DO WE HAVE NO LINES TO IGNORE?
|
||
POPJ P, ;NO, JUST RETURN THEN
|
||
MOVEI T4,(N) ;GET POSITION ON THE LINE
|
||
ADJBP T4,[POINT 1,TABS(X),0] ;MAKE BYTE POINTER TO BIT
|
||
MOVEI C,SP ;AND CHANGE TAB TO A SPACE
|
||
|
||
TABLOP: PUSHJ P,STORE1 ;GO STORE A SPACE
|
||
CAME N,MINN(X) ;AT BEGINNING OF NEXT LINE?
|
||
CAMLE N,MAXN(X) ;OR OUTSIDE THE WINDOW?
|
||
POPJ P, ;YES, RETURN THEN
|
||
ILDB T1,T4 ;NO, GET BIT FOR NEXT POSITION
|
||
JUMPE T1,TABLOP ;IF NOT AT TAB STOP GIVE ANOTHER SPACE
|
||
POPJ P, ;OTHERWISE ARE THERE
|
||
|
||
|
||
|
||
;HERE TO SET UP TO DO NEXT LINE
|
||
|
||
|
||
NEWLIN: MOVE N,MINN(X) ;GET LEFT WINDOW VALUE
|
||
AOJA L,MAKEBP ;INCREMENT LINE, MAKE BYTE POINTER, RETURN
|
||
|
||
;THESE ARE THE "FIXIT" ROUTINES WHICH SEE WHAT WE DO WHEN WE
|
||
;OVERFLOW A LINE, OR THE WHOLE WINDOW. THE CHOICES DEPEND ON WHAT
|
||
;THE USER WANTS. IF WE OVERFLOW A LINE, WE CAN EITHER IGNORE THE
|
||
;CHARACTER, OR DO AN AUTOMATIC CARRIAGE RETURN. IF WE OVERFLOW
|
||
;THE WHOLE WINDOW, WE EITHER INGORE THE CHARACTER, OR WE MOVE THE WINDOW
|
||
;TO THE RIGHT SOME, AND CONTINUE OUTPUTTING IN THE NEW WINDOW.
|
||
;NOTE THESE ROUTINES ARE CALLED FROM THE FUNLOC ROUTINE, ALSO.
|
||
|
||
|
||
;HERE IF WE HAVE GONE OFF THE RIGHT OF THE WINDOW, TO SEE WHETHER WE
|
||
;JUST IGNORE THE CHARACTER, OR PRETEND IT WAS A <LF> CHAR
|
||
|
||
|
||
OFFRHT: TLNN F,FL.ACR!FL.AC2 ;ARE WE DOING AUTO-CRLFS?
|
||
POPJ P, ;NO, THEN IGNORE THE CHARACTER
|
||
PUSHJ P,NEWLIN ;GO MOVE TO THE NEXT LINE
|
||
JRST STORE ;THEN STORE THE CHARACTER
|
||
|
||
|
||
|
||
|
||
;HERE IF WE HAVE GONE OFF THE BOTTOM OF THE WINDOW. WE MUST SEE IF THE
|
||
;USER TOLD US TO FLICK IN THE CHARS, OR TO MOVE THE WINDOW FOR HIM.
|
||
|
||
|
||
OVERFL: SKIPLE T1,OVFVAL(X) ;DID USER SET UP HOW WE MOVE WINDOWS?
|
||
TRNN T1,-1 ;AND ARE THERE ANY WINDOWS LEFT IN COUNT?
|
||
JRST CLROVF ;NO, GO CLEAR WORD FOR SURE AND RETURN
|
||
SOS OVFVAL(X) ;SUBTRACT 1 FROM COUNT OF WINDOWS LEFT
|
||
HLRZ T1,T1 ;GET DISTANCE BETWEEN WINDOWS
|
||
ADD T1,MAXN(X) ;ADD TO CURRENT RIGHT MARGIN
|
||
ADDI T1,1 ;AND THEN ONE MORE
|
||
CAMLE T1,T.WID(U) ;WOULD NEW LEFT MARGIN BE ON SCREEN?
|
||
JRST CLROVF ;NO, CLEAR WORD AND IGNORE THIS CHAR
|
||
EXCH T1,MINN(X) ;SAVE NEW LEFT MARGIN, GET OLD ONE
|
||
MOVE T2,MAXN(X) ;GET OLD RIGHT MARGIN
|
||
SUB T2,T1 ;SUBTRACT OLD LEFT MARGIN
|
||
ADD T2,MINN(X) ;AND ADD NEW LEFT MARGIN TO GET NEW RIGHT ONE
|
||
CAMLE T2,T.WID(U) ;DOES WINDOW GO OFF OF SCREEN?
|
||
MOVE T2,T.WID(U) ;YES, TRUNCATE IT TO FIT
|
||
MOVEM T2,MAXN(X) ;SAVE NEW RIGHT MARGIN
|
||
MOVE L,MINL(X) ;SET OUR LOCATION AT TOP OF WINDOW
|
||
PUSHJ P,MAKEBP ;CREATE A NEW POINTER
|
||
JRST STORE ;AND GO PUT THE CHAR IN THE NEW WINDOW
|
||
|
||
|
||
;HERE WHEN CAN'T MAKE A NEW WINDOW, TO CLEAR THE OVFVAL WORD
|
||
|
||
CLROVF: SETZM OVFVAL(X) ;ZERO SO NOT TO BOTHER US AGAIN
|
||
POPJ P, ;AND RETURN
|
||
|
||
SUBTTL FUNCTION TO REFRESH THE SCREEN
|
||
|
||
|
||
;THIS FUNCTION IS CALLED WHENEVER THE USER WANTS TO MAKE SURE THE
|
||
;SCREEN IS CORRECT, THAT IS WHEN HE THINKS THERE ARE GLITCHES ON THE
|
||
;SCREEN AND WANTS THEM FIXED. CALL IS:
|
||
;
|
||
; REF$ FLAGS
|
||
|
||
|
||
|
||
FUNREF: PUSHJ P,ZAPEND ;FIRST MUNCH ON REST OF WINDOW
|
||
PUSHJ P,CLRCHG ;CLEAR THE CHANGE TABLE
|
||
TRNE F,FR.TTY ;IS THIS ON A NON-VIDEO TERMINAL
|
||
JRST REFTTY ;YES, GO DO IT STRAIGHT
|
||
TRNN A,RE$CLR ;SHOULD WE CLEAR SCREEN FIRST?
|
||
JRST REFHRD ;NO, GO DO IT THE HARD WAY
|
||
|
||
|
||
REFTTY: PUSHJ P,DOCLR ;YES, CLEAR THE SCREEN
|
||
|
||
REFLOP: SETZ N, ;START AT FRONT OF LINE
|
||
PUSHJ P,MAKEBP ;GET A BYTE POINTER TO IT
|
||
|
||
REFLIN: ILDB C,B ;GET NEXT CHAR OF LINE
|
||
TRZE C,UPDATE ;CLEAR UPDATE BIT
|
||
DPB C,B ;AND STORE CHAR BACK WITHOUT THE BIT
|
||
CAIN C,SP ;IS THIS A SPACE?
|
||
JRST REFSPC ;YES, SKIP ON
|
||
PUSH P,C ;NO, SAVE THIS CHAR
|
||
PUSHJ P,MOVE ;GET TO THIS LOCATION
|
||
POP P,C ;RESTORE THE CHAR
|
||
PUSHJ P,DOONE ;OUTPUT IT
|
||
|
||
REFSPC: CAMGE N,T.WID(U) ;DONE WITH THIS LINE?
|
||
AOJA N,REFLIN ;NO, LOOP
|
||
CAMGE L,T.LEN(U) ;DONE WITH ALL LINES?
|
||
AOJA L,REFLOP ;NO, KEEP LOOPING
|
||
PJRST DPYFIN ;YES, GO FINISH UP
|
||
|
||
;HERE IN CASE WHERE WE DID NOT HOME UP AND CLEAR THE SCREEN.
|
||
|
||
|
||
|
||
REFHRD: PUSHJ P,DOHOM ;MAKE SURE WE ARE HOMED UP
|
||
MOVE T1,T.WID(U) ;GET LAST COLUMN
|
||
MOVEM T1,LSTNON ;AND SAVE SO EOL WILL TYPE WHOLE LINE
|
||
|
||
|
||
RFHLOP: SETZ N, ;START AT FRONT OF LINE
|
||
PUSHJ P,MAKEBP ;MAKE A BYTE POINTER FOR THIS LINE
|
||
MOVE T1,B ;GET A COPY
|
||
SETOM LSTCHG ;INITIALIZE TEMPORARY VARIABLE
|
||
|
||
RFHLIN: ILDB C,T1 ;GET NEXT CHAR ON LINE
|
||
TRZE C,UPDATE ;CLEAR UPDATE BIT
|
||
DPB C,T1 ;AND STORE IT BACK WITHOUT BIT
|
||
CAIE C,SP ;IS IT A SPACE?
|
||
MOVEM N,LSTCHG ;NO, REMEMBER LAST NONSPACE
|
||
CAMGE N,T.WID(U) ;SCANNED WHOLE LINE?
|
||
AOJA N,RFHLIN ;NO, KEEP GOING
|
||
SETZ N, ;BACK UP TO FRONT AGAIN
|
||
PUSHJ P,MOVE ;GO THERE
|
||
|
||
RFHTYP: CAMLE N,LSTCHG ;DONE WITH ALL NONSPACES ON LINE?
|
||
JRST RFHDNL ;YES
|
||
ILDB C,B ;NO, GET CHAR AT THIS SPOT
|
||
PUSHJ P,DOONE ;OUTPUT IT
|
||
AOJA N,RFHTYP ;AND CONTINUE
|
||
|
||
RFHDNL: CAMG N,T.WID(U) ;IF NOT AT END OF SCREEN
|
||
PUSHJ P,DOEOL ;THEN CLEAR THE REST OF THE LINE
|
||
CAMGE L,T.LEN(U) ;DID ALL LINES?
|
||
AOJA L,RFHLOP ;NO, LOOP OVER THEM
|
||
PJRST DPYFIN ;YES, FINISH UP
|
||
|
||
SUBTTL FUNCTION TO UPDATE THE SCREEN
|
||
|
||
|
||
;THIS FUNCTION IS WHAT DPY IS ALL ABOUT!!!! AFTER THE USER HAS OUTPUT
|
||
;WHATEVER PARTS OF THE SCREEN HE WISHES TO SHOW, HE CALLS THIS ROUTINE, AND
|
||
;THE CHANGES ARE SHOWN WITH MINIMUM EFFORT. CALL IS SIMPLY:
|
||
;
|
||
; DPY$ FLAGS
|
||
|
||
|
||
|
||
|
||
FUNDPY: PUSHJ P,ZAPEND ;CLEAR REST OF LAST WINDOW USED
|
||
SETZB L,N ;BEGIN SEARCH AT TOP LEFT
|
||
TRNE F,FR.TTY ;NON-VIDIO TERMINAL?
|
||
JRST TTYDPY ;YES, HANDLE SPECIAL
|
||
|
||
FNDLIN: CAMLE L,T.LEN(U) ;LOOKED AT ALL THE LINES?
|
||
JRST DPYFIN ;YES, GO FINISH UP
|
||
PUSHJ P,MINMAX ;LOOK FOR CHANGES ON THIS LINE
|
||
AOJA L,FNDLIN ;IF NONE, GO TO NEXT LINE
|
||
SKIPN T.ADR(U) ;CAN TERMINAL ADDRESS?
|
||
JRST NODPY ;NO, GO DO DIFFERENTLY
|
||
|
||
UPDLIN: MOVE N,FSTCHG ;YES, GET COLUMN OF FIRST CHANGE
|
||
PUSHJ P,MOVE ;GO THERE
|
||
PUSHJ P,SLURP ;DO ALL CHANGES ON THE LINE
|
||
AOJA L,FNDLIN ;THEN LOOK AT NEXT LINE
|
||
|
||
|
||
|
||
;HERE WHEN ALL DONE, TO RESET WINDOWS AND POSSIBLY HOME UP:
|
||
|
||
|
||
DPYFIN: SETZM EATNUM(X) ;NO LONGER WANT TO EAT LINES
|
||
SETZB N,L ;SET AT TOP LEFT CORNER
|
||
TRNN A,DP$NOH ;WANT TO HOME UP WHEN DONE?
|
||
PUSHJ P,MOVE ;YES, DO IT
|
||
MOVE L,MINL(X) ;SET LOCATION TO TOP LINE OF WINDOW
|
||
MOVE N,MINN(X) ;AND LEFTMOST COLUMN OF WINDOW
|
||
TLZ F,FL.OUT ;CLEAR OUTPUT IN WINDOW FLAG
|
||
PJRST MAKEBP ;MAKE A BYTE POINTER AND RETURN
|
||
|
||
;HERE IF THIS TERMINAL CANNOT ADDRESS. WE MUST SEE IF IT IS BETTER
|
||
;TO GO TO THE RIGHT FIRST, OR TO DO A CARRIAGE RETURN FIRST.
|
||
|
||
|
||
|
||
NODPY: MOVE N,TTYN(X) ;GET CURRENT COLUMN NUMBER
|
||
CAMLE N,FSTCHG ;IS CURSER TO LEFT OF FIRST CHANGE?
|
||
CAMLE N,LSTCHG ;OR IS IT TO RIGHT OF LAST CHANGE?
|
||
JRST UPDLIN ;YES, UPDATE LINE FROM LEFT TO RIGHT
|
||
CAMLE N,LSTNON ;ONLY SPACES BEYOND WHERE WE ARE?
|
||
SKIPN T.EOL(U) ;AND CAN WE DO ERASE END OF LINES?
|
||
SKIPA T1,LSTCHG ;NO, GET LAST CHANGE AND SKIP
|
||
JRST UPDLIN ;YES, START AT FRONT OF LINE THEN
|
||
PUSH P,TTYN(X) ;SAVE CURRENT POSITION
|
||
MOVEM T1,TTYN(X) ;CHANGE WHERE WE THINK WE ARE
|
||
MOVE N,FSTCHG ;AND WE WANT TO GET TO FIRST CHANGE
|
||
MOVEI T2,-1 ;GET A LARGE NUMBER
|
||
MOVEM T2,BEST ;SET IT
|
||
PUSHJ P,CHKDL ;SEE HOW MANY CHARS TO BACK UP
|
||
PUSHJ P,CHKCDR ;OR HOW MANY TO CR, THEN FORWARD
|
||
POP P,TTYN(X) ;RESTORE TRUE POSITION
|
||
PUSH P,BEST ;SAVE NUMBER OF CHARS NEEDED
|
||
MOVEI T2,-1 ;GET LARGE NUMBER AGAIN
|
||
MOVEM T2,BEST ;AND SET IT AGAIN
|
||
PUSHJ P,CHKDL ;SEE HOW MANY CHARS TO GET TO FIRST CHANGE
|
||
PUSHJ P,CHKCDR ;ALSO BY CR FIRST
|
||
POP P,T1 ;RESTORE OTHER COUNT
|
||
MOVE T2,TTYN(X) ;GET CURRENT POSITION
|
||
SUB T2,PRECHG ;SUBTRACT NEAREST CHANGE
|
||
ADD T2,BEST ;ADD IN OTHER COUNT
|
||
ADDI T1,PRETTY ;ADD IN PRETTYNESS FACTOR
|
||
CAML T1,T2 ;IS IT BETTER TO CRLF FIRST OR NOT?
|
||
JRST UPDLIN ;YES, JUST UPDATE LINE
|
||
MOVE N,TTYN(X) ;START SEARCH AT CURRENT POSITION
|
||
PUSHJ P,MOVE ;GO TO RIGHT LINE
|
||
PUSHJ P,SLURP ;UPDATE END OF THE LINE
|
||
MOVE T1,PRECHG ;GET LAST CHANGE PRIOR TO MOVEMENT
|
||
MOVEM T1,LSTCHG ;SET IT AS LAST CHANGE
|
||
JRST UPDLIN ;THEN UPDATE FIRST PART OF LINE
|
||
|
||
;HERE IF THIS IS A NON-VIDIO TERMINAL. WE SEE IF ANY CHANGES HAVE
|
||
;OCCURED ON THE SCREEN. IF NOT, WE DO NOTHING. OTHERWISE WE TYPE
|
||
;THE WHOLE SCREEN AGAIN.
|
||
|
||
|
||
|
||
TTYDPY: HRLZ T1,T.LEN(U) ;GET NUMBER OF LINES TO CHECK
|
||
MOVN T1,T1 ;MAKE AOBJN POINTER
|
||
HRRI T1,LINCHG(X) ;GET ADDRESS OF THE TABLE
|
||
SKIPN (T1) ;CHANGES ON THIS LINE?
|
||
AOBJN T1,.-1 ;NO, SEARCH ALL LINES
|
||
JUMPGE T1,DPYFIN ;JUST RETURN IF NO CHANGES
|
||
PUSHJ P,CLRCHG ;CLEAR THE CHANGE TABLE
|
||
PUSHJ P,MOVE ;GO "MOVE" TO HOME POSITION
|
||
JRST REFLOP ;THEN JOIN REFRESH CODE
|
||
|
||
|
||
|
||
CLRCHG: HRLI T1,LINCHG(X) ;GET SET
|
||
HRRI T1,LINCHG+1(X) ;FOR BLT
|
||
MOVE T2,T.LEN(U) ;GET NUMBER OF LINES
|
||
SETZB L,LINCHG(X) ;CLEAR LINE NUMBER AND CHANGE FLAG
|
||
ADDI T2,LINCHG(X) ;GET ADDRESS WE WANT
|
||
BLT T1,(T2) ;ZERO WHOLE CHANGE TABLE
|
||
POPJ P, ;DONE
|
||
|
||
SUBTTL ROUTINE TO OUTPUT THE CHANGES ON A LINE
|
||
|
||
|
||
|
||
;THIS ROUTINE IS CALLED ONCE WE ARE AT A CHANGE ON A LINE, TO FOLLOW
|
||
;THE LINE LOOKING FOR REST OF THE CHANGES. THIS ROUTINE ALSO TAKES
|
||
;CARE OF THE ERASE-END-OF-LINE CHECKS. CALL IS:
|
||
;
|
||
; (CALL MINMAX) ;COLLECT FSTCHG, LSTCHG, ETC.
|
||
; MOVE N,COLUMN ;SET UP COLUMN OF CHANGE
|
||
; MOVE L,LINE ;AND LINE OF CHANGE
|
||
; PUSHJ P,SLURP ;PROCESS THE CHANGES ON THE LINE
|
||
; (RETURN) ;WE TOOK CARE OF ALL CHANGES ON LINE
|
||
|
||
|
||
|
||
|
||
|
||
SLURP: PUSHJ P,MAKEBP ;GET A BYTE POINTER TO THIS PLACE
|
||
SLPLOP: CAMLE N,LSTCHG ;BEYOND THE LAST CHANGE ON THE LINE?
|
||
POPJ P, ;YES, RETURN
|
||
SLPSCN: ILDB C,B ;GET CHARACTER AT THIS POSITION
|
||
TRZN C,UPDATE ;DOES IT NEED UPDATING?
|
||
AOJA N,SLPSCN ;NO, LOOK SOME MORE
|
||
DPB C,B ;YES, STORE CHAR BACK WITHOUT BIT
|
||
CAME N,TTYN(X) ;CURSER NOT AT CURRENT COLUMN?
|
||
PUSHJ P,MOVE ;NO, THEN MOVE THERE
|
||
SKIPE T.EOL(U) ;CAN THIS TERMINAL ERASE END OF LINE?
|
||
CAMG N,LSTNON ;AND LINE CONTAINS ONLY SPACES?
|
||
SKIPA ;NO, THEN DO NOTHING SPECIAL
|
||
JRST SLPEOL ;YES, GO DO END OF LINE
|
||
LDB C,B ;GET BACK CHAR IN CASE WE HAD TO MOVE
|
||
PUSHJ P,DOONE ;THEN OUTPUT THIS CHARACTER
|
||
AOJA N,SLPLOP ;LOOK AT NEXT CHAR
|
||
|
||
|
||
SLPEOL: PUSHJ P,DOEOL ;ERASE REST OF LINE
|
||
MOVEI C,SP ;GET A SPACE
|
||
SLPELL: CAML N,LSTCHG ;DID ALL CHARS ON LINE?
|
||
POPJ P, ;YES, RETURN
|
||
IDPB C,B ;STORE A SPACE IN THE ARRAY
|
||
AOJA N,SLPELL ;AND LOOP
|
||
|
||
SUBTTL FUNCTION WHICH SETS THE "WINDOW" FOR OUTPUT
|
||
|
||
|
||
;THIS FUNCTION IS USED TO SET A "WINDOW" IN WHICH THE USER WANTS TO
|
||
;OUTPUT IN. THE PURPOSE OF THIS IS SO THE USER CAN SPLIT UP THE
|
||
;SCREEN IN PIECES, AND OUTPUT HIS STUFF ONE HUNK AT A TIME, AND
|
||
;THEREFORE NOT HAVE TO WORRY ABOUT FORMATTING EVERYTHING. HE JUST
|
||
;CALLS THIS ROUTINE EACH TIME HE OUTPUTS A DIFFERENT PIECE.
|
||
;USER CALLS THIS ROUTINE WITH:
|
||
;
|
||
; SIZE$ [MINLIN,,MAXLIN ;MIN AND MAX LINE NUMBER
|
||
; MINCHR,,MAXCHR] ;MIN AND MAX CHARACTER POSITION
|
||
;
|
||
;WHERE THE NUMBERS ARE THE MINIMUM AND MAXIMUM VALUES THE USER WISHES
|
||
;TO RANGE BETWEEN. ZERO IS THE TOP LEFT CORNER OF THE PHYSICAL SCREEN.
|
||
;A NEGATIVE MAXIMUM ARGUMENT (I.E., BIT 18 IS SET) IMPLIES TO USE THE
|
||
;MAXIMUM VALUE ALLOWED, THE FULL WIDTH OR LENGTH OF THE SCREEN.
|
||
;WE ALSO SET THE POSITION TO OUTPUT TO TO THE TOP LEFT OF THE WINDOW,
|
||
;TO SAVE THE USER THE TROUBLE, SINCE HE USUALLY WANTS THAT ANYWAY.
|
||
;IF THE UUO CONTAINS ZERO AS THE ADDRESS, WE ASSUME HE WANTS TO HAVE
|
||
;THE WHOLE SCREEN AS THE WINDOW, AND SO DO IT THAT WAY.
|
||
|
||
|
||
FUNSIZ: PUSHJ P,ZAPEND ;CLEAR OUT REST OF PREVIOUS WINDOW FIRST
|
||
TRNN A,-1 ;GIVE US A REASONABLE ADDRESS?
|
||
SIZINI: MOVEI A,T.LEN(U) ;NO, SET UP USUAL SCREEN THEN
|
||
PUSHJ P,GETWRD ;GRAB FIRST USER WORD
|
||
HLRZ L,T1 ;SET MINIMUM LINE NUMBER
|
||
TRNE T1,400000 ;IS THE MAXIMUM VALUE NEGATIVE?
|
||
SKIPA T1,T.LEN(U) ;YES, GRAB LARGEST POSSIBLE VALUE
|
||
MOVEI T1,(T1) ;NO, ISOLATE MAXIMUM LINE NUMBER
|
||
CAIG L,(T1) ;MINIMUM SMALLER THAN MAXIMUM?
|
||
CAMLE T1,T.LEN(U) ;AND MAXIMUM LESS THAN SCREEN?
|
||
DIE IWS ;NO, IS WRONG, DIE
|
||
MOVEM L,MINL(X) ;SAVE THE MINIMUM AWAY
|
||
MOVEM T1,MAXL(X) ;AND THE MAXIMUM
|
||
PUSHJ P,GETWRD ;GET USER'S SECOND ARGUMENT
|
||
HLRZ N,T1 ;GET MINIMUM CHARACTER POSITION
|
||
TRNE T1,400000 ;IS MAXIMUM VALUE NEGATIVE?
|
||
SKIPA T1,T.WID(U) ;YES, USE LARGEST LEGAL VALUE
|
||
MOVEI T1,(T1) ;NO, ISOLATE MAXIMUM POSITION
|
||
CAIG N,(T1) ;MINIMUM SMALLER THAN MAXIMUM?
|
||
CAMLE T1,T.WID(U) ;AND MAXIMUM WITHIN SCREEN BOUNDARY?
|
||
DIE IWS ;NO
|
||
MOVEM N,MINN(X) ;OK, SAVE AWAY MINIMUM POSITION
|
||
MOVEM T1,MAXN(X) ;AND MAXIMUM POSITION
|
||
TLO F,FL.OUT ;ACT LIKE WE HAVE OUTPUT IN WINDOW
|
||
PJRST MAKEBP ;NOW MAKE BYTE POINTER AND RETURN
|
||
|
||
SUBTTL FUNCTION WHICH SETS TABS
|
||
|
||
|
||
;THIS FUNCTION IS USED TO SET WHERE TABS ARE ON THE SCREEN, SO THAT
|
||
;WHEN A TAB CHARACTER IS OUTPUT, WE JUMP TO THE NEXT TAB SETTING.
|
||
;BY LETTING HIM CHANGE THE TABS, WE ALLOW VERSATILITY IN HIS OUTPUT.
|
||
;NOTE THAT TABS ARE SET ALWAYS WITH RESPECT TO THE SCREEN, NEVER TO
|
||
;A WINDOW. USER CALLS THIS ROUTINE WITH:
|
||
;
|
||
; TAB$ ADDR ;LOCATION OF THE TABS
|
||
;
|
||
;WHERE ADDR CONTAINS A BIT TABLE OF WHERE THE TABS ARE, STARTING WITH
|
||
;THE FIRST BIT OF THE FIRST WORD BEING THE LEFT HAND EDGE OF THE SCREEN.
|
||
;IF THE ADDRESS GIVEN IS ZERO, WE SUPPLY DEFAULT TABS.
|
||
|
||
|
||
|
||
FUNTAB: TRNN A,-1 ;DOES HE HAVE HIS OWN TABS?
|
||
DFTTAB: MOVEI A,REGTAB ;NO, THEN USE DEFAULT ONES
|
||
MOVSI T4,-4 ;GET READY FOR LOOP
|
||
HRR T4,X ;POINT AT DATA
|
||
|
||
TABPUT: PUSHJ P,GETWRD ;GRAB THE NEXT WORD OF BITS
|
||
MOVEM T1,TABS(T4) ;SAVE THEM AWAY
|
||
AOBJN T4,TABPUT ;AND LOOP FOR ALL OF THEM
|
||
POPJ P, ;THEN RETURN
|
||
|
||
|
||
|
||
;THE DEFAULT TABS FOLLOW (EVERY EIGHT POSITIONS ON THE SCREEN)
|
||
|
||
|
||
TAB%%==401002004010 ;STARTING POINT OF MAKING TAB TABLE
|
||
|
||
|
||
REGTAB: REPEAT 4,<
|
||
|
||
EXP TAB%% ;;PUT IN THE TABS FOR SOME LOCATIONS
|
||
TAB%%==<TAB%%_4>!<TAB%%_-4> ;;AND GENERATE NEW TABS FOR NEXT ONE
|
||
>
|
||
SUBTTL FUNCTION WHICH SETS PARAMETERS
|
||
|
||
|
||
;THIS FUNCTION IS CALLED TO SET PARAMETERS WHICH CONTROL EXACTLY HOW
|
||
;WE DO CERTAIN THINGS. THIS ALLOWS THE USER TO CONTROL WHAT HAPPENS MORE
|
||
;EXACTLY THAN OTHERWISE. CALL IS:
|
||
;
|
||
; SET$ [FUNCTION,,VALUE] ;SET DESIRED THING
|
||
; (RETURN) ;ALL DONE
|
||
;OR:
|
||
; SET$ [0,,NUMBER OF FUNCTIONS
|
||
; FUNCTION1,,VALUE1
|
||
; FUNCTION2,,VALUE2
|
||
; ...
|
||
; FUNCTIONN,VALUEN] ;SET BUNCH OF VALUES
|
||
;
|
||
;WE USE AC'S T1, T2, AND T4
|
||
|
||
|
||
|
||
FUNSET: PUSHJ P,GETWRD ;GRAB THE USER'S ARGUMENT
|
||
TLNN T1,-1 ;LEFT HALF ZERO?
|
||
SKIPA T4,T1 ;YES, GET COUNT OF THINGS TO SET
|
||
TDZA T4,T4 ;NO, THEN SET COUNT TO JUST 1 THING
|
||
|
||
SETLOP: PUSHJ P,GETWRD ;GRAB THE NEXT THING TO GRUNGE ON
|
||
HLRE T2,T1 ;GET FUNCTION
|
||
SKIPLE T2 ;OUT OF RANGE?
|
||
CAILE T2,MAXSET ;MAYBE
|
||
DIE ISF ;YES, DIE
|
||
XCT SETTAB-1(T2) ;SET THE PARAMETER
|
||
SOJG T4,SETLOP ;AND DO NEXT ONE
|
||
POPJ P, ;UNTIL DID ALL
|
||
|
||
;TABLE OF INSTRUCTIONS FOR THE VARIOUS FUNCTIONS.
|
||
|
||
|
||
SETTAB: DPB T1,[POINT 1,F,^L<(FL.ACR)>] ;(1) AUTOMATIC CRLFS
|
||
DPB T1,[POINT 1,F,^L<(FL.NZP)>] ;(2) DON'T CLEAR REST OF WINDOWS
|
||
DPB T1,[POINT 1,F,^L<(FL.NOS)>] ;(3) CALL USER DIRECTLY
|
||
HRRZM T1,OUTADR(X) ;(4) SET CHARACTER ROUTINE
|
||
HRRZM T1,ERRADR(X) ;(5) SET ERROR ROUTINE
|
||
PUSHJ P,WNDSET ;(6) SET WINDOW MOVEMENT
|
||
DPB T1,[POINT 1,F,^L<(FL.OKU)>] ;(7) UPDATING SAME PLACE IS OK
|
||
HRRZM T1,EATNUM(X) ;(10) SET NUMBER OF LINES TO EAT
|
||
|
||
MAXSET==.-SETTAB ;MAXIMUM FUNCTION
|
||
|
||
|
||
|
||
;HERE TO SET WORD WITH WINDOW MOVING INFORMATION.
|
||
|
||
|
||
WNDSET: PUSH P,A ;SAVE UUO SINCE MAYBE MORE FUNCTIONS
|
||
MOVE A,T1 ;SET UP ADDRESS OF DATA WE WANT
|
||
PUSHJ P,GETWRD ;OBTAIN THE REAL ARGUMENT
|
||
MOVEM T1,OVFVAL(X) ;SAVE IT
|
||
POP P,A ;RESTORE THE UUO
|
||
POPJ P, ;RETURN
|
||
SUBTTL FUNCTION TO RETURN LOCATION IN WINDOW
|
||
|
||
|
||
;THIS FUNCTION IS USED TO GET THE PRESENT LOCATION OF WHERE WE ARE
|
||
;OUTPUTTING ON THE SCREEN. THIS WAY, USER PROGS CAN SEE IF THEY ARE
|
||
;OVERFLOWING WINDOWS, OR THEY CAN MAKE THEIR OUTPUT BETTER. WE
|
||
;ALSO RETURN WHETHER OR NOT THE USER HAS OVERFLOWED THE WINDOW HE
|
||
;IS OUTPUTTING IN. CALL IS:
|
||
;
|
||
; LOC$ ADDRESS ;RETURN LOCATION ON SCREEN WE ARE AT
|
||
; (RETURN) ;GOT IT IN LOCATION ADDRESS
|
||
;
|
||
;ADDRESS WILL CONTAIN LINE,,POSITION NORMALLY. BUT IF THE
|
||
;PRESENT LINE HAS BEEN OVERFLOWED, POSITION = -1. IF THE WHOLE
|
||
;WINDOW HAS BEEN OVERFLOWED, THE WHOLE RESULT IS -1.
|
||
|
||
|
||
|
||
|
||
FUNLOC: SETZ C, ;MAKE A NULL, SO STORE ROUTINE RETURNS
|
||
CAMLE N,MAXN(X) ;ARE WE PAST RIGHT MARGIN?
|
||
PUSHJ P,OFFRHT ;MAYBE, GO MAKE SURE !!
|
||
CAMLE L,MAXL(X) ;SIMILARLY, ARE WE OFF END OF LAST WINDOW?
|
||
PUSHJ P,OVERFL ;MAYBE, MAKE ABSOLUTELY SURE !!
|
||
CAMG N,MAXN(X) ;ARE WE OFF THE RIGHT OF THE WINDOW?
|
||
SKIPA T1,N ;NO, GET POSITION IN T1
|
||
MOVEI T1,-1 ;YES, SET RH TO -1 THEN
|
||
CAMG L,MAXL(X) ;NOW, HAVE WE OVERFLOWED ALL THE WINDOWS?
|
||
TLOA T1,(L) ;NO, SET LINE NUMBER IN LEFT HALF
|
||
SETO T1, ;YES, SET WHOLE RESULT TO -1
|
||
PJRST PUTWRD ;GO STORE VALUE AND RETURN
|
||
|
||
SUBTTL FUNCTION TO ADDRESS TO PARTICULAR SPOT ON SCREEN
|
||
|
||
|
||
|
||
;THIS FUNCTION IS USED IF THE USER WANTS TO MOVE THE CURSOR TO
|
||
;A PARTICULAR PLACE ON THE SCREEN. WE REMEMBER THIS LOCATION
|
||
;FOR OURSELF TOO, SO THAT WE CAN MOVE FROM THERE TO WHERE WE
|
||
;WANT TO UPDATE THE SCREEN. CALL IS:
|
||
;
|
||
; ADR$ [FLAG+LINE,,COLUMN] ;GO TO GIVEN LOCATION
|
||
;
|
||
;IF THE FLAG BIT IS SET, WE DON'T ACTUALLY MOVE THERE, SO THE
|
||
;USER CAN INFORM US HE MOVED AROUND HIMSELF.
|
||
|
||
|
||
|
||
FUNADR: PUSHJ P,GETWRD ;READ USER'S WORD
|
||
PUSH P,N ;SAVE AC'S
|
||
PUSH P,L ;THAT WE DON'T WANT CHANGED
|
||
HLRZ L,T1 ;GET LINE NUMBER
|
||
ANDCMI L,AD$NOM ;CLEAR THE FLAG BIT
|
||
HRRZ N,T1 ;GET COLUMN NUMBER
|
||
CAMG L,T.LEN(U) ;ILLEGAL LINE NUMBER GIVEN?
|
||
CAMLE N,T.WID(U) ;OR ILLEGAL COLUMN POSITION?
|
||
DIE IPG ;YES, LOSE
|
||
TLNN T1,AD$NOM ;WANTS TO ACTUALLY MOVE THERE?
|
||
PUSHJ P,MOVE ;YES, DO SO
|
||
DMOVEM L,TTYL(X) ;SAVE LOCATION WE ARE NOW AT
|
||
POP P,L ;RESTORE AC'S
|
||
POP P,N ;THAT WE DIDN'T WANT HURT
|
||
POPJ P, ;AND RETURN
|
||
|
||
SUBTTL FUNCTION TO OUTPUT SPECIAL THINGS STRAIGHT TO TTY
|
||
|
||
|
||
;THIS FUNCTION IS SO USER PROG CAN OUTPUT CERTAIN THINGS TO THE TTY
|
||
;WHILE NOT KNOWING HOW TO GO ABOUT IT. THE THINGS WE CAN OUTPUT ARE
|
||
;PRETTY LIMITED, BUT THAT IS BECAUSE NOT EVERYTHING CAN BE DONE FOR
|
||
;A PARTICULAR TERMINAL. CALL IS:
|
||
;
|
||
; TTY$ FUNCTION ;OUTPUT SOMETHING
|
||
; (RETURN) ;OK
|
||
;
|
||
|
||
|
||
|
||
FUNTTY: MOVEI A,(A) ;GET ARGUMENT BY ITSELF
|
||
CAILE A,TTYMAX ;TOO LARGE?
|
||
DIE ITF ;YES, DIE BIG
|
||
PJRST @TTYTAB(A) ;NO, OUTPUT IT AND RETURN
|
||
|
||
|
||
|
||
|
||
;THE THINGS WE OUTPUT FOLLOW
|
||
|
||
|
||
|
||
TTYTAB: EXP DOHOM ;(0) TO HOME UP
|
||
EXP DOCLR ;(1) TO HOME UP AND CLEAR THE SCREEN
|
||
|
||
|
||
TTYMAX==.-TTYTAB-1 ;MAXIMUM FUNCTION
|
||
|
||
SUBTTL SUBROUTINE TO SCAN A LINE FOR CHANGES
|
||
|
||
|
||
;THIS SUBROUTINE IS CALLED TO SCAN A LINE OF THE SCREEN, RETURN NICE
|
||
;THINGS ABOUT THE LINE WHICH NEED CHANGING. CALL IS:
|
||
;
|
||
; MOVE L,LINE NUMBER ;SET UP LINE TO LOOK AT
|
||
; PUSHJ P,MINMAX ;FIND OUT ABOUT LINE CHANGES
|
||
; (NO CHANGES) ;THIS LINE NEEDS NO CHANGING
|
||
; (CHANGES NEEDED) ;CHANGES ARE TO BE DONE
|
||
;
|
||
;ON A SKIP RETURN, THE FOLLOWING INFORMATION IS KNOWN:
|
||
;
|
||
; FSTCHG - FIRST COLUMN ON LINE WHICH NEEDS CHANGING
|
||
; LSTCHG - LAST COLUMN ON LINE TO NEED CHANGING
|
||
; PRECHG - LAST COLUMN PREVIOUS TO CURRENT COLUMN TO NEED CHANGING
|
||
; LSTNON - LAST COLUMN ON LINE WHICH WASN'T A SPACE, -1 IF NONE
|
||
|
||
|
||
|
||
|
||
MINMAX: MOVEI T4,LINCHG(X) ;POINT AT LINE CHANGES
|
||
HRLI T4,L ;INSERT INDEX ACCUMULATOR
|
||
SKIPE @T4 ;ANY CHANGES INDICATED FOR THIS LINE?
|
||
AOSA (P) ;YES, SET UP SKIP RETURN
|
||
POPJ P, ;NO, NON-SKIP RETURN
|
||
SETZM @T4 ;CLEAR CHANGE FLAG SINCE NOW ON LINE
|
||
MOVE T1,T.WRDS(U) ;GET NUMBER OF WORDS OF STORAGE PER LINE
|
||
IMULI T1,(L) ;MAKE OFFSET INTO SCREEN FOR THIS LINE
|
||
ADD T1,[POINT 9,SCREEN(X)] ;MAKE POINTER TO START OF LINE
|
||
SETZB T2,PRECHG ;INITIALIZE FOR LOOP
|
||
SETOM LSTNON ;MORE
|
||
SETOM LSTCHG ;MORE
|
||
SETOM FSTCHG ;AND MORE
|
||
|
||
|
||
;HERE TO LOOK AT NEXT CHARACTER ON THE LINE
|
||
|
||
|
||
MINNXT: ILDB T3,T1 ;GRAB NEXT CHAR ON LINE
|
||
TRZN T3,UPDATE ;THIS POSITION CHANGED?
|
||
JRST MINNOU ;NO, GO DO NEXT ONE
|
||
SKIPGE FSTCHG ;SAVED FIRST CHANGE COLUMN YET?
|
||
MOVEM T2,FSTCHG ;NO, THEN THIS IS FIRST
|
||
MOVEM T2,LSTCHG ;COLUMN IS LAST TO NEED CHANGING SO FAR
|
||
CAMGE T2,TTYN(X) ;BEFORE CURRENT TTY POSITION?
|
||
MOVEM T2,PRECHG ;YES, REMEMBER POSITION THEN
|
||
MINNOU: CAIE T3,SP ;IS THIS CHARACTER A SPACE?
|
||
MOVEM T2,LSTNON ;NO, REMEMBER LAST NON-SPACE COLUMN
|
||
CAMGE T2,T.WID(U) ;MORE CHARACTERS TO LOOK AT?
|
||
AOJA T2,MINNXT ;YES, KEEP GOING
|
||
POPJ P, ;NO, THEN RETURN ALL DONE
|
||
|
||
SUBTTL ROUTINE TO CLEAR THE REST OF A WINDOW
|
||
|
||
|
||
;THIS ROUTINE IS CALLED WHENEVER WE ARE DONE WITH A WINDOW. THIS
|
||
;MEANS WHEN WINDOWS ARE CHANGED, OR WE UPDATE OR REFRESH THE SCREEN.
|
||
;THE PURPOSE OF THIS IS SO WHEN A USER DOESN'T FINISH FILLING THE
|
||
;WINDOW WITH DATA, THEN WINDOW DOESN'T HAVE OLD JUNK LEFT, IT IS
|
||
;EATEN AS IF HE TYPED INFINITE SPACES.
|
||
|
||
|
||
|
||
ZAPEND: SETZM EATNUM(X) ;CLEAR NUMBER OF LINES TO EAT
|
||
TLNE F,FL.OUT ;NOTHING BEEN OUTPUT IN WINDOW YET?
|
||
TLNE F,FL.NZP ;OR USER NOT WANT WINDOW CLEARED?
|
||
JRST CLROVF ;YES, JUST CLEAR OVFVAL AND RETURN
|
||
TLO F,FL.AC2 ;SET SO WILL DO AUTO-CRLFS
|
||
MOVEI C,SP ;GET A SPACE
|
||
|
||
ZAPLOP: PUSHJ P,STORE1 ;STUFF IT AWAY IN THE SCREEN
|
||
CAMLE L,MAXL(X) ;NOT DONE WITH WINDOW YET?
|
||
SKIPE OVFVAL(X) ;OR MORE WINDOWS LEFT TO CLEAR?
|
||
JRST ZAPLOP ;YES, THEN KEEP GIVING SPACES
|
||
TLZ F,FL.AC2 ;CLEAR SPECIAL FLAG
|
||
POPJ P, ;AND RETURN
|
||
|
||
SUBTTL ROUTINES TO READ AND STORE WORDS FROM THE USER
|
||
|
||
|
||
|
||
|
||
;THESE ROUTINES ARE CALLED TO READ OR WRITE THE USER'S CORE. THE
|
||
;REASON A STRAIGHT MOVE OR MOVEM IS IMPOSSIBLE IS BECAUSE THE ADDRESS
|
||
;TO USE MIGHT BE IN THE SAVED AC AREA, AND WE HAVE TO RELOCATE THE
|
||
;ADDRESS IN THIS CASE.
|
||
|
||
|
||
|
||
;HERE TO READ INTO T1 THE WORD POINTED TO BY AC A. THE AC IS INCREMENTED
|
||
;ALSO, SO THAT SUCCESSIVE CALLS WILL READ SUCCESSIVE WORDS.
|
||
|
||
|
||
GETWRD: MOVEI A,1(A) ;CLEAR LEFT HALF AND INCREMENT
|
||
CAIG A,U+1 ;IS THE WORD IN A SAVED AC?
|
||
SKIPA T1,SAVEF-1(A) ;YES, GET IT
|
||
MOVE T1,-1(A) ;NO, GET DIRECTLY THEN
|
||
POPJ P, ;AND RETURN
|
||
|
||
|
||
|
||
|
||
;HERE TO STORE THE CONTENTS OF AC T1 INTO THE ADDRESS GIVEN
|
||
;IN RIGHT HALF OF AC A.
|
||
|
||
|
||
PUTWRD: ANDI A,-1 ;ONLY KEEP THE ADDRESS HALF
|
||
CAIG A,U ;IS IT ONE OF HIS AC'S WE SAVED?
|
||
ADDI A,SAVEF ;YES, OFFSET TO SAVED AREA
|
||
MOVEM T1,(A) ;SAVE THE WORD AWAY
|
||
POPJ P, ;AND RETURN
|
||
|
||
SUBTTL ROUTINE TO MAKE A BYTE POINTER
|
||
|
||
|
||
;ROUTINE TO TAKE THE PRESENT LINE AND CHARACTER POSITION (AS GIVEN IN
|
||
;AC'S L AND N) AND CONSTRUCT A BYTE POINTER WHICH POINTS TO THE BYTE
|
||
;JUST PRIOR TO THAT LOCATION. POINTER IS RETURNED IN AC B. CALL IS:
|
||
;
|
||
; MOVEI L,LINE ;SET UP DESIRED LINE NUMBER
|
||
; MOVEI N,CHAR ;AND DESIRED CHARACTER POSITION
|
||
; PUSHJ P,MAKEBP ;GENERATE BYTE POINTER
|
||
; (RETURN) ;GOT IT IN AC B
|
||
;
|
||
;USES AC'S T1, T2, AND B
|
||
|
||
|
||
MAKEBP: MOVE B,L ;GET LINE NUMBER
|
||
IMUL B,T.WRDS(U) ;MULTIPLY BY WORDS PER LINE
|
||
MOVE T1,N ;GET POSITION ON LINE
|
||
IDIVI T1,4 ;DIVIDE BY CHARACTERS IN A WORD
|
||
ADD B,T1 ;ADD IN WORDS IN THIS LINE WE ARE ON
|
||
ADD B,PNTTAB(T2) ;AND ADD WHICH BYTE, SCREEN LOCATION
|
||
POPJ P, ;AND RETURN
|
||
|
||
|
||
|
||
|
||
;THE LIST OF BYTE POINTERS FOR USE IN THE ABOVE ROUTINE
|
||
|
||
|
||
PNTTAB: POINT 9,SCREEN-1(X),35 ;LAST BYTE IN PREVIOUS WORD
|
||
POINT 9,SCREEN(X),8 ;FIRST BYTE IN THE WORD
|
||
POINT 9,SCREEN(X),17 ;SECOND BYTE IN THE WORD
|
||
POINT 9,SCREEN(X),26 ;THIRD BYTE IN THE WORD
|
||
|
||
SUBTTL ROUTINE TO MOVE TO A LOCATION ON THE SCREEN
|
||
|
||
|
||
|
||
;THIS ROUTINE IS CALLED WITH THE DESIRED POSITION TO MOVE TO IN
|
||
;AC'S L AND N, AND THE CURRENT TERMINAL CURSER POSITION IN LOCATIONS
|
||
;TTYL AND TTYN. THE BEST WAY TO MOVE TO THE NEW POSITION IS CALCULATED,
|
||
;AND THE CURSER IS MOVED THERE THAT WAY.
|
||
|
||
|
||
|
||
MOVE: CAMN L,TTYL(X) ;SEE IF ALREADY AT DESIRED LOCATION
|
||
CAME N,TTYN(X) ;TO SAVE SOME WORK
|
||
TROA T1,-1 ;NO, SET UP A LARGE NUMBER
|
||
POPJ P, ;YES, THEN RETURN NOW
|
||
HRRZM T1,BEST ;SAVE LARGE NUMBER
|
||
MOVEI T1,[DIE CDS] ;SET UP ERROR ROUTINE IN CASE CAN'T MOVE
|
||
PUSHJ P,CHKADR ;SEE HOW MANY CHARACTERS ADDRESSING TAKES
|
||
CAML L,TTYL(X) ;IS NEW LOCATION LOWER ON SCREEN?
|
||
TDZA T2,T2 ;YES, CLEAR AC
|
||
MOVEI T2,1 ;NO, SET LOW ORDER BIT
|
||
CAMGE N,TTYN(X) ;IS NEW LOCATION TO LEFT OF OLD?
|
||
IORI T2,2 ;YES, SET BIT
|
||
PJRST @[ EXP MOVDR ;DISPATCH FOR DOWN AND RIGHT
|
||
EXP MOVUR ;UP AND RIGHT
|
||
EXP MOVDL ;DOWN AND LEFT
|
||
EXP MOVUL ](T2) ;UP AND LEFT
|
||
|
||
|
||
|
||
MOVDR: PUSHJ P,CHKDR ;SEE IF JUST MOVING IS BETTER
|
||
PJRST (T1) ;DISPATCH TO BEST ROUTINE
|
||
|
||
MOVDL: PUSHJ P,CHKDL ;SEE HOW GOOD DIRECT MOTION IS
|
||
PUSHJ P,CHKCDR ;SEE IF CR, DOWN, RIGHT IS BEST
|
||
SKIPN T.CR(U) ;CAN TERMINAL DO CR?
|
||
PUSHJ P,CHKHDR ;NO, THEN CHECK HOMING UP
|
||
PJRST (T1) ;DISPATCH TO BEST ROUTINE
|
||
|
||
MOVUR: PUSHJ P,CHKUR ;SEE HOW GOOD THE DIRECT ROUTE IS
|
||
PUSHJ P,CHKHDR ;SEE IF HOMING UP HELPS ANY
|
||
PJRST (T1) ;GO TO BEST ROUTINE
|
||
|
||
MOVUL: PUSHJ P,CHKUL ;CHECK OUT THE DIRECT MOTION
|
||
PUSHJ P,CHKHDR ;SEE HOW HOMING UP WORKS
|
||
PUSHJ P,CHKCUR ;SEE IF CR, UP AND RIGHT IS GOOD
|
||
PJRST (T1) ;DISPATCH TO BEST ROUTINE
|
||
|
||
;FOLLOWING ARE THE ROUTINES TO SEE IF A PARTICULAR WAY OF MOVING
|
||
;TAKES FEWER CHARACTERS THAN THE PRECEEDING WAYS. LOWEST NUMBER OF
|
||
;CHARS IS IN ADDRESS BEST, AND ROUTINE WHICH DOES THAT ACTION IS IN T1.
|
||
|
||
|
||
|
||
;ROUTINE TO COMPUTE THE COST OF ADDRESSING.
|
||
;THIS ROUTINE KNOWS IT IS THE FIRST ROUTINE CALLED.
|
||
|
||
|
||
CHKADR: SKIPN T2,T.ADR(U) ;SEE IF ADDRESSING IS POSSIBLE
|
||
POPJ P, ;NO, THEN RETURN
|
||
TRNE F,FR.ANS ;ANSI MODE ADDRESSING?
|
||
JRST ANSICK ;YES, DIFFERENT COMPUTATIONS
|
||
ADD T2,T.ADR2(U) ;ADD IN MORE CHARACTERS
|
||
ADD T2,T.ADR3(U) ;AND ADD IN MORE CHARS
|
||
MOVEI T2,2(T2) ;THEN ADD 2 CHARS FOR COORDINATES
|
||
CHKADF: MOVEM T2,BEST ;REMEMBER NUMBER OF CHARS NEEDED
|
||
MOVEI T1,DOADR ;SET UP ADDRESS FOR ADDRESSING
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
ANSICK: MOVEI T1,1(N) ;GET COLUMN NUMBER
|
||
PUSHJ P,COLADD ;ADD IN DEPENDING ON SIZE
|
||
MOVEI T1,1(L) ;GET LINE NUMBER
|
||
PUSHJ P,COLADD ;ADD IN DEPENDING ON SIZE
|
||
SKIPE N ;ANY COLUMN?
|
||
ADDI T2,1 ;YES, WILL NEED A SEMICOLON
|
||
AOJA T2,CHKADF ;COUNT ENDING CHAR AND RETURN
|
||
|
||
|
||
COLADD: CAIL T1,^D100 ;THREE DIGITS?
|
||
ADDI T2,1 ;YES, COUNT IT
|
||
CAIL T1,^D10 ;TWO DIGITS?
|
||
ADDI T2,1 ;YES, COUNT IT
|
||
CAIL T1,2 ;NEED ANY DIGITS?
|
||
ADDI T2,1 ;YES, COUNT IT
|
||
POPJ P, ;DONE
|
||
|
||
;ROUTINE TO COMPUTE COST OF MOVING UP AND LEFT.
|
||
|
||
|
||
CHKUL: SKIPE T3,T.UP(U) ;CAN WE MOVE UP?
|
||
SKIPN T4,T.LEFT(U) ;AND CAN WE MOVE LEFT?
|
||
POPJ P, ;NO, CAN'T DO THIS THEN
|
||
MOVE T2,TTYL(X) ;GET CURRENT LINE
|
||
SUB T2,L ;SUBTRACT DESIRED LINE
|
||
CHKANL: IMULI T2,(T3) ;COMPUTE CHARS NEEDED TO MOVE UP
|
||
MOVE T3,TTYN(X) ;GET CURRENT COLUMN
|
||
SUB T3,N ;AND SUBTRACT DESIRED COLUMN
|
||
CHKANY: IMULI T3,(T4) ;COMPUTE CHARS NEEDED TO MOVE LEFT
|
||
MOVEI T4,DOANY ;SET UP ROUTINE TO DO ACTION
|
||
|
||
CHKALL: ADD T2,T3 ;ADD TOGETHER
|
||
CAML T2,BEST ;BETTER THAN OLD BEST?
|
||
POPJ P, ;NO, RETURN
|
||
MOVEM T2,BEST ;YES, SAVE NUMBER
|
||
MOVE T1,T4 ;AND ROUTINE TO DO IT
|
||
MOVE T4,TABNUM ;GET NUMBER OF TABS THAT WILL BE USED
|
||
MOVEM T4,TABUSE ;AND SET IT
|
||
POPJ P, ;RETURN
|
||
|
||
;ROUTINE TO COMPUTE COST OF MOVING DOWN AND LEFT.
|
||
|
||
|
||
CHKDL: SKIPN T3,T.DOWN(U) ;CAN WE MOVE DOWN?
|
||
CAMN L,TTYL(X) ;NO, BUT OK IF DON'T HAVE TO
|
||
SKIPN T4,T.LEFT(U) ;CAN WE MOVE LEFT TOO?
|
||
POPJ P, ;NO, RETURN
|
||
MOVE T2,L ;GET DESIRED LINE NUMBER
|
||
SUB T2,TTYL(X) ;SUBTRACT PRESENT LINE
|
||
JRST CHKANL ;JOIN OTHER CODE
|
||
|
||
|
||
|
||
|
||
;ROUTINE TO COMPUTE COST OF MOVING DOWN AND RIGHT.
|
||
|
||
|
||
CHKDR: SKIPN T.DOWN(U) ;SEE IF CAN MOVE DOWN
|
||
CAMN L,TTYL(X) ;OR SEE IF DON'T NEED TO
|
||
JRST .+2 ;OK, PROCEED
|
||
POPJ P, ;CAN'T DO THIS, RETURN
|
||
PUSHJ P,CHKTAB ;COMPUTE COUNT FOR MOVING RIGHT
|
||
MOVE T3,L ;GET LINE TO MOVE TO
|
||
SUB T3,TTYL(X) ;SUBTRACT CURRENT LINE
|
||
MOVE T4,T.DOWN(U) ;GET NUMBER NEEDED TO GO DOWN
|
||
JRST CHKANY ;JOIN COMMON CODE
|
||
|
||
|
||
|
||
|
||
;ROUTINE TO COMPUTE COST OF MOVING UP AND RIGHT.
|
||
|
||
|
||
CHKUR: SKIPN T.UP(U) ;SEE IF WE CAN MOVE UP
|
||
POPJ P, ;NO, RETURN
|
||
PUSHJ P,CHKTAB ;YES, COMPUTE COUNT FOR MOVING RIGHT
|
||
MOVE T3,TTYL(X) ;GET CURRENT LINE
|
||
SUB T3,L ;SUBTRACT DESTINATION LINE
|
||
MOVE T4,T.UP(U) ;GET CHARS NEEDED TO GO UP
|
||
JRST CHKANY ;JOIN OTHER CODE
|
||
|
||
;ROUTINE TO COMPUTE COST OF HOMING UP, THEN MOVING DOWN AND RIGHT.
|
||
|
||
|
||
CHKHDR: SKIPN T.DOWN(U) ;MAKE SURE WE CAN MOVE DOWN
|
||
CAMN L,TTYL(X) ;OR THAT WE DON'T HAVE TO
|
||
SKIPN T.HOM(U) ;AND MAKE SURE WE CAN HOME UP
|
||
POPJ P, ;NO, THEN CAN'T DO THIS
|
||
PUSH P,TTYN(X) ;SAVE CURRENT POSITION
|
||
SETZM TTYN(X) ;CLEAR POSITION AS IF HOME WAS DONE
|
||
PUSHJ P,CHKTAB ;SEE HOW MANY TO MOVE RIGHT
|
||
POP P,TTYN(X) ;RESTORE TRUE COLUMN NUMBER
|
||
MOVE T3,T.HOM(U) ;GET CHARS NEEDED FOR CARRIAGE RETURN
|
||
ADDI T2,(T3) ;ADD INTO TOTAL
|
||
HRRZ T3,T.DOWN(U) ;GET CHARS NEEDED TO DO DOWN
|
||
IMULI T3,(L) ;MULTIPLY BY DESTINATION LINE
|
||
MOVEI T4,DOHDR ;GET ROUTINE FOR THIS ACTION
|
||
JRST CHKALL ;GO SEE IF THIS IS BEST
|
||
|
||
|
||
|
||
;ROUTINE TO COMPUTE COST OF DOING CR, THEN MOVING DOWN AND RIGHT.
|
||
|
||
|
||
CHKCDR: SKIPN T.DOWN(U) ;CAN WE MOVE DOWN?
|
||
CAMN L,TTYL(X) ;OR WE DON'T HAVE TO?
|
||
SKIPN T.CR(U) ;AND CAN WE DO A CARRIAGE RETURN?
|
||
POPJ P, ;NO, RETURN
|
||
PUSH P,TTYN(X) ;SAVE CURRENT POSITION
|
||
SETZM TTYN(X) ;CLEAR POSITION AS IF A CR WAS DONE
|
||
PUSHJ P,CHKTAB ;AND COMPUTE COUNT FOR MOVING RIGHT
|
||
POP P,TTYN(X) ;RESTORE TRUE COLUMN NUMBER
|
||
MOVE T3,T.CR(U) ;GET CHARS USED FOR CARRIAGE RETURN
|
||
ADDI T2,(T3) ;ADD IT IN
|
||
MOVE T3,L ;GET DESTINATION LINE
|
||
SUB T3,TTYL(X) ;AND SUBTRACT CURRENT ONE
|
||
MOVE T4,T.DOWN(U) ;GET CHARS NEEDED TO MOVE DOWN
|
||
IMULI T3,(T4) ;FIND TOTAL CHARS TO MOVE DOWN
|
||
MOVEI T4,DOCDR ;GET ROUTINE TO DO ACTION
|
||
JRST CHKALL ;SEE IS THIS IS BEST METHOD
|
||
|
||
;ROUTINE TO COMPUTE COST OF DOING CARRIAGE RETURN, THEN UP AND RIGHT.
|
||
|
||
|
||
CHKCUR: SKIPE T.CR(U) ;SEE IF CAN DO CARRIAGE RETURN
|
||
SKIPN T.UP(U) ;AND SEE IF CAN GO UP
|
||
POPJ P, ;NO, RETURN
|
||
PUSH P,TTYN(X) ;SAVE CURRENT COLUMN
|
||
SETZM TTYN(X) ;ASSUME WE DID A CARRIAGE RETURN
|
||
PUSHJ P,CHKTAB ;SEE HOW MANY TO MOVE RIGHT
|
||
POP P,TTYN(X) ;RESTORE TRUE COLUMN
|
||
MOVE T3,T.CR(U) ;GET CHARS NEEDED FOR CR
|
||
ADDI T2,(T3) ;ADD IN
|
||
MOVE T3,TTYL(X) ;GET CURRENT LINE NUMBER
|
||
SUB T3,L ;SUBTRACT DESTINATION LINE
|
||
MOVE T4,T.UP(U) ;GET COUNT TO MOVE UP
|
||
IMULI T3,(T4) ;FIND TOTAL CHARS NEEDED TO MOVE DOWN
|
||
MOVEI T4,DOCDR ;GET ROUTINE TO DO ACTION
|
||
JRST CHKALL ;AND SEE IF THIS IS BEST
|
||
|
||
;ROUTINE TO COMPUTE COST OF MOVING RIGHT.
|
||
;THIS IS A SUBROUTINE CALLED BY THE PREVIOUS ROUTINES.
|
||
;IT SAVES THE NUMBER OF TABS NEEDED FOR LATER.
|
||
;RETURNS WITH TOTAL CHARS NEEDED IN AC T2.
|
||
|
||
|
||
CHKTAB: SETZB T2,TABNUM ;CLEAR NUMBER OF TABS NEEDED
|
||
CAMN N,TTYN(X) ;ALREADY AT CORRECT COLUMN?
|
||
POPJ P, ;YES, RETURN NOW
|
||
TRNN F,FR.TAB ;DOES THIS TERMINAL HAVE TABS?
|
||
JRST CHKSPS ;NO, JUST MOVE RIGHT
|
||
MOVE T2,N ;GET COLUMN WE DESIRE TO GET TO
|
||
IORI T2,7 ;MOVE TO FAR RIGHT OF TAB COLUMN
|
||
SUB T2,TTYN(X) ;SUBTRACT CURRENT POSITION
|
||
LSH T2,-3 ;COMPUTE NUMBER OF TABS NEEDED
|
||
MOVEM T2,TABNUM ;SAVE NUMBER OF TABS NECESSARY
|
||
TRNN N,7 ;GOING TO EXACT TAB STOP?
|
||
POPJ P, ;YES, ALL DONE
|
||
JUMPE T2,CHKTBN ;JUMP SOME IF USING NO TABS
|
||
MOVE T3,N ;GET COLUMN MOVING TO
|
||
TRZA T3,7 ;BACK UP TO PREVIOUS TAB STOP
|
||
CHKTBN: MOVE T3,TTYN(X) ;IF NO TABS, GET CURRENT POSITION
|
||
MOVE T2,N ;GET COPY OF POSITION
|
||
SUB T2,T3 ;COMPUTE NUMBER OF SPACES NEEDED
|
||
SKIPN T4,T.LEFT(U) ;CAN WE GO LEFT?
|
||
JRST CHKSPT ;NO, THEN ALWAYS MOVE RIGHT
|
||
MOVEI T3,^D10(N) ;GET COLUMN POSITION PLUS SOME
|
||
CAMLE T3,T.WID(U) ;GETTING NEAR END OF SCREEN?
|
||
JRST CHKSPT ;YES, THEN CAN'T TAB AND BACK UP
|
||
MOVE T3,N ;GET COLUMN TO MOVE TO
|
||
IORI T3,7 ;MOVE TO FAR RIGHT OF COLUMN
|
||
SUBI T3,-1(N) ;COMPUTE COLUMNS TO BACK UP BY
|
||
IMULI T3,(T4) ;MULTIPLY BY CHARS TO BACK UP 1 PLACE
|
||
ADDI T3,1 ;ADD A CHAR DUE TO THE TAB
|
||
CAML T3,T2 ;TAKES LESS CHARS TO BACK UP?
|
||
JRST CHKSPT ;NO, GO USE SPACES
|
||
AOS T2,TABNUM ;YES, INCREMENT TAB COUNT
|
||
ADDI T2,-1(T3) ;ADD CHARS NEEDED TO BACKSPACE
|
||
POPJ P, ;AND RETURN
|
||
|
||
|
||
CHKSPS: MOVE T2,N ;GET COLUMN TO MOVE TO
|
||
SUB T2,TTYN(X) ;SUBTRACT COLUMN WE ARE AT
|
||
CHKSPT: ADD T2,TABNUM ;ADD IN TABS NEEDED
|
||
POPJ P, ;THEN RETURN
|
||
|
||
SUBTTL ROUTINES TO MOVE SLOWLY TO A LOCATION
|
||
|
||
|
||
|
||
;THESE ROUTINES ARE CALLED WITH THE COLUMN AND LINE NUMBERS IN N AND L,
|
||
;AND THE CURRENT POSITION IN TTYN AND TTYL. THE ROUTINE MOVES THE
|
||
;CURSOR LEFT, RIGHT, UP, OR DOWN TO GET THERE.
|
||
|
||
|
||
|
||
DOHDR: PUSHJ P,DOHOM ;HOME UP
|
||
JRST DOANY ;THEN GO TO NORMAL CODE
|
||
|
||
DOCDR: PUSHJ P,DOCR ;DO A CARRIAGE RETURN FIRST
|
||
;THEN FALL INTO NORMAL CODE
|
||
|
||
|
||
|
||
DOANY: CAMN L,TTYL(X) ;ALREADY AT RIGHT LINE?
|
||
JRST MOVCOL ;YES, GO CHECK COLUMN
|
||
CAMG L,TTYL(X) ;WANT TO MOVE DOWN?
|
||
JRST MOVUP ;NO, GO MOVE UP
|
||
|
||
MOVDWN: PUSHJ P,DODOWN ;YES, MOVE THAT WAY
|
||
CAME L,TTYL(X) ;AT RIGHT COLUMN YET?
|
||
JRST MOVDWN ;NO, KEEP GOING
|
||
JRST MOVCOL ;YES, NOW CHECK COLUMN
|
||
|
||
MOVUP: PUSHJ P,DOUP ;MOVE UP
|
||
CAME L,TTYL(X) ;AT RIGHT LINE YET?
|
||
JRST MOVUP ;NO, KEEP LOOKING
|
||
|
||
|
||
|
||
|
||
|
||
MOVCOL: CAMLE N,TTYN(X) ;WANT TO MOVE TO RIGHT?
|
||
JRST MOVRHT ;YES, GO DO IT
|
||
MOVLFT: CAMN N,TTYN(X) ;AT RIGHT COLUMN YET?
|
||
POPJ P, ;YES, RETURN
|
||
PUSHJ P,DOLEFT ;NO, GO LEFT
|
||
JRST MOVLFT ;AND CHECK AGAIN
|
||
|
||
MOVRHT: SKIPN T3,TABUSE ;ANY TABS USED TO MOVE RIGHT?
|
||
JRST MOVSPS ;NO, GO USE SPACES
|
||
PUSHJ P,DOTAB ;YES, OUTPUT A TAB
|
||
SOJG T3,.-1 ;LOOP UNTIL DID THEM ALL
|
||
CAML N,TTYN(X) ;DID WE TAB BEYOND DESTINATION?
|
||
JRST MOVSPS ;NO, GO FINISH WITH SPACES
|
||
|
||
MOVBCK: PUSHJ P,DOLEFT ;YES, MOVE LEFT
|
||
CAMN N,TTYN(X) ;REACHED DESTINATION?
|
||
POPJ P, ;YES, ALL DONE
|
||
JRST MOVBCK ;NO, KEEP GOING
|
||
|
||
|
||
MOVSPS: CAMN N,TTYN(X) ;AT DESTINATION YET?
|
||
POPJ P, ;YES, RETURN
|
||
MOVE T1,TTYL(X) ;GET CURRENT LINE
|
||
IMUL T1,T.WRDS(U) ;MULTIPLY BY WORDS PER LINE
|
||
MOVE T2,TTYN(X) ;GET CURRENT COLUMN
|
||
IDIVI T2,4 ;DIVIDE BY CHARS TO A WORD
|
||
ADD T2,T1 ;ADD IN WORDS INTO THIS LINE
|
||
ADD T2,PNTTAB(T3) ;MAKE A BYTE POINTER
|
||
MOVSPL: ILDB C,T2 ;GET CHAR AT THIS POSITION
|
||
PUSHJ P,DOONE ;OUTPUT IT
|
||
CAME N,TTYN(X) ;REACHED RIGHT PLACE YET?
|
||
JRST MOVSPL ;NO, KEEP GOING
|
||
POPJ P, ;YES, DONE
|
||
|
||
SUBTTL SUBROUTINE TO ADDRESS
|
||
|
||
|
||
|
||
;CALLED WITH NEW X AND Y COORDINATES IN AC'S N AND L, TO ADDRESS TO
|
||
;THAT POSITION. CAN ONLY BE CALLED FOR TERMINALS CAPABLE OF DOING
|
||
;ADDRESSING.
|
||
|
||
|
||
|
||
|
||
|
||
DOADR: DMOVEM L,TTYL(X) ;SET NEW TERMINAL CURSOR POSITION
|
||
MOVE T1,T.ADR(U) ;GET SEQUENCE TO START
|
||
PUSHJ P,SEQOUT ;OUTPUT IT
|
||
TRNE F,FR.ANS ;ANSI STYLE TERMINAL?
|
||
JRST ANSIAD ;YES, ADDRESSING DIFFERS
|
||
HRRZ T3,N ;GET POSITION ON LINE TO GO TO
|
||
ADD T3,T.XOFF(U) ;ADD IN OFFSET FOR OUTPUT
|
||
HRRZ C,L ;GET LINE NUMBER TO GO TO
|
||
ADD C,T.YOFF(U) ;ADD IN ITS OFFSET ALSO
|
||
TRNE F,FR.XBY ;SHOULD X COORDINATE BE FIRST?
|
||
EXCH C,T3 ;YES, SWAP THE COORDINATES
|
||
PUSHJ P,TTYOUT ;OUTPUT THE FIRST COORDINATE
|
||
SKIPE T1,T.ADR2(U) ;ANY FILLER BETWEEN COORDINATES?
|
||
PUSHJ P,SEQOUT ;YES, OUTPUT THAT
|
||
MOVE C,T3 ;GET SECOND COORDINATE
|
||
PUSHJ P,TTYOUT ;OUTPUT IT
|
||
SKIPE T1,T.ADR3(U) ;ANY FILLS AFTER COORDINATE?
|
||
JRST SEQOUT ;YES, GO GIVE IT AND RETURN
|
||
POPJ P, ;NO, ALL DONE
|
||
|
||
|
||
|
||
ANSIAD: SKIPE T1,L ;ANY LINE POSITION?
|
||
PUSHJ P,DECOU1 ;YES, OUTPUT IT
|
||
JUMPE N,ANSIAE ;SKIP SOME IF AT FIRST COLUMN
|
||
MOVEI C,";" ;GET SEPARATOR CHAR
|
||
PUSHJ P,TTYOUT ;OUTPUT IT
|
||
MOVE T1,N ;GET COLUMN
|
||
PUSHJ P,DECOU1 ;OUTPUT IT
|
||
ANSIAE: MOVEI C,"H" ;GET ENDING CHAR
|
||
JRST TTYOUT ;OUTPUT IT
|
||
|
||
SUBTTL SPECIAL SEQUENCE OUTPUT ROUTINES
|
||
|
||
|
||
|
||
|
||
;HERE TO OUTPUT SPECIAL SEQUENCES OF CHARACTERS FOR A TERMINAL.
|
||
;THESE ROUTINES KEEP THE VALUES OF TTYN AND TTYL CORRECT.
|
||
;THESE ROUTINE CAN USE T1, T2, AND C.
|
||
|
||
|
||
|
||
|
||
DOTAB: MOVEI C,7 ;GET SET
|
||
IORM C,TTYN(X) ;SET TO FAR RIGHT OF CURRENT COLUMN
|
||
AOS TTYN(X) ;THEN MOVE TO NEXT TAB STOP
|
||
MOVEI C,TAB ;GET A TAB CHARACTER
|
||
PJRST TTYOUT ;OUTPUT IT AND RETURN
|
||
|
||
|
||
|
||
DOEOL: MOVE T3,LSTNON ;GET LOCATION OF LAST NONSPACE
|
||
CAMGE T3,LSTCHG ;IS LAST CHANGE BEYOND THAT?
|
||
MOVE T3,LSTCHG ;YES, GET THAT LOCATION
|
||
SUB T3,TTYN(X) ;GET NUMBER OF SPACES TO CLEAR LINE
|
||
ADDI T3,1 ;ADD ONE MORE
|
||
SKIPE T1,T.EOL(U) ;GET SEQUENCE TO DO END OF LINE
|
||
CAIGE T3,(T1) ;AND SEE IF FASTER TO TYPE SPACES
|
||
SKIPA C,[SP] ;YES, GET A SPACE
|
||
PJRST SEQOUT ;NO, FASTER TO DO END OF LINE SEQUENCE
|
||
PUSHJ P,DOONE ;OUTPUT A SPACE
|
||
SOJG T3,.-1 ;LOOP REQUIRED TIMES
|
||
POPJ P, ;THEN RETURN
|
||
|
||
|
||
DOUP: SOSA TTYL(X) ;DECREMENT TERMINAL'S LINE NUMBER
|
||
DODOWN: AOSA TTYL(X) ;OR INCREMENT LINE NUMBER
|
||
SKIPA T1,T.UP(U) ;THEN GET SEQUENCE TO MOVE UP
|
||
MOVE T1,T.DOWN(U) ;OR SEQUENCE TO MOVE DOWN
|
||
JRST SEQOUT ;GO OUTPUT IT
|
||
|
||
|
||
DOCR: SETZM TTYN(X) ;CLEAR COLUMN USER SEES CURSER AT
|
||
MOVE T1,T.CR(U) ;GET SEQUENCE TO DO CR
|
||
JRST SEQOUT ;GO OUTPUT IT
|
||
|
||
DOLEFT: SOSA TTYN(X) ;DECREMENT COLUMN NUMBER
|
||
DORHT: AOSA TTYN(X) ;OR INCREMENT IT
|
||
SKIPA T1,T.LEFT(U) ;GET SEQUENCE TO MOVE LEFT
|
||
MOVE T1,T.RHT(U) ;OR SEQUENCE TO MOVE RIGHT
|
||
JRST SEQOUT ;OUTPUT IT AND RETURN
|
||
|
||
|
||
|
||
DOONE: CAIN C,SP ;OUTPUTTING A SPACE?
|
||
MOVE C,T.EATC(U) ;YES, CONVERT TO EATING CHAR
|
||
AOS T1,TTYN(X) ;INCREMENT COLUMN NUMBER
|
||
CAMG T1,T.WID(U) ;AT LAST COLUMN ON LINE?
|
||
JRST TTYOUT ;NO, JUST OUTPUT CHAR AND RETURN
|
||
SOS TTYN(X) ;YES, BACK UP POSITION
|
||
TRNN F,FR.ELC ;GET A CRLF TYPING LAST COLUMN?
|
||
JRST TTYOUT ;NO, THEN TYPE THE CHAR AND RETURN
|
||
MOVE T1,TTYL(X) ;GET CURRENT LINE
|
||
CAML T1,T.LEN(U) ;ON LAST LINE?
|
||
POPJ P, ;YES, DON'T TYPE CHAR OR ELSE SCREEN SCROLLS!
|
||
SETZM TTYN(X) ;NO, CLEAR COLUMN
|
||
AOS TTYL(X) ;INCREMENT LINE NUMBER
|
||
PJRST TTYOUT ;THEN OUTPUT CHARACTER
|
||
|
||
|
||
|
||
DOCLR: SKIPA T1,T.CLR(U) ;GET SEQUENCE TO HOME AND CLEAR
|
||
DOHOM: MOVE T1,T.HOM(U) ;OR GET SEQUENCE TO JUST HOME
|
||
SETZM TTYL(X) ;RESET LINE POSITION USER SEES
|
||
SETZM TTYN(X) ;AND THE COLUMN POSITION
|
||
; PJRST SEQOUT ;GO OUTPUT IT
|
||
|
||
SUBTTL ROUTINES TO OUTPUT SEQUENCES OF CHARACTERS
|
||
|
||
|
||
|
||
|
||
;THIS ROUTINE IS CALLED WITH THE STANDARD POINTER TO A SEQUENCE OF
|
||
;CHARACTERS TO BE OUTPUT IN AC T1. SUCH A POINTER IS OF THE FORM
|
||
; ADDR,,N WHERE N IS THE NUMBER OF CHARACTERS IN THE STRING, AND
|
||
;ADDR IS THE ADDRESS OF THE STRING.
|
||
|
||
|
||
|
||
|
||
SEQOUT: HLRZ T2,T1 ;GET ADDRESS OF STRING
|
||
HRLI T2,(POINT 7,) ;AND MAKE BYTE POINTER TO IT
|
||
ANDI T1,-1 ;KEEP ONLY COUNT
|
||
JUMPE T1,[DIE CDS] ;IF NO CHARS, DIE
|
||
|
||
SEQOUL: ILDB C,T2 ;GET NEXT CHARACTER IN SEQUENCE
|
||
SOJLE T1,TTYOUT ;IF LAST CHAR, GO OUTPUT AND RETURN
|
||
PUSHJ P,TTYOUT ;OUTPUT TO TERMINAL
|
||
JRST SEQOUL ;LOOP
|
||
|
||
|
||
|
||
|
||
|
||
;CALLED TO OUTPUT A DECIMAL NUMBER IN T1. USED FOR ANSI MODE ADDRESSING,
|
||
;WHERE COORDINATES ARE DECIMAL INTEGERS.
|
||
|
||
|
||
DECOU1: ADDI T1,1 ;COORDINATES ARE OFFSET BY ONE
|
||
DECOUT: IDIVI T1,^D10 ;SPLIT OFF A DIGIT
|
||
JUMPE T1,DECFIN ;JUMP IF DONE
|
||
HRLM T2,(P) ;SAVE DIGIT
|
||
PUSHJ P,DECOUT ;LOOP UNTIL HAVE ALL DIGITS
|
||
HLRZ T2,(P) ;GET BACK A DIGIT
|
||
DECFIN: MOVEI C,"0"(T2) ;MAKE INTO ASCII
|
||
JRST TTYOUT ;OUTPUT IT AND RETURN
|
||
|
||
SUBTTL ROUTINES TO CLEAR OR SET IMAGE STATE FOR TERMINAL
|
||
|
||
|
||
|
||
|
||
;CALLED TO SET THE MODE OF THE TERMINAL TO BE IMAGE MODE. THIS MODE
|
||
;IS NECESSARY TO PREVENT THE CONVERSION OF OUR OUTPUT CHARACTERS TO
|
||
;DIFFERENT ONES. IN ADDITION, THE TERMINAL OUTPUT BUFFER IS SET UP.
|
||
;NO AC'S ARE CHANGED. THIS ROUTINE IS NOT NECESSARY FOR TOPS-10.
|
||
|
||
|
||
|
||
|
||
IF20,<
|
||
|
||
SETIMG: PUSH P,[POINT 7,TTYBUF(X)] ;GET BYTE POINTER
|
||
POP P,BUFPTR(X) ;INITIALIZE IT
|
||
SKIPE TTYJFN(X) ;NEED TO GET A JFN?
|
||
POPJ P, ;NO, THEN ALL SET
|
||
PUSH P,T1 ;SAVE SOME AC'S
|
||
PUSH P,T2 ;THAT WE USE
|
||
MOVSI T1,(GJ%SHT+GJ%ACC) ;SHORT FORM, RESTRICTED
|
||
HRROI T2,[ASCIZ/TTY:/] ;OUR TERMINAL
|
||
GTJFN ;GET THE JFN
|
||
DIE IFF ;CAN'T
|
||
MOVEM T1,TTYJFN(X) ;SAVE THE JFN
|
||
MOVE T2,[8B5+OF%WR+OF%RD] ;SET FOR BINARY
|
||
OPENF ;OPEN THE TERMINAL
|
||
DIE IFF ;FAILED
|
||
POP P,T2 ;RESTORE THE ACS
|
||
POP P,T1 ;THAT WERE USED
|
||
POPJ P, ;RETURN
|
||
>
|
||
|
||
SUBTTL ROUTINE TO OUTPUT CHARS TO TTY OR TO USER PROGRAM
|
||
|
||
|
||
|
||
;SUBROUTINE TO SEND CHARACTERS OUT. OUTPUT CAN BE SENT TO THE PROGRAM
|
||
;IF DESIRED. OTHERWISE WE BUFFER UP CHARACTERS AND SEND THEM OUT
|
||
;OURSELVES. CHARACTER TO BE OUTPUT IS IN AC C.
|
||
|
||
|
||
|
||
|
||
TTYOUT: SKIPE OUTADR(X) ;OUTPUT BEING INTERCEPTED?
|
||
JRST USROUT ;YES, GO GIVE IT TO PROGRAM
|
||
|
||
IF20,< TLON F,FL.PNT ;FIRST OUTPUT?
|
||
PUSHJ P,SETIMG ;YES, SET UP BUFFERS AND JFN
|
||
IDPB C,BUFPTR(X) ;STORE CHAR IN BUFFER
|
||
PUSH P,T1 ;SAVE AN AC
|
||
AOS T1,BUFCNT(X) ;INCREMENT COUNT OF STORED CHARACTERS
|
||
CAIL T1,<TTYLEN*5>-1 ;IS BUFFER FULL YET?
|
||
PUSHJ P,PUNT ;YES, FORCE OUT BUFFER
|
||
POP P,T1 ;RESTORE AC
|
||
POPJ P, ;RETURN
|
||
>
|
||
|
||
|
||
IF10,< SKIPN TTYJFN(X) ;HAVE ANY CHANNEL TO OUTPUT TO?
|
||
IONEOU C ;NO, OUTPUT STRAIGHT
|
||
SKIPN TTYJFN(X) ;WELL?
|
||
POPJ P, ;NO, DONE
|
||
PUSH P,T1 ;SAVE AN AC
|
||
HLRZ T1,TTYJFN(X) ;GET BUFFER HEADER ADDRESS
|
||
SOSG 2(T1) ;ANY MORE ROOM LEFT IN BUFFER?
|
||
PUSHJ P,PUNT ;NO, FORCE OUTPUT NOW
|
||
IDPB C,1(T1) ;STORE THE CHARACTER
|
||
TLO F,FL.PNT ;REMEMBER OUTPUT EXISTS
|
||
POP P,T1 ;RESTORE AC
|
||
POPJ P, ;DONE
|
||
>
|
||
|
||
SUBTTL ROUTINE TO FORCE OUT ALL OF TERMINAL OUTPUT SO FAR
|
||
|
||
|
||
|
||
|
||
;ROUTINE TO FORCE OUT TO THE TERMINAL ALL STORED CHARACTERS.
|
||
;NO AC'S ARE CHANGED.
|
||
|
||
|
||
|
||
PUNT: IF20,<
|
||
TLZ F,FL.PNT ;NO LONGER NEED TO PUNT OUTPUT
|
||
SKIPN BUFCNT(X) ;ANY CHARACTERS TO BE OUTPUT?
|
||
POPJ P, ;NO, JUST RETURN
|
||
PUSH P,T1 ;YES, SAVE AN AC
|
||
PUSH P,T2 ;SAVE SOME MORE AC'S
|
||
PUSH P,T3 ;THAT WE NEED
|
||
MOVE T1,TTYJFN(X) ;GET JFN FOR OUTPUT
|
||
HRROI T2,TTYBUF(X) ;FROM TEXT BUFFER
|
||
MOVN T3,BUFCNT(X) ;GET COUNT OF CHARACTERS
|
||
SOUT ;OUTPUT THE CHARS
|
||
SETZM BUFCNT(X) ;CLEAR COUNT
|
||
MOVE T1,[POINT 7,TTYBUF(X)] ;GET A NEW BYTE POINTER
|
||
MOVEM T1,BUFPTR(X) ;AND RESET IT
|
||
POP P,T3 ;RESTORE AC'S
|
||
POP P,T2 ;THAT WERE SAVED
|
||
POP P,T1 ;RESTORE THE AC
|
||
POPJ P, ;AND RETURN
|
||
>
|
||
|
||
|
||
|
||
IF10,<
|
||
|
||
TLZ F,FL.PNT ;NO LONGER NEED TO PUNT OUTPUT
|
||
SKIPN TTYJFN(X) ;ANY OUTPUT CHANNEL SET UP?
|
||
POPJ P, ;NO, DO NOTHING
|
||
MOVEM T1,TEMP ;SAVE AN AC
|
||
HRLZ T1,TTYJFN(X) ;GET CHANNEL
|
||
LSH T1,5 ;POSITION TO AC FIELD
|
||
TLO T1,(<OUT 0,>) ;FINISH THE INSTRUCTION
|
||
EXCH T1,TEMP ;RESTORE AC AND STORE INSTRUCTION
|
||
XCT TEMP ;DO THE I/O
|
||
POPJ P, ;DONE
|
||
DIE OPF ;FAILED
|
||
>
|
||
|
||
SUBTTL ROUTINE TO GIVE CHARS TO USER'S PROGRAM
|
||
|
||
|
||
|
||
;HERE WHEN USER WANTS TO GET OUTPUT WE WOULD NORMALLY GIVE TO THE
|
||
;TERMINAL. THE USER HAS THE CHOICE OF HAVING HIS ORIGINAL AC'S, OR
|
||
;TO BE FASTER, IF FLAG FL.NZP IS SET, WE JUMP DIRECTLY TO
|
||
;HIS ROUTINE, ASSUMING HE DOESN'T HURT ANY AC'S. WE GIVE HIM ONE
|
||
;CHARACTER AT A TIME. THE USER DOES THE FOLLOWING:
|
||
;
|
||
; POP P,AC ;BRING THE CHARACTER OFF OF THE STACK
|
||
; .
|
||
; . ; (THE USER'S RANDOM CODE)
|
||
; .
|
||
; POPJ P, ;RETURN TO DPY AND CONTINUE AS BEFORE
|
||
;
|
||
;CALL AT USRLST WHEN ALL OUTPUT FOR THIS UUO IS FINISHED, TO NOTIFY
|
||
;THE PROGRAM THAT WE ARE DONE BY SENDING A CHARACTER WITH 1B0 SET.
|
||
|
||
|
||
|
||
|
||
USRLST: MOVSI C,(1B0) ;FLAG THIS AS LAST OUTPUT
|
||
USROUT: TLNN F,FL.NZP ;DOES USER WANT HIS OWN ACS?
|
||
JRST USRPAI ;YES, GO DO WORK
|
||
PUSH P,C ;NO, THEN JUST PUSH THE CHAR
|
||
PJRST @OUTADR(X) ;AND GO TO USER'S ROUTINE
|
||
|
||
|
||
;HERE IF WE MUST SAVE THE AC'S BEFORE CALLING USER
|
||
|
||
|
||
USRPAI: PUSH P,[USRRET] ;PUT THE RETURN ADDRESS ON THE STACK
|
||
PUSH P,C ;AND PUT THE CHARACTER ON TOO
|
||
MOVEM F,OURF(X) ;SAVE AN AC OF OURS
|
||
MOVEI F,@OUTADR(X) ;GET ADDRESS OF ROUTINE TO GO TO
|
||
MOVEM F,TEMP ;SAVE IT
|
||
HRLI F,T1 ;SET UP
|
||
HRRI F,OURT1(X) ;BLT POINTER
|
||
BLT F,OURBU+1(X) ;SAVE ALL OF OUR AC'S
|
||
MOVSI U,SAVEF ;NOW GET SET
|
||
BLT U,U ;RESTORE ALL THE USER'S AC'S
|
||
JRST @TEMP ;AND GO TO THE USER'S ROUTINE
|
||
|
||
|
||
USRRET: MOVEM F,SAVEF ;SAVE A USER'S AC
|
||
MOVE F,[T1,,SAVET1] ;GET SET
|
||
BLT F,SAVEU ;SAVE ALL OF USER'S AC'S WE USE
|
||
MOVE X,@DP+$DPADR ;RESTORE RELOCATION AC
|
||
MOVSI U,OURF(X) ;GET SET
|
||
BLT U,U ;RESTORE OUR OWN AC'S
|
||
POPJ P, ;AND RETURN FROM THIS BIG MESS
|
||
|
||
SUBTTL THE ERROR ROUTINE
|
||
|
||
|
||
;WE GET HERE FROM ONE OF THE DIE CALLS, TO DIE. WE EITHER OUTPUT A
|
||
;MESSAGE AND EXIT, OR GO BACK TO THE USER WITH AN ERROR CODE. THE CALL IS:
|
||
;
|
||
; XCT CODE,DIEBIG ;GO DIE, AND GIVE ERROR CODE IN AC FIELD
|
||
;
|
||
;THERE IS NO RETURN. IF THE USER TRAPPED THE ERROR, HE CAN DO THE FOLLOWING:
|
||
;
|
||
; POP P,LOCATION ;RESTORE THE ERROR CODE
|
||
; POPJ P, ;RETURN TO LOCATION AFTER DPY
|
||
; ;CALL WHICH FAILED
|
||
|
||
|
||
DIEBIG: JSP T2,.+1 ;REMEMBER PC SO CAN GET ERROR CODE
|
||
LDB T2,[POINT 4,-1(T2),12] ;GRAB THE CODE
|
||
CAILE T2,MAXERR ;IS IT ILLEGAL !!!!????
|
||
SETZ T2, ;YES, TAME IT SOMEWHAT
|
||
SKIPE ERRADR(X) ;DID USER GIVE US A TRAP ADDRESS?
|
||
JRST TRAP ;YES, GO TO HIM THEN
|
||
|
||
|
||
IF10,< OUTSTR [ASCIZ/
|
||
? DPY - /] ;NO, THEN GIVE SOME OF MESSAGE
|
||
OUTSTR @ERRTAB(T2) ;AND REST
|
||
EXIT 1, ;THEN EXIT
|
||
JRST .-1 ;AND STAY THAT WAY
|
||
>
|
||
|
||
|
||
IF20,< HRROI T1,[ASCIZ/
|
||
? DPY - /] ;GET SOME OF MESSAGE
|
||
PSOUT ;OUTPUT IT
|
||
HRROI T1,@ERRTAB(T2) ;GET REST OF TEXT
|
||
PSOUT ;OUTPUT IT TOO
|
||
HALTF ;QUIT
|
||
JRST .-1 ;AND STAY THAT WAY
|
||
>
|
||
|
||
|
||
|
||
;HERE TO RETURN TO THE USER WITH THE ERROR CODE
|
||
|
||
|
||
TRAP: MOVE P,SAVEP ;RESTORE A POINTER WE KNOW IS GOOD
|
||
PUSH P,T2 ;SAVE THE ERROR CODE ON IT
|
||
MOVE T1,ERRADR(X) ;GET ADDRESS WHERE TO TRAP TO
|
||
MOVEM T1,TEMP ;SAVE IN KNOWN PLACE
|
||
PUSHJ P,RETURN ;RESTORE THE USER'S AC'S
|
||
JRST @TEMP ;JUMP BACK TO USER
|
||
|
||
;HERE ARE THE POSSIBLE ERRORS
|
||
|
||
|
||
|
||
|
||
ERRTAB: ERR UKE,Unknown error
|
||
ERR ILR,Illegal luuo received
|
||
ERR USL,Updated same location twice
|
||
ERR IWS,Illegal window size given
|
||
ERR ISF,Illegal set function given
|
||
ERR ITF,Illegal tty function given
|
||
ERR CDS,Cannot output desired sequence
|
||
ERR OPF,Output error occurred
|
||
ERR IPG,Illegal terminal address given
|
||
ERR ING,Initialize function not given
|
||
ERR IFF,Initialize function failed
|
||
|
||
|
||
MAXERR==.-ERRTAB-1 ;THE MAXIMUM ERROR
|
||
|
||
SUBTTL CONSTANTS AVAILABLE TO USER PROGRAM
|
||
|
||
|
||
;THE FOLLOWING TABLE IS INCLUDED SO THAT THE USER PROGRAM
|
||
;CAN READ SOME PARAMETERS WHICH DPY USES. THESE ARE REFERENCED
|
||
;BY THEIR OFFSET INTO THE DPYTAB TABLE.
|
||
|
||
|
||
|
||
|
||
DP: ;ALTERNATIVE LABEL
|
||
DPYTAB: EXP DATBEG+TERSIZ ;(0) POINTER TO TERMINAL LENGTH
|
||
EXP DATBEG+TERSIZ+1 ;(1) POINTER TO TERMINAL WIDTH
|
||
EXP DATBEG+MINL ;(2) POINTER TO PRESENT WINDOW SIZE
|
||
EXP DATBEG+OVFVAL ;(3) POINTER TO CURRENT WINDOW COUNTER
|
||
EXP DATLEN ;(4) LENGTH OF IMPORTANT DATA
|
||
EXP DATADR ;(5) POINTER TO ADDRESS OF THE DATA
|
||
EXP DATBEG+SCREEN ;(6) ADDRESS OF STORAGE FOR SCREEN
|
||
XWD MAXERR,ERRTAB ;(7) ERROR TABLE -- NOTE NOT RELOCATABLE
|
||
EXP TTYTYP ;(10) POINTER TO TERMINAL TYPE TABLE
|
||
EXP DATBEG+TTYJFN ;(11) POINTER TO JFN USING FOR TTY
|
||
EXP DATBEG+EATNUM ;(12) POINTER TO NUMBER OF LINES TO EAT
|
||
|
||
SUBTTL LOW SEGMENT STORAGE
|
||
|
||
|
||
;FIRST, DUMP OUT ALL THE HIGH-SEG LITERALS
|
||
|
||
XLIST ;LITERALS
|
||
LIT
|
||
LIST
|
||
|
||
|
||
|
||
;HERE IS THE ACTUAL DATA REQUIRED BY THE PROGRAM. THESE ARE IN THE
|
||
;LOW SEGMENT SO THAT THE PROGRAM CAN BE PURE.
|
||
|
||
|
||
RELOC 0 ;MOVE TO LOW SEGMENT NOW
|
||
|
||
|
||
SAVEF: BLOCK 1 ;STORAGE OF THE USER'S AC'S
|
||
SAVET1: BLOCK 1
|
||
SAVET2: BLOCK 1
|
||
SAVET3: BLOCK 1
|
||
SAVET4: BLOCK 1
|
||
SAVEX: BLOCK 1
|
||
SAVEC: BLOCK 1
|
||
SAVEA: BLOCK 1
|
||
SAVEL: BLOCK 1
|
||
SAVEN: BLOCK 1
|
||
SAVEB: BLOCK 1
|
||
SAVEU: BLOCK 1
|
||
ZERO: BLOCK 1 ;CONTAINS ZERO
|
||
SAVEP: BLOCK 1 ;PUSH-POINTER STORED IN CASE OF ERROR
|
||
TEMP: BLOCK 1 ;TEMPORARY STORAGE
|
||
DATADR: BLOCK 1 ;ADDRESS OF THE RELOCATABLE DATA
|
||
INIFLG: BLOCK 1 ;FLAGS FROM INI$ FUNCTION
|
||
INICNT: BLOCK 1 ;NUMBER OF ARGUMENTS IN INI$ FUNCTION
|
||
BEST: BLOCK 1 ;LOWEST NUMBER OF CHARS TO MOVE CURSER
|
||
TABNUM: BLOCK 1 ;NUMBER OF TABS NEEDED TO MOVE TO RIGHT
|
||
TABUSE: BLOCK 1 ;TABS NEEDED IN BEST CASE
|
||
FSTCHG: BLOCK 1 ;FIRST PLACE ON A LINE NEEDING CHANGING
|
||
LSTCHG: BLOCK 1 ;LAST PLACE ON A LINE TO NEED CHANGING
|
||
PRECHG: BLOCK 1 ;LAST PLACE TO CHANGE PRECEEDING PRESENT
|
||
;LOCATION ON A LINE
|
||
LSTNON: BLOCK 1 ;THE LOCATION OF THE LAST NON-SPACE
|
||
|
||
;THE FOLLOWING DATA IS REFERENCED BY INDEXING OFF OF AC X. THUS THE ACTUAL
|
||
;ADDRESS OF THE DATA IS VARIABLE, AND CAN BE SET BY THE USER.
|
||
|
||
|
||
DEFINE WD(SYM,LEN<1>),< ;;MACRO TO DEFINE OFFSETS
|
||
SYM:! BLOCK LEN
|
||
>
|
||
|
||
|
||
DATBEG: PHASE 0 ;THIS DATA IS PHASED SINCE INDEXED OFF OF X
|
||
|
||
WD OURF ;STORAGE FOR OUR AC'S
|
||
WD OURT1
|
||
WD OURT2
|
||
WD OURT3
|
||
WD OURT4
|
||
WD OURX
|
||
WD OURC
|
||
WD OURA
|
||
WD OURLN,2 ;STORAGE FOR ACS L AND N
|
||
WD OURBU,2 ;STORAGE FOR ACS B AND U
|
||
WD MINL ;LOWEST LINE NUMBER IN CURRENT WINDOW
|
||
WD MAXL ;HIGHEST LINE NUMBER IN WINDOW
|
||
WD MINN ;LOWEST COLUMN NUMBER IN WINDOW
|
||
WD MAXN ;HIGHEST COLUMN NUMBER IN WINDOW
|
||
WD TTYL ;LINE NUMBER THE TTY CURSER IS AT NOW
|
||
WD TTYN ;COLUMN NUMBER THE TTY CURSER IS AT NOW
|
||
WD BUFPTR ;BYTE POINTER INTO TTY BUFFER
|
||
WD BUFCNT ;NUMBER OF CHARACTERS IN TTY BUFFER
|
||
WD TTYBUF,TTYLEN ;TTY BUFFER
|
||
WD TERSIZ,2 ;TERMINAL'S LENGTH AND WIDTH
|
||
WD TTYJFN ;JFN OR BUFFER,,CHANNEL FOR OUTPUT
|
||
WD TABS,4 ;BIT TABLE FOR TAB STOPS
|
||
WD SCREEN,MAXARE ;SCREEN STORAGE
|
||
|
||
|
||
;THE REMAINING LOCATIONS ARE CLEARED ON INITIALIZATION:
|
||
|
||
|
||
ZERBLK: WD OUTADR ;ADDRESS OF ROUTINE TO GIVE OUTPUT CHARS TO
|
||
WD ERRADR ;ADDRESS OF ROUTINE TO GO TO ON FATAL ERRORS
|
||
WD OVFVAL ;WINDOW MOVING INFORMATION WHEN ONE FILLS UP
|
||
WD EATNUM ;NUMBER OF LINES TO IGNORE FROM USER
|
||
WD LINCHG,MAXLEN ;FLAGS TO KNOW IF A LINE HAS BEEN CHANGED
|
||
|
||
ZEREND==.-1 ;LAST LOCATION TO ZERO
|
||
|
||
|
||
DATLEN: DEPHASE ;LENGTH OF RELOCATABLE DATA
|
||
|
||
|
||
END
|