.sbttl ^r mode commands ;this section processes the ^r mode commands. rch is the main dispatch ;routine of these commands corresponding to chx for the normal commands. ;the control r mode commands differ from normal commands in that they are ;executed as soon as the char is read from the tty. normally, non-control, ;non-rubout chars are simply inserted in the buffer and some display update ;is rts pc. control chars and rubout execute special function such as moving ;the cursor around, deleting chars etc. ;^r mode dispatching ;as each char is read in, it is used to execute a command based on the ;the r mode dispatch table, rcmac. this table is a vector of numbers ;which can be modified by the user via the fv^rcmacro$ command. the char ;read in, dispatches into this table and a number is read out. positive ;numbers are assumed to be the ascii value of a qregister to macro. ;the qregister is macro'd via chm and returns to rch via the chx jmp. ;negative numbers are first converted to positive, then used to select ;a ^rmode command via the rdtab. .csect pgm rch: clr rmode1 ;just some initialization for control kludge tst rmode ;are we still in ^r mode? beq 1$ ;no, return to caller mov #rcmac,r1 ;use the c table for dispatching jsr pc,rchdsp ;now dispatch br rch ;now check for more 1$: rts pc ;dispatch routine. Expects r1 to hold a pointer to a table 128 words long. ;Negative numbers in the table refer to rdtab routines, positive numbers ;refer to q registers. rchdsp: jsr pc,tyi ;get a char into r0 mov r0,lastch ;save the char bic #177600,r0 ;make sure it's 0-127 asl r0 ;convert to word offset add r0,r1 ;add the base address of the table mov (r1),r0 ;get the function to execute ble rchjmp ;negative, thus dispatch into rdtab jsr pc,findq1 ;set pointers to proper q register ble 1$ ;not alpha q reg mov #1,rmode1 ;tell some people we are doing ^R mode jmp chm3 ;otherwise, macro this qregister 1$: error rchcnt: rts pc ;continuation point for macros ;routine to actually jump through the dispatch table. It is labled ;separately because it is also called by symexc to execute functions. rchjmp: neg r0 ;convert to positive asl r0 ;convert to word offset cmp r0,#rdsiz ;make sure its a valid function bhis 1$ ;too high jmp @rdtab(r0) ;execute the function 1$: error ;routine to ring the terminal's bell implying undefined ^r char rchudf: jsr pc,bell ;ring the terminal's bell rts pc ;routine to escape from ^r mode rchesc: clr rmode ;just clear the flag rts pc ;routine to select a new display window and update the screen rchl: jsr pc,setwin ;select a new window mov window,r0 add bob,r0 ;make it absolute jsr pc,typscn ;type everything from r0 to bottom jsr pc,update ;now set the cursor rts pc ;routine to multiply the expt by 4 rchu: mov rexpt,r0 ;get the rmode expt mul #4.,r0 ;multiply it by 4 mov r1,rexpt ;put it back rts pc ;routine to read a quoted char rchq: jsr pc,tyi ;get a char into r0 jsr pc,rstty ;reset some tty stuff mov r0,lastch ;save it jsr pc,rchnrm ;insert it into the buffer rts pc ;routine to insert normal chars into buffer rchnrm: push ;save current cursor position jsr pc,linsiz ;get the screen size of . line into r0 mov r0,r1 ;save it mov lastch,r0 ;get the actual char jsr pc,insert ;insert it into the buffer jsr pc,linsiz ;get the screen size of . line into r0 cmp r0,r1 ;has the line grown? bne 1$ ;yes, must redisplay rest of screen mov (sp),r0 ;get our old cursor position mov #1,r1 ;go forward one line jsr pc,line ;advance r0 to end of current line mov r0,r2 ;this will be the end pointer mov (sp),r1 ;old char position is start pointer push ;save our old position jsr pc,typer ;type to end of line pop ;set up the arguments to count mov #1,r5 ;we want to count 1 char position jsr pc,count ;figure out where to leave the cursor mov r1,vpos ;new vertical position mov r2,hpos ;new horizontal position jsr pc,setcur ;put the cursor there rts pc 1$: pop ;restore our original cursor position jsr pc,typscn ;type everything from here down jsr pc,update ;put the cursor in the right spot rts pc ;routine to insert a newline rchj: push ;save our current cursor mov #12,r0 ;insert a nl in buffer jsr pc,insert pop ;get our old cursor position jsr pc,typscn ;type to bottom of the screen jsr pc,update ;put the cursor in the right place rts pc ;routine to delete chars from the buffer rchd: mov rexpt,r1 ;get a copy of the expt beq 5$ ;zero, so nothing to do cmp cptr,eoa ;are we at the end of the world? bhis rcher1 ;yes, nothing to delete mov cptr,r0 ;now see if we will delete any nl's 1$: cmp r0,eoa ;are we at the end yet? bhis 2$ ;yup, ok nothing left to check cmpb (r0)+,#12 ;check for a newline beq 6$ ;found one, do whole screen update sob r1,1$ ;keep checking 2$: jsr pc,linsiz ;get the length of current line push ;save it mov cptr,r0 ;get another copy of cursor mov r0,r2 ;copy it add rexpt,r2 ;to delete this many chars cmp r2,eoa ;have we gone too far? blos 3$ ;no, it's ok mov eoa,r2 ;else, put it to the end 3$: jsr pc,dele ;delete it from buffer jsr pc,linsiz ;now see how long the line is cmp r0,(sp)+ ;has it changed? bne 8$ ;yes, type to bottom of screen mov cptr,r0 ;get another copy of cursor mov #1,r1 ;we want to go forward 1 line jsr pc,line ;move r0 mov r0,r2 ;copy it mov cptr,r0 ;get pointer to starting position jsr pc,gtyper ;type it cmp r2,eoa ;are we at end of world? blo 4$ ;no, everythings ok jsr pc,killln ;else kill to end of this line 4$: jsr pc,update ;put the cursor where it belongs 5$: mov #1,rexpt ;reset the expt rts pc 6$: mov cptr,r0 ;get the cursor mov r0,r2 ;copy the cursor add rexpt,r2 ;delete this much cmp r2,eoa ;would we go too far? blos 7$ ;no, it's ok mov eoa,r2 ;else reset it 7$: jsr pc,dele ;do it 8$: mov cptr,r0 ;get copy of cursor position jsr pc,typscn ;type to bottom of screen jsr pc,update ;put the cursor where it belongs mov #1,rexpt ;reset the expt rts pc ;routine to kill rest of a line rchk: cmp cptr,eoa ;is there anything to kill? bhis rcher1 ;no, error mov cptr,r0 ;copy the pointer mov rexpt,r1 ;to go forward one line ble 1$ ;for now, had better be positive jsr pc,line ;move r0 forward mov r0,r2 ;this will be end marker mov cptr,r0 ;copy pointer again jsr pc,dele ;kill the line mov cptr,r0 ;copy pointer once more jsr pc,typscn ;type to end of screen jsr pc,update ;put cursor where it belongs 1$: mov #1,rexpt ;reset rexpt rts pc ;routine to rubout rchrub: cmp cptr,bob ;are we already at beginning blos rcher1 ;yes, nothing to rubout mov cptr,r0 ;get a copy of the cursor sub rexpt,r0 ;see if this would cause it to go too far cmp r0,bob ;too far? bhis 1$ ;no, it's ok mov cptr,r0 ;else compute the maximum we can go back sub bob,r0 ;this is it mov r0,rexpt ;use this amount 1$: push ;save it jsr pc,rchh ;go back expt chars pop ;now delete this much jsr pc,rchd ;kill the char mov #1,rexpt ;reset the expt rts pc ;error routine, just rings a bell rcher1: jsr pc,bell ;give him an error mov #1,rexpt ;reset the expt rts pc ;routine to handle the special keys on a vt52. The default is ;to use this table to dispatch on the $x chars. rchalt: mov #ramac,r1 ;use the a table to dispatch jmp rchdsp ;dispatch off the next input char ;routine to dispatch on still another table. the default is ;to use this table to dispatch on the $?x chars ie numbers on alt keypad. rchqst: mov #rbmac,r1 ;use the b table to dispatch jmp rchdsp ;dispatch off the next input c ;routine to move back lines rchp: cmp cptr,bob ;are we at the beginning? blos rcherr ;yes, no where to go neg rexpt ;to move back rexpt lines br rchnp ;common routine ;routine to move to next line rchn: cmp cptr,eoa ;are we at the end already? bhis rcherr ;yes error rchnp: mov cptr,r0 mov rexpt,r1 ;go down expt lines mov #1,rexpt ;reset expt jsr pc,line ;move r0 mov r0,cptr ;reset pointer jsr pc,update ;reset cursor rts pc ;routine to move back chars rchh: cmp cptr,bob ;are we already at beginning? blos rcherr ;yes, can't go back any more sub rexpt,cptr ;move the cursor back cmp cptr,bob ;did we go too far? bhis rchfh ;no, it's ok mov bob,cptr ;else fix it br rchfh ;common routine ;routine to move forward chars rchf: cmp cptr,eoa ;are we at the end? bhis rcherr ;yup, no where to go add rexpt,cptr ;move the cursor forward cmp cptr,eoa ;too far? blos rchfh ;no, its ok mov eoa,cptr ;else fix it rchfh: mov #1,rexpt ;reset the expt jsr pc,update ;put cursor where it belongs rts pc ;common error routine rcherr: mov #1,rexpt ;reset the expt jsr pc,bell ;bleep to tell him rts pc ;routine to go to beginning of a line rcha: cmp rexpt,#1 ;did he type any ^U's bne rche1 ;yes, well then do the opposite, namely ^E rcha1: mov cptr,r0 ;get our initial position clr r1 ;this means beginning like for l command jsr pc,line ;go to beginning of line br rchaeb ;join common routine to update display ;routine to go to end of a line rche: cmp rexpt,#1 ;did he type any ^U's bne rcha1 ;yes, do the opposite, namely ^A rche1: mov cptr,r0 ;get our initial position mov #1,r1 ;go forward one line jsr pc,line cmpb -1(r0),#12 ;is the char just before cursor a nl? bne rchaeb ;no, must be at the end of world dec r0 ;otherwise, back up before nl br rchaeb ;join common routine ;routine to go to beginning of buffer rchb: cmp rexpt,#1 ;did he type any ^U's bne 1$ ;yes, then he want to go to end of buffer mov bob,r0 ;otherwise, cursor go to start br rchaeb ;join common routine to update display 1$: mov eoa,r0 ;set cursor to end of world rchaeb: mov #1,rexpt ;reset rexpt to its default value mov r0,cptr ;people should leave new cursor loc in r0 jsr pc,update ;fix up the screen rts pc ;routine to insert a nl and back over it rcho: mov rexpt,r1 ;make sure there is something to do beq 2$ ;no 1$: push ;save cursor mov #12,r0 ;we want to insert a nl jsr pc,insert ;insert the char pop ;go back to our current position sob r1,1$ 2$: mov #1,rexpt ;reset rexpt mov cptr,r0 ;arg to typscn jsr pc,typscn ;type from r0 to end of screen jsr pc,update ;put the cursor back to right spot rts pc ;routine to page some number of times rchv: dec rexpt ;anything left to do blt 1$ ;nope jsr pc,page ;write out one page br rchv ;do it again 1$: mov #1,rexpt ;reset rexpt jsr pc,rchl ;reset the window and retype the screen rts pc ;table ^r mode functions ;the rcm names are the values stored in rcmac ;the rch names are the actual routines .macro defr name rcm'name = - .word rch'name rdsiz = rdsiz + 2 .endm rdsiz = 0 .csect stack rdtab: defr udf ;undefined, just bleep defr nrm ;insert normal chars defr d ;delete chars defr esc ;escape from ^r mode defr l ;select a new window defr j ;insert a linefeed defr k ;kill to end of line defr rub ;rub out a char defr n ;go forward expt lines defr p ;go back expt lines defr f ;go forward expt chars defr h ;go back expt chars defr u ;multiply rexpt by 4 defr q ;insert any char, quoted insert defr alt ;alt mode stuff, to handle special keys defr a ;go to beginning of line defr b ;go to beginning or end of buffer defr e ;go to end of line defr o ;insert nl and back over it defr v ;page defr qst ;dispatch off of "B" dispatch table ;control r mode char dispatch table ;to find the function specified by rcm'name, look for a routine labled rch'name rcmac: .word rcmudf ;^@ .word rcma ;^a .word rcmb ;^b .word rcmudf ;^c .word rcmd ;^d .word rcme ;^e .word rcmf ;^f .word rcmudf ;^g .word rcmh ;^h .word rcmnrm ;^i .word rcmj ;^j .word rcmk ;^k .word rcml ;^l .word rcmesc ;^m .word rcmn ;^n .word rcmo ;^o .word rcmp ;^p .word rcmq ;^q .word rcmudf ;^r .word rcmudf ;^s .word rcmudf ;^t .word rcmu ;^u .word rcmv ;^v .word rcmudf ;^w .word rcmudf ;^x .word rcmudf ;^y .word rcmudf ;^z .word rcmalt ;esc .word rcmudf ;^\ .word rcmudf ;^] .word rcmudf ;^^ .word rcmudf ;^_ .rept 95. .word rcmnrm ;non-control non-rubout chars .endr .word rcmrub ;rubout ;"A" dispatch table. Normally used to dispatch on the char following ;an altmode. ramac: .rept 77 ;^@ up to > .word rcmudf ;nothing defined for these .endr .word rcmqst ;used for further dispatching on alt keypad ($?) .word rcmudf ;undefined ($@) .word rcmp ;up arrow key ($A) .word rcmn ;down arrow key ($B) .word rcmf ;left arrow key ($C) .word rcmh ;right arrow key ($D) .rept 13 ;E through O .word rcmudf ;nothing defined .endr .word rcmu ;blue key ($P) .word rcmd ;red key ($Q) .word rcmk ;black key ($R) .rept 65 ;rest of chars .word rcmudf ;nothing defined .endr ;"B" dispatch table. For now, completely undefined. Will be used for ;further dispatching on the alternate keypad mode chars ie $?x. rbmac: .rept 200 ;all chars ^@ through del .word rcmudf ;nothing defined .endr