home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
kermit11.tar.gz
/
kermit11.tar
/
k11edi.mac
< prev
next >
Wrap
Text File
|
1989-06-13
|
16KB
|
723 lines
.title k11edi Command line editing
.ident /3.52/
; 18-Jul-86 12:00:29 Brian Nelson
;
; This code is used (currently) for the RSTS/E Command Line
; Editor (CLE.RTS) written by the above author, and for 5.1
; of MINITAB. The encryption calls are for the RSTS/E CLE.
.iif ndf, $MINITAB, $MINITAB = 0
.if eq ,$Minitab
.if ndf, K11INC
.ift
.include /IN:K11MAC.MAC/
.endc
.endc
.enabl gbl
.psect rwdata ,rw,d,lcl,rel,con
.psect CLECTX ,rw,d,gbl,rel,con
curpos: .word edipos
curlen: .word edilen
curcmd: .word edicmd
maxsiz: .word edisiz
clests: .word edists
enckey: .word $enckey
deckey: .word $deckey
.if ne ,$Minitab
.ift
.macro dump v
mov v ,-(sp)
call o$dump
.globl o$dump
.endm dump
CR = 15
LF = 12
LN$MAX = 80.
LN$CNT = 3
ER$EOF == -1
$lastl: .blkb <<LN$MAX+2>*LN$CNT>+2
lastli: .word $lastl ,$lastl+<1*<LN$MAX+2>>,$lastl+<2*<LN$MAX+2>>,0
lastcn: .word LN$CNT
edipos: .word 0
edilen: .word 0
edicmd: .word -1
edists: .word 0
edikey: .word 0
edisiz: .word LN$MAX
$enckey:
$deckey:
TTY = 0
.endc ; If NE, $Minitab
.psect $pdata ,ro,d,lcl,rel,con
.psect $code ,i,ro,i,lcl,rel
FALSE = 0
TRUE = 1
IN$MODE = 1
SET$VT1 = 2
$DEBUG = 0
.iif ndf, $DEBUG, $DEBUG = 0
.sbttl Define macros
.if ne ,$MINITAB
.ift
.MACRO ENCRYPT txt,key
.ENDM ENCRYPT
.MACRO DECRYPT txt,key
.ENDM DECRYPT
.MACRO DEBUG a,b,c
.ENDM DEBUG
.MACRO STRCPY dst,src
mov src ,-(sp)
mov dst ,-(sp)
jsr pc ,strcpy
.ENDM STRCPY
.MACRO STRLEN src
mov src ,-(sp)
call strlen
.ENDM STRLEN
.MACRO SCAN ch,str
mov str ,-(sp)
clr -(sp)
bisb ch ,@sp
call scanch
.ENDM SCAN
.MACRO SAVE list
.if b , <list>
.ift
SAVE <r0,r1,r2,r3,r4,r5>
.iff
.irp x,<list>
mov x,-(sp)
.endr
.endc
.ENDM SAVE
.MACRO UNSAVE list
.if b , <list>
.ift
UNSAVE <r5,r4,r3,r2,r1,r0>
.iff
.irp x,<list>
mov (sp)+,x
.endr
.endc
.ENDM UNSAVE
.MACRO GLOBAL LIST
.GLOBL LIST
.ENDM GLOBAL
.iff ; Kermit or CLE
.MACRO ENCRYPT txt,key
mov key ,-(sp)
mov txt ,-(sp)
call ENCRYPT
.endm ENCRYPT
.MACRO DECRYPT txt,key
mov key ,-(sp)
mov txt ,-(sp)
call DECRYPT
.endm DECRYPT
.MACRO DEBUG txt,sts=1,docr=1
.if ne ,$DEBUG
.if ne ,sts
.save
.psect $pdata
$$ = .
.if b ,<txt>
.ift
.byte 15,12,0
.iff
.asciz @txt@
.endc
.even
.restore
mov #$$ ,-(sp) ; dump the text next please
CALL mout ; to the terminal
.globl mout ; perhaps
.if nb ,<txt>
.ift
.iif nb,docr, message
.endc
.endc
.endc
.endm DEBUG
.endc ; if NE, $Minitab
.macro WRTALL arg ; IO.WAL for an .asciz string
mov arg ,-(sp) ; Pass the address
call wrtall ; Do it
GLOBAL <wrtall> ; Insure globalized
.endm WRTALL ; Done
.enabl lsb
Kbredi::.iif ne, $MINITAB, mov r1,-(sp);
.iif ne, $MINITAB, mov r5,-(sp);
SAVE <r2,r3,r4> ; Save
cmpb vttype ,#TTY ; Not a VT100 or VT2xx?
bne 10$ ; No, try editing
.if ne ,$MINITAB ; Minitab today?
.ift ; Yes
sec ; Just set carry and exit
.iff ; Kermit or CLE
WRTALL @r5 ; Prompt
CALLS kbread ,<2(r5)> ; Hardcopy, use vanilla reads
.endc ; All done
br 100$ ; Exit
10$: WRTALL #$cr ;
WRTALL @r5 ;
bit #SET$VT1,@clests ; Insure terminal in VT100 mode
bne 15$ ; Already did it
WRTALL #$setvt1 ; Not done, do so
bis #SET$VT1,@clests ; Flag as having been done
15$: clr @curpos ; Assume at start of the line.
clr @curlen ; No length
mov 2(r5) ,r4 ; Buffer address
clrb @r4 ; Insure starting with .ASCIZ
20$: CALL read1ch ; Read one character now
mov r0 ,r3 ; Any data persent?
beq 90$ ; Yes, treat as a control Z
SCAN r3 ,#scanlst ; Look for a match
asl r0 ; And dispatch
jsr pc ,@scandsp(r0) ; Do it
bcs 20$ ; Not done
.iif ne, $MINITAB, mov r1,r0 ;
br 100$ ; Done
;
90$: mov #ER$EOF ,r0 ; Error, return END_OF_FILE
clr r1 ; And no data
100$: UNSAVE <r4,r3,r2> ; Exit
.iif ne, $MINITAB, mov (sp)+,r5;
.iif ne, $MINITAB, mov (sp)+,r1;
return
.dsabl lsb
.save
.psect $pdata
scanlst:.byte 'H&37 ,'E&37 ,'B&37 ,'U&37 ,'Z&37 ,CR ,LF
.byte 'I&37 ,177 ,33 ,233 ,'R&37 ,'X&37 ,'C&37
.byte 'A&37
.byte 0
.even
scandsp:.word INSCH
.word SOL ,EOL ,PREV ,CTRLU ,EOF ,NOOP ,DONE
.word NOOP ,DORUB ,DOESC ,DO220 ,RETYPE ,CANTYP ,CTRLC
.word TOGGLE
esclst: .byte 'A&137 ,'B&137 ,'C&137 ,'D&137 ,0
.even
escdsp: .word NOOP
.word PREV ,NEXT ,RIGHT ,LEFT
$cc: .asciz /^C/
$cz: .asciz /^Z/
$bs: .byte 'H&37,0
$cr: .byte 15,0
$right: .asciz <33>/[C/
$left: .asciz <33>/[D/
$save: .asciz <33>/7/
$resto: .asciz <33>/8/
$ceol: .asciz <33>/[K/
$crlf: .byte CR,LF,0
$rrub: .byte 10,40,10,0
$setvt: .byte 33,'<
.even
.restore
Doesc: DEBUG <Doesc> ; ...
CALL read1ch ; Get next in esc seq
Do220: DEBUG <Do220> ; You know
CALL read1ch ; Ditto
mov r0 ,r3 ; Get the data
beq 90$ ; Error Exit
SCAN r3 ,#esclst ; Process the character
asl r0 ; Convert to word offset
jsr pc ,@escdsp(r0) ; Do it
br 100$ ; Ok
90$: sec ; Failure on the READ
100$: return ; And Exit
Noop: DEBUG <Noop> ; ...
sec ; Ignore
return ; And Exit
Insch: DEBUG <Insch>,FALSE ; ...
sub #200 ,sp ; A temp buffer
mov sp ,r2 ; A pointer to it
tst r3 ; Null?
beq 100$ ; Ignore
cmp @curlen ,@maxsiz ; Too many chars?
blo 10$ ; No
CALL done ; Yes, exit
br 100$ ; Bye
10$: inc @curlen ; Save this
mov @curpos ,r1 ; Get the offset into line
add r4 ,r1 ; Where to stuff the data
tstb @r1 ; Already at end of line?
beq 20$ ; Yes, we have the stop to stuff it
bit #IN$MODE,@clests ; Insert or overstrike?
bne 15$ ; Insert
movb r3 ,(r1)+ ; Overstrike
br 30$ ; Exit
15$: STRCPY r2 ,r1 ; No, so save the data now
movb r3 ,(r1)+ ; And insert the new character
STRCPY r1 ,r2 ; And put the trailing data back in.
br 30$ ; Now for the echoing
20$: movb r3 ,(r1)+ ; Already at eol, insert
clrb @r1 ; And insure .ASCIZ
dec r1 ; ...
WRTALL r1 ; Echo
br 90$ ; Exit
30$: WRTALL #$save ; Save cursor pos
dec r1 ; Back to to the new character
WRTALL r1 ; Dump the data
WRTALL #$restore ; Put the cursor back now
WRTALL #$right ; Move over on the display
90$: inc @curpos ; Move over one
100$: add #200 ,sp ; Pop buffer
sec ; Not done
return ; Exit
.sbttl More line editing routines
; SOL Move to start of line (Control H)
Sol: DEBUG <Sol> ; ...
tst @curpos ; Stop when at position 0
ble 100$ ; Done
WRTALL #$bs ; Move
dec @curpos ; Fix position
br sol ; Next please
100$: clr @curpos ; Insure correct
sec ; Not done
return ; Exit
; EOL Move to End of Line, Control E
Eol: DEBUG <Eol> ; ...
STRLEN r4 ; Find string length
10$: cmp @curpos ,r0 ; End yet?
bhis 100$ ; Yes
WRTALL #$right ; No
inc @curpos ; Fix this
br 10$ ; Next
100$: sec ; Not done
return ; Exit
Gotoeol:STRLEN r4 ; Find string length
10$: cmp @curpos ,r0 ; End yet?
bhis 100$ ; Yes
inc @curpos ; Fix this
br 10$ ; Next
100$: return ; Exit
; EOF Control Z on input
.enabl lsb ; Temp
Ctrlc: DEBUG <Control C> ; ...
WRTALL #$cc ; Echo a control C
br 100$ ; Common exit now
Eof: DEBUG <Eof> ; ...
WRTALL #$cz ; Echo a control Z
.if ne ,$MINITAB ;
WRTALL #$crlf ;
.endc ;
100$: mov #ER$EOF ,r0 ; Control Z
clr r1 ; And return byte count of zero
clc ; All done
return ; Exit
.dsabl lsb ; Done
.enabl lsb
.sbttl Carriage return (actually LF) processing
; Done. CR on input, store new line and bubble previous ones back
Done: mov r5 ,-(sp) ; A scratch register we need
DEBUG <Done> ; ...
WRTALL #$crlf ;
STRLEN r4 ; Get byte count (we have CR or LF)
mov r0 ,r1 ; Return it
beq 90$ ; Nothing there, don't copy it.
clr r2 ; The index
mov lastcnt ,r3 ; Number of lines to do
10$: mov lastli(r2),r0 ; Look to find a free spot.
tstb @r0 ; Empty?
beq 60$ ; Yes
add #2 ,r2 ; No, keep looking
sob r3 ,10$ ; ....
; No room for command line.
clr r2 ; The index
mov r4 ,-(sp) ; Save it
mov lastcnt ,r3 ; Number of lines to do
dec r3 ; ...
asl r3 ; See if this is same as last
mov lastli(r3),r5 ; Current address
inc r5 ; Skip the length
mov r5 ,-(sp) ; Save
DECRYPT r5,deckey ; Undo the old line
STRLEN r4 ; Length
cmpb -1(r5) ,r0 ; Same length
bne 20$ ; No
15$: cmpb (r4)+ ,(r5)+ ; Check for string equality
bne 20$ ; Not the same
sob r0 ,15$ ; Same, check next
20$: mov (sp)+ ,r5 ; Restore old text pointer
mov (sp)+ ,r4 ; Restore the current pointer
ENCRYPT r5,enckey ; Restore the data
asr r3 ; Restore r3
tst r0 ; Same ?
bne 30$ ; No
mov r3 ,@curcmd ; Yes, save index
br 100$ ; Exit
30$:
40$: mov lastli(r2),r0 ; Counted string format
mov lastli+2(r2),r1 ; Again
movb (r1) ,(r0)+ ; Copy the string length
beq 55$ ; Can't happen, but may as well check
clr r5 ; Counter for the copy operation
bisb (r1)+ ,r5 ; Copy the byte count
50$: movb (r1)+ ,(r0)+ ; Copy the string now
sob r5 ,50$ ; Next
55$: add #2 ,r2 ; Move up
sob r3 ,40$ ; Next please
;
60$: mov lastli(r2),r1 ; Copy the line at last
STRLEN r4 ; Get the line length
mov @maxsiz ,r3 ; For padding with spaces
movb r0 ,(r1)+ ; Copy the length
beq 80$ ; Nothing
mov r4 ,r5 ; Source string
mov r1 ,-(sp) ; Save text address
70$: movb (r5)+ ,(r1)+ ; Copy the data now
dec r3 ; Keep track of remaining space
beq 75$ ; No room left
sob r0 ,70$ ; Next please
74$: movb #40 ,(r1)+ ; Now space fill the line
sob r3 ,74$ ; Next please
75$: mov (sp)+ ,r1 ; Restore text address
ENCRYPT r1,enckey ; Encode it
80$: asr r2 ; Set 'Current' Command index
mov r2 ,@curcmd ; And save it
br 100$ ; Exit
90$: movb #CR ,@r4 ; Return only a carriage return
clrb 1(r4) ; .ASCIZ
100$: STRLEN r4 ; Get line length
mov r0 ,r1 ; Where to return it.
clr r0 ; No errors
mov (sp)+ ,r5 ; Restore r5
clc ; All done
return ; Exit
.dsabl lsb
; PREV: Recall previous command line, UP-Arrow Key.
Prev: DEBUG <Prev> ; ...
mov r5 ,-(sp) ; Save it
10$: mov @curcmd ,r2 ; Current command number
blt 100$ ; Never been here.
CALL sol ; Back up
WRTALL #$cr ; Start of line
WRTALL #$ceol ; Clear
WRTALL @r5 ; Prompt
asl r2 ; We want addresses today
mov lastli(r2),r2 ; At last
tstb @r2 ; Anything to copy?
bne 20$ ; Yes
dec @curcmd ; No, back up again
bge 10$ ; Ok
clr @curcmd ; Reached the end
br 100$ ; And exit
20$: clrb @r4 ; TO be safe
clr r3 ; Get length next
bisb (r2)+ ,r3 ; Do it
beq 50$ ; Nothing?
mov @maxsiz ,r0 ; Copy all for DES types
mov r4 ,r5 ; A copy of the destination
30$: movb (r2)+ ,(r5)+ ; Copy it
sob r0 ,30$ ; Next please
DECRYPT r4,deckey ; Decode the data
add r4 ,r3 ; Point to the real end of data
clrb @r3 ; Insure .asciz
WRTALL r4 ; Echo it
50$: CALL gotoeol ; Move to end of the line
STRLEN r4 ; Get length
mov r0 ,@curlen ; And save it
tst @curcmd ; Check for underflow
ble 100$ ; Yes, exit
dec @curcmd ; No, backup now.
br 100$ ; Exit
90$: clrb @r4 ; Nothing, kill the buffer
100$: sec ; Not done yet
mov (sp)+ ,r5 ; Restore this
return ; Exit
; Control U: Erase entire line
Ctrlu: DEBUG <Ctrlu> ; ...
CALL sol ; Move to start of the line
WRTALL #$ceol ; Erase to the end of the line
clrb @r4 ; No data left over
clr @curlen ; No length
sec ; Not done
return ; Exit
Right: DEBUG <Right> ; ...
STRLEN r4 ; Get current length of the line
cmp @curpos ,r0 ; Already at EOL?
bhis 100$ ; Yes
inc @curpos ; No, move over
WRTALL #$right ; Simple to do.
100$: sec ; Not done
return ; Exit
.sbttl Rubouts and move left
; DORUB: Erase character
Dorub: DEBUG <Dorub>,FALSE ; ...
sub #200 ,sp ; Allocate a buffer again
mov sp ,r3 ; And a pointer to such.
tstb @r4 ; Is there ANYTHING in the line?
beq 100$ ; No, it's a NO-OP
tst @curpos ; Already at SOL (start of line)?
bgt 10$ ; No
clr @curpos ; Insure correct position
clr @curlen ; Save this
br 20$ ; Off to common code
10$: mov r4 ,r2 ; See if at eoln
add @curpos ,r2 ; Compute address
dec @curpos ; Correct offset now
dec @curlen ; Fix this up
movb @r2 ,-(sp) ; Get current
beq 20$ ; Nothing to do
WRTALL #$LEFT ; Go back one please
20$: mov r4 ,r2 ; And move down
add @curpos ,r2 ; Point to CURRENT character
mov r2 ,r1 ; Again
inc r1 ; Next position please
STRCPY r3 ,r1 ; Make a temporary copy of the data
STRCPY r2 ,r3 ; Move it down
tstb (sp)+ ; Were we already at EOL?
bne 30$ ; No
WRTALL #$rrub ; Use simple style BS SP BS if EOL
br 100$ ; Exit
30$: WRTALL #$save ; Save cursor position
WRTALL #$ceol ; Erase to EOL
WRTALL r2 ; Dump buffer
WRTALL #$restore ; And go back
100$: add #200 ,sp ; Pop local buffer and Exit
sec ; Not done
return ; Exit
; Left: Move left one character
Left: DEBUG <Left> ; ...
tst @curpos ; Can we back up ?
ble 100$ ; No
dec @curpos ; Yes, backup a bit
WRTALL #$left ; And do so.
100$: sec ; Not done
return ; Exit
.sbttl Command recall and control R processing
Next: DEBUG <Next> ; ...
mov r5 ,-(sp) ; Save
mov curcmd ,r2 ; Point to CURCMD
tst @r2 ; Current command number
blt 100$ ; Never been here.
mov lastcnt ,-(sp) ; Get the recall buffer count
dec (sp) ; ...
cmp @r2 ,(sp)+ ; Can we move up?
bge 100$ ; No
inc @r2 ; Yes, move up.
CALL sol ; Back up
WRTALL #$cr ; Start of line
WRTALL #$ceol ; Clear
WRTALL @r5 ; Prompt
mov @r2 ,r2 ; Copy it.
asl r2 ; We want addresses today
mov lastli(r2),r2 ; At last
tstb @r2 ; Anything to copy?
beq 90$ ; No
;
clrb @r4 ; TO be safe
clr r3 ; Get length next
bisb (r2)+ ,r3 ; Do it
mov @maxsiz ,r0 ; Copy ALL for DES type routines
mov r4 ,r5 ; A copy of the destination
30$: movb (r2)+ ,(r5)+ ; Copy it
sob r0 ,30$ ; Next please
DECRYPT r4,deckey ; Decode the data
add r4 ,r3 ; Point to the real end of data
clrb @r3 ; And force to .ASCIZ
WRTALL r4 ; Dump the data
call gotoeol ; Fix internal pointers
STRLEN r4 ; Get last line length
mov r0 ,@curlen ; And save it
mov lastcnt ,-(sp) ; Get the recall buffer count
dec (sp) ; ...
cmp @curcmd ,(sp)+ ; Poised at the last command?
bne 100$ ; No
dec @curcmd ; Fix so PREV works correctly.
br 100$ ; Exit
90$: clrb @r4 ; Nothing, kill the buffer
100$: sec ; Not done yet
mov (sp)+ ,r5 ; Restore
return ; Exit
Retype: DEBUG <Retype> ; ...
WRTALL #$cr ; Start of line
WRTALL #$ceol ; Clear
WRTALL @r5 ; Prompt
WRTALL r4 ; Dump the buffer
WRTALL #$cr ; Back up again
STRLEN @r5 ; Get a new poistion now
add @curpos ,r0 ; Get to correct position
beq 100$ ; Nothing (?)
10$: WRTALL #$right ; Move over
sob r0 ,10$ ; Simple
100$: sec ; Not yet done
return ; Exit
Cantyp: call clrcns ; Eat up console data
sec ; Not done
return ; Exit
Toggle: mov #IN$MODE,r0 ; Toggle modes
xor r0 ,@clests ; Do it
sec ; Not done
return ; Exit
.sbttl Utilities
.if ne ,$MINITAB
.ift
Strlen: mov 2(sp) ,r0 ; Get string length
10$: tstb (r0)+ ; Look for end
bne 10$ ; Not yet
sub 2(sp) ,r0 ; Compute length
dec r0 ; Fix
mov (sp)+ ,(sp) ; Pop stack
return ; Exit
; Strcpy
;
; input:
; 0(sp) return address
; 2(sp) dst address
; 4(sp) src address
; output: r0 dest address
Strcpy: save <r1> ; save temp registers please
mov 2+2(sp) ,r0 ; destination address
mov 2+4(sp) ,r1 ; source .asciz address
10$: movb (r1)+ ,(r0)+ ; copy until a null
bne 10$ ; not done
mov 2+2(sp) ,r0 ; return the dst address
unsave <r1> ; pop r1 and exit
mov (sp) ,4(sp) ; move return address up now
cmp (sp)+ ,(sp)+ ; pop junk and exit
return
; S C A N C H
;
; input: 4(sp) the string address
; 2(sp) the character to look for
; output: r0 position of ch in string
Scanch: save <r2> ; save temps
mov 6(sp) ,r2 ; get address of the string
clr r0 ; initial found position
10$: tstb @r2 ; end of the string yet ?
beq 90$ ; yes
inc r0 ; no, pos := succ(pos)
cmpb 4(sp) ,(r2)+ ; does the ch match the next one?
bne 10$ ; no, try again
br 100$ ; yes, exit loop
90$: clr r0 ; failure, return postion = 0
100$: unsave <r2> ; pop r2
mov @sp ,4(sp) ; move return address up
cmp (sp)+ ,(sp)+ ; pop stack
return ; and exit
.endc ; If NE, $Minitab
.end