[comp.sys.cbm] MRterm Source - Part 2 of 3

mark@unisec.UUCP (05/15/87)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	editor.a
#	end.a
#	fkey.a
#	global.a
#	interrupt.a
#	kernal.i
#	lpfspf.a
#	main.a
#	mem.i
#	modem.a
#	mrterm.i
#	mrterm.lctl
# This archive created: Fri May 15 15:04:51 1987
export PATH; PATH=/bin:$PATH
if test -f 'editor.a'
then
	echo shar: will not over-write existing file "'editor.a'"
else
cat << \SHAR_EOF > 'editor.a'
;MRTERM Text Editor
;Filename: editor.a
;History:
; 08/30/86 - 3.0 - added screen print

 .nlst
#include "mem.i" ;remove these
#include "kernal.i"
#include "char.i"
#include "printpkt.i"
 .list
 
;Externally referenced symbols

 .ref blinkon,blinkoff
 .ref blkmov
 .ref buzz,sid$init
 .ref hilite
 .ref i$tbuf
 .ref kbwait
 .ref offline
 .ref print,printpkt
 .ref rvsoff,rvson
 .ref scrndmp
 .ref typenum

;Externally defined symbols

 .def ed$start,ed$end,ed$max

ed$start .word 0 ;start of text buffer
ed$end .word 0 ;current end of text buffer +1
ed$max .word 0 ;max text buffer address +1

;**************************************
;Package Data

;Note: curchar and curline MUST be zero
;page locations, and those locations
;must be left undisturbed by other
;routines.

curchar = $8b ;address of character under cursor
curline = $8d ;address of current line
logo$p  = $af ;C=p => screen dump
maxleng = 240 ;maximum line length

;Note: this section can be optimized
;by equating these variables to unused
;zero page locations.

ccol .byte 0 ;current column
colnum .byte 0 ;current column number
crow .byte 0 ;current screen row
curleng .byte 0 ;length of current line
firstline .word 0 ;first line on screen
lastchr .byte 0 ;last character typed
lastrow .byte 0 ;
linnum .word 0 ;current line number
margin .byte 0 ;column offset for lines
temp .byte 0 ;work cell
thischr .byte 0 ;current character
wantcol .byte 0 ;column position wanted

edkeymax = 13 ;max edit key index
edkey ;edit key code table
 .byte home ;home cursor
 .byte clrscrn ;clear screen
 .byte csrup ;up
 .byte csrdn ;down
 .byte csrlt ;left
 .byte csrrt ;right
 .byte del ;delete character
 .byte inst ;insert (delete line)
 .byte 141 ;shifted return (soft left)
 .byte f1 ;page forward
 .byte f2 ;page backward
 .byte f5 ;string search
 .byte f7 ;hard right
 .byte f8 ;hard left
 .byte 0 ;end of table

edfcn ;edit key function addresses
 .word edhome
 .word fclear
 .word fup
 .word fdown
 .word fleft
 .word fright
 .word fdel
 .word fdelln
 .word fsleft
 .word ffwd
 .word fback
 .word fsearch
 .word fhright
 .word fhleft
 .word 0

;**************************************

;Main edit function
;Called with:
;  ed$start set to the start of the text buffer
;  ed$end set to current end of buffer address +1
;  ed$max set to max buffer address +1

 .def edit
edit
 jsr edinit

edit0
 lda ed$end ;insure CR at end of buffer
 sta ptr1
 lda ed$end+1
 sta ptr1+1
 lda #13
 ldy #0
 sta (ptr1),y

 jsr lineinfo ;set up line info
 jsr stline ;display status line
 jsr showline ;position to current line
 lda thischr ;remember last character
 sta lastchr

 jsr blinkon ;enable blinking cursor 

edit1
 jsr kbwait ;get a character
 pha ;save character
 jsr blinkoff ;disable blinking cursor
 pla ;restore character
 cmp #logo$p ;screen dump?
 bne edit10
 jsr scrndmp
 jmp edit0

edit10
 sta thischr ;remember last key pressed
 cmp #$83 ;shift run/stop?
 bne edit2
 jmp editx

edit2 ;is it an editing key?
 ldx #0

edit21
 cmp edkey,x
 beq editkey
 inx
 cpx #edkeymax+1
 bne edit21
 cmp #13 ;CR is ok
 beq edit22
 cmp #32
 bcs edit22
 jsr buzz ;illegal character
 jmp edit0

edit22
 jsr edput ;store character
 jmp edit0

editx
 jsr edexit
 rts


;Handle special edit key.
;Code is in X.

editjmp .byte $4c ;jump to edit function
editadr .word 0 ;edit function address

editkey
 txa
 clc
 rol A ;index = index * 2
 tax
 lda edfcn,x
 sta editadr
 lda edfcn+1,x
 sta editadr+1
 jsr editjmp
 jmp edit0


;Initialize the editor
edinit
 lda #0
 sta thischr
 sta margin
 sta colnum
 sta wantcol
 sta margin
 sta crow
 sta ccol
 lda ed$start
 sta firstline
 lda ed$start+1
 sta firstline+1
 jsr edtop1 ;go to top of file
 rts

;Exit the editor
edexit
 rts


;Home the cursor.  If the last character
;entered was cursor home, move to the
;top of the file.

edhome
 lda lastchr ;last character home?
 cmp #home
 bne edhome1
 jsr edtop
 rts

edhome1
 lda #0
 sta ccol
 sta colnum
 sta wantcol
 sta margin

 lda crow ;at top row?
 beq edhome3 ;yes

edhome2
 ldx curline
 ldy curline+1
 jsr prevline
 stx curline
 sty curline+1
 jsr declnum

edhome21
 dec crow
 bne edhome2

edhome3
 ldx curline
 ldy curline+1
 jsr fillscreen

edhomex
 rts


;Move to top or bottom of buffer,
;redraw screen.

edtop
 lda firstline ;if at top, go to bottom
 cmp ed$start
 bne edtop1
 lda firstline+1
 cmp ed$start+1
 bne edtop1
 jmp edbot ;go to bottom line

edtop1 ;Don't move this label!!!
 ldx ed$start
 ldy ed$start+1
 stx curline
 sty curline+1
 jsr fillscreen
 lda #home
 jsr chrout
 lda #0
 sta crow
 sta ccol
 sta colnum
 sta wantcol
 sta linnum+1
 lda #1
 sta linnum
 rts

;Go to bottom of file
edbot
 ldx curline
 ldy curline+1

edbot0
 jsr nextline
 bcs edbot2
 stx curline
 sty curline+1
 jsr inclnum ;increment line number
 bcc edbot0

edbot2
 stx firstline
 sty firstline+1
 stx curline
 sty curline+1
 lda #0
 sta crow
 jsr refresh
 rts


;Fill screen and initialize pointers
;Called with:
;  X,Y = address of first line

filladr .word 0

refresh ;special entry to use 'firstline'
 ldx firstline
 ldy firstline+1


fillscreen
 stx filladr
 sty filladr+1
 stx firstline
 sty firstline+1

 lda curline ;save current line pointer
 pha
 lda curline+1
 pha

 lda #clrscrn
 jsr chrout
 lda #0
 sta lastrow

fs1
 ldx filladr
 ldy filladr+1
 stx curline
 sty curline+1
 jsr lineinfo
 ldx curline
 ldy curline+1
 lda lastrow
 jsr pline ;print one line 
 bcs fsx ;end of buffer?
 ldx filladr
 ldy filladr+1
 jsr nextline ;advance to next line
 bcs fsx ;end of buffer?
 stx filladr
 sty filladr+1
 lda lastrow
 cmp #23
 beq fsx
 inc lastrow
 bne fs1

fsx
 pla ;restore current line pointer
 sta curline+1
 pla
 sta curline
 rts


;Print one line, with offset
;Called with:
;  ACC = row to print on
;  X,Y = address of line
;Assumes:
;  Cursor is positioned at left hand margin
;Returns:
;  Carry set => end of buffer

pline$mrgn .byte 0
pline$row .byte 0
pline$col .byte 0
pline$cnt .byte 0 ;characters printed

pline
 stx ptr1
 sty ptr1+1

 tax ;set cursor position
 ldy #0
 sty pline$col
 sty pline$cnt
 clc
 jsr plot

 lda curleng ;line too short for window?
 cmp margin
 bcc plinex

 ldx ptr1 ;get first character
 ldy ptr1+1
 jsr getchar

pline1
 bcc pline11 ;end of buffer?
 rts ;yes - exit now

pline11
 cmp #13 ;CR?
 beq plinex

;suppress printing if not past left margin

 ldy pline$col
 cpy margin ;past left margin?
 bcc pline2 ;no
 jsr edout
 inc pline$cnt ;count characters
 lda pline$cnt ;printed 40 yet?
 cmp #40
 beq plinex ;yes - exit

pline2
 inc pline$col
 ldx ptr1
 ldy ptr1+1
 jsr nextchar
 jmp pline1

plinex
 clc ;clear end of buffer indicator
 rts


;Check PTR1 for full buffer
;Returns:
;  Carry set   => full
;  Carry clear => not full
ckfull
 ldx ed$end ;end+1 >= max?
 ldy ed$end+1
 jsr incxy
 sec
 txa
 sbc ed$max
 tya
 sbc ed$max+1
 rts


;Check PTR1 for start of buffer
;Called with:
;  X,Y = test address
;Returns:
;  Carry clear if not at sob
;  Carry set if at sob
cksob
 stx ptr1
 sty ptr1+1
 sec
 lda ed$start
 sbc ptr1
 lda ed$start+1
 sbc ptr1+1
 rts


;Check for end of buffer
;Called with:
;  X,Y = test address
;Returns:
;  Carry clear if not at eob
;  Carry set if at eob

ckeob
 sec
 txa
 sbc ed$end
 tya
 sbc ed$end+1
 rts


;Output a character for the editor
;Control characters are printed as
;their lower case eqivalents, in reverse.
;All other characters are printed without
;interpretation by setting the quote mode
;switch.

;Called with:
;  ACC = character to output

edout
 cmp #141 ;shifted return?
 bne edout0
 lda #13 ;convert it
edout0
 cmp #32 ;control character?
 bcs edout1
 jsr rvson ;set reverse mode
 clc
 adc #'a ;convert to printable character
 jsr chrout
 jsr rvsoff
 rts

edout1
 ldx #1 ;set quote mode
 stx qtsw ;quote switch ($d4)
 jsr chrout
 dec qtsw ;clear quote switch
 rts

;Start a new line
newline
 lda row ;at last line
 cmp #23
 bne newline1
 jsr scrollup
 rts

newline1
 lda #13
 jsr chrout
 rts

 
;Scroll up one line.
;(Move toward end of buffer.)
 
scrollup
 ldx firstline ;get address of first line
 ldy firstline+1
 jsr nextline
 stx firstline
 sty firstline+1

 ldx #0 ;set high bits of line link table
scrollup1
 lda $d9,x ;(ldtb1)
 ora #$80 ;set high bit
 sta $d9,x
 inx
 cpx #25
 bne scrollup1

 dex ;clear status line (24)
 jsr eraseln
 ldy #0
 clc
 jsr plot
 lda #13 ;force scroll of screen
 jsr chrout
 rts

;Scroll down one line.
;(Move toward start of buffer.)

scrolldown
 ldx firstline ;address of first line
 ldy firstline+1
 jsr prevline
 jsr fillscreen
 lda firstline
 sta curline
 lda firstline+1
 sta curline+1
 rts


;Scroll left
scrolleft
 lda margin ;no need?
 beq scrollftx
 sec
 sbc #10
 bpl scrolleft1
 lda #0 ;jump 10 characters

scrolleft1
 sta margin
 jsr refresh

scrollftx
 rts


;Scroll right
scrollright
 clc
 lda margin
 adc #10
 cmp curleng
 bcc scrollr1
 lda curleng

scrollr1
 sta margin
 jsr refresh
 rts


;Gather information about the current
;line.

lnx .byte 0
lineinfo
 ldx curline ;test for end of buffer
 ldy curline+1
 lda #0
 sta lnx

lninfo1
 stx ptr1
 sty ptr1+1
 jsr ckeob
 bcs lninfo2
 ldy #0
 lda (ptr1),y
 cmp #13
 beq lninfo2
 ldx ptr1
 ldy ptr1+1
 jsr incxy ;increment

 inc lnx
 lda lnx
 cmp #maxleng ;limit length
 bne lninfo1

lninfo2
 lda lnx
 sta curleng
 cmp wantcol ;within length?
 bcs lninfo21 ;yes

 sta colnum ;use length as column
 bcc lninfo3

lninfo21
 lda wantcol
 sta colnum

lninfo3 ;column within length?
 sec
 lda colnum ;screen column = column-margin
 sbc margin
 bcs lninfo31 ;margin <= colnum?
 lda #0 ;no - set to zero

lninfo31
 sta ccol

 clc ;compute char loc
 lda curline
 adc colnum
 sta curchar
 lda curline+1
 adc #0
 sta curchar+1
 rts


;Display current line, then position
;cursor to current character
showline
 ldx curline
 ldy curline+1
 lda crow
 jsr pline ;reprint line

 ldx crow ;position cursor
 ldy ccol
 clc
 jsr plot
 rts


;Display status line
lengmsg .byte "  Length: ",0

stline
 lda hilite
 sta color

 ldx #24
 jsr eraseln

 ldx #24
 ldy #0
 clc
 jsr plot
 lda #'L
 jsr chrout

 ldx linnum
 ldy linnum+1
 jsr typenum

 lda #32
 pha
 jsr chrout
 pla
 jsr chrout

 lda #'C
 jsr chrout

 ldx colnum
 ldy #0
 jsr incxy ;normalize to 1
 jsr typenum

 ldx #<lengmsg
 ldy #>lengmsg
 jsr print

 ldx curleng
 ldy #0
 jsr typenum

 jsr bufleft
 lda offline
 sta color
 rts


;Display Buffer Left at cursor position
leftmsg .byte "  Left: ",0

 .def bufleft
bufleft
 ldx #<leftmsg
 ldy #>leftmsg
 jsr print
 sec
 lda ed$max
 sbc ed$end
 tax
 lda ed$max+1
 sbc ed$end+1
 tay
 jsr typenum
 rts

 


;Put new character into buffer at
;current character location
;Called with:
;  ACC = character code

edput
 ldx curleng ;if (curleng==max)
 cpx #maxleng
 beq edputx ;return
 inx ;if ((curleng+1) < wantcol)
 cpx wantcol
 bcs edput0
 lda margin ;if (margin!=0)
 beq edputx ;return
 ldx curleng ;else wantcol = curleng
 sta wantcol

edput0
 jsr ckfull ;buffer full?
 bcc edput1
 jsr buzz ;razz user
 rts ;quit

edput1
 ldx curchar ;do block move
 ldy curchar+1
 stx ptr1
 sty ptr1+1
 jsr incxy
 stx ptr2
 sty ptr2+1

 sec ;length = end-current
 lda ed$end
 sbc curchar
 tax
 lda ed$end+1
 sbc curchar+1
 tay
; jsr incxy
 jsr blkmov

 ldy #0
 lda thischr
 sta (curchar),y ;store new character
 inc ed$end ;extend buffer
 bne edput3
 inc ed$end+1

edput3
 cmp #13 ;just put CR?
 beq edput4
 inc wantcol
 lda ccol ;at right hand margin?
 cmp #39
 bne edputx
 jsr scrollright

edputx
 rts

edput4
 lda #0 ;back to left margin
 sta wantcol
 sta margin
 jsr fdown ;move down 1 line
 jsr refresh
 rts


;Backup to previous character
;Called with:
;  X,Y  = address of current character
;Returns:
;  ACC  = next character
;  X,Y  = address of previous character
;  Carry set => start of buffer
prevchar
 jsr cksob
 bcs prevcharx
 jsr decxy

prevchar1
 clc ;not start of buffer
 stx ptr1
 sty ptr1+1

prevcharx
 ldy #0
 lda (ptr1),y
 ldy ptr1+1 ;restore y
 rts


;Advance to the next character
;Called with:
;  X,Y  = address of current character
;Returns:
;  ACC  = next character
;  X,Y  = address of next character
;  Carry set => end of buffer
nextchar
 jsr incxy
 jsr ckeob
 bcs getchar1

nextchar1
 stx ptr1
 sty ptr1+1
 ldy #0
 lda (ptr1),y
 ldy ptr1+1 ;restore y
 rts

;Special entry to get current character
getchar
 jsr ckeob
 bcc nextchar1

getchar1
 lda #32 ;return space
 rts


;Backup to previous line
;Called with:
;  X,Y = start address of current line
;Returns:
;  X,Y = address of previous line

crcnt .byte 0 ;CR counter

prevline
 lda #0
 sta crcnt

prevln1
 jsr prevchar
 bcs prevlnx
 cmp #13
 bne prevln1
 inc crcnt ;count CR's
 lda crcnt
 cmp #2
 bne prevln1
 jsr nextchar ;come back 1

prevlnx
 rts


;Backup to Beginning of Current Line
;Called with:
;  X,Y = current character address
;Returns:
;  Same as prevline
begline
 lda #1
 sta crcnt
 bne prevln1


;Advance to next line
;Called with:
;  X,Y = start address of current line
;Returns:
;  X,Y = address of next line
;Note:
;  X,Y are expected to remain 'live'
;  throughout this routine.

nextline
 jsr getchar ;1st char may be CR
 cmp #13
 beq nxtln2

nxtln1
 jsr nextchar
 bcs nxtlnx ;at end of buffer
 cmp #13 ;character a return?
 bne nxtln1

nxtln2
 jsr nextchar ;advance past CR

nxtlnx
 rts


;***** Editing Functions *****

clrmsg .byte "Erase buffer - are you sure? ",0
clrpkt
 .byte PP$EOL|PP$GONG|PP$RVS|PP$WAIT
 .byte 24,0
 .word clrmsg

fclear
 lda hilite
 ldx #<clrpkt
 ldy #>clrpkt
 jsr printpkt

fclear1
 cmp #'y
 beq fclear2
 cmp #'Y
 beq fclear2
 rts

fclear2
 lda ed$start
 sta ed$end
 lda ed$start+1
 sta ed$end+1
 jsr i$tbuf ;zero the buffer
 jsr edtop1 ;unconditional top of screen
 rts

fup
 ldx crow ;not at top?
 bne fup1

;Cursor is at top.  Go to previous line
;and redraw the screen.

fup0
 jsr scrolldown
 lda linnum ;at line 1?
 cmp #1
 bne fup2 ;no
 lda linnum+1
 bne fup2

fupx
 rts

fup1
 ldx curline
 ldy curline+1
 jsr prevline
 stx curline
 sty curline+1
 dec crow

fup2
 jsr declnum
 rts


;Move down 1 line
fdown
 ldx curline
 ldy curline+1
 jsr ckeob ;new code
 bcs fdownx
 jsr nextline
 bcc fdown0 ;end of buffer?
 lda thischr ;if last line in buffer,
 cmp #13 ;only new line on CR
 bne fdownx

fdown0
 stx curline
 sty curline+1
 jsr inclnum

fdown1
 lda crow ;current column
 cmp #23 ;at last row?
 bne fdown2
 jsr scrollup
 jmp fdownx

fdown2
 inc crow

fdownx
 rts

;Move left 1 character (no wrap)
fleft
 lda wantcol ;at physical start of line?
 beq fleftx ;yes
 dec wantcol
 lda ccol ;get actual cursor column
 beq fleft1
 lda curleng
 cmp wantcol
 bcs fleftx
 sta wantcol

fleftx
 rts


;Cursor is hard left - need to scroll left
fleft1
 jsr scrolleft
 rts


;Hard left to beginning of line
fhleft
 lda wantcol ;already there?
 beq fhleftx
 lda #0
 sta margin
 sta wantcol

fhleft1
 jsr refresh
fhleftx
 rts

;Soft left to left margin
fsleft
 lda margin ;already there?
 beq fhleftx
 sta wantcol ;no - do it
 bne fhleft1 ;share code above


;No, this is not a scary routine.
;Move the cursor right one position.
fright
 sec
 lda curleng ;if wantcol > curleng
 sbc wantcol
 bcc frightx ;quit

 lda wantcol ;max reached?
 cmp #maxleng
 beq frightx

 inc wantcol ;advance to next column
 sec
 lda wantcol
 sbc margin
 cmp #40 ;beyond right margin?
 bcc frightx
 jsr scrollright

frightx
 rts


;Hard right to end of line
fhright
 lda wantcol ;already there?
 cmp curleng
 beq fhrightx
 lda curleng ;where we want to be
 sta wantcol
 cmp #40 ;at or beyond col 40?
 bcs fhright1
 rts

fhright1 ;scroll screen right
 sbc #10 ;adjust margin
 sta margin
 jsr refresh

fhrightx
 rts


;Delete current character
delcr .byte 0 ;1 => deleted cr

fdel
 lda #0
 sta delcr
 ldx curleng
 inx ;curleng+1 < wantcol?
 cpx wantcol
 bcc fdelx ;at curleng+2 or greater?

fdel0
 ldx curchar
 ldy curchar+1
 jsr cksob ;start of buffer?
 bcs fdelx ;yes - do nothing
 jsr ckeob
 bcs fdel41
 

fdel1

fdel2
 stx ptr1 ;source = current character
 sty ptr1+1

 jsr decxy
 stx ptr2 ;dest = previous character
 sty ptr2+1

 ldy #0

fdel3

 lda colnum ;at column zero?
 beq fdel31 ;treat like CR deletion
 lda (ptr2),y ;test for CR
 cmp #13
 bne fdel4

fdel31
 inc delcr

fdel4
 sec ;length = end-current
 lda ed$end
 sbc curchar
 tax
 lda ed$end+1
 sbc curchar+1
 tay
 jsr blkmov

fdel41
 ldx ed$end ;adjust buffer end
 ldy ed$end+1
 jsr decxy
 stx ed$end
 sty ed$end+1

 lda delcr ;delete a CR?
 bne fdel5 ;yes
 dec wantcol ;back up one
 ldx crow ;erase the line
 jsr eraseln

fdelx
 rts

fdel5
 ldx curchar
 ldy curchar+1
 jsr prevline
 stx curline
 sty curline+1
 jsr declnum ;decrement line number
 lda crow
 beq fdel51
 dec crow
 jsr refresh
 rts

fdel51
 ldx curline
 stx firstline
 ldy curline+1
 sty firstline+1
 jsr refresh
 rts


;Delete remainder of line
delcnt .byte 0 ;bytes deleted (0..maxleng)
oldcur .word 0 ;old current character

fdelln
 lda #0
 sta delcnt
 ldx curchar
 ldy curchar+1
 stx oldcur
 sty oldcur+1
 jsr getchar ;get first character
 bcs fdellnx ;at beginning?

fdelln1
 inc delcnt
 cmp #13 ;reached end of line?
 bne fdelln12
 jsr nextchar ;skip past CR
 bcs fdelln2
 inc delcnt
 jmp fdelln2

fdelln12
 lda delcnt ;delete max length?
 cmp #maxleng
 beq fdelln2
 jsr nextchar
 bcc fdelln1

fdelln2
 stx ptr1 ;current = source for move
 sty ptr1+1
 ldx oldcur ;destination
 stx ptr2
 ldy oldcur+1
 sty ptr2+1
 sec ;compute move length
 lda ed$end
 sbc ptr2
 tax
 lda ed$end+1
 sbc ptr2+1
 tay
 jsr blkmov ;do the shuffle

 sec ;adjust end of buffer
 lda ed$end
 sbc delcnt
 sta ed$end
 lda ed$end+1
 sbc #0
 sta ed$end+1
 jsr refresh

fdellnx
 rts

;Advance a 'page'

ffwd
 lda #0
 sta temp
 sta crow ;position to top of screen
 ldx curline
 ldy curline+1

ffwd1
 jsr nextline
 bcs ffwd2
 stx curline
 sty curline+1
 jsr inclnum
 inc temp
 lda temp
 cmp #20
 bne ffwd1

ffwd2
 jsr fillscreen
 rts


;Go back a 'page'
fback
 lda #0
 sta temp
 sta crow ;top of screen
 ldx curline
 ldy curline+1

fback1
 jsr prevline
 stx curline
 sty curline+1
 php ;save status reg
 jsr declnum
 plp ;restore status (carry)
 bcs fback2
 inc temp
 lda temp
 cmp #20
 bne fback1

fback2
 
 ldx curline
 ldy curline+1
 jsr fillscreen
 rts

fsearch
 rts


;Decrement Line Number
declnum
 dec linnum
 lda linnum
 cmp #$ff
 bne declnum1
 dec linnum+1
declnum1
 lda linnum ;did it go to zero?
 ora linnum+1
 bne declnumx
 inc linnum ;reset to 1
declnumx
 rts

;Increment Line Number
inclnum
 inc linnum
 bne inclnumx
 inc linnum+1
inclnumx
 rts


;Decrement X,Y
decxy
 dex
 cpx #$ff
 bne decxyx
 dey
decxyx
 rts

;Increment X,Y
incxy
 inx
 bne incxyx
 iny
incxyx
 rts


test = 0
 .ifeq test,1
 .def start
start
 lda #<$8000
 sta ed$start
 lda #>$8000
 sta ed$start+1
 lda #<$9000
 sta ed$max
 lda #>$9000
 sta ed$max+1
 lda ed$start
 sta ptr1
 lda ed$start+1
 sta ptr1+1
 lda #'a
 sta lastchr
 ldx #0

start1
 ldy #0

start2
 lda lastchr
 sta (ptr1),y

start3
 iny
 cpy #40 ;40 character lines
 bne start2
 lda #13
 sta (ptr1),y
 iny
 tya
 clc
 adc ptr1
 sta ptr1
 lda #0
 adc ptr1+1
 sta ptr1+1
 inc lastchr
 lda lastchr
 cmp #'z+1
 bne start4
 lda #'a
 sta lastchr

start4
 inx
 cpx #30 ;30 lines?
 bne start1
 lda ptr1
 sta ed$end
 lda ptr1+1
 sta ed$end+1
 jsr sid$init 
 jsr edit

 rts
 .fi

SHAR_EOF
fi # end of overwriting check
if test -f 'end.a'
then
	echo shar: will not over-write existing file "'end.a'"
else
cat << \SHAR_EOF > 'end.a'
;End module for MRterm
;Filename: end.a
;
;This module MUST be linked at the very end of
;MRterm, after all libraries have been searched.
;It defines the starting address of the capture
;buffer. If it is not last, part of MRterm will
;be overwritten.
;


 .def tbuf
tbuf
  .word tbuf+2 ;address of terminal buffer
SHAR_EOF
fi # end of overwriting check
if test -f 'fkey.a'
then
	echo shar: will not over-write existing file "'fkey.a'"
else
cat << \SHAR_EOF > 'fkey.a'
;MRTERM Function Key Management
;Filename: fkey.a

 .nlst
#include "mem.i"
#include "kernal.i"
#include "char.i"
 .list

;External References
 .ref asc2cbm,cbm2asc
 .ref bkrd,bkwt
 .ref buzz
 .ref center
 .ref disk$status
 .ref eraseeol,eraseeos
 .ref errmsg
 .ref fclose
 .ref gets
 .ref gong
 .ref hilite
 .ref imath$val
 .ref imul
 .ref itoa
 .ref kbwait
 .ref mdmrd,mdmwrt
 .ref menu,menu$list,menu$title
 .ref mfill
 .ref modemtype
 .ref offline
 .ref open$seq
 .ref print,println
 .ref rvsoff,rvson
 .ref scratch
 .ref scrndmp
 .ref sleep
 .ref strcpy,string$1,string$2
 .ref term
 .ref tsleep
 .ref typenum

;Package Constants

crkey   = '^ ;substitute CR for this key
fkeymax = 7 ;max fkey number - 1
keyleng = 20 ;max fkey def. length
fk2kx .byte 0,2,4,6,1,3,5,7 ;converts key code to index

keysize = [fkeymax+1]*[keyleng+1]
logo$p = $af ;screen print code
noload .byte "Can't load function keys!",0
keyname .byte "mrterm.fkey",0

;External Data
keydefs .dseg keysize+2 

;Local Data
dfn .byte 0 ;disk file number
keycnt .byte 0 ;count of fkeys stored
kx .byte 0 ;fkey edit index
rvflag .byte 0 ;1 => display in reverse
trm .byte 0 ;termination character

m$title .byte "Function Key Utilities",0
m$quit .byte "Quit",0
m$dial .byte "Auto-Dial",0
m$edit .byte "Edit Keys",0
m$load .byte "Load Key Definitions",0
m$save .byte "Save Key Definitions",0

m$list
 .word m$quit
 .word m$edit
 .word m$load
 .word m$save
null
 .word 0

m$vect
 .word $ffff ;quit handled specially
 .word editkey
 .word loadkey
 .word savekey

pjump jmp $ffff


;Test for function key substitution
;Called with:
;  ACC = character code
;Returns:
;  ACC = 0  => substitution performed
;  ACC <> 0 => no substitution

ksubx .byte 0

 .def keysub
keysub
 cmp #f1
 bcc keysubx
 cmp #f8+1
 bcs keysubx
 sec ;convert code to index
 sbc #f1
 tax
 lda fk2kx,x
 sta kx
 jsr keyaddr ;compute string address
 stx ptr1
 sty ptr1+1
 lda #0
 sta ksubx

keysub1
 ldy ksubx
 lda (ptr1),y ;note: null value is returned
 beq keysubx
 cmp #crkey ;CR substitution?
 bne keysub2
 lda #13 ;output a cr
 jsr mdmwrt
 jmp keysub3

keysub2
 tax
 lda cbm2asc,x
 jsr mdmwrt

keysub3
 ldx #3 ;delay a few ticks
 ldy #0
 jsr tsleep
 inc ksubx
 bne keysub1

keysubx
 rts
  
 
;Function Key Utilities - Main Routine

 .def keyutil
keyutil
 lda #<m$list
 sta menu$list
 lda #>m$list
 sta menu$list+1
 ldx #<m$title
 ldy #>m$title
 jsr menu
 cmp #0 ;quit?
 beq kutlx
 
 clc
 rol A
 tay
 lda m$vect,y
 sta pjump+1
 lda m$vect+1,y
 sta pjump+2

 lda #clrscrn ;display command as title
 jsr chrout
 
 lda m$list,y
 tax
 lda m$list+1,y
 tay
 jsr center
 jsr pjump
 jmp keyutil

kutlx 
 rts

;======================================
keyprmpt .byte "Key string (20): ",0

editkey
 lda #0
 sta kx
 sta rvflag
 jsr dspkey

edkey1
 jsr select
 cmp #$83 ;abort?
 beq edkeyx

edkey2
 inc rvflag ;redisplay in reverse
 jsr typkey
 dec rvflag
 ldx #23
 jsr eraseeos
 ldx #23
 ldy #0
 clc
 jsr plot
 lda hilite
 sta color
 ldx #<keyprmpt
 ldy #>keyprmpt
 jsr print
 lda offline
 sta color
 lda #keyleng
 jsr gets
 lda buf ;null => changed mind
 beq edkey1

 jsr keyaddr ;copy to database
 stx string$1
 sty string$1+1
 lda #<buf
 sta string$2
 lda #>buf
 sta string$2+1
 jsr strcpy

 jmp edkey1 

edkeyx
 ldx #23
 jsr eraseeos
 rts

;Display All Function Keys

dspkey
 lda kx ;save current index
 pha
 lda #0
 sta kx

dk1
 jsr typkey
 inc kx
 lda kx
 cmp #fkeymax+1
 bne dk1
 pla ;restore index
 sta kx
 rts


;Type one function key definition
;Called with:
;  kx = phone number index
typkey
 lda kx
 clc
 adc #2 ;start at row 2
 tax
 jsr eraseln
 ldy #0
 clc
 jsr plot

tph0
 lda #'F
 jsr chrout
 ldx kx ;print kx+1
 inx
 ldy #0
 jsr typenum

tph1 ;print definition
 ldx row
 ldy #3
 clc
 jsr plot

 lda rvflag ;print reversed?
 beq tph11
 jsr rvson

tph11
 jsr keyaddr ;get name string address
 jsr print
 lda #32
 jsr chrout
 jsr rvsoff
 rts

;Compute Function Key String Address
;Called with:
;  kx = key index
keyaddr
 ldy #0
 ldx kx ;offset = number*keyleng+1
 beq keyadr1
 lda #keyleng+1
 jsr imul

keyadr1
 clc
 txa
 adc #<keydefs
 tax
 tya
 adc #>keydefs
 tay
 rts


;Select a key definition

selmsg .byte "Position to entry, then RETURN to",13
       .byte "select or SHIFT-RUN/STOP to abort.",0

select
 ldx #23
 jsr eraseeos

 ldx #23
 ldy #0
 clc
 jsr plot
 lda hilite
 sta color
 ldx #<selmsg
 ldy #>selmsg
 jsr print
 lda offline
 sta color
 inc rvflag
 jsr typkey ;display in reverse
 dec rvflag
 jsr kbwait
 pha ;save character
 jsr typkey ;redisplay - normal mode
 pla
 jsr scrndmp
 cmp #logo$p
 beq select
 cmp #13 ;CR?
 beq selectx
 cmp #$83 ;SHIFT/STOP
 beq selectx
 cmp #csrup
 beq select1
 cmp #csrdn
 beq select2
 jsr buzz
 jmp select

selectx
 rts


select1 ;cursor up
 ldx kx
 bne select10
 ldx #fkeymax
 bne select11

select10
 dex

select11
 stx kx ;store new phone index

select12
 jmp select

select2 ;cursor down
 ldx kx
 cpx #fkeymax
 bne select20
 ldx #0
 beq select11

select20
 inx
 bne select11


;Load Function Keys

 .def loadkey
loadkey
 jsr i$fkey ;zero phone directory
 ldx #<keyname
 ldy #>keyname
 lda #'r ;read access
 jsr open$seq
 sta dfn
 bne ldk1

showstatus
 ldx #23
 ldy #0
 clc
 jsr plot
 ldx #<disk$status
 ldy #>disk$status
 jsr print
 ldx #<noload
 ldy #>noload
 jsr errmsg
 rts

ldk1
 ldx dfn
 jsr chkin
 jsr getin ;get number of numbers
 pha
 jsr clrchn
 pla
 sta keycnt
 cmp #fkeymax ;must be exact
 beq ldk2

ldkerr
 ldx #<noload
 ldy #>noload
 jsr errmsg
 jmp ldkx

ldk2
 lda #<keydefs
 sta ptr1
 lda #>keydefs
 sta ptr1+1
 ldx #<keysize
 ldy #>keysize
 lda dfn
 jsr bkrd ;read key definitions
 bcs ldkerr

ldkx
 lda dfn
 jsr fclose
 rts

;Save Key Definitions
savekey
 ldx #<keyname
 ldy #>keyname
 jsr scratch
 ldx #<keyname
 ldy #>keyname
 lda #'w ;write access
 jsr open$seq
 sta dfn
 bne svk1
 jmp showstatus

svk1
 ldx dfn
 jsr chkout
 lda #fkeymax ;output number of fkeys
 jsr chrout
 jsr clrchn
 lda #<keydefs
 sta ptr1
 lda #>keydefs
 sta ptr1+1
 ldx #<keysize
 ldy #>keysize
 lda dfn
 jsr bkwt ;output key strings

 ldx dfn
 jsr chkout
 lda #13 ;1 'safety' byte
 jsr chrout
 jsr clrchn

svkx
 lda dfn
 jsr fclose
 rts

;Initialize Phone Directory
 .def i$fkey
i$fkey
 lda #<keydefs
 sta ptr1
 lda #>keydefs
 sta ptr1+1
 lda #<keysize
 sta ptr2
 lda #>keysize
 sta ptr2+1
 lda #0
 jsr mfill

 rts

SHAR_EOF
fi # end of overwriting check
if test -f 'global.a'
then
	echo shar: will not over-write existing file "'global.a'"
else
cat << \SHAR_EOF > 'global.a'
;
; MRTERM Global Data
; Filename: global.a
; History:
;   08/12/86 - added printer/disk info,
;              xon/xoff flag

; Configuration data

 .def config,configsz
 .def baud,databits,stopbits,parity
 .def protocol,background,border,online
 .def offline,hilite,modemtype,dialcmd
 .def klick,kaps,lecho
 .def sdisk,ddisk
 .def pdvc,pinit,psa

config ;beginning of configuration block

baud       .byte 1 ;0=300, 1=1200
databits   .byte 0 ;0=7, 1=8
stopbits   .byte 0 ;0=1, 1=2
parity     .byte 0 ;0=none
protocol   .byte 0 ;0=Punter, 1=Xmodem
background .byte 0
border     .byte 0
online     .byte 7
offline    .byte 14
hilite     .byte 3
modemtype  .byte 1 ;0=1650, 1=Hayes
dialcmd    .byte "atdt",0,0,0,0,0
klick      .byte 0 ;1=enable keyboard click
kaps       .byte 0 ;1=all caps
lecho      .byte 0 ;1=local echo
sdisk      .byte 8 ;system disk device
ddisk      .byte 8 ;data disk device
pdvc       .byte 4 ;printer device
psa        .byte 7 ;printer secondary address
pinit      .bss 9  ;printer init string
                   ;1st byte = length (0..8)
xonxoff    .byte 0 ;1 = enable xon/xoff

configsz .byte configsz-config

;**************************************

SHAR_EOF
fi # end of overwriting check
if test -f 'interrupt.a'
then
	echo shar: will not over-write existing file "'interrupt.a'"
else
cat << \SHAR_EOF > 'interrupt.a'
;MRTERM Interrupt Routines
;Filename: interrupt.a
;History:
; 08/30/86 - 3.0 - new module

#include "mem.i"
#include "kernal.i"

 .ref hilite ;highlight color code

cinv = $0314

svcinv .word 0 ;saved interrupt vector

;Initialize interrupt handler
 .def i$int
i$int
 sei ;prevent interrupts
 lda cinv ;save old vector
 sta svcinv
 lda cinv+1
 sta svcinv+1
 lda #<inthandlr
 sta cinv
 lda #>inthandlr
 sta cinv+1
 cli
 rts


;Reset interrupt handler
 .def r$int
r$int
 sei
 lda svcinv
 sta cinv
 lda svcinv+1
 sta cinv+1
 cli
 rts

;The main purpose of this interrupt
;handler is to provide a uniform
;method for handling cursor blink.  It
;appears that older style C64's don't
;blink the cursor the same way that
;the newer ones do.
;
;Note: This handler makes no attempt
;to restore the color of the character
;under the cursor.  The current color
;code is always used.

inthandlr
 jsr $ffea ;stop key, jiffy timer
 lda $cc ;get blink flag
 bne kbchk
 dec $cd ;decrement blink counter
 bne kbchk
 lda #20 ;reset blink counter
 sta $cd
 ldy $d3 ;cursor column
 lsr $cf ;blink switch
;(old) ldx $0287 ;color under cursor
 ldx $0286 ;current color
 lda ($d1),y ;get char code
 bcs flip ;was on, continue
 inc $cf ;toggle
 sta $ce ;save char under cursor
 jsr $ea24 ;compute color ram loc.
;(old) lda ($f3),y ;get color code
;(old) sta $0287 ;save it
 ldx $0286 ;current color
 lda $ce ;character under cursor
flip
 eor #$80 ;reverse character
 jsr $ea1c ;store new char and color
;
;Note: the tape switch processing
;has been omitted from this handler.
;
kbchk
 jsr $ea87 ;do keyboard processing
 lda $dc0d ;clear IRQ
 pla ;restore registers
 tay
 pla
 tax
 pla
 rti
SHAR_EOF
fi # end of overwriting check
if test -f 'kernal.i'
then
	echo shar: will not over-write existing file "'kernal.i'"
else
cat << \SHAR_EOF > 'kernal.i'
;
;KERNAL ROM Routine Entry Points
;Filename: kernal.i
;History:
; 08/27/86 - Made listen,talk,unlsn,etc. available

acptr = $ffa5 ;get byte from serial port
chkin = $ffc6 ;open channel for input
chkout = $ffc9 ;open channel for output
chrin = $ffcf ;input character from channel
chrout = $ffd2 ;output char to channel
ciout = $ffa8 ;output byte to serial bus
clall = $ffe7 ;close all channels
close = $ffc3 ;close logical file
clrchn = $ffcc ;close input/output channels
eraseln = $e9ff ;erase screen line in X 
getin = $ffe4 ;get kb chr
ioinit = $ff84 ;init. i/o
listen = $ffb1 ;
open = $ffc0 ;open logical file
plot = $fff0 ;read/set cursor
rdtim = $ffde ;read jiffy clock
readst = $ffb7 ;read status word
second = $ff93 ;send secondary address
setlfs = $ffba ;set log. 1st, 2nd addr.
setnam = $ffbd ;set file name
stop = $ffe1 ;stop key pressed?
talk = $ffb4 ;command dvc to talk
tksa = $ff96 ;send 2nd addr after talk
unlsn = $ffae
untlk = $ffab
SHAR_EOF
fi # end of overwriting check
if test -f 'lpfspf.a'
then
	echo shar: will not over-write existing file "'lpfspf.a'"
else
cat << \SHAR_EOF > 'lpfspf.a'
; MRTERM Load/Save Parameter File
; Filename: lpfspf.a
; History:
;   08/13/86 - fixed bug related to configsz use

#include "mem.i"
#include "kernal.i"
#include "char.i"

;Global data references

 .ref background,border
 .ref bkrd,bkwt
 .ref hilite,online,offline
 .ref baud,databits,parity,stopbits
 .ref config,configsz

 .ref errmsg
 .ref ckdisk,disk$status
 .ref protocol,modemtype

;Other external support

 .ref buzz
 .ref center
 .ref eraseeol
 .ref fclose
 .ref kbwait
 .ref menu,menu$title,menu$list
 .ref open$seq
 .ref openmodem
 .ref print,println
 .ref rvsoff,rvson
 .ref scratch

parmname .byte "mrterm.parms",0

dfn .byte 0 ;disk file number
fname .word 0 ;filename

;***************************************

;General Load Parameter File
;Called with:
; X,Y = address of file name string
;Returns:
; 0 = failure
; 1 = success

lpfbad .byte "Failed to load parameter file",0
notparm .byte "Not an MRTERM parameter file!",0

 .def lpf
lpf
 jsr ckpfnm ;check parameter file name
 lda #'r ;read access
 jsr open$seq ;open the file
 sta dfn
 beq lpffl
 tax
 jsr chkin
 ldy #0

;read the first line of the file to
;verify that it is an mrterm parameter
;file.

lpf1
 lda parmname,y
 beq lpf2 ;passed verify test
 jsr getin
 cmp parmname,y
 bne badparm
 iny
 lda status
 beq lpf1

badparm
 jsr closepf
 ldx #<notparm
 ldy #>notparm
 jsr errmsg
 lda #0
 rts

lpf2
 jsr getin ;discard carriage return
 ldy #0

lpf3
 lda #<config
 sta ptr1
 lda #>config
 sta ptr1+1
 lda dfn
 ldx configsz
 ldy configsz+1
 jsr bkrd
 
lpfok ;success exit
 jsr closepf
 lda #1
 rts

lpffl ;failure exit
 jsr closepf
 jsr dkstat ;show disk status
 ldx #<lpfbad
 ldy #>lpfbad
 jsr errmsg
 lda #0
 rts

 
;General Save Parameter File
;Called with:
; X,Y = address of file name string
;Returns:
; 0 = failure
; 1 = success

spfbad .byte "Failed to write parameter file",0

 .def spf
spf
 jsr ckpfnm ;check file name
 jsr scratch ;scratch original file
 lda #'w ;write access
 ldx fname
 ldy fname+1
 jsr open$seq
 sta dfn
 beq spffl
 tax
 jsr chkout
 ldx #<parmname ;write filename as
 ldy #>parmname ;verification key
 jsr println ;assumes println prints to current device

spf1
 lda #<config
 sta ptr1
 lda #>config
 sta ptr1+1
 lda dfn
 ldx configsz
 ldy configsz+1
 jsr bkwt
 bcs spffl
  
spfok ;success exit
 jsr closepf
 lda #1
 rts

spffl ;failure exit
 jsr closepf 
 jsr dkstat ;show disk status
 ldx #<spfbad
 ldy #>spfbad
 jsr errmsg
 lda #0
 rts

;Check parameter file name
;Called with:
;  X,Y = file name string address
;Returns:
;  default name if X,Y points to null string
;  X,Y if X,Y points to non-null string

ckpfnm
 stx ckpfnm1+1
 sty ckpfnm1+2
ckpfnm1
 lda $ffff ;test first character
 bne ckpfnmx ;non-null, exit
 ldx #<parmname ;use default filename
 ldy #>parmname
ckpfnmx
 stx fname ;save copy in
 sty fname+1 ;filename pointer
 rts


;Close parameter file

closepf
 lda dfn
 jsr fclose
 jsr clrchn
 rts


;Show disk status for bad load/save

dkstat
 jsr clrchn
 jsr ckdisk ;read error channel
 ldx #23
 ldy #0
 clc
 jsr plot
 ldx #<disk$status
 ldy #>disk$status
 jsr errmsg
 rts
SHAR_EOF
fi # end of overwriting check
if test -f 'main.a'
then
	echo shar: will not over-write existing file "'main.a'"
else
cat << \SHAR_EOF > 'main.a'
; MRTERM Terminal Program for the 
; Commodore 64.
; Author:  Mark R. Rinfret
; Date:    04/30/86
;
; Filename: main.a
; History: (most recent change first)
;
;   04/20/87 - 3.5 - expanded buffer
;   12/05/86 - 3.4 - modified dialer
;   09/28/86 - 3.3 - Clear Buffer command
;   09/21/86 - 3.2 - convert FF to CLR in trtable
;   09/15/86 - added XMODEM mode options
;   08/13/86 - added function key utilities
;   08/12/86 - close modem on exit
;   07/14/86 - added buffer utilities

 .nlst
#include "mrterm.i"
#include "mem.i"
#include "char.i"
#include "kernal.i"
#include "printpkt.i"
 .list

 .ref bkrd
 .ref bufutil
 .ref configure
 .ref center
 .ref dial
 .ref disk$dvc,disk$status,open$cmd
 .ref diskutil
 .ref errmsg
 .ref fclose
 .ref fil$num
 .ref i$int,r$int
 .ref i$tbuf
 .ref itrtbl
 .ref kbwait
 .ref keyutil
 .ref loadkey
 .ref loadphone
 .ref lpf
 .ref menu,menu$list,menu$title
 .ref offline,online,hilite
 .ref open$prg,open$seq
 .ref openmodem
 .ref phoneutil
 .ref println,printpkt
 .ref ppinit,ppreset,ppterm
 .ref precv
 .ref protocol
 .ref psend
 .ref raster,noraster
 .ref setcolors
 .ref sid$init
 .ref sleep
 .ref term
 .ref xrecv,xsend

;**************************************
maintitle 
 .byte "MRTERM V3.5  04/20/87",0

quitmsg
 .byte 13
 .byte "If you had difficulties with this",13
 .byte "program, or if you have suggestions for",13
 .byte "enhancing it, PLEASE contact the author",13
 .byte "by mail, phone or Punter Net:",13,13

 .byte "Mark R. Rinfret",13
 .byte "348 Indian Avenue",13
 .byte "Portsmouth, RI 02871",13,13
 .byte "Home: 401-846-7639",13
 .byte "Work: 401-849-4174",13
 .byte "Punter Net Node 52, 401-847-8934",13,0

quitpkt
 .byte PP$CLR
 .byte 0,0
 .word quitmsg

;**************************************
 .def start
start
 jsr init ;initialize program
 jsr mainmenu
 rts


;Initialize program

init
 jsr i$int ;new interrupt handler
 lda #0 ;reserve file numbers
 ldx #mdmfn
 sta fil$num,x ;modem
 ldx #pfn
 sta fil$num,x ;printer

 lda #mdmfn
 jsr openmodem

 lda #8 ;device 8
 sta disk$dvc
 jsr open$cmd

 jsr sid$init ;init sound chip

 jsr ldtitle ;load title screen

 lda #clrscrn
 jsr chrout

 lda #lowercase ;switch to lowercase
 jsr chrout

 jsr itrtbl ;translation tables
 jsr i$tbuf ;init buffer
 jsr ppinit ;initialize Punter package

 jsr loadphone ;load phone book
 jsr loadkey ;load function keys

 ldx #<null ;load default parameters
 ldy #>null
 jsr lpf
 beq initx ;failed to load?

 lda #mdmfn ;re-open modem with new parameters
 jsr openmodem

initx
 jsr setcolors
 lda 1 ;map out BASIC
 and #$fe
 sta 1
 rts

;*****************************
;* Main menu data structures *
;*****************************


m$dial  .byte "Auto-Dial",0
m$buf   .byte "Buffer Utilities",0
m$cfg   .byte "Configure",0
m$disk  .byte "Disk/File Utilities",0
m$fkey  .byte "Function Key Utilities",0
m$phone .byte "Phone Book Utilities",0
m$quit  .byte "Quit",0
m$recv  .byte "Receive File",0
m$send  .byte "Send File",0
m$term  .byte "Terminal",0

mainlist ;list of string pointers
 .word m$term
 .word m$dial
 .word m$recv
 .word m$send
 .word m$cfg
 .word m$disk
 .word m$buf
 .word m$phone
 .word m$fkey
 .word m$quit
null
 .word 0 ;null list terminator

mainvect
 .word term
 .word dial
 .word rcvfil
 .word sndfil
 .word configure
 .word diskutil
 .word bufutil
 .word phoneutil
 .word keyutil
 .word quit

mainjump jmp $ffff ;dispatch jump

;
;Main menu/dispatch routine
;

mainmenu
 lda #<maintitle ;title string
 sta menu$title
 lda #>maintitle
 sta menu$title+1

 lda #<mainlist ;command string list
 sta menu$list
 lda #>mainlist
 sta menu$list+1
 lda offline ;set offline color
 sta color
 jsr menu ;returns with index in ACC
 cmp #9 ;quit?
 bne notquit

quit
 lda #0
 sta $d015 ;disable sprites
 sta 54296 ;kill sid chip
 lda 1 ;
 ora #1 ;map in BASIC
 sta 1
 lda #mdmfn ;close modem
 jsr close
 jsr r$int ;reset interrupt handler
 lda hilite
 ldx #<quitpkt
 ldy #>quitpkt
 jsr printpkt
 rts ;just return


notquit
 rol A ;times 2 for word index
 tax
 lda mainvect,x
 sta mainjump+1
 lda mainvect+1,x
 sta mainjump+2
 jsr mainjump
 jmp mainmenu ;loop forever

;
; Receive a file
;
 .def rcvfil
rcvfil
 lda protocol
 bne rcvfil1
 jsr precv


;Clear the screen prior to exit, since
;we might come here via terminal mode.

rcvfilx
 lda #clrscrn
 jsr chrout
 rts

rcvfil1
 jsr xrecv
 jmp rcvfilx

;
; Send a file
;
 .def sndfil
sndfil
 lda protocol
 bne sndfil1
 jsr psend
 jmp rcvfilx ;use common exit

sndfil1 ;protocol 1 => XMODEM/CRC, 2 => XMODEM/CHECKSUM
 jsr xsend
 jmp rcvfilx
  

;Load Title Screen

titlename .byte "mrterm.s",0
titlemsg .byte " Press any key to begin ",0
titlpkt
 .byte PP$CENTER|PP$WAIT
 .byte 24,0
 .word titlemsg
 

ldtitle
 lda #1 ;white
 sta color
 lda #lowercase
 jsr chrout
 ldx #<titlename
 ldy #>titlename
 lda #'r ;read access
 jsr open$prg ;program image
 beq ldtitlex ;failed?
 pha ;save file number on stack
 tax
 jsr chkin
 jsr getin ;discard load address
 jsr getin
 jsr noraster ;kill raster
 pla
 pha
 ldx #<1024 ;ptr1 = screen address
 stx ptr1
 ldx #>1024
 stx ptr1+1
 ldx #<$400 ;400 (hex) bytes of
 ldy #>$400 ;screen memory
 jsr bkrd
 ldx #<colormem
 stx ptr1
 ldx #>colormem
 stx ptr1+1
 pla
 pha
 ldx #<$400 ;400 (hex) bytes of
 ldy #>$400 ;color memory 
 jsr bkrd 
 pla
 jsr fclose
 lda #14 ;border light blue
 sta 53280
 lda #0 ;background = black
 sta 53281

ldtitlex
 jsr raster ;enable raster
 lda hilite
 ldx #<titlpkt
 ldy #>titlpkt
 jsr printpkt
 rts

SHAR_EOF
fi # end of overwriting check
if test -f 'mem.i'
then
	echo shar: will not over-write existing file "'mem.i'"
else
cat << \SHAR_EOF > 'mem.i'
;
; C64 Memory Assignments
; Filename: mem.i
;
; Zero-page Equates
; -----------------
;
;History:
;
curx     = $d3 ;cursor 'x' position
col      = $d3 ;an alias for curx
crsw     = $d0 ;screen/keyboard flag
cury     = $d6 ;cursor 'y' position
row      = $d6 ;an alias for cury
d6510    = $00 ;data direction register
dfltn    = $99 ;default input device
dflto    = $9a ;default output device
fa       = $ba ;current device number
fnadr    = $bb ;filename
fnlen    = $b7 ;filename length
indx     = $c8 ;end of logical line
jclock   = $a0 ;jiffy clock
la       = $b8 ;current logical file

lstx     = $c5 ;matrix coord. of last keypress

ptr1     = $fb ;pointer ($fb..$fc)
ptr2     = $fd ;pointer ($fd..$fe)
ptr3     = $c3 ;pointer ($c3..$c4)
;
r6510    = $01 ;memory map register
ribuf    = $f7 ;rs-232 input buffer pointer 
robuf    = $f9 ;rs-232 output buffer pointer
rvs      = $c7 ;reverse video flag
;
sa       = $b9 ;current secondary address
status   = $90 ;kernal i/o status byte
;
; *************************************
;
; Non-Zero Page Variables

baudof   = $299 ;rs-232 bit time
buf      = 512 ;input buffer
color    = 646 ;current character color
colormem = $d800 ;color ram
enabl    = $2a1 ;rs-232 busy flag
m51ajb   = $295 ;rs-232 non-standard bit time
qtsw     = 212 ;quote mode switch
rsstat   = $297 ;rs-232 status register
SHAR_EOF
fi # end of overwriting check
if test -f 'modem.a'
then
	echo shar: will not over-write existing file "'modem.a'"
else
cat << \SHAR_EOF > 'modem.a'
; MRTERM Modem Support Routines
; Filename: modem.a
; History:
;   08/2/86 - 2.5 - cosmetic surgery (.nlst)
;
 .nlst
#include "mem.i"
#include "kernal.i"
#include "char.i"
 .list

;References to module 'global'

 .ref baud,databits,parity,stopbits
 .ref dialcmd,modemtype
 .ref offline,online,hilite

;References to module 'punter'

 .ref ppbtime

;References to module 'terminal'

 .ref term


;Other external references
 .ref asc2cbm,cbm2asc
 .ref center
 .ref eraseeol
 .ref gets
 .ref gong
 .ref imath$val,itoa
 .ref sleep,tsleep
 .ref strcpy,string$1,string$2

;
; Open modem.
; Called with:
;   file number in ACC
;
mdmctl .word 0 ;control/command registers
 .byte 0 ;always null

 .def openmodem
openmodem
 pha ;save ACC
 clc
 lda stopbits ;stopbits << 7
 rol A
 rol A
 ora databits ;databits << 5
 rol A
 rol A
 rol A
 rol A
 rol A
 sta mdmctl

 lda parity ;parity << 5 
 rol A
 rol A 
 rol A
 rol A
 rol A
 sta mdmctl+1

 pla ;restore file number
 pha 
 jsr close

 lda #<$ce00 ;set up buffer addresses
 sta ribuf
 lda #>$ce00
 sta ribuf+1
 lda #<$cf00
 sta robuf
 lda #>$cf00
 sta robuf+1

 pla ;restore file number
 ldx #2 ;device number
 ldy #0 ;secondary address
 jsr setlfs

 lda #2 ;control string length
 ldx #<mdmctl
 ldy #>mdmctl
 jsr setnam

 jsr open ;open modem
 jsr clrchn
 jsr fixbaud ;fix baud rates
 rts


; Fix up baud rate timing
; Local routine (not externally defined)

fixbaud
 lda baud
 bne fix1200 ;1200 baud
 lda #<3409 
 sta 665
 sta ppbtime
 lda #>3409
 sta 666
 sta ppbtime+1
 lda #<1609
 sta 661
 lda #>1609
 sta 662
 rts

fix1200
 lda #<852 ;output timer is
 sta ppbtime ;different than
 lda #>852 ;input timer
 sta ppbtime+1
 
 lda #<823
 sta 665
 lda #>823
 sta 666

 lda #<326
 sta 661
 lda #>326
 sta 662
 rts


;Read untranslated character from modem
;Returns:
;  Carry set = no character
;  Carry clear = got character
;    ACC = character code
;  X = modem status

 .def mdmrd
mdmrd
 lda #0
 sta rsstat ;clear old status
 ldx #5
 jsr chkin
 jsr getin
 pha
 jsr clrchn
 pla
 clc ;assume good status
 ldx rsstat
 beq mdmrdx ;good character
 sec ;no character
mdmrdx
 rts

;Write untranslated character to modem
;Called with:
;  ACC = character to write

 .def mdmwrt
mdmwrt
 pha ;save character
 ldx #5
 jsr chkout
 pla
 jsr chrout
 jsr clrchn
 rts

SHAR_EOF
fi # end of overwriting check
if test -f 'mrterm.i'
then
	echo shar: will not over-write existing file "'mrterm.i'"
else
cat << \SHAR_EOF > 'mrterm.i'
;MRTERM Main Definition File
;Filename: mrterm.i
;

mdmfn = 5 ;modem file number
pfn   = 4 ;printer file number


SHAR_EOF
fi # end of overwriting check
if test -f 'mrterm.lctl'
then
	echo shar: will not over-write existing file "'mrterm.lctl'"
else
cat << \SHAR_EOF > 'mrterm.lctl'
a
global.o
main.o
trtable.o
terminal.o
modem.o
pprotocol.o
configure.o
lpfspf.o
diskutil.o
xmprotocol.o
buffer.o
editor.o
phone.o
printer.o
fkey.o
interrupt.o

s
mrterm.l
q
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0
-- 
| Mark R. Rinfret, SofTech, Inc.		mark@unisec.usi.com |
| Guest of UniSecure Systems, Inc., Newport, RI                     |
| UUCP:  {gatech|mirror|cbosgd|uiucdcs|ihnp4}!rayssd!unisec!mark    |
| work: (401)-849-4174	home: (401)-846-7639                        |