.title EDIRTN screen edit subroutine
; subroutine to do a screen edit on vt100 terminals
; uses same commands as "KED", with some not implemented.
; author: Paul Lustgraaf, Iowa State University, Ames, Iowa 515-294-1832
; calling sequence: call edirtn(x,size,wrap,max,lines,wrapstr)
; where: x = an array which holds the text to edit
; size = the length of the text
; wrap = the line length at which we 'wrap around'
; max = the maximum size of the array
; lines = the # of screen lines we can use
; (24-lines lines may be reserved by main program)
; wrapstr = a null-delimited string to insert when we wrap
.enabl gbl
.enabl lc
.nlist bex
.mcall .ttinr,.ttyout,.scca
.psect USER$I,RW,I,LCL,REL,CON
edirtn:: mov r5,saver5 ;save r5
mov 2(r5),x ;save address of array
mov @4(r5),size ;get the size
add x,size ;compute an address
mov @6(r5),wrap ;save wrap value
mov @8.(r5),max ;save max value
add x,max ;compute an address
mov @10.(r5),lines ;get # of lines we can use
mov 12.(r5),wrapstr ;get address of wrap string
call pckpam ;set keypad applications mode
call pcawmr ;reset (turn off) auto wrap mode
call scssg ;set G1 character set=special graphics
mov #50000,@#44 ;set special mode and uplow in jsw
clr abort ;init double control-c indicator
.scca #area,#abort ;intercept control-c's
mov x,cursor ;cursor starts at beginning
mov #1,logcol ;ditto logical column
clr chrsize ;nothing in character buffer
clr wordsize ;ditto word buffer
clr linesize ;ditto line buffer
mov #1,direct ;initial direction is forward
clr gold ;init gold function
clr goldn ;no repeat function yet
clrb last ;no previous character
call paint ;write the first screen-full
.page
; main loop
;
loop: mov #prmblk,r5 ;load parm block address
call readvt ;read a character from the keyboard
movb char,r3 ;put it in r3
tst escflg ;was it an escape sequence?
beq 5$ ;if not, branch
mov #chrtab,r0 ;load address of character table
mov #gldtab,r1 ;load branch table for gold functions
tst gold ;was gold key struck last?
bne 2$ ;if so, branch
mov #jmptab,r1 ;load address of table for non-gold functions
2$: mov (r1)+,r2 ;load a branch address
beq 9$ ;branch if end of table
cmpb r3,(r0)+ ;is this the function?
bne 2$ ;if not, loop
3$: clr gold ;turn off gold
jsr pc,(r2) ;call the correct routine
br 9$
5$: cmp r3,#40 ;is it a control character?
bhis 7$ ;if not, branch
mov #ctltab,r0 ;load address of control character table
mov #brtab,r1 ;load address of table for control characters
6$: mov (r1)+,r2 ;load a function address
beq 9$ ;branch if end of table
cmpb r3,(r0)+ ;is this the function?
bne 6$ ;if not, loop
br 3$ ;go do it
7$: cmp r3,#177 ;delete key?
bne 8$ ;if not, branch
call delete ;call delete routine
br 9$
8$: call insert ;call character insertion routine
9$: movb char,last ;remember last character
br loop ;loop forever
;
; command function means exit
;
command: bis #100,@#44 ;enable carry return from .ttinr
1$: .ttinr ;flush input buffer
bcc 1$ ;branch until buffer empty
.scca #area,#0 ;return to normal control-c handling
call pckpnm ;set keypad to numeric mode
call pcawms ;set auto wrap mode
bic #50100,@#44 ;restore jsw to normal mode
mov saver5,r5 ;restore parm block address
sub x,size ;compute actual length
mov size,@4(r5) ;return new size to main program
tst (sp)+ ;pop the return address
return ;return to main program
.page
; handle control-c. two of them in a row causes us to return with size=0.
;
cancel: tst abort ;double control-c?
beq 9$ ;if not, branch
clr abort ;clear the indicator
mov x,size ;return size=0
br command ;return to main
9$: return
;
; functions not implemented. ring the bell
;
help: specins: paste: fill: replace: reset: substitute: find:
cut: append: select: enter: findnext: tab:
;
; error indicator is the bell
;
bell: .ttyout #7 ;output a bell character
return
;
; direction is forward
;
advance: mov #1,direct ;remember direction
return
;
; direction is backward
;
backup: mov #-1,direct ;remember direction
return
;
; remember gold key
;
goldkey: inc gold ;gold key was last
return
;
; go to top of text
;
top: cmp cursor,x ;are we already at top?
beq bell ;if so, branch
mov x,cursor ;set cursor to beginning
mov #1,logcol ;logical column is one
call paint ;re-paint the screen
return
;
; go to bottom of text
;
bottom: cmp cursor,size ;are we already at bottom?
bhis bell ;if so, branch
mov size,cursor ;set cursor to end
mov #1,logcol ;logical column is one
call paint ;re-paint the screen
return
.page
; insert a blank line
;
openline: cmp size,max ;is the buffer full?
bhis 10$ ;if so, branch
clr temp ;store a newline char in temp
mov #temp,r2 ;load address of char to insert
mov #1,r0 ;load # of chars to insert
mov cursor,r1 ;load cursor
call strins ;insert a newline into the file
call insnl ;figure out how many lines to print
dec row ;leave cursor on top of newline
mov cursor,r1 ;load cursor
call prtlin ;print x lines
call poscur ;position the cursor
return
10$: jmp bell
;
; move cursor 16 lines
;
page:
section: mov cursor,r1 ;load the cursor
mov #16.,r0 ;load 16
tst direct ;are we going forward?
bpl 2$ ;is so, branch
neg r0 ;must be going backwards
cmp r1,x ;are we already at beginning?
beq 10$ ;if so, branch
br 3$
2$: cmp r1,size ;are we already at end?
bhis 10$ ;if so, branch
3$: call movlin ;move 16 lines
mov r1,cursor ;save the new cursor
mov #1,logcol ;we are now at col one
call paint ;re-paint the screen
return
10$: jmp bell ;error
.page
; change the case of cursor characters
;
chngcase: mov cursor,r1 ;load cursor
cmp r1,size ;are we at eof?
beq 9$ ;if so, branch
movb (r1),r0 ;get the current character
cmp r0,#'A ;Z?
bhi 2$ ;if so, branch
add #40,r0 ;convert to lower case
br 5$
2$: cmp r0,#'a ;z?
bhi 9$ ;if so, branch
sub #40,r0 ;convert to upper case
5$: movb r0,(r1) ;change the character
.ttyout ;output the character
.ttyout #10 ;output a backspace
9$:
;
; move the cursor one character
;
charkey: tst direct ;are we going forwards?
bmi left ;if not, must be going backwards
;
; move the cursor one character right
;
right: mov cursor,r1 ;load cursor
cmp r1,size ;are we at eof?
beq 10$ ;if so, branch
inc cursor ;move the cursor
inc col ;move physical col
mov col,logcol ;logical=physical col
tstb (r1)+ ;was this character a newline?
beq 2$ ;if so, branch
mov #colprm,r5 ;load parm block address
call cuf ;move the cursor right
br 9$
2$: mov #1,col ;col=1
mov #1,logcol
call down3 ;scroll the display up
9$: return
10$: jmp bell ;error
.page
; move the cursor one character left
;
backsp:
left: mov cursor,r1 ;load cursor
cmp r1,x ;at beginning?
beq 10$ ;if at beginning, branch
dec cursor ;move left
dec col ;update physical col
mov col,logcol ;logical=physical col
tstb -(r1) ;is the new character a newline?
beq 2$ ;if so, branch
.ttyout #10 ;move cursor left
br 9$
2$: call up3 ;scroll the display down
mov col,logcol ;logical=physical col
9$: return
10$: jmp bell ;error
;
; move the cursor up one line
;
up: cmp cursor,x ;are we at beginning?
beq up9 ;if so, branch
mov cursor,r1 ;load cursor
mov #-1,r0 ;move one line up
call movlin ;move
tst r2 ;did we really move?
beq up9 ;if not, branch
call logcur ;move cursor to logical position
up3: mov r1,cursor ;update cursor
dec row ;up one
cmp row,#8. ;upper half of screen?
bgt 8$ ;if not, branch
mov homead,r1 ;move to current top of screen
mov #-1,r0 ;move up one line
call movlin ;move
tst r2 ;did we really move?
beq 8$ ;if not, branch
mov r1,homead ;save new top of screen
call cuh ;move the cursor home
call ri ;reverse index (scroll down)
inc row ;cursor moves with screen
mov #1,r0 ;print one line
call prtlin ;print it
8$: call poscur ;position cursor on the screen
return
up9: jmp bell ;error
.page
; move cursor down one line
;
down: cmp cursor,size ;eof?
bhis down9 ;if so, branch
mov cursor,r1 ;load cursor
mov #1,r0 ;move down one line
call movlin ;move
tst r2 ;did we hit end of buffer?
beq down10 ;if so, branch
call logcur ;move to logical position
down3: mov r1,cursor ;update cursor
inc row ;move cursor down
cmp row,#16. ;top half of screen?
ble 8$ ;if so, branch
mov homead,r1 ;go to current top of screen
mov #1,r0 ;move down one line
call movlin ;move
tst r2 ;did we really move?
beq 8$ ;if not, branch
mov r1,r4 ;save new cursor
mov lines,r0 ;try to move to last line
dec r0 ;we want to move lines-1 lines
call movlin ;move
cmp r2,r0 ;did we really move to last line?
blt 8$ ;if not, branch
mov r4,homead ;save new top of screen address
mov row,r4 ;save current row
mov lines,row ;go to bottom row
mov col,r3 ;save current col
mov #1,col ;go to col 1
mov #cupprm,r5 ;load parm block address
mov r1,-(sp) ;save r1
mov r4,-(sp) ;save r4
call cup ;position cursor to bottom row, col 1
mov (sp)+,r4 ;restore r4
mov (sp)+,r1 ;restore r1
call ind ;index (scroll up)
mov #1,r0 ;print one line
call prtlin ;print it
dec r4 ;cursor moves with screen
mov r4,row ;update row
8$: call poscur ;position the cursor
return
down10: mov r1,cursor ;move cursor to eob
call poscur ;move physical cursor
mov col,logcol ;update logical column
down9: jmp bell ;error
.page
; move cursor to beginning of next line
;
bline: mov cursor,r1 ;load cursor
tst direct ;are we going backward?
bpl 2$ ;if not, branch
cmp cursor,x ;beginning of buffer?
beq 5$ ;if so, branch
tstb -1(r1) ;are we at beginning of line?
beq 5$ ;if so, branch
2$: clr r0 ;go to beginning of this line
call movlin ;do it
mov #1,logcol ;logical=1
mov r1,cursor ;update cursor
call poscur ;move physical cursor
tst direct ;backup?
bmi 9$ ;if so, branch
jmp down ;move cursor down
5$: jmp up ;move cursor up
9$: return
;
; move cursor to end of line
;
eol: mov #1000.,logcol ;logical col=infinity
tst direct ;backup?
bmi 5$ ;if so, branch
mov cursor,r1 ;load cursor
tstb (r1) ;are we on newline?
bne 2$ ;if not, branch
call down ;move cursor to next line
br 8$
2$: cmp cursor,size ;eof?
bhis down9 ;if so, branch
mov #1,r0 ;move one line
call movlin ;do it
tst r2 ;did we really move past a newline?
beq 3$ ;if not, branch
dec r1 ;point to newline
3$: mov r1,cursor ;update cursor
call poscur ;go to end of this line
br 8$
5$: call up ;move cursor up
8$: mov col,logcol ;logical col=last col
return
.page
; move cursor one word
;
word: mov cursor,r1 ;load cursor
mov direct,r0 ;load direction
bmi 5$ ;if backup, branch
cmp r1,size ;at eof?
bhis 10$ ;if so, branch
tstb (r1) ;is cursor on newline?
bne 1$ ;if not, branch
jmp right ;if so, go to col 1 next line
1$: call movword ;move the cursor forward one word
br 8$
5$: cmp r1,x ;at beginning?
beq 10$ ;if so, branch
call movword ;move backward one word
tstb (r1) ;did we hit newline?
bne 8$ ;if not, branch
jmp eol ;go to end of previous line
8$: mov r1,cursor ;update cursor
call poscur ;update physical cursor
mov col,logcol ;logical=physical
9$: return
10$: jmp bell ;error
.page
; insert a character
;
insert: mov cursor,r1 ;load cursor
cmp size,max ;is the array full?
bhis 10$ ;if so, branch
movb r3,temp ;store character in temp
mov #temp,r2 ;load character address
mov #1,r0 ;insert one character
call strins ;do it
dec r1 ;point at this char
inc cursor ;update cursor
inc col ;update physical col
mov col,logcol ;logical=physical
mov #1,r0 ;print one line
tstb temp ;was it a newline?
bne 8$ ;if not, branch
call insnl ;compute # of lines to print
mov #1,col ;cursor is now in column 1
mov col,logcol ;logical=physical
8$: call prtlin ;print the rest of the line
call poscur ;re-position the cursor
tst wrap ;are we supposed to word wrap?
beq 9$ ;if not, branch
cmp col,wrap ;are we past wrap point?
blos 9$ ;if not, branch
mov #-1,r0 ;search backwards for start of word
mov cursor,r1 ;load cursor
call movword ;search for start of word
mov cursor,r0 ;load cursor
dec r1 ;point to char before word
sub r1,r0 ;compute length of word
cmp r0,col ;does this word start in col 0?
bhis 9$ ;if so, branch
mov r0,logcol ;remember logical column
mov r1,cursor ;update cursor
clrb (r1)+ ;change blank? to newline
mov wrapstr,r2 ;load wrap string address
mov #-1,r0 ;set up for count
1$: inc r0 ;count a byte
tstb (r2)+ ;end of string?
bne 1$ ;if not, branch
tst r0 ;anything in string?
beq 2$ ;if not, branch
add r0,logcol ;update logical column
mov wrapstr,r2 ;re-load wrap string address
call strins ;insert wrap string
2$: mov cursor,r1 ;load cursor
call poscur ;position the physical cursor
mov cursor,r1 ;reload cursor
call insnl ;compute # of lines to print
call prtlin ;print them
mov cursor,r1 ;reload cursor
inc r1 ;point at first char of line
call logcur ;point r1 at logical cursor
mov r1,cursor ;update cursor
call poscur ;update physical cursor
9$: return
10$: jmp bell ;error
;
; CR received. Insert a newline.
;
newline: clr r3 ;null is newline character
br insert ;insert a newline
.page
; DEL key struck. Delete one character to the left.
;
delete: cmp cursor,x ;at beginning?
beq del9 ;if so, branch
call left ;move left
mov #2,chrsize ;remember delete
br del1 ;join common code
;
; DELCHAR key struck. Delete character under cursor.
;
delchar: cmp cursor,size ;eof?
bhis del9 ;if so, branch
mov #1,chrsize ;remember delchar
del1: mov cursor,r1 ;load cursor
movb (r1),chrbuf ;save character for future reference
mov #1,r0 ;delete one character
call strdel ;delete it
tstb chrbuf ;was it a newline?
bne del2 ;if not, branch
del0: call clreos ;clear to end of screen
mov lines,r0 ;r0=# of lines
inc r0 ;r0=r0+1
sub row,r0 ;compute # of lines left on screen
br del3
del2: call clreol ;clear to end of line anyway
mov #1,r0 ;print one line
del3: mov cursor,r1 ;load cursor
call prtlin ;print x lines
call poscur ;position the cursor
return
del9: jmp bell ;error
;
; Un-delete a character.
;
undelchar: tst chrsize ;do we have a character?
beq 9$ ;if not, branch
movb chrbuf,r3 ;load it
call insert ;re-insert it
cmp chrsize,#1 ;was it delchar?
bne 9$ ;if not, branch
call left ;move cursor left
9$: return
.page
; delete a word
;
delword: mov #1,r0 ;direction is forward
mov cursor,r1 ;load cursor
cmp r1,size ;eof?
bhis 10$ ;if so, branch
call movword ;find the beginning of next word
mov r1,r0 ;r0=r1
mov cursor,r1 ;load cursor
sub r1,r0 ;compute length
ble 10$ ;if bad, branch
mov #wordbuf,r2 ;load address of buffer
call sdelsv ;save the word and delete
mov r3,wordsize ;save length
tstb wordbuf ;newline?
beq 3$ ;if so, branch
call del2 ;rewrite line
br 9$
3$: call del0 ;change lines
9$: return
10$: jmp bell ;error
;
; LF received. If it follows a CR, ignore it.
; Else delete a word to the left.
;
linefeed: cmpb last,#15 ;was last char CR?
beq 9$ ;if so, branch
mov #-1,r0 ;search backward
mov cursor,r1 ;load cursor
cmp r1,x ;at beginning?
blos 10$ ;if so, branch
call movword ;go to previous word
mov cursor,r0 ;r0=cursor
sub r1,r0 ;compute length
ble 10$ ;if bad, branch
mov r1,cursor ;update cursor
mov #wordbuf,r2 ;load buffer address
call sdelsv ;save word and delete it
neg r3 ;length=-length
mov r3,wordsize ;save length
tstb wordbuf ;newline?
beq 3$ ;if so, branch
call poscur ;re-position the cursor
call del2
br 9$
3$: dec row ;we changed rows
call poscur ;re-position the cursor
call del0
9$: return
10$: jmp bell ;error
.page
; delete remainder of line
;
delline: mov cursor,r1 ;load cursor
cmp r1,size ;eof?
bhis 10$ ;if so, branch
mov #1,r0 ;search forwards
call movlin ;do it
mov r1,r0 ;r0=next line
mov cursor,r1 ;load cursor
sub r1,r0 ;compute length
ble 10$ ;if bad, branch
mov #linebuf,r2 ;load buffer address
call sdelsv ;save line and delete it
mov r3,linesize ;save length
call del0
return
10$: jmp bell ;error
;
; delete up to next newline
;
deleol: mov cursor,r1 ;load cursor
cmp r1,size ;eof?
bhis 10$ ;if so, branch
inc r1 ;skip first char in case newline
mov #1,r0 ;skip one line
call movlin ;do it
dec r1 ;don't delete newline
mov r1,r0 ;ro=(newline)
mov cursor,r1 ;load cursor
sub r1,r0 ;compute length
ble 10$ ;if bad, branch
mov #linebuf,r2 ;load buffer address
call sdelsv ;save line and delete
mov r3,linesize ;save length
tstb linebuf ;was first char newline?
beq 3$ ;if so, branch
call del2
br 9$
3$: call del0
9$: return
10$: jmp bell ;error
.page
; control-u delete from cursor to beginning of line
;
delbol: mov cursor,r1 ;load cursor
cmp r1,x ;at beginning?
blos 10$ ;if so, branch
clr r0 ;go to beginning of line
tstb -1(r1) ;are we already in col 1?
bne 5$ ;if not, branch
call up ;go up one line
call delline ;delete previous line
neg linesize ;indicate delbol
br 9$
5$: call movlin ;go to col 1
mov cursor,r0 ;r0=cursor
sub r1,r0 ;compute length
ble 10$ ;if bad, branch
mov r1,cursor ;update cursor
mov #linebuf,r2 ;load buffer address
call sdelsv ;save line and delete
neg r3 ;indicate delbol
mov r3,linesize ;save length
call poscur ;re-position the cursor
call del2
9$: return
10$: jmp bell ;error
.page
; undelete a word
;
undelword: cmp size,max ;is buffer full?
bhis 10$ ;if so, branch
mov cursor,r1 ;load cursor
mov wordsize,r0 ;load size of word in buffer
beq 10$ ;if none, branch
bpl 1$ ;if positive, delword, branch
neg r0 ;if negative, linefeed
1$: mov #wordbuf,r2 ;load buffer address
call strins ;re-insert the word
mov cursor,-(sp) ;save cursor
tst wordsize ;delword?
bpl 2$ ;if so, branch
mov r1,(sp) ;leave cursor after the word for linefeed
2$: mov cursor,r1 ;load cursor
mov #1,r0 ;assume print one line
tstb wordbuf ;newline?
bne 8$ ;if not, branch
call insnl ;compute # of lines to print
tst wordsize ;delword?
bmi 8$ ;if not, branch
dec row ;change rows
8$: call prtlin ;print n lines
mov (sp)+,cursor ;update cursor
call poscur ;position cursor
mov col,logcol ;logical=physical
9$: return
10$: jmp bell ;error
;
; undelete a line
;
undelline: cmp size,max ;is the buffer full?
bhis 10$ ;if so, branch
mov cursor,r1 ;load cursor
mov linesize,r0 ;load length
beq 10$ ;if none saved, branch
bpl 1$ ;if delline or deleol, branch
neg r0 ;- = delbol (ctrl-u)
1$: mov #linebuf,r2 ;load buffer address
call strins ;re-insert the line
tst linesize ;delbol?
bpl 2$ ;if not, branch
mov r1,cursor ;position cursor after insertion
2$: call paint ;I give up, help!!!
return
10$: jmp bell ;error
.page
; Clear the screen and re-write it.
;
paint: call cuh ;home the cursor
call clreos ;clear to end of screen
mov cursor,r1 ;load cursor
mov #-12.,r0 ;attempt to move up 12 lines
call movlin ;try it
mov r1,homead ;save top of screen address
neg r2 ;r2=-r2
inc r2 ;compute row address(1-24)
mov r2,row ;save row address
mov lines,r0 ;paint the whole screen
call prtlin ;do it
call poscur ;position the cursor
return
;
; move to the start of a line
; r0 = # of lines to advance(+) or backup(-)
; r1 = (input)=current cursor (output)=new cursor value
; r2 = # of lines moved
;
movlin: clr r2 ;init lines moved
tst r0 ;advance?
ble 5$ ;if not, branch
1$: cmp r1,size ;eof?
bhis 9$ ;if so, branch
tstb (r1)+ ;newline?
bne 1$ ;if not, loop
inc r2 ;one more line
cmp r2,r0 ;far enough?
blt 1$ ;if not, loop
br 9$
5$: cmp r1,x ;beginning?
blos 9$ ;if so, branch
tstb -(r1) ;newline?
bne 5$ ;if not, loop
dec r2 ;one more line
cmp r2,r0 ;far enough?
bge 5$ ;if not, loop
inc r2 ;fix up line count
inc r1 ;fix up cursor
9$: return
.page
; print x lines
; r0 = # of lines to print
; r1 = address to start
; r2 = # of lines printed
;
prtlin: mov r0,r5 ;save r0
clr r2 ;init # lines printed
1$: cmp r1,size ;eof?
bhis 8$ ;if so, branch
movb (r1)+,r0 ;load a character
beq 2$ ;branch if newline
.ttyout ;print it
br 1$ ;loop
2$: inc r2 ;one more line
cmp r2,r5 ;far enough?
bge 9$ ;if so, branch
.ttyout #15 ;print CR
.ttyout #12 ;print LF
br 1$ ;loop
8$: call scsg1 ;switch to character set g1 (graphics)
.ttyout #141 ;print eof symbol (checkerboard)
call scsg0 ;switch back to character set g0
9$: return
;
; Position the cursor on the screen.
;
poscur: mov cursor,r1 ;load cursor
clr r0 ;col=0
1$: inc r0 ;inc col
cmp r1,x ;beginning?
blos 2$ ;if so, branch
tstb -(r1) ;newline?
bne 1$ ;if not, loop
2$: mov r0,col ;save col
mov #cupprm,r5 ;load parm block address
call cup ;position the physical cursor
return
;
; move cursor to logical column in line
; r1= (input) first character of a line
; (output) logical column
;
logcur: clr col ;start at col one
mov logcol,r2 ;load logical col
1$: inc col ;keep track of current col
cmp r1,size ;eof?
bhis 9$ ;if so, branch
tstb (r1)+ ;newline?
beq 2$ ;if so, branch
sob r2,1$ ;count loop
2$: dec r1 ;point to correct character
9$: return
.page
; Insert a string of characters.
; If too long for buffer, sounds bell and truncates.
; r0 = # of characters to insert
; r1 = starting address in buffer
; r2 = address of string to insert
;
strins: mov size,r3 ;load size
mov r3,r4 ;r4=size
add r0,r4 ;compute new size
mov r4,size ;update size
cmp r4,max ;too big?
blos 1$ ;if not, branch
mov r4,r5 ;r5=new size
sub max,r5 ;r5=excess
sub r5,r0 ;truncate
sub r5,r4 ;compute new size
sub r5,size ;update size
call bell ;indicate error
1$: cmp r3,r1 ;done sliding yet?
blos 2$ ;if so, branch
movb -(r3),-(r4) ;slide rest of buffer right
br 1$ ;loop
2$: movb (r2)+,(r1)+ ;insert the string
sob r0,2$ ;count loop
return
;
; Delete a string of characters.
; r0 = # of characters to delete
; r1 = starting address
;
strdel: mov r1,r2 ;save r1
add r0,r2 ;compute end address
1$: cmp r2,size ;eof?
bhis 9$ ;if so, branch
movb (r2)+,(r1)+ ;delete a character
br 1$ ;loop
9$: sub r0,size ;compute new size
return
;
; save a string in a save buffer and then delete it
; r0=length of string
; r1=starting address of string
; r2=save buffer address
; r3=size of string put in save buffer
;
sdelsv: mov r0,r5 ;save r0
mov r1,r4 ;save r1
cmp r0,#82. ;too long for buffer?
blos 1$ ;if not, branch
call bell ;indicate buffer full
mov #82.,r0 ;truncate
1$: mov r0,r3 ;return actual length saved
2$: movb (r4)+,(r2)+ ;save a byte
sob r0,2$ ;count loop
mov r5,r0 ;restore r0
call strdel ;delete the string
return
.page
; decide whether or not to scroll up after inserting a newline
;
insnl: mov r1,-(sp) ;save current address
call clreos ;clear from cursor to end of screen
cmp row,#16. ;are we at bottom of screen?
ble 8$ ;if not, branch
mov homead,r1 ;go to top of screen
mov #1,r0 ;move down one line
call movlin ;try to move
tst r2 ;did we really move?
beq 8$ ;if not, branch
mov r1,r4 ;save new top of screen address
mov lines,r0 ;move to last line
dec r0 ;from line 1
call movlin ;try to move
cmp r2,r0 ;did we get to last line?
blt 8$ ;if not, branch
mov r4,homead ;update top of screen address
dec row ;scroll up one line
8$: mov lines,r0 ;r0=# of lines
inc r0 ;r0=r0+1
sub row,r0 ;compute # of lines to print
inc row ;move cursor down one line
mov (sp)+,r1 ;restore r1
return
.page
; move one word forward or backward
; r0=direction +=forward -=backward
; r1= (input)=current cursor
; (output)=start of next word
;
movword: tst r0 ;backward?
bmi 5$ ;if so, branch
cmp r1,size ;eof?
bhis 9$ ;if so, branch
tstb (r1) ;on newline?
beq 7$ ;if so, branch
cmpb (r1),#10 ;on tab?
beq 7$ ;if so, branch
cmpb (r1)+,#40 ;on a blank?
beq 3$ ;if so, branch
2$: cmp r1,size ;eof?
bhis 9$ ;if so, branch
tstb (r1) ;newline?
beq 9$ ;if so, branch
cmpb (r1),#10 ;tab?
beq 9$ ;if so, branch
cmpb (r1)+,#40 ;blank?
bne 2$ ;if not, loop
3$: cmp r1,size ;eof?
bhis 9$ ;if so, branch
cmpb (r1)+,#40 ;blank?
beq 3$ ;if so, loop
dec r1 ;point to first char of next word
br 9$ ;r1 now points to next word
5$: cmp r1,x ;at beginning?
blos 9$ ;if so, branch
cmpb -(r1),#40 ;blank?
beq 5$ ;if so, loop
tstb (r1) ;newline?
beq 9$ ;if so, branch
cmpb (r1),#10 ;tab?
beq 9$ ;if so, branch
6$: cmp r1,x ;at beginning?
blos 9$ ;if so, branch
tstb -(r1) ;newline?
beq 7$ ;if so, branch
cmpb (r1),#10 ;tab?
beq 7$ ;if so, branch
cmpb (r1),#40 ;blank?
bne 6$ ;if not, loop
7$: inc r1 ;r1 now points to word
9$: return
.page
; PURE DATA AREA
;
.psect $DATAP,RW,D,LCL,REL,CON
prmblk: .word 2,escflg,char ;parm block for readvt
cupprm: .word 2,row,col ;parm block for cursor position
colprm: .word 1,one ;parm block for cuf
one: .word 1
chrtab: .asciz /ABCDPQpqrstuvwxylmnMRS/
.even
gldtab: .word up,down,right,left,goldkey,help
.word openline,chngcase,deleol,specins,bottom,top,paste
.word command,fill,replace,undelchar,undelword,reset
.word substitute,find,undelline,0
jmptab: .word up,down,right,left,goldkey,help
.word bline,word,eol,charkey,advance,backup,cut
.word page,section,append,delchar,delword,select
.word enter,findnext,delline,0
ctltab: .byte 15,12,11,10,3,25,27,0
.even
brtab: .word newline,linefeed,tab,backsp,cancel,delbol,paint,0
; IMPURE DATA AREA
.psect $DATA,RW,D,LCL,REL,CON
saver5: .blkw 1 ;saved r5
x: .blkw 1 ;address of buffer
size: .blkw 1 ;address of buffer size
wrap: .blkw 1 ;line length at which to wrap
max: .blkw 1 ;max size of buffer
lines: .blkw 1 ;# of screen lines we can use
wrapstr: .blkw 1 ;address of wrap string
escflg: .blkw 1 ;0=normal char,1=esc sequence
char: .blkb 1 ;character from readvt
last: .blkb 1 ;last character read
gold: .blkw 1 ;1=gold key was last
goldn: .blkw 1 ;# of times to repeat
area: .blkw 2 ;area for macros
abort: .blkw 1 ;double control-c indicator
chrsize: .blkw 1 ;0=no char,1=delchar,2=del
wordsize: .blkw 1 ;# of chars in word buffer
linesize: .blkw 1 ;# of chars in line buffer
direct: .blkw 1 ;1=advance,-1=backup
cursor: .blkw 1 ;cursor value
row: .blkw 1 ;physical row(1-24)
col: .blkw 1 ;physical column(1-80)
logcol: .blkw 1 ;logical column
homead: .blkw 1 ;address of top of screen
temp: .blkw 1
chrbuf: .blkw 1 ;character save buffer
wordbuf: .blkb 82. ;word save buffer
linebuf: .blkb 82. ;line save buffer
.end