; C/;/ ;/ ; C/ ;/;/ ; ; the following are mpp macros ; ; $MACRO TTY A B C D E ... ** TTY1 #@1 #@2 #@3 #@4 #@5 #@6 #@7 #@8 #@9 #@A #@B #@C $ENDM ; $MACRO TTY1 I%IN <#@1> END <> > $ENDM ; $MACRO TTY2 S%SW 21 I%IN <#@1> <> I%SW 21 R0 > CALL TTYCC $ENDM ; $MACRO FUNCTION set to parm3 I%IDN R0 <#@2> > TTY ESC 'R I%DF R0 <#@3> call ttycc $ENDM ; $MACRO CURSOR TO X,Y MOV #@2,-(SP) MOV #@3,-(SP) CALL CURSR2 $ENDM ; ;;; $MACRO CURSOR TO LINE COL ;;; I%IDN R0 <#@2> > ;;; TTY ESC 'Y ;;; MOV #@2,R0 ;;; ADD #31.,R0 ;;; TTY R0 ;;; MOV #@3,R0 ;;; ADD #31.,R0 ;;; TTY R0 ;;; $ENDM / PROGRAM v7. SCREEN EDIT ;just sets up op tables inside mpp .PSECT EDI07 .TITLE EDI07 .IDENT /V1/ .enabl lc .mcall wtse$,mrkt$,dir$,callr ; - - - local macros inside macro -11 .MACRO return rts pc .ENDM .MACRO push this mov this,-(sp) .ENDM .MACRO pop that mov (sp)+,that .ENDM ; - - - Global declarations .globl ttynll .globl cursl .globl cursr2 .globl ceol .globl fixscn .globl bcom ;entry for b command .globl bcom1 ;alt entry for b command .globl smode ;variable to determine screen/line mode .globl prescn .globl postscn .globl bottom ;the line # of the bottom line .globl fpage .globl fdot ; - - - global data smode: .word 0 ;0= not screen mode, <>0 = in screen mode ; - - - local symbolics tab = 11 esc = 33 linefd = 12 sdel = 123 home = 110 bottom = 24. insert = 114 delete = 115 ceol = 113 ceop = 'J rightmost = 80. screen = 1 line = 0 blank = 40 lbrk = 133 ;a [ langle = 74 ;a < ; - - - local data olddot: .word 0 ;previous dot value I: .word 0 ;local index K: .word 0 ;local index flag1: .word 0 ;used by dot checker cursl: .word 13. cursc: .word 1. fpage: .word '@ fdot: .word 'H nocmd: .word 0 ;0= bypass the regular ued command smacro: .word 0 ;the a and i commands may be s macros multadr:.word 0 ;set to 0 if a multi address cmd in process mark: mrkt$ 30.,4,1 wait: wtse$ 30. ; - - - Entries for the pre-command and post-command screen editor dispatcher prescn: clr nocmd call fixscn ;keep the cursor in the right place IF smode = #screen mov r0,-(sp) call @pretbl(r0) mov (sp)+,r0 IF nocmd NE #0 add #10,(sp) ;bump return past the subroutine call FI FI return postscn: IF smode = #screen mov r0,-(sp) call @psttbl(r0) CURSOR to #bottom-2,#1 TTY END mov (sp)+,r0 FI return ; - - - the pre table pretbl: .WORD Apre ;APPEND .WORD no.op ;B .WORD Cpre ;CHANGE .WORD Dpre ;DELETE .WORD Epre ;EDIT .WORD Fpre ;FACTS .WORD Gpre ;GLOBAL .WORD ERR2 ;H .WORD Ipre ;INSERT .WORD Jpre ;JOIN .WORD Kpre ;KOPY .WORD NO.OP ;L .WORD Mpre ;MOVE .WORD no.op ;N .WORD Opre ;OPTIONS .WORD Ppre ;PRINT .WORD Qpre ;QUIT .WORD Rpre ;READ .WORD Spre ;SUBSTITUTE .WORD no.op ;T .WORD upre ;U .WORD Vpre ;EXCLUDE .WORD Wpre ;WRITE .WORD Xpre ;WRITE WITH NEW VERSION .WORD NO.OP ;Y .WORD Zpre ;Z COMMAND ; - - - the post table psttbl: .WORD Apst ;APPEND .WORD no.op ;B .WORD Cpst ;CHANGE .WORD Dpst ;DELETE .WORD Epst ;EDIT .WORD Fpst ;FACTS .WORD Gpst ;GLOBAL .WORD ERR2 ;H .WORD Ipst ;INSERT .WORD Jpst ;JOIN .WORD Kpst ;KOPY .WORD NO.OP ;L .WORD Mpst ;MOVE .WORD no.op ;N .WORD Opst ;OPTIONS .WORD Ppst ;PRINT .WORD Qpst ;QUIT .WORD Rpst ;READ .WORD Spst ;SUBSTITUTE .WORD no.op ;T .WORD upst ;U .WORD Vpst ;EXCLUDE .WORD Wpst ;WRITE .WORD Xpst ;WRITE WITH NEW VERSION .WORD NO.OP ;Y .WORD Zpst ;Z COMMAND ; - - - dispatched routines Apre: ;APPEND mov cursl,r1 ;if its not an s macro, clear bottom br app1 Ipre=. ;INSERT mov cursl,r1 dec r1 app1: clr smacro ;assume not a macro call getc ;look ahead one character mov r0,peek ;and put it back IF r0 NE #nl inc smacro ;its a macro call cmultadr ;so we then check mult adresses ELSE inc r1 CURSOR to R1,#1 TTY esc ceop ;clear bottom half of screen CURSOR TO R1,#1 TTY END FI return ;B Cpre: ;CHANGE IF oe NE #0 ;test option e jmp spre1 ;and its really an s command FI cpre1: Dpre: ;DELETE return Epre: ;EDIT clr smode return Fpre: ;FACTS return Vpre: ;EXCLUDE Gpre: ;GLOBAL clr smode ;out of screen mode mov #1,onum ;turn on line numbers return ;H Jpre: ;JOIN Kpre: ;KOPY ;L Mpre: ;MOVE ;N Opre: ;OPTIONS return Ppre: ;PRINT IF adr1 NE adr2 ;what mode do we want clr smode ;out of screen mode and print ELSE inc nocmd ;we do it all call nonzer ;check it out LET R0 = adr1 - dot ;how far is it IF r0 LT #0 neg r0 FI mov dot,olddot ;save it mov adr1,dot ;set new dot IF r0 GT #24. call bcom1 ;too far, use b command ELSE IF adr1 = olddot ;not moving? call redisp ;re display the center line ELSE IF adr1 HI olddot ;which way to go call upit ELSE call downit ;down FI FI FI FI return upit: ;scroll up until dot reaches adr1 mov olddot,dot LOOP FOR I = #1 TO #24. add #2,dot ; dir$ #mark ;display is too slow ; dir$ #wait ;must give it some time call upscroll BREAK IF dot HIS adr1 NEXT I return downit: ;scroll down until dot gets to adr1 mov olddot,dot ;need this again LOOP for I = #1 TO #24. ;for loop safety, max=24 sub #2,dot ;back a line ; dir$ #mark ;display is too slow ; dir$ #wait ;must give it some time call downscroll ;and scroll BREAK IF dot LOS adr1 ;and check for done NEXT I return Qpre: ;QUIT Rpre: ;READ return Spre: ;SUBSTITUTE IF oe NE #0 jmp cpre1 FI spre1: call cmultadr ;check for multiple addresses return ;T upre: ;U Wpre: ;WRITE Xpre: ;WRITE WITH NEW VERSION ;Y return Zpre: ;Z COMMAND clr smode no.op: return Apst: ;APPEND Ipst: ;INSERT IF smacro = #0 ;if it was a macro mov dot,adr1 ;it requires this mov dot,adr2 ;and this call bcom1 ;re-display ELSE jmp spst1 FI return ;B Cpst: ;CHANGE IF oe NE #0 jmp spst1 FI cpst1: return Dpst: ;DELETE mov dot,adr1 ;it requires this mov dot,adr2 ;and this call bcom1 return Epst: ;EDIT return Fpst: ;FACTS callr sfacts ;in screen mode Gpst: ;GLOBAL ;H return Jpst: ;JOIN return Kpst: ;KOPY ;L Mpst: ;MOVE jmp dpst ;new display needed ;N Opst: ;OPTIONS Ppst: ;PRINT Qpst: ;QUIT return Rpst: ;READ jmp dpst return Spst: ;SUBSTITUTE IF oe NE #0 jmp spst1 FI spst1: ;This is the sub entry IF multadr NE #0 ;there were multiple addresses jmp dpst ;new display ELSE call redisp ;update center-line call getc ;get next char mov r0,peek ;put it back bic #40,r0 ;make it upper case IF r0 = #'P mov #-1,peek ;clear peek char FI FI return ;T upst: ;U call redisp Vpst: ;EXCLUDE Wpst: ;WRITE Xpst: ;WRITE WITH NEW VERSION ;Y Zpst: ;Z COMMAND return ; - - - fix up the cursor if in screen mode fixscn: IF smode = #screen PUSH R0 TTY esc 'Y '6 blank esc ceop END ;clear bottom two lines POP R0 FI return ; - - - B command processor bcom: ;The b command does the BEGIN SCREEN mode TTY esc lbrk '? '2 'l ;out of ascii mode ;;; PUSH R1 ;;; PUSH R0 ;;; CURSOR TO #1,#1 ;;; TTY esc 'G ;;; mov #2,r1 ;;; LOOP FOR I = #1 to #17. ;;; IF I GT #9. ;;; inc r1 ;;; ELSE ;;; add #8.,r1 ;;; FI ;;; CURSOR TO #1,R1 ;;; TTY esc 'F ;set tab ;;; NEXT I ;;; TTY END ;;; POP R0 ;;; POP R1 ;;; call setfld ;get new field functions bcom1: PUSH R0 ;entry to not set screen fields PUSH R2 mov #screen,smode ;into screen mode IF adr2 NE #0 mov adr2,dot ;set dot FI LET r2 = dot - #24. ;start at dot - 12 lines TTY esc 'H esc 'J END ;output an escape j - clr page & home LOOP FOR I = #1 TO #22. CURSOR TO I,#1 IF i = cursl call uline1 FI call get.line ;get the input line (our routine) mov #lbuf1,r0 ;its put into lbuf1 null terminated call xttystr ;THE string has a nl inbedded in it IF i = cursl call uline2 FI add #2,r2 ;go to next location NEXT I POP R2 POP R0 RTS PC ; - - - errors err2: mov #2,r1 jmp error ; - - - just a new line output hook (non implemented) ttynll: jmp ttynl ;+ ; ; get.line - get line but range check ; ; r2 = line pointer (like a dot, or zero, dol etc) ; ; output lbuf1 is an asciz string which is either the ; line from the temp file or a line with one blank ;- get.line: ;get line but check range of dot PUSH R0 clr flag1 ;assume ok IF r2 LOS zero ;range check it and get a blank line if bad inc flag1 FI IF r2 HI dol ;must be higher than zero, lower or= dol inc flag1 FI IF flag1 = #0 mov (r2),r0 ;contents of pointer to line call getlin ;get from the temp file ELSE movb #' ,lbuf1 ;simulate a blank line clrb lbuf1+1 ;and null terminate it FI POP R0 return upscroll: LET R2 = dot + #18. call get.line ;get it now, makes smoother screen transition CURSOR to #bottom,#1 ;prepare to scroll up 1 line TTY esc langle esc 'D esc lbrk TTY '? '2 'l END ;scroll up using the index command in ascii LET r1 = cursl CURSOR to r1,#1 ;redraw line dot with underlining LET r2 = dot call get.line ;get dot IF lmode = #0 call uline1 ;set for underlining mov #lbuf1,r0 call xttystr call uline2 ;end underlining FI LET r1 = cursl - #1 CURSOR to r1,#1 ;and redo the next line LET r2 = dot - #2 call get.line mov #lbuf1,r0 call xttystr LET R2 = dot + #18. ;now do the bottom line CURSOR to #bottom-2,#1 ;to the bottom line call get.line ;this appears at the bottom mov #lbuf1,r0 call xttystr ;and output it CURSOR to #bottom-1,#rightmost ;down to our place in the sun TTY esc ceop END ;and clear a spot for ourselves return Downscroll: TTY esc home esc 'I ;scroll screen down 1 line LET r1 = cursl CURSOR to r1,#1 ;redraw line dot with underlining mov dot,r2 call get.line ;get dot IF lmode = #0 call uline1 ;set for underlining mov #lbuf1,r0 call xttystr call uline2 ;end underlining FI LET r1 = cursl + #1 CURSOR to r1,#1 ;and redo the next line LET r2 = dot + #2 call get.line mov #lbuf1,r0 call xttystr LET R2 = dot - #24. ;now do the top line TTY esc home ;to the top call get.line ;this appears at the top mov #lbuf1,r0 call xttystr ;and output it CURSOR to #bottom-2,#rightmost ;down to our place in the sun TTY esc ceop END ;and clear a spot for ourselves return ; - - - redisp re display the center line redisp: push r0 push r2 CURSOR to cursl,#1 ;go there TTY esc ceol END ;clear the line mov dot,r2 call get.line mov #lbuf1,r0 call uline1 call xttystr call uline2 pop r2 pop r0 return ; - - - set default field parms setfld: PUSH R0 call getcx IF R0 NE #nl ;by pass if new line mov r0,fpage ;and set page function FI call getcx IF R0 NE #nl mov r0,fdot ;set dot function FI POP R0 return ; - - - getcx getcx: ;get char, check for newline, correct case ;and clear protect bit. Make a space an '@' call getc ;get a char IF R0 NE #nl IF R0 = #40 ;check for space mov #'@,r0 ;and make it an '@' FI bic #60,r0 ;map to upper and clear protect bit ELSE mov r0,peek ;put it back FI return ; - - - cmultadr check for multiple address, set/reset mlflag cmultadr: ;check for multiple addresses clr multadr ;assume single address IF adr1 NE adr2 inc multadr ;note fact FI return uline1: ;underline begin push r0 TTY esc langle esc lbrk '4 'm ;into ascii mode and under line TTY END pop r0 return uline2: push r0 TTY esc lbrk 'm esc lbrk ;end under line, out of ascii TTY '? '2 'l END pop r0 return ; ; ; xttystr - output string, but at least one blank line ; ; xttystr: ;do a ttystr but at least 1 char IFB (r0) = #nl push r0 TTY blank pop r0 FI call ttystr return ;+ ; cursr2 - routine to output cursor movement (used by the CURSOR macro) ; ; input: tos=return address ; nos=y cord of cursor position (1-24.) ; 3os=x cord of cursor position (1-80.) ; i.e. push x ; push y ; call cursr2 ; ; output ; the x,y cursor positioning is performed ; uses r0 ;- cursr2: TTY esc 'Y mov (sp),r0 ; get ret address mov 4(sp),(sp) ; replace tos with x cord mov r0,4(sp) ; replace 3os with return address pop r0 ; pop x into r0 add #31.,r0 ; convert to teleray cord's call ttycc ; output it pop r0 ; pop y into r0 add #31.,r0 ; convert call ttycc ; output it rts pc .end