; -*-MIDAS-*- TITLE XGP DISPLAY ;FILES MUST END WITH LF OR FF ;NOTE THAT IF I EVER WANT TO ALLOW PAPER TO BE NOT 8.5*11, ;MUST CHANGE CENTER CURSOR COMMAND, AND THE ENDPAG CHECK IN LF. ZR==0 ;SUPER TEMP A=1 B=2 C=3 D=4 E=5 F=6 G=7 H=10 T=11 TT=12 PTO=13 PTI=14 CODE=15 ;ASCII CODE FOR THIS CHAR FONT=16 ;CURRENT FONT P=17 ;STACK POINTER BUFSIZ==6000 ;SIZE OF BUFFER MXSTSZ==200 ;MAX CHARACTER SET SIZE MXNFNT==20 ;MAX NUMBER OF FONTS PDLLEN==40 ;LENGTH OF PDL TTYOCH==1 ;TTY OUTPUT CHANNEL DSKICH==2 ;DISK FILE INPUT FNTICH==3 ;FONT INPUT TTYICH==4 ;TTY OUTPUT ERRICH==5 ;ERR DEVICE %TXTOP==4000 ;"TOP" KEY. %TXSFL==2000 ;"SHIFT-LOCK" KEY. %TXSFT==1000 ;"SHIFT" KEY. %TXMTA==400 ;"META" KEY. %TXCTL==200 ;"CONTROL" KEY. %TXASC==177 ;THE ASCII PART OF THE CHARACTER. %TIFUL==400 ;1 => use the full TV character set if possible. %TJDIS==4000 ;1 => recognize "^P" as an escape for display commands CIOR==16 ;TV ALU FUNCTION TO DO IORM. CSET==17 ;TV ALU FUNCTION TO DO MOVEM. CREGFN==340800 ;BYTE SPEC FOR TV ALU FUNCTIONS .XCREF A,B,C,P PJRST==JRST ;FOR PUSHJ P, FOLLOWED BY POPJ P, DEFINE CONC A,B A!B!TERMIN ;DECREMENT A 7 BIT BYTE POINTER DEFINE DBP7 AC ADD AC,[070000,,0] TLNE AC,400000 SUB AC,[430000,,1] TERMIN LOC 42 JSR TSINT ;INTERRUPT HANDLER ROUTINE FOR TTY INPUT. LOC 100 SUBTTL INITIALIZATION GO: MOVE P,[-PDLLEN,,PDB-1] .CALL [SETZ ;TTY INPUT SIXBIT /OPEN/ [%TIFUL+.UAI,,TTYICH] ;USE FULL CHAR SET SETZ [SIXBIT /TTY/]] .LOSE 1000 .CALL [SETZ ;TTY OUTPUT SIXBIT /OPEN/ [%TJDIS+.UAO,,TTYOCH] ; USE ^P CURSOR CODES SETZ [SIXBIT /TTY/]] .LOSE 1000 .CALL [SETZ ; GET THE TCTYP WORD SIXBIT /CNSGET/ MOVEI TTYOCH MOVEM MOVEM SETZM A] .LOSE 1000 CAIE A,%TNTV ; IS THIS A TV? .VALUE [ASCIZ /:SORRY, XD ONLY WORKS ON TV'SKILL /] MOVEI A,ICORE ; SET UP FREE STORAGE LOSSAGE .CORE (A) .LOSE 1000 MOVEM A,CORSIZ LSH A,12 MOVEM A,FSP SETZM FREE SETZM CHCNT SETZI FONT, ; START WITH NO FONTS .SUSET [.RSNAME,,FILDIR] ; SET UP DEFAULT FILE DIRECTORY .SUSET [.ROPTION,,A] ; IS THERE IS JCL, TLNN A,%OPCMD JRST FI6 ; NO, ACCEPT INPUT FROM THE TTY ; READS INTO JCLBUF AND RETURNS TO FI3. .BREAK 12,[..RJCL,,FILSPC] ; YES, READ IT IN. FI3: MOVE A,[FILDEV,,XDEV] ; SET UP DEFAULTS BLT A,XDIR MOVE H,[440700,,FILSPC] MOVE A,[ILDB A,H] MOVEM A,RXCT ; INSN TO GIVE READER THE JCL. PUSHJ P,READER MOVE A,[XDEV,,FILDEV] ; SET UP THE FILE SPEC BLT A,FILDIR ;OPEN THE FILE AND MAP IT INTO OUR ADDRESS SPACE FI4: .CALL [ SETZ ;OPEN THE USERS FILE AGAIN SIXBIT /OPEN/ [.UAI,,DSKICH] JFFO ERRCOD ;ERROR CODE FILDEV ;FILE SPEC FILFN1 FILFN2 SETZ FILDIR] JRST FI5 ;ERROR IN OPENING FILE. .CALL [SETZ SIXBIT /FILLEN/ MOVEI DSKICH ;CHANNEL SETZM FILLEN] .LOSE 1000 MOVE A,[-200,,100] ;MAP THE DISK FILE INTO ADDRESS SPACE ; STARTING AT LOCATION 200000 SETZ B,0 .CALL [SETZ ;MAP IT IN SIXBIT /CORBLK/ MOVEI %CBRED ;TRY FOR READ ACCESS MOVEI -1 ;HACK MY OWN CORE A ;BLOCK MODE, GRAB AS MUCH AS POSSIBLE MOVEI DSKICH ;CHANNEL SETZ B] ;STARTING AT BEGINNING OF DISK FILE .LOSE 1000 SETZM IOCNT ; SINCE WE HAVEN'T READ ANYTHING IN YET MOVE H,[440700,,200000] ; SET UP THE BYTE POINTER FOR COMSCN, JRST COMSCN ; AND START LOOKING FOR SCRIMP COMMANDS ;HERE FOR ERROR IN OPENING USERS FILE. GIVE HIM ERROR ; MESSAGE ON TTY, AND TRY AGAIN. FI5: MOVEI A,[ASCIZ /ERROR /] PUSHJ P,OUTST1 PUSHJ P,ERRDEV ;TYPE OUT ERROR MESSAGE FROM ERR DEVICE. ;GET FILENAME FROM TTY, WITH RUBOUT PROCESSING. RETURN TO FI3. FI6: MOVEI A,[ASCIZ /INPUT FILE NAME? /] PUSHJ P,OUTSTR MOVE H,[440700,,FILSPC] FI7: .IOT TTYICH,A PUSHJ P,UCASE ANDI A,%TXASC CAIN A,177 ;RUBOUT JRST FI9 IDPB A,H CAIn A,15 JRST FI3 ; cariage return cain a,07 jrst done ; control g cain a,32 jrst done ; control z JRST FI7 ; NOT A CR, GO GET MORE FI9: CAME H,[440700,,FILSPC] ;LEADING RUBOUTS? CAMN H,[10700,,FILSPC-1] JRST FI7 ;IGNORE DBP7 H FI11: .IOT TTYOCH,[^P] .IOT TTYOCH,["X] ;RUB IT OUT JRST FI7 SUBTTL SCRIMP COMMAND SCANNER ;EXPECTS BYTE POINTER IN H. COMSCN: SETZI B, ILDB A,H CAIE A,12 ;IF IT'S A LF CAIN A,15 ;OR A CR JRST COMSCN ;THEN IGNORE IT CAIE A,"; JRST MAIN CM1: ILDB A,H PUSHJ P,UCASE ;MAKE IT UPPER CASE CAIN A,40 ;SPACE, COMMAND WHICH TAKES ARG JRST CM2 CAIN A,15 ;CR, MUST BE COMMAND WHICH TAKES NO ARG JRST [ ILDB A,H JRST COMSCN] ;IGNORE MEANINGLESS COMMAND LSH B,6 CAIL A,"a ;CONVERT TO SIXBIT (USING HACK THAT CAILE A,"z ; LOWER CASE IS ALREADY SIXBIT... SUBI A,40 ANDI A,77 ADD B,A JRST CM1 CM2: CAMN B,[SIXBIT/ KSET/] JRST KSET MOVE C,[-6,,0] CM3: CAMN B,SCRDS(C) JRST DECIN AOBJN C,CM3 COMIGN: ILDB A,H ;SKIP REST OF LINE, AND IGNORE COMMAND CAIE A,12 JRST COMIGN JRST COMSCN ;IGNORE MEANINGLESS COMMAND DECIN: SETZI B, ;READ IN DECIMAL NUMBER DEC1: ILDB A,H CAIN A,40 ;SPACE? JRST DEC1 ;IGNORE. CAIL A,"0 CAILE A,"9 JRST DEC2 IMULI B,10. ADDI B,-"0(A) JRST DEC1 DEC2: CAIE A,". ;DECIMAL POINT? JRST DEC3 DEC4: ILDB A,H CAIE A,15 JRST DEC4 DEC3: MOVEM B,TOPMAR(C) JRST COMSCN SCRDS: SIXBIT /TOPMAR/ SIXBIT /BOTMAR/ SIXBIT /LFTMAR/ SIXBIT / VSP/ SIXBIT / SKIP/ SIXBIT / SIZE/ ; GENERAL PURPOSE ROUTINE TO UPPERCASIFY A LETTER IN A. UCASE: trne a,%txctl andi a,37 CAIL A,"a CAILE A,"z POPJ P, ;NOT LOWER CASE SUBI A,40 ;MAKE IT UPPER CASE CPOPJ: POPJ P, ;ROUTINES USED BY COMSCN KSET: MOVE A,[KDEFLT,,XDEV] ; SET UP THE KSET DEFAULTS BLT A,XDIR MOVE A,[ILDB A,H] ; INSTRUCTION TO FETCH A CHAR MOVEM A,RXCT PUSHJ P,READER ; AND READ IN A FILENAME JUMPL A,[SETZM FONDEV(FONT) ; IF NO FILENAME WAS READ, GO HERE. JRST KSET1] MOVE B,XDEV ; STOW AWAY THE RESULTS MOVEM B,FONDEV(FONT) MOVE B,XFN1 MOVEM B,FONFN1(FONT) MOVE B,XFN2 MOVEM B,FONFN2(FONT) MOVE B,XDIR MOVEM B,FONDIR(FONT) KSET1: ADDI FONT,1 ; COUNT ANOTHER FONT HLLI A, ;CLEAR LEFT HALF CAIE A,", ; WAS THE LAST CHAR A COMMA? JRST COMSCN JRST KSET ; YES, GO BACK FOR MORE SUBTTL GET FONTS, INITIALIZE ;;; ENTER HERE WITH FONT=0 IF NO FONTS WERE SPECIFIED, OR FONT = <# OF FONTS> MAIN: ; ****** THIS IS AN INELEGANT KLUDGE, I REALIZE, BUT AT LEAST ; I'M DOCUMENTING IT... IF LUSER HAS SPECIFIED NO FONTS AT ALL, GIVE ; HIM THE DEFAULT AND READ IT IN ANYWAY. JUMPN FONT,[ SUBI FONT,1 JRST M9] MOVE B,KDEFLT ;MOVE IN THE DEFAULT MOVEM B,FONDEV MOVE B,KDEFLT+1 MOVEM B,FONFN1 MOVE B,KDEFLT+2 MOVEM B,FONFN2 MOVE B,KDEFLT+3 MOVEM B,FONDIR ; ****** END OF INELEGANT KLUDGE. ;NOW FONT=INDEX OF HIGHEST FONT. M9: MOVEM FONT,NFONTS SKIPE FONDEV(FONT) ;IF DEVICE=0, THIS FONT WAS NOT SPECIFIED PUSHJ P,KSTRED SOJGE FONT,.-2 PUSHJ P,REORG ;GENERATE THE REORGANIZED COPY OF THE FONTS MOVE A,CORSIZ ;SAVE NEW FREE CORE STATISTICS MOVEM A,FCRSIZ LSH A,12 MOVEM A,FCORE ;OPEN THE TV BUFFER AT TVBBAS MOVE A,[-11,,TVBBAS/2000] SETZI B, .CALL [SETZ SIXBIT /CORBLK/ MOVEI %CBWRT+%CBRED ;TRY FOR READ AND WRITE ACCESS MOVEI -1 ;HACK MY OWN CORE A ;BLOCK MODE, GET ALL 10 PAGES OF TV BUFFER ; AND PUT THEM AT TVBBAS MOVEI %JSTVB ;VIDEO BUFFER PAGES SETZ B] ;STARTING AT ZERO PAGE OF THE TV BUFFER .LOSE 1000 ;INITIALIZE VARIOUS VARIABLES PUSHJ P,ICHBP SETZM XOFF ;START OFF IN HOME POSITION SETZM YOFF SETZM GOPAGC PUSHJ P,DSPLAY ;DISPLAY THE FIRST PAGE MOVE A,BCHBP MOVEM A,CHBP pushj p,port .SUSET [.SMSK2,,[1_TTYICH]] ;ENABLE INTERRUPT JRST CURSOR SUBTTL MAIN DISPATCH ROUTINE CURSOR: SETZM INTFLG ;WE DON'T WANT INTERRUPTS NOW .IOT TTYOCH,[^P] ;HOME DOWN CURSOR .IOT TTYOCH,["Z] SKIPN FLAG ;THIS IS THE HACK FOR PEOPLE WHO GO OFF THE END ; OF THE FILE WITH THE P COMMAND. JRST CUR2 MOVEI A,[ASCIZ/SORRY, THAT EXCEEDS THE LENGTH OF THE FILE./] PUSHJ P,OUTSTR SETZM FLAG JRST CURSOR CUR2: MOVEI A,[ASCIZ/PAGE #/] PUSHJ P,OUTST1 MOVE A,PAGENO PUSHJ P,DECTYP ;TYPE OUT PAGE NUMBER MOVEI A,[ASCIZ/ -->/] PUSHJ P,OUTST1 .IOT TTYICH,A SETZI C, CUR1: TRZ A,%TXSFL+%TXSFT ;COMPUTE THE MULTIPLIER IN B MOVEI B,1 TRZE A,%TXTOP LSH B,4 ;TOP TRZE A,%TXMTA LSH B,2 ;META TRZE A,%TXCTL LSH B,1 ;CONTROL CAIE A,"[ ;OPEN-BRACKET CAIN A,"{ ;OR OPEN-BRACE JRST LEFT CAIE A,"] ;CLOSE-BRACKET CAIN A,"} ;OR CLOSE-BRACE JRST RIGHT CAIE A,"\ ;BACKSLASH CAIN A,"| ;OR VERTICAL LINE JRST UP CAIE A,"/ ;SLASH CAIN A,16 ;OR INFINITY-SIGN JRST DOWN PUSHJ P,UCASE ;MAKE IT UPPER CASE CAIN A,"N ;MAIN DISPATCH TABLE JRST NEXTPG CAIN A,"Q JRST DONE CAIN A,"R JRST SHOW1 CAIN A,"H JRST HOME CAIN A,"C JRST CENTER CAIN A,^F ; (TOP C) JRST TOPCEN CAIN A,"A JRST SKIPAG CAIN A,"P JRST GOPAG CAIN A,"? JRST HELP CAIN A,"M JRST [ SETOM MODE JRST SHOW] CAIGE A,"0 JRST CURSOR CAILE A,"9 JRST CURSOR JRST RD1 RDDEC: .IOT TTYICH,A ;READ IN A DECIMAL #, DIGITS IN A, RETURN IT IN C ANDI A,%TXASC CAIL A,"0 CAILE A,"9 JRST CUR1 RD1: IMULI C,10. ADDI C,-"0(A) JRST RDDEC SUBTTL RANDOM COMMANDS LEFT: MOVEI A,60 IMUL A,B ADDM A,XOFF JRST SHOW1 RIGHT: MOVE A,[-60] IMUL A,B ADDM A,XOFF JRST SHOW1 UP: MOVEI A,60 IMUL A,B ADDM A,YOFF JRST SHOW1 DOWN: MOVE A,[-60] IMUL A,B ADDM A,YOFF JRST SHOW1 HOME: SETZM XOFF SETZM YOFF JRST SHOW1 CENTER: MOVEI A,1100 MOVEM A,XOFF MOVEI A,1500 MOVEM A,YOFF JRST SHOW1 TOPCEN: MOVEI A,1100 MOVEM A,XOFF SETZM YOFF JRST SHOW1 HELP: MOVEI A,[ASCIZ# XD COMMANDS: N---NEXT PAGE H---HOME WINDOW TO TOP LEFT C---CENTER WINDOW ON PAGE TOP-C MOVE WINDOW TO TOP CENTER OF PAGE Q---QUIT R---REDISPLAY PAGE M--REDISPLAY PAGE IN MINI-DISPLAY MODE nA--ADVANCE n PAGES nP--GO TO nTH PAGE ?---TYPE THIS CRUFT [---MOVE PAGE LEFT \ / CTRL MULTIPLIES BY 2 ]---MOVE PAGE RIGHT |--| META MULTIPLIES BY 4 \---MOVE PAGE UP | | TOP MULTIPLIES BY 8 /---MOVE PAGE DOWN / \ SHIFT IS IGNORED FOR MORE DETAILED INSTRUCTIONS, SEE .INFO.;XD ORDER. #] PUSHJ P,OUTSTR JRST CURSOR SUBTTL PAGE MOVING ROUTINES SHOW1: SETZM MODE ;(ENTRY TO RETURN TO REGULAR MODE) SHOW: PUSHJ P,DSPLAY ;REDISPLAY THE PAGE MOVE A,BCHBP MOVEM A,CHBP pushj p,port JRST CURSOR port: movei a,cset dpb a,[cregfn,,creg] ; do MOVEMs movei c,38. movei a,18. move b,[400000,,000020] port1: movem b,tvbbas+17.(a) addi a,18. sojg c,port1 hrrei b,-20 movem b,tvbbas+17. movem b,tvbbas+17.+<18.*39.> movei a,cior dpb a,[cregfn,,creg] ; do IORs move c,[777000,,0] move d,xoff idiv d,[-60] lsh c,(d) movei d,9. move a,yoff idivi a,60 imuli a,18. port2: movem c,tvbbas+17.(a) addi a,18. sojg d,port2 popj p, DONE: .BREAK 16,160000 NEXTPG: MOVEI C,1 SKIPAG: JUMPLE C,CURSOR ;SKIPS OVER THE NUMBER OF PAGES DESIGNATED IN C MOVE A,PAGENO MOVEM A,SPAGEN SK4: MOVE B,TOPMAR ; MINUS 1 ADD B,BOTMAR SK1: PUSHJ P,FILEND JRST SLOSES ;ERROR RETURN, END OF FILE PUSH P,B PUSHJ P,SCAN ;CHECK FOR FALLING OFF THE PHYSICAL PAGE POP P,B ADD B,MXDP ADD B,MXBS CAIL B,2200. JRST SK3 SK2: ILDB A,CHBP CAIN A,12 ;LINE FEED JRST SK1 CAIN A,14 ;FORM FEED JRST SK3 CAIE A,177 ;XGP ESCAPE JRST SK2 ;NORMAL CHARACTER, KEEP GOING ILDB A,CHBP ;INTERPRET ESCAPED CHARACTER CAILE A,3 JRST SK2 ;NOTHING INTERESTING JRST @.+1(A) ;DISPATCH ON TYPE OF ESCAPE CODE SK2 SKESC1 SKESC2 SKESC3 SKESC1: ILDB A,CHBP CAIGE A,40 JRST SK2 ;LOW NUMBERS ARE FONT CHANGES CAIL A,40+X1DSPL .VALUE [ASCIZ / : Error! This file contains XGP commands not supported here. Please :BUG XD for help.  /] JRST @.+1-40(A) SKE1T: SKIP2 ;40 SKIP3 ;41 SKIP1 ;42 SKIP1 ;43 [.VALUE] ;44 [.VALUE] ;45 SK2 ;46 SKIP1 ;47 SKIP1 ;50 SKIP2 ;51 SKIP1 ;52 SKIP3 ;53 SKIP3: IBP CHBP SKESC3: SKIP2: IBP CHBP SKESC2: SKIP1: IBP CHBP JRST SK2 SK3: AOS PAGENO SOJLE C,SK5 JRST SK4 SK5: PUSHJ P,FILEND JRST SLOSES MOVE A,CHBP MOVEM A,BCHBP JRST SHOW GOPAG: SUB C,PAGENO JUMPE C,SHOW ;GO TO RIGHT HERE JUMPG C,SKIPAG ;SKIP UNTIL WE GET THERE ADD C,PAGENO ;WE MUST GO BACK TO THE BEGINNING PUSHJ P,ICHBP ;REINITIALIZE CHBP AND PAGENO SUBI C,1 ;BECAUSE TO GO TO N FROM 1, YOIU SKIP N-1 CAIE C,0 JRST SKIPAG ; PUSHJ P,DSPLAY ; MOVE A,BCHBP ; MOVEM A,CHBP ; JRST CURSOR jrst show SLOSES: SETOM FLAG ;SO THAT IT PRINTS THE MESSAGE PUSHJ P,ICHBP ;REINITIALIZE CHBP AND PAGENO MOVE C,SPAGEN ;GO BACK TO WHERE HE CAME FROM JRST GOPAG SUBTTL DISPLAY THE PAGE DSPLAY: SETOM INTFLG ;ALLOW INTERRUPTS .STATUS TTYICH,A TRNN A,20000 ;PENDING CHARACTERS? JRST DS5 ;NO, GO AHEAD POP P, ;IGNORE SAVED RETURN ADDRESS JRST CURSOR DS5: .IOT TTYOCH,[^P] ;HOME DOWN CURSOR .IOT TTYOCH,["Z] .iot ttyoch,[^P] ; clear to end of line .iot ttyoch,["L] MOVEI A,3 ;WAIT 1/10 SEC FOR 11 TO BLINK CURSOR. .SLEEP A, ; (SUPER-HAIRY PROCESS COORDINATION.) MOVEI A,CSET ;SET ALU FUNCTION TO DO MOVEMS. DPB A,[CREGFN,,CREG] MOVE A,[-17754,,TVBBAS] ;CLEAR THE TV SETZM (A) ;(CANNOT USE BLT HACK SINCE TV MEMORY IS AOBJN A,.-1 ; TOO UNRELIABLE, AND IT'S SLOWER) SETZI FONT, MOVEI A,CIOR DPB A,[CREGFN,,CREG] ;SET ALU FUNCTION TO DO IORMS SKIPL MODE ;IF IN M-MODE, PRINT OUT THE BORDER JRST DS1 ;THE XGP IS 1700 DOTS ACROSS. WE SQUEEZE BY 4, GIVING US 425 TV DOTS ; IN THE TOP AND BOTTOM LINES. WITH 32 BITS PER WORD DISPLAYED, THIS IS ; 13 WORDS PLUS 9 BITS. THE TOP LINE IS ON THE TOP OF THE TV, AND THE ; BOTTOM LINE IS 2200./5.=440. LINES DOWN AND STARTS AT TVBBAS+440.*18.=7920. MOVE C,[-13.,,0] HRREI A,-20 DS2: MOVEM A,TVBBAS(C) MOVEM A,TVBBAS+7920.(C) AOBJN C,DS2 HRLZI A,-1000 MOVEM A,TVBBAS(C) MOVEM A,TVBBAS+7920.(C) ;NOW PUT IN THE RIGHT AND LEFT WALLS. THERE ARE 440. TV LINES TO BE ; CHANGED, AND THE BITS TO BE SET ARE THE FIRST BIT AND THE 14TH WORD'S ; 9TH BIT FORM THE LEFT. MOVEI C,440. SETZI D, HRLZI A,400000 HRLZI B,1000 DS3: IORM A,TVBBAS(D) IORM B,TVBBAS+13.(D) ADDI D,18. SOJG C,DS3 DS1: MOVE A,LFTMAR ;INITIALIZE TVXP, TVYP, ETC. SUB A,XOFF MOVEM A,TVXP MOVEM A,ITVXP MOVE A,TOPMAR SUB A,YOFF MOVEM A,TVYP MOVEM A,ITVYP IMULI A,18. ADDI A,TVBBAS MOVEM A,LTVWD MOVEI A,576. MOVEM A,MXTVXP SETZM STTVYP ;; FOLLOWING PARAGRAPH IS A KLUDGE SO THAT XESC3'S ARE HACKED ON THE FIRST LINE ;; OF A PAGE. SETZM X3FLAG PUSHJ P,SCAN SKIPN X3FLAG JRST NEWCHR MOVE A,X3VAL ; THERE WAS AN XGP ESACPE 3. SUB A,YOFF MOVEM A,TVYP MOVEM A,ITVYP IMULI A,18. ADDI A,TVBBAS MOVEM A,LTVWD ; CONVERT INTO AN ADDRESS IN TV MEMORY NEWCHR: ILDB A,CHBP CAIN A,0 ;IGNORE NULL BYTE JRST NEWCHR CAIG A,7 JRST NORMAL CAIN A,13 JRST NORMAL CAIN A,177 JRST ESCAPE CAILE A,15 JRST NORMAL JRST @DISTAB-10(A) ;DISPATCH TABLE ;This routine is used for displying characters which are handled ; normally by the xgp. "Normal" decides which version of tvchr to use, and ; also handles the xgp's feature that characters off the end of the paper ; do not get printed. (it may be that the xgp will print part of a char on the ; very edge of the paper, but since this is not ever a desirable feature, etc., ; xd simply doesn't print such chars at all. This seems like a reasonable short-cut.) NORMAL: MOVE CODE,A MOVE A,@CHARDT(FONT) HRRZ A,(A) ;CHARACTER WIDTH ADD A,TVXP ADD A,XOFF ;IGNORE OFFSET CAIL A,1700. ;IS RIGHT EDGE OF CHAR OFF THE PAPER? JRST NEWCHR ; YES, FORGET IT. SKIPGE MODE ;ARE WE IN M-MODE? JRST [ PUSHJ P,MTVCHR ;YES JRST NEWCHR] MOVE A,TVYP ;NO, WE MUST BE IN NORMAL MODE CAIL A,454. ;ALL OFF BOTTOM? JRST NEWCHR ADD A,MXBS ADD A,MXDP CAIL A,0 ;ALL OFF TOP? PUSHJ P,TVCHR JRST NEWCHR DISTAB: BS ;BACKSPACE TAB ;TAB LF ;LINEFEED 0 ;SHOULDN'T HAPPEN, 13 IS NORMAL FF ;FORM FEED CR ;CARRIAGE RETURN ESCAPE: ILDB A,CHBP CAIN A,13 JRST RES ;RESERVED CAIN A,0 JRST NORMAL CAIG A,7 JRST @EDSTAB-1(A) ;ESCAPE DISPATCH TABLE CAIL A,40 JRST NORMAL CAIG A,16 JRST NORMAL JRST RES EDSTAB: XESC1 XESC2 XESC3 XESC4 RES ;NEW XGP ESCAPES WOULD GO HERE RES RES BS: MOVEI CODE,40 ;SPACE MOVE A,@CHARDT(FONT) HRRZ A,(A) ;CHAR WIDTH MOVN A,A ADDM A,TVXP JRST NEWCHR TAB: MOVE A,TVXP ADD A,XOFF ;TO GET XGPXP SUB A,LFTMAR ;COMPENSATE FOR MARGIN MOVE CODE,C40 MOVE F,@CHARDT(FONT) HRRZ C,(F) ;CHARACTER WIDTH OF A SPACE IN THIS FONT ADD A,C ;TAB ALWAYS GOES AT LEAST ONE SPACE IMULI C,8. IDIV A,C AOJ A, IMUL A,C ;ROUND UP SUB A,XOFF ;UNCOMPENSATE FOR OFFSET ADD A,LFTMAR ;UNCOMPENSATE FOR MARGIN MOVEM A,TVXP JRST NEWCHR FF: POPJ P, CR: MOVE A,LFTMAR SUB A,XOFF MOVEM A,TVXP JRST NEWCHR RES: JRST NEWCHR LF: SETZM ICS ;ICS RESET AT END OF LINE PUSHJ P,FILEND POPJ P, ;HACK THE RESETTING OF THE X POSITION. MOVE A,LFTMAR SUB A,XOFF MOVEM A,TVXP MOVEM A,ITVXP ;SCAN SETZM X3FLAG PUSHJ P,SCAN ;NOW FIGURE OUT WHAT HAPPENED TO THE Y POSITION. FIRST LOOKS FOR XESC3'S. SKIPN X3FLAG JRST LF1 MOVE A,X3VAL ; THERE WAS AN XGP ESACPE 3. SUB A,YOFF JRST LF3 ;NO XESC3'S. NOW, WAS THIS AN XESC1 42 RATHER THAN A REAL LF? LF1: SKIPN LSFLAG ; THIS WANSN'T REALLY A LF, IT WAS AN XESC1 42 JRST LF2 SETZM LSFLAG MOVE A,MXDP ADD A,MXBS CAMGE A,LS MOVE A,LS ADD A,ITVYP JRST LF3 LF2: MOVE A,MXDP ; COMPUTE THE NEW TVYP FROM THE OLD TVYP. ADD A,MXBS ; (THESE ARE THE SCANNER PARAMETERS OF THE OLD LINE.) ADD A,VSP ; (FROM THE ";VSP" COMMAND.) ADD A,ITVYP ; INITIAL TVYP OF THE OLD LINE ;HERE A HAS THE NEW TV Y POSITION. LF3: MOVEM A,TVYP ; GOT IT, BUT MAY OVERRIDE LATER IN SCANNER. MOVEM A,ITVYP IMULI A,18. ADDI A,TVBBAS MOVEM A,LTVWD ; CONVERT INTO AN ADDRESS IN TV MEMORY ;NOW CHECK FOR AUTO-EJECT, USING THE RESULTS OF SCAN. MOVE A,MXBS ADD A,MXDP ADD A,TVYP ; (WHICH WE JUST COMPUTED ABOVE) ADD A,YOFF ; TURN IT INTO AN XGPYP ADD A,BOTMAR CAILE A,2200. ; NUMBER OF SCAN LINES ON AN 11 INCH PAGE POPJ P, ; AUTOMATIC EJECT STRIKES AGAIN. JRST NEWCHR XESC1: ILDB A,CHBP CAIL A,40+X1DSPL .VALUE [ASCIZ / : Error! This file contains XGP commands not supported here. Please :BUG XD for help.  /] CAIL A,40 JRST @X1DSP-40(A) MOVE FONT,A MOVE A,[BASE,,ABASE] BLT A,ABASE+MXNFNT-1 JRST NEWCHR X1DSP: X40 X41 X42 X43 XHUH XHUH X46 X47 X50 X51 X52 X53 X1DSPL=.-X1DSP X40: PUSHJ P,G2CHBP ; XGP COLUMN SELECT, ASCII SPACE SUB B,XOFF ; NEXT TWO BITS ARE 14-BIT NEW XGPXP MOVEM B,TVXP JRST NEWCHR ;GET A 14-BIT NUMBER FROM THE CHBP STREAM INTO B. CLOBBERS A. G2CHBP: ILDB A,CHBP MOVE B,A LSH B,7 ILDB A,CHBP ADD B,A POPJ P, X41: ILDB A,CHBP ;XGP UNDERSCORE, ASCII ! MOVE B,A ; NEXT 7 BITS TWO'S-COMP. SCAN LINE OFFSET TRNE B,100 ;EXTEND SIGN. SUBI B,200 ILDB A,CHBP ; (POSITIVE => DOWN) NEXT 14 BITS LENGTH OF MOVE C,A ; UNDERSCORE LSH C,7 ILDB A,CHBP ADD A,C MOVE C,TVXP PUSHJ P,UNDRSC ;(THIS ROUTINE DOES THE WORK) JRST NEWCHR X42: ILDB A,CHBP ;LINE SPACE, ASCII " MOVEM A,LS ;DO LF, AND NEXT 7 BITS # OF LINES BETWEEN THIS LINES SETOM LSFLAG ;BASELINE, AND THE NEW LINE'S. JRST LF X43: ILDB A,CHBP ;BASE-LINE ADJUST, ASCII # CAILE A,77 ;NEXT SEVEN BITS ARE ADDED TO BASELINE TEMPORARILY SUBI A,200 ;NEGATIVE? ADD A,BASE(FONT) MOVEM A,ABASE(FONT) JRST NEWCHR X46: MOVE A,TVXP ;START UNDERSCORE, ASCII & MOVEM A,STAUND JRST NEWCHR X47: ILDB A,CHBP ;STOP UNDERSCORE, ASCII ' MOVE B,A ; BYTE IS SCAN LINE INCREMENT, LIKE X41 TRNE B,100 ;EXTEND SIGN. SUBI B,200 MOVE A,TVXP MOVE C,STAUND SUB A,C PUSHJ P,UNDRSC JRST NEWCHR X50: ILDB A,CHBP ;INTERCHARACTER SPACING, ASCII ( MOVEM A,ICS JRST NEWCHR X51: ILDB D,CHBP ;THICKNESS OF UNDERLINE ILDB B,CHBP TRNE B,100 ;EXTEND SIGN. SUBI B,200 JUMPLE D,NEWCHR MOVE A,TVXP MOVE C,STAUND SUB A,C X51A: PUSH P,D PUSHJ P,UNDRSC POP P,D ADDI B,1 SOJG D,X51A JRST NEWCHR X52: ILDB A,CHBP ;RELATIVE BASE-LINE ADJUST, ASCII # CAILE A,77 ;NEXT SEVEN BITS ARE ADDED TO ADJUSTED BASELINE TEMPORARILY SUBI A,200 ;NEGATIVE? ADD A,ABASE(FONT) MOVEM A,ABASE(FONT) JRST NEWCHR X53: ILDB A,CHBP ;RELATIVE XGP UNDERSCORE, ASCII ! MOVE B,A ; NEXT 7 BITS TWO'S-COMP. SCAN LINE OFFSET TRNE B,100 ;EXTEND SIGN. SUBI B,200 ILDB A,CHBP ; (POSITIVE => DOWN) NEXT 14 BITS LENGTH OF MOVE C,A ; UNDERSCORE LSH C,7 ILDB A,CHBP ADD A,C MOVE C,TVXP ADD B,BASE(FONT) SUB B,ABASE(FONT) PUSHJ P,UNDRSC ;(THIS ROUTINE DOES THE WORK) JRST NEWCHR XESC2: ILDB A,CHBP ;NEXT 7 BITS ARE XGPXP INCREMENT CAILE A,77 SUBI A,200 ADDM A,TVXP JRST NEWCHR XESC3: ILDB A,CHBP ;SCAN LINE OF THIS TEXT LINE MOVE B,A LSH B,7 ILDB A,CHBP ADD B,A MOVEM B,STTVYP JRST NEWCHR XESC4: JRST NEWCHR XHUH: .VALUE [ASCIZ /:NO SUCH XESC/] SUBTTL UNDERSCORE ROUTINE ; Arguments passed to this routine ; A / length of underscore ; B / baseline increment ; C / starting tv x-position UNDRSC: PUSH P,A PUSH P,B PUSH P,C ADD B,TVYP ADD B,MXBS ; Now, B / the tvyp of the underscore. JUMPL B,UNDR9 CAIGE B,454. CAIL C,576. JRST UNDR9 SKIPE MODE JRST UNDR9 ;NO UNDERSCORES IN MINI-MODE!!!! MOVEI D,576. SUB D,C ;ROOM TO THE RIGHT CAIL A,(D) MOVEI A,(D) ;TRUNCATE ON THE RIGHT JUMPGE C,UNDRS1 ADD A,C ;TRUNCATE ON THE LEFT SETZI C, UNDRS1: JUMPLE A,UNDR9 LDB D,[053700,,C] ;WORD-ADDRESS PART OF C. MOVE E,B IMULI E,18. ADDI D,TVBBAS(E) MOVNI G,20 MOVNI H,1 ;NOW ALL ARGUMENTS DESCRIBE A PERFECTLY LEGAL LINE, ALL ON THE SCREEN. ;THE FOLLOWING IS A PER-WORD LOOP. WHEN WE GET HERE THE ACS ARE SET UP TO: ; A / NUMBER OF POINTS REMAINING TO HACK ; B / Y POSITION ; C / X POSITION ; D / CURRENT WORD'S EFFECTIVE ADDRESS ; G / WORD OF ONES TO MOVEM ; H / WORD FULL OF ONES TO DPB UNDL: LDB E,[000500,,C] ;BIT-POSITION PART. MOVNS E ADDI E,32. ;BITS REMAINING IN CURRENT WORD CAIL E,(A) MOVE E,A ;E / # OF BITS TO HACK THIS TIME AROUND THE LOOP ; = MIN(BITS_LEFT_IN_WORD,BITS_LEFT_TO_DO) CAIN E,32. JRST UNDWRD ;WHOLE WORD, DO QUICKLY LDB F,[000500,,C] ;BIT POSITION IN WORD MOVNS F ADDI F,36. SUBI F,(E) ;F / 36. - SIZE_OF_BYTE - BIT_POS_IN_WORD LSH F,36 ;PUT IN PP FIELD DPB E,[300600,,F] ;PUT IN THE SS FIELD HRR F,D ;F / BP TO THE BYTE WE WANT TO HACK DPB H,F ;PUT IN ONES. JRST UNDXL UNDWRD: MOVEM G,(D) UNDXL: SUBI A,(E) JUMPE A,UNDR9 ADDI C,(E) AOJA D,UNDL UNDR9: POP P,C POP P,B POP P,A POPJ P, SUBTTL READ IN FONT COMMENT $ XD INTERNAL FORMAT CHARD(CODE) ;points to character description FORMAT OF CHARACTER DESCRIPTION LEFT_KERN,,CHARACTER_WIDTH ;used to be CHARIACTER ID WORDS_PER_RASTER_LINE,,RASTER_WIDTH CHARACTER_MATRIX ;THE MATRIX IS STORED ONE COLUMN OF BYTES AT A TIME, ;INVERTED FROM THE KST SO IT GOES THE RIGHT WAY. $ KSTRED: .CALL [SETZ ;OPEN THE FONT FIE SIXBIT /OPEN/ JFFO ERRCOD ;ERROR CODE [.BII,,FNTICH] FONDEV(FONT) ;FILE SPEC, INDEXED BY FONT FONFN1(FONT) FONFN2(FONT) SETZ FONDIR(FONT)] JRST NOFONT SETZM IOCNT PUSHJ P,WORDIN ;READ KST ID WORD. (UNUSED) MOVEM A,KSTID(FONT) PUSHJ P,WORDIN ;READ IN HEIGHT,BASE LINE,CPA HRRZM A,HEIGHT(FONT) LDB B,[221100,,A] MOVEM B,BASE(FONT) MOVEM B,ABASE(FONT) ;INITIAL BASE LINE ADJUST IS ZERO LDB B,[331100,,A] MOVEM B,CPA(FONT) SETZI CODE, ;ZERO OUT THE CHARDT BLOCK MOVE A,CHARDT(FONT) SETZM (A) MOVEI B,MXSTSZ-1(A) HRL A,A ADDI A,1 BLT A,B ;I.E., THE BLT HACK MOVEI E,MXSTSZ ;FOR EACH CHAR. IN THE FONT... KST1: PUSHJ P,CHARIN ;CHEW UP A CHAR. MOVE A,MISSED JUMPN A,KST2 KST3: SOJG E,KST1 ;LOOP AROUND KST4: .CLOSE FNTICH, ;LEAVE POPJ P, KST2: SKIPE IOCNT ;IF IOCNT=0 AND MISSED0, IT IS THE END OF THE FILE JRST KST3 JRST KST4 NOFONT: MOVEI A,[ASCIZ /ERROR READING FONT FILE:/] PUSHJ P,OUTSTR IRPS XXX,DEL,[DEV: DIR; FN1 FN2 ] MOVE A,FON!XXX(FONT) PUSHJ P,SIXTYP .IOT TTYOCH,["!DEL!] TERMIN PUSHJ P,ERRDEV .VALUE ;READ IN A KST CHARACTER CHARIN: PUSHJ P,WORDIN ;USER ID, IGNORE PUSHJ P,WORDIN ;LEFT KERN,,CODE HRRZ CODE,A HLLM A,TEMP CAIN CODE,777777 POPJ P, ; HANDY END-OF-FILE MARKER? CAILE CODE,177 JRST [ MOVEI A,[ASCIZ/ILLEGAL CODE /] ; ILLEGAL CODE JRST TERPRI] ; I.E., PRINT OUT AND RETURN SKIPE @CHARDT(FONT) JRST [ MOVEI A,[ASCIZ/DUPLICATE CHARACTER/] PUSHJ P,TERPRI JRST .+1] PUSHJ P,CONS MOVEM A,@CHARDT(FONT) MOVE B,A PUSHJ P,WORDIN ;RASTER WIDTH,,CHARACTER WIDTH HLL C,TEMP HRR C,A MOVEM C,(B) ;LEFT KERN,,CHARACTER WIDTH HLRZ C,A ;GET RASTER WIDTH SKIPN C HRRZ C,(B) HRRZ B,C ;RASTER WIDTH ADDI B,7. LSH B,-3 ; I.E. IDIVI B,8. BYTES PER ROW CAILE B,72. .VALUE [ASCIZ/:BPR TOO BIG /] HRRZM B,BPR HRL C,B PUSHJ P,CONS MOVEM C,(A) PUSHJ P,CONS HRR PTO,A HRLI PTO,441000 MOVE D,HEIGHT(FONT) SETZI PTI, CH1: PUSHJ P,ROWIN ;READ IN A ROW SOJG D,CH1 POPJ P, ; READ IN A LINE OF KST FONT MATRIX ; FROM DISK INTO FREE STORAGE ROWIN: MOVE B,BPR BYTEIN: TLNE PTI,700000 JRST CR1 PUSHJ P,WORDIN MOVE C,A MOVE PTI,[441000,,C] CR1: ILDB T,PTI CIRC T,-10 ; SECURITY IN OBSCURITY TLNE PTO,700000 JRST CR3 PUSHJ P,CONS HRR PTO,A HRLI PTO,441000 CR3: IDPB TT,PTO SOJG B,BYTEIN POPJ P, SUBTTL REORGANIZE THE CHARACTER MATRICIES REORG: MOVE FONT,NFONTS ;INDEX OF HIGHEST FONT RE3: SKIPN FONDEV(FONT) ;SKIP NON-EXISTANT FONTS. SOJGE FONT,RE3 JUMPL FONT,CPOPJ MOVE CODE,[-MXSTSZ,,0] ;FOR ALL CHARS RECHR: MOVE A,@CHARDT(FONT) JUMPE A,RE1 HLRZ B,1(A) MOVEM B,BPR ;SAVE NUMBER OF BYTES PER ROW MOVE B,(A) MOVEM B,REBUF MOVE B,1(A) MOVEM B,REBUF+1 ADDI A,2 ;SET UP THE BYTE POINTERS MOVEM A,TEMP HRLI A,341000 MOVEM A,INBP MOVE A,[441000,,REBUF+2] MOVEM A,OUTBP MOVE B,BPR RECOL: MOVE C,INBP MOVE D,HEIGHT(FONT) REBYT: LDB A,C MOVE E,BPR IBP C SOJG E,.-1 IDPB A,OUTBP SOJG D,REBYT IBP INBP SOJG B,RECOL ;NOW COPY THE CONTENTS OF REBUF BACK INTO THE CHARACTER. HRLI A,REBUF ;POINTER TO REBUF IN LH HRR A,@CHARDT(FONT) ;POINTER TO CHARDT AREA IN RH MOVE B,OUTBP SUBI B,REBUF ;B/ NUMBER OF WORDS IN REBUF-1 ADD B,@CHARDT(FONT) ;LAST LOCATION TO STORE INTO BLT A,(B) ;AND COPY RE1: AOBJN CODE,RECHR SOJGE FONT,RE3 POPJ P, SUBTTL THE SCANNER ;THIS ROUTINE DOES THE FIRST PASS OVER EACH LINE, ; FINDING THE MAXIMUM BASELINE AND MAXIMUM DEPTH ; (# OF LINES BELOW THE BASELINE) FOR THE LINE. ;THIS IS TO HELP LINE UP CHARS IN DIFFERENT ; FONTS ALONG THEIR BASELINES, AND TO SEE HOW FAR ; DOWN THE TEXT GOES ON THE PAGE, TO SEE IF THE XGP ; DO AN AUTOMATIC EJECT. SCAN: PUSH P,CHBP MOVE A,ABASE(FONT) MOVEM A,MXBS MOVE A,HEIGHT(FONT) SUB A,ABASE(FONT) MOVEM A,MXDP SCLOOP: ILDB A,CHBP CAIE A,12 ;LINE FEED CAIN A,14 ;FORM FEED JRST SCEND CAIN A,177 JRST SCESC JRST SCLOOP SCEND: POP P,CHBP POPJ P, SCESC: ILDB A,CHBP CAILE A,3 JRST SCLOOP JRST @SCDT(A) SCDT: SCLOOP ;0 IS NORMAL SCESC1 ;XGP ESCAPE 1 SC1 ;XGP ESCAPE 2 SCXE3 ;XGP ESCAPE 3 SCESC1: ILDB A,CHBP CAIE A,51 CAIN A,40 JRST SC2 CAIN A,41 JRST SC3 CAIE A,52 CAIN A,43 JRST SC1 CAIN A,47 JRST SC1 CAIN A,50 JRST SC1 CAILE A,3 JRST SCLOOP PUSH P,B MOVE B,ABASE(A) CAMLE B,MXBS MOVEM B,MXBS MOVE B,HEIGHT(A) SUB B,ABASE(A) CAMLE B,MXDP MOVEM B,MXDP POP P,B JRST SCLOOP SC3: IBP CHBP SC2: IBP CHBP SC1: IBP CHBP JRST SCLOOP SCXE3: PUSHJ P,G2CHBP MOVEM B,X3VAL SETOM X3FLAG JRST SCLOOP SUBTTL ROUTINE TO PUT CHARACTERS INTO DISPLAY MEMORY ;CHARS CAN BE OFF SCREEN FOR SEVERAL REASONS: ;ALL OF THE CHAR CAN BE OFF THE RIGHT OR LEFT EDGES ; THIS IS HANDLED BY THE COMPARISONS OF TVXP AND TVXPR AT TVCHR+11, ETC. ;ALL OF THE CHAR CAN BE OFF THE TOP OR BOTTOM EDGES ; THIS IS HANDLED BY THE CALLING ROUTINE (NORMAL:) [WHICH MAY BE A LOSING WAY] ;PART OF THE CHAR CAN BE OFF THE TOP OR BOTTOM EDGES ; THIS IS HANDLED BY TVCNTB AND TVCNTT AT TVCHR+45, ETC. ;PART OF A CHAR CAN BE OFF THE RIGHT OR LEFT EDGES. ; IF THIS HAPPENS IN THE MIDDLE OF A BYTE, TVL12 HANDLES IT. THE ; VARIABLE LINEST IS USED AT TVL12+16 FOR THIS. ALSO, IF WE ARE OFF THE ; RIGHT EDGE, TVCOL SHOULD NOT BE CALLED AGAIN. THIS IS HANDLED BY COMPARING ; THE WOULD-BE NEW TVBP TO SEE IF IT POINTS TO THE NEXT TV LINE, AS ; OPPOSED TO FURTHER OVER IN THE CURRENT LINE, WHERE IT SHOULD BE POINTING. ; THE VARIABLE TVLIN IS USED AT TVCHR+37, ETC. ; ALSO, A WHOLE BYTE COULD BE OFF THE LEFT EDGE, AND IF ; IT IS, THE FURTHER BYTES MUST STILL BE CONSIDERED. ; THIS IS HANDLED BY THE CODE AT TVCOL:. TVCHR: MOVE F,@CHARDT(FONT) SKIPG F POPJ P, ;UNDEFINED CHAR, IGNORE HLRE B,(F) ;LEFT KERN SUB B,ICS ;INTERCHARACTER SPACING ADD B,CPA(FONT) MOVNS B PUSHJ P,ADTVXP ;ADD TO TVXP (SETTING TVBP AND TVWD) MOVE C,TVXP HRRZ B,1(F) ;RASTER WIDTH CAML C,MXTVXP JRST TVCH2 ;ALL OF CHAR OFF RIGHT EDGE (NEVER CALL TVCOL) ADDI C,-1(B) ;TVXPR CAMG C,MNTVXP JRST TVCH2 ;ALL OF CHAR OFF LEFT EDGE (NEVER CALL TVCOL) MOVEM C,TVXPR ;POS. OF RIGHT HAND SIDE OF BYTE HLRZ C,1(F) ;BYTES PER ROW MOVEM C,COLCNT HRLI C,1000 ;CONSTRUCT TVBP: 8-BIT BYTES MOVE D,TVBT DPB D,[360600,,C] ;P=TVBT HRR C,TVWD MOVE D,MXBS ;ADJUST FOR BASELINE SUB D,ABASE(FONT) IMULI D,18. ADD C,D MOVEM C,TVBP ;THAT'S IT HRRZ C,C SUBI C,TVBBAS IDIVI C,18. AOJ C, IMULI C,18. ADDI C,TVBBAS MOVEM C,TVLIN ;FIRST WORD OF NEXT LINE MOVE B,[441000,,2] ADD B,F MOVEM B,FSBP MOVEI B,454. ;DON'T FALL OFF BOTTOM OF SCREEN HRRZ C,TVBP ; THIS IS FOR THE CASE IN WHICH SUBI C,TVBBAS ; PART OF THE WORD IS OFF EITHER IDIVI C,18. ; THE TOP OR THE BOTTOM OF THE MOVEM C,TVCNTT ; SCREEN. ACCUMS. H AND TT ARE SUB B,C ; USED WITH THIS IN TVCOL. MOVEM B,TVCNTB TVCH1: PUSHJ P,TVCOL SOSLE COLCNT JRST TVCH1 TVCH2: HLRE C,(F) ;LEFT KERN ADD C,CPA(FONT) ;PLUS CPA HRRZ B,(F) ;CHARACTER WIDTH ADD B,C ;SUBTRACT LEFT KERN AND CPA, ADD CHAR WIDTH PUSHJ P,ADTVXP POPJ P, SUBTTL PUT IN A COLUMN OF BYTES ;DOUBLE SKIPS DURING CERTAIN OFF-RIGHT-EDGE CONDITION ;IF WE ARE HERE AT ALL, AT LEAST SOME OF THE CHAR SHOULD BE DISPLAYED TVCOL: MOVE A,TVXP CAMG A,[-10] JRST TVCOLE MOVE D,HEIGHT(FONT) ;ARE WE AT THE EDGE OF A TV RASTER LINE? SETZM LINEST ;INNOCENT UNTIL PROVEN GUILTY MOVE C,TVXP CAMGE C,MNTVXP SOS LINEST ;HANGING OFF LEFT EDGE MOVE C,TVXPR CAMLE C,MXTVXP AOS LINEST ;HANGING OFF RIGHT EDGE MOVE TT,TVCNTT MOVE H,TVCNTB LDB A,[360600,,TVBP] CAIG A,8+4 JRST TVL12 ;GO TO HARD CASE, WRAPS ACROSS WORDS. ;EASY--DEPOSIT INTO A WORD. IBP TVBP MOVE C,TVBP LDB E,[360600,,TVBP] TVC1: ILDB B,FSBP JUMPL TT,TVC3 ;PARTIALLY OFF TOP LSH B,(E) MOVEM B,(C) ;DUE TO ALU FUNCTION, THIS IS REALLY AN IORM. TVC3: ADDI TT,1 ADDI C,18. SOJLE H,TVCOLE ;PARTIALLY OFF BOTTOM SOJG D,TVC1 JRST TVCOLE ;FINISHED WITH COLUMN ;HARD--DEPOSIT ACROSS BOUNDARY BETWEEN TWO WORDS. ;THE NEW BYTE IN E MUST BE BROKEN INTO TWO PARTS ;EBP POINTS TO THE FIRST PART. ;BP1 AND BP2 POINT TO THE DESTINATION OF THE TWO ;PARTS, RESPECTIVELY ;NOTE ON ACCUMULATOR USAGE IN THIS ROUTINE: ; A: #OF BITS IN FIRSTR PART OF WORD. ; B: #OF BITS IN LAST PART OF WORD. ; C: WORKING ACCUMULATOR. ; D: COUNTS # OF SCAN LINES NORMALLY IN THIS CHAR. ; E: THE NEW BYTE BEING PUT IN. ; F: POINTS INTO THE CHARACTER MATRIX. ; G: ANOTHER WORKING ACCUMULATOR. ; H: MAKING SURE CHAR DOESN'T FALL OFF THE BOTTOM. ; T: BYTE POINTER INTO TV MEMORY. ; TT: MAKING SURE CHAR ISN'T OFF TOP EDGE. ; CODE, FONT, P: THE USUAL TVL12: SUBI A,4 MOVEI B,8 SUB B,A DPB B,[360600,,EBP] ;SET UP E DPB A,[300600,,EBP] HRRI C,E HRRM C,EBP HRLI C,040000 ;SET UP BP1 HLLZM C,BP1 DPB A,[300600,,BP1] MOVEI C,36. ;SET UP BP2 SUB C,B DPB C,[360600,,BP2] DPB B,[300600,,BP2] MOVE T,TVBP TVL121: ILDB E,FSBP JUMPL TT,TVL122 SKIPGE LINEST JRST TVL123 LDB C,EBP ;FIRST PART OF BYTE HRRM T,BP1 DPB C,BP1 ;THIS IS REALLY LIKE AN IORM DUE TO THE ALU FUNCTION. TVL123: SKIPLE LINEST JRST TVL122 HRRM T,BP2 ;SECOND PART OF BYTE AOS BP2 DPB E,BP2 ;THIS IS REALLY LIKE AN IORM DUE TO THE ALU FUNCTION. TVL122: AOJ TT, ADDI T,18. SOSLE H ;DON'T FALL OFF BOTTOM OF SCREEN SOJN D,TVL121 MOVE A,BP2 MOVEI C,8. DPB C,[300600,,A] HRR A,TVBP ADDI A,1 MOVEM A,TVBP HRRZ A,A CAMGE A,TVLIN JRST TVCOLE AOS (P) AOS (P) ;OFF RIGHT EDGE TVCOLE: SUBI D,1 TVC2: JUMPLE D,CPOPJ SOJ D, IBP FSBP JRST TVC2 ;THIS IS LIKE TVCHR FOR MINI-DISPLAY MODE. IT COMPRESSES BY 5 VERTICALLY ;AND BY 4 HORIZONTALLY AND LEAVES BARS OF GLITCHS IN THE MINI DISPLAY. MTVCHR: MOVE B,XOFF ;IGNORE XOFF AND YOFF ADDM B,TVXP MOVE B,YOFF ADDM B,TVYP MOVE F,@CHARDT(FONT) JUMPE F,CPOPJ ;UNDEFINED CHAR, IGNORE HLRE B,(F) ;LEFT KERN SUB B,ICS ;INTERCHARACTER SPACING ADD B,CPA(FONT) MOVNS B PUSHJ P,ADTVXP HLRZ C,1(F) ;BYTES PER ROW MOVEM C,COLCNT MOVE B,[441000,,2] ADD B,F MOVEM B,FSBP MOVE A,TVXP LSH A,-2 ; COMPRESS BY 4 IDIVI A,32. ; 32 BITS IN A WORD. [DO NOT MAKE THIS A LSH, ; WE USE THE REMAINDER.] ADDI A,TVBBAS MOVEM A,TVADR1 CAIG B,2 ;HACK TO AVOID HAVING TVBIT1 OR TVBIT2 ZERO MOVEI B,2 MOVEI C,36. SUB C,B MOVEI B,1 LSH B,(C) MOVEM B,TVBIT2 LSH B,1 MOVEM B,TVBIT1 MOVE G,COLCNT MTV1: MOVE H,HEIGHT(FONT) MOVE A,TVYP MOVEM A,TVADR2 MTV2: MOVE A,TVADR2 IDIVI A,5 IMULI A,18. ADD A,TVADR1 ILDB B,FSBP ;THE BYTE LDB C,[040400,,B] ;GET THE FIRST FOUR BITS JUMPE C,MTV3 ;IF ALL ZEROES, DON'T DO ANYTHING MOVE D,TVBIT1 IORM D,(A) MTV3: LDB C,[000400,,B] ;THE SECOND FOUR BITS JUMPE C,MTV4 MOVE D,TVBIT2 IORM D,(A) MTV4: AOS TVADR2 SOJG H,MTV2 MOVE A,TVBIT2 LSH A,-2 MOVEM A,TVBIT2 MOVE A,TVBIT1 LSH A,-2 MOVEM A,TVBIT1 AND A,[-16] ;MASK OUT LOWEST 4 BITS JUMPN A,MTV5 ;IT DIDN'T FALL OFF THE EDGE OF THE WORD AOS TVADR1 HRLI A,400000 MOVEM A,TVBIT1 HRLI A,200000 MOVEM A,TVBIT2 MTV5: SOJG G,MTV1 HLRE C,(F) ;LEFT KERN ADD C,CPA(FONT) ;PLUS CPA HRRZ B,(F) ;CHARACTER WIDTH ADD B,C ;SUBTRACT LEFT KERN AND CPA, ADD CHAR WIDTH PUSHJ P,ADTVXP MOVN B,XOFF ;RESTORE XOFF AND YOFF ADDM B,TVXP MOVN B,YOFF ADDM B,TVYP POPJ P, SUBTTL RANDOM ROUTINES ;WORDIN READS IN A WORD FROM DISK WIBUF: MOVE A,[-BUFSIZ,,BUF];NO,REPLENISH THE BUFFER .IOT FNTICH,A HLREM A,MISSED ;SAVE HOW MANY WE NEVER GOT (USUALLY 0) MOVEI A,BUF MOVEM A,IOPTR MOVEI A,BUFSIZ ADD A,MISSED MOVEM A,IOCNT WORDIN: SOSGE IOCNT JRST WIBUF ;BUFFER EMPTY MOVE A,@IOPTR AOS IOPTR POPJ P, ;PRINT OUT A STRING OUTSTR: .IOT TTYOCH,[15] .IOT TTYOCH,[12] OUTST1: PUSH P,B MOVE B,A HRLI B,440700 OUTS1: ILDB A,B JUMPE A,CPOPBJ CAIN A,14 ;IT SHOULD STOP ON SEEING FORMFEED, FOR THE ERR DEVICE JRST CPOPBJ .IOT TTYOCH,A JRST OUTS1 TERPRI: PUSHJ P,OUTSTR .IOT TTYOCH,[15] .IOT TTYOCH,[12] POPJ P, CPOPBJ: POP P,B POPJ P, ;ADD TO TVXP, ADJUSTING TVBT AND TVWD IF NECESSARY ADTVXP: ADDB B,TVXP PUSH P,C IDIVI B,32. ADD B,LTVWD MOVEM B,TVWD SUBI C,36. MOVNM C,TVBT POP P,C POPJ P, DECTYP: SETZ C, ;TYPE OUT A POSITIVE DECIMAL INTEGER IN A. DECT1: IDIVI A,10. ; CLOBBERS B & C & A ADDI B,60 ;MAKE IT ASCII PUSH P,B ADDI C,1 JUMPN A,DECT1 DECT2: POP P,A .IOT TTYOCH,A SOJG C,DECT2 POPJ P, SIXTYP: PUSH P,B SIXTY1: SETZI B, ROTC A,6 ADDI B,40 .IOT TTYOCH,B JUMPN A,SIXTY1 POP P,B POPJ P, ;;; Print out error message. Expects to find error code in ERRCOD. ERRDEV: MOVEI A,[ASCIZ /-- /] PUSHJ P,OUTST1 .CALL [ SETZ SIXBIT/OPEN/ [.UAI,,ERRICH] [SIXBIT /ERR/] MOVEI 4 SETZ ERRCOD] .LOSE 1400 ERRDE1: .IOT ERRICH,A CAIGE A,40 JRST CPOPJ .IOT TTYOCH,A JRST ERRDE1 ;GET NEXT WORD OF FREE STORAGE ;RETURN ITS ADDRESS IN A. CONS: SOSL FREE JRST CONS1 .CALL [ SETZ ;CREATE A NEW PAGE SIXBIT /CORBLK/ MOVEI %CBNDW MOVEI %JSELF CORSIZ SETZI %JSNEW] .LOSE 1000 AOS CORSIZ MOVEI A,2000 ADDM A,FREE CONS1: MOVE A,FSP AOS FSP SETZM (A) POPJ P, ;Skip if CHBP is pointing past the end of the file. FILEND: PUSH P,A PUSH P,B PUSH P,C HRRZ A,CHBP ; CONVERT INTO CHARACTER ADDRESS SUBI A,200000-1 IMULI A,5 LDB B,[360600,,CHBP] ; GET PP FIELD IDIVI B,7 MOVNS B ADD B,A ; B HAS THE CHARACTER ADDRESS ADDI B,1 CAMGE B,FILLEN ; SKIP IF CHBP IS TOO BIG CPOPJ1: AOS -3(P) POP P,C POP P,B POP P,A POPJ P, ;Interrupt level code. TSINT: 0 0 EXCH A,TSINT JUMPGE A,.+2 TRNN A,1_TTYICH .VALUE [ASCIZ/: INTERRUPT BUG. /] MOVEI A,TTYICH .ITYIC A, ;ITS WANTS TO SEE THIS, THOUGH I DONT CARE .DISMIS TSINT+1 SKIPE INTFLG ;ENABLED? JRST TSIN1 ;YES, DO THINGS MOVE A,TSINT ;NO, PRETEND IT DIDN'T HAPPEN .DISMIS TSINT+1 TSIN1: MOVE P,[-PDLLEN,,PDB-1] ;REINITIALIZE P MOVEI A,CSET ;SET ALU FUNCTION TO DO MOVEMS. DPB A,[CREGFN,,CREG] SETZM INTFLG ;DISABLE INTERRUPTS MOVE A,BCHBP MOVEM A,CHBP ;RESTORE CHBP .DISMIS [CURSOR] ;GO BACK TO CURSOR ROUTINE ;REINITIALIZE CHBP, BCHBP, AND PAGENO TO THE BEGINNING OF THE FILE ICHBP: MOVE A,[440700,,200000] ;START POINTER AT BEGINNING OF DISK FILE MOVEM A,CHBP MOVEM A,BCHBP MOVEI A,1 ;START ON PAGE 1 MOVEM A,PAGENO POPJ P, SUBTTL FILE NAME READER ; FILE NAME READER. TAKES AN INSN TO XCT IN RXCT TO PUT ; THE NEXT SIXBIT CHAR INTO IN ACCUMULATOR A. ; THE FILE SPEC IS LEFT IN XDEV, XFN1, XFN2, AND XDIR. ; THIS CLOBBERS A,B, AND C. IT IS CALLED WITH PUSHJ P,READER ; IF NO FILE SPEC WAS READ, RETURN -1 IN THE LEFT HALF OF A. ; ALWAYS RETURN THE LAST CHAR READ (THE DELIMITER) IN A. READER: SETZI ZR, READE2: SETZI B, MOVE C,[440600,,B] REANEX: XCT RXCT ; GET A CHAR INTO AC A CAIN A,": JRST READEV CAIN A,"; JRST READIR CAIG A,40 JRST READEL ;IF NOT >40, DELIMITER CAIN A,", JRST READEL ;COMMA IS A DELIMITER CAIL A,"a CAILE A,"z SUBI A,40 ;IF NOT LOWER CASE, CONVERT TO SIXBIT ; (LOWER CASE IS ALREADY SIXBIT) TRO ZR,1 ; SET FLAG INDICATING WE HAVE DONE SOMETHING TLNE C,770000 IDPB A,C JRST REANEX READEV: MOVEM B,XDEV ; COLON, THIS IS THE DEVICE NAME JRST READE2 READIR: MOVEM B,XDIR ; SEMI, THIS IS THE SNAME JRST READE2 READEL: JUMPE B,READE1 ; DELIMITER, IF NOTHING INPUT THEN DONT CLOBBER ANYTHING TRNE ZR,2 MOVEM B,XFN2 ; IT IS SET, SO WE ALREADY GOT THE FN1 TRON ZR,2 MOVEM B,XFN1 ; THIS IS THE FIRST TIME, STORE IN FN1 AND SET THE FLAG READE1: CAIN A,40 ; IF NOT A SPACE, RETURN, LEAVING JRST READE2 ; WHATEVER IT WAS IN AC A TRNE ZR,1 POPJ P, ; (IF NOTHIG HAS HAPPENED) TLO A,-1 ; IF NOTHING WAS EVER READ, SET LEFT HALF OF A TO -1 POPJ P, SUBTTL DATA AREA NFONTS: 0 ;INDEX OF HIGHEST KNOWN FONT. FONDEV: BLOCK MXNFNT ;THE FONT FILES INDEXED BY FONT NUMBER. FONFN1: BLOCK MXNFNT FONFN2: BLOCK MXNFNT FONDIR: BLOCK MXNFNT KDEFLT: SIXBIT /DSK/ ;THE DEFAULT FONT FILE SPEC SIXBIT /25FG/ SIXBIT /KST/ SIXBIT /FONTS/ FILDEV: SIXBIT /DSK/ ; THE USER'S FILE FOR INPUT FILFN1: SIXBIT /@/ FILFN2: SIXBIT />/ FILDIR: 0 ; (GETS INITIALIZED TO THE MSNAME) XDEV: 0 ; FOR THE READER ROUTINE. XFN1: 0 XFN2: 0 XDIR: 0 RXCT: 0 ; LOC TO PUT THE INSN NEEDED BY READER FOR INPUT. MODE: 0 ;0=NORMAL -1=MINI-DISPLAY INTFLG: 0 ;INTERRUPT FLAG. 0 => DISABLED, 1 => ENABLED FILLEN: 0 ;LENGTH OF THE FILE, IN WORDS TVADR1: 0 TVADR2: 0 TVBIT1: 0 TVBIT2: 0 KSTID: BLOCK MXNFNT HEIGHT: BLOCK MXNFNT BASE: BLOCK MXNFNT ABASE: BLOCK MXNFNT CPA: BLOCK MXNFNT CHRCNT: 0 MISSED: 0 IOPTR: 0 ;POINTER FOR BUF IOCNT: 0 ;COUNTER FOR BUF FILSPC: BLOCK 100 ;FILE SPEC, FROM JCL OR TTY BPR: 0 ;BYTES PER ROW (I.E. RASTER) FLAG: 0 ;RANDOM FLAG EOFFLG: 0 ;END OF FILE FLAG PTT: 0 ;POINTS AT TT TEMP: 0 ;TEMP LOCATION ;TVCOL'S VARIABLES EBP: 0 ;BYTE POINTER TO AC E BP1: 0 ;BYTE POINTER BP2: 0 ;BYTE POINTER TVLIN: 0 ;FIRST WORD OF NEXT LINE IN TV MEMORY TVXPR: 0 ;POSITION OF RIGHT HAND BIT OF BYTE LINEST: 0 ;-1 => OFF LEFT EDGE. 0 => OK. 1 => OFF RIGHT EDGE. ;THE NEXT SIX WORDS MUST BE CONTIGUOUS TOPMAR: 128 ;TOP MARGIN BOTMAR: 124 ;BOTTOM MARGIN LFTMAR: 128 ;LEFT MARGIN VSP: 6 ;VERTICAL SPACEING BETWEEN LINES SKIPP: 0 ;NUMBER OF PAGES TO SKIP SIZEE: 0 ;SIZE OF PAGE TVXP: 0 ;TV'S X-AXIS POSITION TVYP: 0 ;TV'S Y-AXIS POSITION ITVXP: 0 ;TVXP AT BEGINNING OF LINE ITVYP: 0 ;LIKEWISE STTVYP: 0 ;TVYP SHOULD BE SET TO THIS NEXT LF PAGENO: 0 ;THE NUMBER OF THE PHYSICAL PAGE WE ARE NOW DISPLAYING SPAGEN: 0 ;SAVE PAGENO IN CASE HE GOES OFF THE END OF THE FILE GOPAGC: 0 ; HOLDS C TEMPORARILY FOR THE GOPAG ROUTINE XOFF: 0 ;X OFFSET YOFF: 0 ;Y OFFSET ;THAT IS, TVXP = XGP_POSITION - XOFF MXTVXP: 0 ;MAX TVXP MNTVXP: 0 ;MIN TVXP ICS: 0 ;INTERCHARACTER SPACING (XESC1 50) LS: 0 ;ARGUMENT OF XESC1 42 (LINE SPACE) LSFLAG: 0 ;FLAG FOR XESC1 42 (LINE SPACE) STAUND: 0 ;TVXP AT START UNDERSCORE (XESC1 46) COLCNT: 0 ;COUNTS COLUMNS IN A CHAR CHCNT: 0 ;CHARACTERS LEFT IN BUFFER BCHCNT: 0 ;CHCNT AT BEGINNING OF THIS PAGE CHBP: 0 ;BYTE POINTER TO CHARACTERS IN BUFFER BCHBP: 0 ;CHBP AT BEGINNING OF THIS PAGE BCORSZ: 0 ;CORSIZ AT BEGINNING OF THIS PAGE CHMISS: 0 ;HOW MANY CHARS MISSED WHILE READING IN CHARS FCORE: 0 ;LOC OF FREE CORE AFTER FONT AREA. ; MUST BE AT THE TOP OF THE PAGE. FCRSIZ: 0 ;NUMBER OF BLOCKS BEFORE (FCORE) X3FLAG: 0 ;-1 => AN XGP ESCAPE 3 WAS DONE ON THIS LINE. X3VAL: 0 ;VALUE OF ANY X-ESC 3 IN THIS LINE. FSBP: 0 TVBP: 0 INBP: 0 OUTBP: 0 CHWD: 0 ;CHAR WIDTH TVWD: 0 TVBT: 0 LTVWD: 0 ;TVWD AT BEGINNING OF THE CURRENT LINE MXDP: 0 ;SCANNER - MAX DEPTH (BELOW BASELINE) SO FAR IN THIS LINE MXBS: 0 ;SCANNER - MAX BASELINE SO FAR IN THIS LINE (ADJUSTED) TVCNTT: 0 ;TV LINE COUNTER FOR TOP OF SCREEN TVCNTB: 0 ;MUST NOT TRY TO PUT IN MORE THAN THIS MANY BYTES C40: 40 ;CODE FOR SPACE BITSIN: 0 ;NUMBER OF BITS TO PUT IN PER ROW IN MINI-MODE ERRCOD: 0 ;CODE OF ERROR COMMITTED, ARGUMENT TO ERRDEV SUBROUTINE PATCH: BLOCK 100 CHARDT: REPEAT MXNFNT, CONC CHAR,\.RPCNT,(CODE) REPEAT MXNFNT, CONC CHAR,\.RPCNT,: BLOCK MXSTSZ ;THESE SYMBOLS ARE ONLY REFERENCED FROM ; THE CHARDT TABLE ABOVE. BUF: BLOCK BUFSIZ ;DISK INPUT BUFFER REBUF: BLOCK BUFSIZ ;TO REORGNIZE BUF PDB: BLOCK PDLLEN FREE: 0 CORSIZ: 0 FSP: 0 CONSTANTS LOC <.+1777>/2000*2000 TVBBAS: ;TV BUFFER BASE CREG=TVBBAS+8*2000 ;THE TV CONTROL REGISTER ;FREE STORAGE STARTS HERE. FS=9*2000+TVBBAS ICORE==FS_<-12> END GO