summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo C2015-12-04 22:40:11 +0100
committerLeo C2015-12-04 22:40:11 +0100
commite58a7a2546e59e692ea958cbdcdbb184654383be (patch)
tree698a2b2cb8b95c4b2414e0f50b6c03f13c78fb76
parentc25f6a44a6e2266617af2f326fa5dc0c4864035f (diff)
downloadkermit-80-e58a7a2546e59e692ea958cbdcdbb184654383be.zip
Convert line endings to CP/M format (cr/lf).
-rw-r--r--cpscmd.asm2280
-rw-r--r--cpscom.asm2742
-rw-r--r--cpscpm.asm1864
-rw-r--r--cpsdat.asm1296
-rw-r--r--cpsdef.asm574
-rw-r--r--cpsker.asm630
-rw-r--r--cpsmit.asm1668
-rw-r--r--cpspk1.asm3808
-rw-r--r--cpspk2.asm2672
-rw-r--r--cpsrem.asm2298
-rw-r--r--cpsser.asm88
-rw-r--r--cpstt.asm1724
-rw-r--r--cpsutl.asm2454
-rw-r--r--cpswld.asm444
-rw-r--r--cpxapp.asm1498
-rw-r--r--cpxbbi.asm1236
-rw-r--r--cpxbee.asm1992
-rw-r--r--cpxcif.asm1492
-rw-r--r--cpxcom.asm972
-rw-r--r--cpxgni.asm880
-rw-r--r--cpxhea.asm1842
-rw-r--r--cpxlnk.asm412
-rw-r--r--cpxmrl.asm908
-rw-r--r--cpxnor.asm1174
-rw-r--r--cpxpcw.asm1824
-rw-r--r--cpxpro.asm1122
-rw-r--r--cpxsb.asm1392
-rw-r--r--cpxswt.asm588
-rw-r--r--cpxsy2.asm2728
-rw-r--r--cpxsyo.asm778
-rw-r--r--cpxsys.asm2772
-rw-r--r--cpxtm4.asm980
-rw-r--r--cpxtor.asm2458
-rw-r--r--cpxtyp.asm1444
-rw-r--r--cpxvdu.asm924
-rw-r--r--cpxz80.asm700
-rw-r--r--mload.asm2986
37 files changed, 28822 insertions, 28822 deletions
diff --git a/cpscmd.asm b/cpscmd.asm
index 6cff603..6044c7f 100644
--- a/cpscmd.asm
+++ b/cpscmd.asm
@@ -1,1140 +1,1140 @@
-; CPSCMD.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-;
-; This file provides a user oriented way of parsing commands.
-; It is similar to that of the COMND JSYS in TOPS-20.
-;
-; revision history (latest first):
-;
-;edit 13, 17-Jan-1991 by MF. Modified "cmifil" routine to zero the entire
-; fcb (not just the extent) to fix a bug in the COPY command which
-; prevented successive COPY commands from working properly.
-;edit 12, 16-Jan-1991 by MF. Modified routine "cmkeyw" to ignore leading
-; spaces/tabs before a keyword. This apparently was the intent in
-; "prompt" and "repars" (at least for command-lines) as the variable
-; "cmsflg "is set upon command parse and reparse. The intent was ,
-; subverted, however, as "cmkeyw" did not reset the flag to ignore
-; leading white space for each search thru the key tables (even though
-; the buffer pointer to the keyword entered was reset). The fix was
-; to reset the "spaces seen" flag (cmsflg) after "cmkey2" so that
-; it is reset each time a new table entry is compared to the text
-; the user has entered from the keyboard/TAKE-file etc. The upshot
-; of all this is that the kluge code in "cminbf" at "cminb0" designed
-; to force Kermit to ignore leading white space on command-lines in
-; TAKE-files and on the CP/M command-line is no longer needed and,
-; therefore, has been eliminated. Also modify "comnd" to expect leading
-; spaces for functions other than "get keyword".
-;edit 11, 26-Dec-1990 by MF. Modified routines to ignore leading white space
-; in lines from TAKE-files as well as during input from the CP/M
-; command-line (form-feeds are now considered white space under these
-; circumstances).
-;edit 10, 8-Sep-1990 by Mike Freeman. Modified routines to ignore leading
-; spaces/tabs when processing Kermit commands from the CP/M
-; command-line.
-; Added flag CMBFLG to allow initial word on a command-line
-; to be blank (useful for Remote commands such as Remote CWD etc).
-; Added flag cmqflg to prevent character-echoing while entering
-; commands so Remote CWD etc can have nonechoing password entry.
-; edit 9, 15 June, 1987 by OBSchou. Bug fixing to allow a second filename
-; (quiet) be entered as d:<blank>. Previous revision put the drive name
-; in first character of FCB, I put that character back to a space.
-;
-; edit 8, 12 June, 1987 by OBSchou. Addedin code in cmkeyw to print
-; 20 lines of help, then pause for a key from the user befor
-; proceeding with help.
-;
-; edit 7, 11 March, 1987 by OBSchou for Richard Russell, BBC. He writes:
-; Bug in cmtext which prevented use of octal characters (\nnn) fixed.
-;
-; edit 6, 18 June, 1986 by OBSchou, Loughborough University, Leics. UK
-; added code to parse a number from user input. Added check to make
-; sure the input command buffer does not overflow the limit.
-;
-; edit 5a: 7 March, 1986. OBSchou. Added stuff rom MJ Carter. He writes:
-; 7th May 85, MJ Carter [majoc], Nottingham University
-; Code in cmifil() put one too many spaces in the FCB; this caused
-; the BDOS of the British Micro Mimi to search for exteny 32,
-; rather than extent 0, so era() always said "can't find file"
-; Puttig a null at the point in question ought to fix 9 it.
-;
-; edit 5: 6-Feb-85 by Charles Carvalho
-; Make ffussy a runtime (rather than assembly-time) switch, to
-; eliminate conditional assembly in system-independent module.
-; Don't allow _%|()/\ in filenames if ffussy set; my CP/M manual
-; disallows those, too.
-;
-; edit 4: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
-;
-;pcc006 2-jan-85 VJC modules:cp4cmd,cp4utl
-; Problems with "?" in filespecs. On reparse, may cause action
-; flag to be reset at wrong point, requiring multiple <CR>'s
-; to terminate the line or other weird stuff. Also need to
-; check flag and complain if wild-cards illegal.
-
-;pcc007 2-Jan-85 vjc modules:cp4def,cp4cmd
-; Cmifil is too fussy about what characters to accept in a
-; filespec. My CP/M manual says any printable character is ok
-; except <>.,;:?*[], and lower case. In practice, even those work
-; sometimes. Kermit itself uses '&' if file warning is on,
-; and then won't let you reference the file. Allow all
-; printable characters except those above. Add conditional
-; ffussy, so that if not ffussy, all special characters will be
-; allowed, just convert lower to upper-case.
-
-; edit 3: July 8, 1984 (CJC)
-; integrate Toad Hall changes for LASM compatibility: CP4CPM is linked
-; by CP4WLD, and links CP4UTL.
-;
-; edit 2: June 5, 1984 (CJC)
-; formatting and documentation; delete unnecessary code at cminb7; add
-; module version string.
-;
-; edit 1: May, 1984 (CJC)
-; extracted from CPMBASE.M80 version 3.9; modifications are described in
-; the accompanying .UPD file.
-
-cmdver: db 'CPSCMD.ASM (13) 17-Jan-1991$' ; name, edit number, date
-
-; This routine prints the prompt in DE and specifies the reparse
-; address.
-; called by: kermit
-
-prompt: pop h ;Get the return address.
- push h ;Put it on the stack again.
- shld cmrprs ;Save it as the address to go to on reparse.
- lxi h,0 ;Clear out hl pair.
- dad sp ;Get the present stack pointer.
- shld cmostp ;Save for later restoral.
- xchg ;Save the pointer to the prompt.
- shld cmprmp
- xchg
- lxi h,cmdbuf
- shld cmcptr ;Initialize the command pointer.
- shld cmdptr
- xra a
- sta cmaflg ;Zero the flags.
- sta cmccnt
-; mvi a,0FFH ;Try it this way (Daphne.)
-; sta cmsflg
- call prcrlf ;Print a CR/LF [Toad Hall]
- jmp prprmp ;Print the prompt. [Toad Hall]
-;
-; This address is jumped to on reparse.
-; here from: cmcfrm, cmkeyw, cmifil, cminbf
-
-repars: lhld cmostp ;Get the old stack pointer.
- sphl ;Make it the present one.
- lxi h,cmdbuf
- shld cmdptr
-; mvi a,0FFH ;Try it this way (Daphne.)
-; sta cmsflg
- lhld cmrprs ;Get the reparse address.
- pchl ;Go there.
-
-; This address can be jumped to on a parsing error.
-; here from: cmkeyw, cminbf
-
-prserr: lhld cmostp ;Get the old stack pointer.
- sphl ;Make it the present one.
- lxi h,cmdbuf
- shld cmcptr ;Initialize the command pointer.
- shld cmdptr
- xra a
- sta cmaflg ;Zero the flags.
- sta cmccnt
-; mvi a,0FFH ;Try it this way (Daphne.)
-; sta cmsflg
- call prcrlf ;Print a CR/LF [Toad Hall]
- call prprmp ;Print the prompt [Toad Hall]
-;* Instead return to before the prompt call.
- lhld cmrprs
- pchl
-;
-; This routine parses the specified function in A. Any additional
-; information is in DE and HL.
-; Returns +1 on success
-; +4 on failure (assumes a JMP follows the call)
-; called by: log, setcom, read, send, xmit, dir, era, keycmd, cfmcmd
-; and CPSREM
-
-comnd: sta cmstat ;Save what we are presently parsing.
- call cminbf ;Get chars until an action or a erase char.
- push psw ;[MF]Save function
- mvi a,0ffh ;[MF]Expect leading spaces
- sta cmsflg ;[MF]...
- pop psw ;[MF]Restore function
- cpi cmcfm ;Parse a confirm?
- jz cmcfrm ;Go get one.
- cpi cmkey ;Parse a keyword?
- jz cmkeyw ;Try and get one.
- cpi cmifi ;Parse an input file spec?
- jz cmifil ;Go get one.
- cpi cmifin ;Input file-spec silent?
- jz cmifil ;do as he wishes
- cpi cmofi ;Output file spec?
- jz cmofil ;Go get one.
- cpi cmtxt ;Parse arbitrary text?
- jz cmtext ;Go do it.
- cpi cmnum ;[7] Parse a number?
- jz cmnumb ;[7] go do it
- lxi d,cmer00 ;"?Unrecognized COMND call"
- call prtstr
- ret
-;
-; This routine parses arbitrary text up to a CR.
-; Accepts DE: address to put text
-; Returns in A: number of chars in text (may be 0)
-; DE: updated pointer
-; called by: comnd
-
-cmtext: xra a ; clear counters erc for slashes etc
- sta slshsn ; if we are in a slash sequence
- sta slashn ; the octal number being entered
- sta slashc ; number of characters entered
-
- xchg ;Put the pointer to the dest in HL.
- shld cmptab ;Save the pointer.
- mvi b,0 ;Init the char count
-cmtxt1: call cmgtch ;Get a char.
- ora a ;Terminator?
- jp cmtx3 ;No, put in user space. [rtr] was cmtx5
- ani 7FH ;Turn off minus bit.
- cpi esc ;An escape?
- jnz cmtxt2 ;No.
- mvi c,conout
- mvi e,bell ;Get a bell.
- call bdos
- xra a
- sta cmaflg ;Turn off the action flag.
- lhld cmcptr ;Move the pointer to before the escape.
- dcx h
- shld cmcptr
- shld cmdptr
- lxi h,cmccnt ;Get the char count.
- dcr m ;Decrement it by one.
- jmp cmtxt1 ;Try again.
-
-cmtxt2: cpi '?' ;Is it a question mark?
- jz cmtxt4 ;If so put it in the text. [rtr] was cmtx3
- cpi ff ;Is it a formfeed?
- cz clrtop ;If so blank the screen.
- mov a,b ;Return the count.
- lhld cmptab ;Return updated pointer in HL.
- xchg
- jmp rskp ;Return success.
-
-cmtx3: cpi '\' ; slash?
- jnz cmtx3a ; nope, so try something else
- lda slshsn ; a slash already entered?
- ana a
- cma ;[rtr]
- jnz cmtx3a ; yes, so assume its a valid slash to enter
- sta slshsn ; make sure the flag is set for next time routnd
- jmp cmtxt1 ; get another character
-
-cmtx3a:
-; lxi h,cmaflg ;Point to the action flag.
-; mvi m,0 ;Set it to zero.
- mov e,a ; save it in case we are interpreting a slash
- lda slshsn ; slash already entered?
- ana a ; test flag
- mov a,e ; restore it in case...
- jz cmtx5 ; not a slash seen, so enter as a normal character
- cpi '\'
- jnz cmtx3b ; \\ not detected
- lda slashn ; else get number
- jmp cmtx5b ; and enter it ( in the case of \n or \nn)
- ; here if an octal number of 1 or 2 digits
- ; entered instead of 3, followed by \ again
-
-cmtx3b:
- sui 30h ; else it should be an octal number
- jm cmtxt6 ; if not a digit complain
- cpi 8 ; ditto
- jp cmtxt6 ;[rtr] was cmtxt
- mov e,a ; else add it to the number already entered
- lda slashn
- add a
- add a
- add a ; multiply by 8
- add e
- sta slashn
- lda slashc ; get the count
- inr a
- sta slashc ; plus one. If three then a number entered
- cpi 3
- lda slashn ; get the number in case...
- jz cmtx5
- jmp cmtxt1 ; else loop
-
-cmtxt4: lhld cmdptr ;[rtr] Get a pointer into the buffer
- inx h ;[rtr] Bump past '?'
- shld cmdptr ;[rtr]
-cmtx5: call cmtx5c
- jmp cmtxt1 ; put this into a subroutine
-
-cmtx5b:
- call cmtx5c ; here if we see \n\ or \nn\ rather than \nnn\
- mvi a,'\' ; so send slash number to buffer,
- sta slshsn ; re-store a slash seen
- jmp cmtxt1 ; try next one
-
-cmtx5c:
- inr b ;Increment the count.
- lhld cmptab ;Get the pointer.
- mov m,a ;Put the char in the array.
- inx h
- shld cmptab ;Save the updated pointer.
- xra a ; clear slash counters etc
- sta slashc
- sta slashn
- sta slshsn
- ret ; and exit
-
-cmtxt6: lxi d,cmer05 ; complain - not a valid \ parameter
- call prtstr
- jmp kermit ; and try another command
- ds 20h ; for debugging
-;
-; This routine gets a number from user input.
-; Called by: comnd
-;
-cmnumb: lxi h,0 ; make sure the number is zero to start with
- shld number
-cmnum0: call cmgtch ; get another character
- ora a ; if negative then its an action
- jp cmnum1 ; nope, so (possibly) valid input
- ani 7fh ; else lets see what it is...
- cpi esc ; do not know what to do with this one...
- cpi ' ' ; if it is a space then either a return or more
- jnz cmnum2 ; else
- jmp rskp ; space is a deliminter
- dw 0 ; set three bytes aside for a jump/call
- dw 0 ; and then another three just in case...
- dw 0 ; making 6 bytes
-cmnum2: cpi '?' ; user is curious
- jz gnum2
- cpi cr ; end of input?
- jz cmnumx
-gnum1: jmp prserr ; did not under stand this, so error
-cmnumx: dw 0
- dw 0
- jmp rskp ; return ok
-
-gnum2: lhld number ; get the number.. if at all entered
- mov a,l
- ora h ; if hl = 0 then possibly no number entered
- lxi d,cmin02 ; say confirm...or more on line
- jnz gnum21 ; else say enter a return
- lxi d,cmin01 ; say enter a number
-gnum21: call prtstr ; say it
- call prcrlf ; do a lf
- call prprmp ; another reprompt
- lhld cmdptr ; get pointer of string already entered
- mvi m,'$' ; dollar it to set end of line
- lhld cmcptr
- dcx h ; decrement and save the buffer pointer
- shld cmcptr
- lxi d,cmdbuf
- call prtstr ; print what has already been entered
- xra a
- sta cmaflg ; turn the action flag off
- jmp repars ; and try again
-
- mvi a,cmcfm ; parse a confirm
-dw 0
-dw 0
-dw 0
-dw 0
-dw 0 ; some space to patch...
-dw 0
-
-cmnum1: ani 7fh ; here for a (potentially) valid number
- sui '0' ; less ascii bias
- jc gnum3
- cpi 10 ; if 10 or more its still bad
- jnc gnum3
- cmc
- lhld number ; now multiply number by ten and add the new value
- push h
- pop d
- dad h ; hl = hl * 2
- dad h ; * 4
- dad d ; * 5
- dad h ; * 10
- mvi d,0
- mov e,a ; add de to hl...
- dad d
- shld number
- jmp cmnum0
-;
-gnum3: lxi d,cmer04 ; invalid number...
- call prtstr
- jmp rskp
-;
-
-;
-; This routine gets a confirm.
-; called by: comnd
-
-cmcfrm: call cmgtch ;Get a char.
- ora a ;Is it negative (a terminator;a space or
- ;a tab will not be returned here as they
- ;will be seen as leading white space.)
- rp ;If not, return failure.
- ani 7FH ;Turn off the minus bit.
- cpi esc ;Is it an escape?
- jnz cmcfr2
- mvi c,conout
- mvi e,bell ;Get a bell.
- call bdos
- xra a
- sta cmaflg ;Turn off the action flag.
- lhld cmcptr ;Move the pointer to before the escape.
- dcx h
- shld cmcptr
- shld cmdptr
- lxi h,cmccnt ;Get the char count.
- dcr m ;Decrement it by one.
- jmp cmcfrm ;Try again.
-
-cmcfr2: cpi '?' ;Curious?
- jnz cmcfr3
- lxi d,cmin00 ;Print something useful.
- call prtstr
- call prcrlf ;Print a crlf. [Toad Hall]
- call prprmp ;Reprint the prompt [Toad Hall]
- lhld cmdptr ;Get the pointer into the buffer.
- mvi a,'$' ;Put a $ there for printing.
- mov m,a
- lhld cmcptr
- dcx h ;Decrement and save the buffer pointer.
- shld cmcptr
- lxi d,cmdbuf
- call prtstr
- xra a ;Turn off the action flag.
- sta cmaflg
- jmp repars ;Reparse everything.
-
-cmcfr3: cpi ff ;Is it a form feed?
- cz clrtop ;If so blank the screen.
- jmp rskp
-;
-; This routine parses a keyword from the table pointed
-; to in DE. The format of the table is as follows:
-;
-; addr: db n ;Where n is the # of entries in the table.
-; db m ;M is the size of the keyword.
-; db 'string$' ;Where string is the keyword.
-; db a,b ;Where a & b are pieces of data
-; ;to be returned. (Must be two of them.)
-;
-; The keywords must be in alphabetical order.
-;**** Note: The data value a is returned in registers A and E. The
-;**** data value b is returned in register D. This allows the two data
-; bytes to be stored as:
-; dw xxx
-; and result in a correctly formatted 16-bit value in register pair
-; DE.
-; called by: comnd
-
-cmkeyw: shld cmhlp ;Save the help.
- xchg ;Get the address of the table.
- shld cmptab ;Save the beginning of keyword tab for '?'.
- mov b,m ;Get the number of entries in the table.
- inx h
- shld cmkptr
- lhld cmdptr ;Save the command pointer.
- shld cmsptr
-cmkey2: mov a,b ;Get the number of entries left.
- ora a ;Any left?
- rz ;If not we failed.
- mvi a,0ffh ;[MF]Make sure we ignore leading spaces
- sta cmsflg ;[MF]...
- lhld cmkptr
- mov e,m ;Get the length of the keyword.
- inx h
-cmkey3: dcr e ;Decrement the number of chars left.
- mov a,e
- cpi 0FFH ;Have we passed the end?
- jm cmkey5 ;If so go to the next.
- call cmgtch ;Get a char.
- ora a ;Is it a terminator?
- jp cmkey4 ;If positive, it is not.
- ani 7FH ;Turn off the minus bit.
- cpi '?'
- jnz cmky31
- xra a
- sta cmaflg ;Turn off the action flag.
- lxi h,cmccnt ;Decrement the char count.
- dcr m
-;* Must go through the keyword table and print them.
- lhld cmhlp ;For now print the help text.
- xchg
- call p20ln ;[8] print at most 20 lines then pause
-; call prtstr
- call prcrlf ;Print a crlf [Toad Hall]
- call prprmp ;Reprint the prompt [Toad Hall]
- lhld cmdptr ;Get the pointer into the buffer.
- mvi a,'$' ;Put a $ there for printing.
- mov m,a
- lhld cmcptr
- dcx h ;Decrement and save the buffer pointer.
- shld cmcptr
- lxi d,cmdbuf
- call prtstr
- jmp repars ;Reparse everything.
-
-cmky31: cpi esc ;Is it an escape?
- jnz cmky35
- xra a
- sta cmaflg ;Turn off the action flag.
- push d
- push b
- push h
- call cmambg
- jmp cmky32 ;Not ambiguous.
- mvi c,conout
- mvi e,bell
- call bdos ;Ring the bell.
- lhld cmcptr ;Move the pointer to before the escape.
- dcx h
- shld cmcptr
- shld cmdptr
- lxi h,cmccnt ;Get the char count.
- dcr m ;Decrement it by one.
- pop h
- pop b
- pop d
- inr e ;Increment the left to parse char count.
- jmp cmkey3
-
-cmky32: lhld cmcptr ;Pointer into buffer.
- dcx h ;Backup to the escape.
- xchg
- pop h
- push h
-cmky33: mov a,m ;Get the next char.
- cpi '$' ;Finished?
- jz cmky34
- inx h
- xchg
- mov m,a ;Move it into the buffer.
- inx h
- xchg
- lda cmccnt ;Increment the char count.
- inr a
- sta cmccnt
- jmp cmky33
-
-cmky34: lda cmccnt ;Get the character count.
- inr a ;Increment and save it.
- sta cmccnt
- xchg ;Put the command buffer pointer in HL.
- mvi a,' ' ;Get a blank.
- mov m,a ;Put it in the command buffer.
- inx h ;Increment the pointer
- shld cmcptr ;Save the updated pointer.
- shld cmdptr
- pop h
- push h
- xchg
- call prtstr ;Print the rest of the keyword.
- mvi c,conout
- mvi e,' '
- call bdos ;Print a blank.
- pop h
- pop b
- pop d
- jmp cmky37
-
-cmky35: push h
- push d
- call cmambg
- jmp cmky36
- lxi d,cmer01
- call prtstr ;Say its ambiguous.
- jmp prserr ;Give up.
-
-cmky36: pop d
- pop h
-cmky37: inr e ;Add one incase it is negative.
- mvi d,0
- dad d ;Increment past the keyword.
- inx h ;Past the $.
- mov e,m ;Get the data.
- inx h
- mov d,m
- mov a,e
- jmp rskp
-
-cmkey4: cpi 'a' ;Is it less than a?
- jm cmky41 ;If so don't capitalize it.
- cpi 'z'+1 ;Is it more than z?
- jp cmky41 ;If so don't capitalize it.
- ani 137O ;Capitalize it.
-cmky41: mov d,m ;Get the next char of the keyword.
- inx h
- cmp d ;Match?
- jz cmkey3 ;If so get the next letter.
-
-cmkey5: mvi d,0
- mov a,e ;Get the number of chars left.
- ora a ;Is it negative?
- jp cmky51
- mvi d,0FFH ;If so, sign extend.
-cmky51: dad d ;Increment past the keyword.
- lxi d,0003H ;Plus the $ and data.
- dad d
- shld cmkptr
- dcr b ;Decrement the number of entries left.
- lhld cmsptr ;Get the old cmdptr.
- shld cmdptr ;Restore it.
-;* check so we don't pass it.
- jmp cmkey2 ;Go check the next keyword.
-;
-; Test keyword for ambiguity.
-; returns: nonskip if ambiguous, skip if OK.
-; called by: cmkeyw
-
-cmambg: dcr b ;Decrement the number of entries left.
- rm ;If none left then it is not ambiguous.
- inr e ;This is off by one;adjust.
- mov c,e ;Save the char count.
- mov a,e
- ora a ;Any chars left?
- rz ;No, it can't be ambiguous.
- mvi d,0
- dad d ;Increment past the keyword.
- mvi e,3 ;Plus the $ and data.
- dad d
- mov b,m ;Get the length of the keyword.
- inx h
- xchg
- lhld cmkptr ;Get pointer to keyword entry.
- mov a,m ;Get the length of the keyword.
- sub c ;Subtract how many left.
- mov c,a ;Save the count.
- cmp b
- jz cmamb0
- rp ;If larger than the new word then not amb.
-cmamb0: lhld cmsptr ;Get the pointer to what parsed.
-cmamb1: dcr c ;Decrement the count.
- jm rskp ;If we are done then it is ambiguous.
- xchg ;Exchange the pointers.
- mov b,m ;Get the next char of the keyword
- inx h
- xchg ;Exchange the pointers.
- mov a,m ;Get the next parsed char.
- inx h
- cpi 'a' ;Is it less than a?
- jm cmamb2 ;If so don't capitalize it.
- cpi 'z'+1 ;Is it more than z?
- jp cmamb2 ;If so don't capitalize it.
- ani 137O
-cmamb2: cmp b ;Are they equal?
- rnz ;If not then its not ambiguous.
- jmp cmamb1 ;Check the next char.
-;
-; cmofil - parse output filespec
-; cmifil - parse input filespec
-; here from: comnd
-
-cmofil: mvi a,0 ;Don't allow wildcards.
-; jmp cmifil ;For now, the same as CMIFI.
-cmifil: sta cmfwld ;Set wildcard flag
- xchg ;Get the fcb address.
- shld cmfcb ;Save it.
- mvi e,0 ;Initialize char count.
- mvi m,0 ;Set the drive to default to current.
- inx h
- shld cmfcb2
- xra a ;Initialize counter.
-cmifi0: mvi m,' ' ;Blank the FCB.
- inx h
- inr a
-; cpi 0CH ;Twelve? [5a dont use this]
- cpi 0Bh ; [majoc 850585] Eleven?
- jm cmifi0
-cmif0a: ;[MF]Zero entire fcb, not just the extent
- mvi m,0 ; [majoc 850507] Specify extent 0
- inx h ;[MF]Increment fcb byte pointer
- inr a ;[MF]Increment fcb byte count
- cpi 32 ;[MF]Done with fcb?
- jm cmif0a ;[MF]No, zero until done
-cmifi1: call cmgtch ;Get another char.
- ora a ;Is it an action character?
- jp cmifi2
- ani 7FH ;Turn off the action bit.
- cpi '?' ;A question mark?
- jnz cmif12
- lda cmfwld ;[pcc006] Wildcards allowed?
- ora a ;[pcc006]
- jz cmif11 ;[pcc006] complain if not
- lhld cmdptr ;[jd] Increment buffer pointer
- inx h ;[jd] that was decremented in cmgtch
- shld cmdptr ;[jd] since we want this chr
- lda cmcptr ;[pcc006] get lsb of real input pointer
- cmp l ;[pcc006] is this the last chr input?
- jnz cmif1a ;[pcc006] no, don't reset action flag
- xra a ;[pcc006] yes, reset action flag
- sta cmaflg ;[pcc006]
-cmif1a: mvi a,'?' ;[pcc006] get it back in A
- jmp cmifi8 ;Treat like any other character
-
-cmif12: cpi esc ;An escape?
- jnz cmif13
-;Try to recognize file-spec a'la TOPS-20
- xra a
- sta cmaflg ;Turn off the action flag.
- lhld cmcptr ;Move the pointer to before the escape.
- dcx h
- shld cmcptr
- shld cmdptr
- lxi h,cmccnt ;Get the char count.
- dcr m ;Decrement it by one.
- mov a,e ;Save character count up to now.
- sta temp1
- cpi 9 ;Past '.'?
- jm cmfrec ;No.
- dcr a ;Yes, don't count point.
-cmfrec: lhld cmfcb2 ;Fill the rest with CP/M wildcards.
-cmfrc1: cpi 11 ;Done?
- jp cmfrc2 ;Yes.
- mvi m,'?'
- inx h
- inr a
- jmp cmfrc1
-
-cmfrc2: mvi c,sfirst ;Find first matching file?
- lhld cmfcb
- xchg
- call bdos
- cpi 0FFH
- jz cmfrc9 ;No, lose.
- lxi h,fcbblk ;Copy first file spec.
- call fspcop
- lxi h,fcbblk+10H ;Get another copy (in case not ambiguous).
- call fspcop
- mvi c,snext ;More matching specs?
- lhld cmfcb
- xchg
- call bdos
- cpi 0FFH
- jz cmfrc3 ;Only one.
- lxi h,fcbblk+10H ;Copy second file spec.
- call fspcop
-cmfrc3: lxi d,fcbblk ;Start comparing file names.
- lxi h,fcbblk+10H
- lda temp1 ;Bypass characters typed.
- cpi 9 ;Past '.'?
- jm cmfrc4 ;No.
- dcr a ;Yes, don't count point.
-cmfrc4: mvi c,0
-cmfrl1: cmp c ;Bypassed?
- jz cmfrl2 ;Yes.
- inx d
- inx h
- inr c
- jmp cmfrl1 ;Repeat.
-
-cmfrl2: mov a,c ;Get file name characters processed.
- cpi 11 ;All done?
- jz cmfrc5 ;Yes.
- cpi 8 ;End of file name?
- jnz cmfrl3 ;No.
- lda temp1 ;Exactly at point?
- cpi 9
- jz cmfrl3 ;Yes, don't output a second point.
- mvi a,'.' ;Output separator.
- call cmfput
-cmfrl3: ldax d ;Get a character from first file spec.
- inx d
- mov b,m ;Get from second file spec.
- inx h
- cmp b ;Compare.
- jnz cmfrc5 ;Ambiguous.
- inr c ;Same, count.
- cpi ' ' ;Blank?
- jz cmfrl2 ;Yes, don't output.
- call cmfput ;Put character into buffer.
- jmp cmfrl2 ;Repeat.
-
-cmfrc5: mov a,c ;Get count of characters processed.
- sta temp1 ;Save it.
- mvi a,'$' ;Get terminator.
- call cmfput ;Put it into buffer.
- lhld cmdptr ;Output recognized characters.
- xchg
- mvi c,prstr
- call bdos
- lhld cmcptr ;Remove terminator from buffer.
- dcx h
- shld cmcptr
- lxi h,cmccnt
- dcr m
- lda temp1 ;Characters processed.
- cpi 11 ;Complete file name.
- jz repars ;Yes, don't beep.
-
-cmfrc9: mvi c,conout
- mvi e,bell
- call bdos ;Ring the bell.
- jmp repars
-;
-; Continue file spec parsing.
-
-cmif13: mov a,e ;It must be a terminator.
- ora a ;Test the length of the file name.
- jz cmifi9 ;If zero complain.
- cpi 0DH
- jp cmifi9 ;If too long complain.
- jmp rskp ;Otherwise we have succeeded.
-
-cmifi2: cpi '.'
- jnz cmifi3
- inr e
- mov a,e
- cpi 1H ;Any chars yet?
- jz cmifi9 ;No, give error.
- cpi 0AH ;Tenth char?
- jp cmifi9 ;Past it, give an error.
- mvi c,9H
- mvi b,0
- lhld cmfcb
- dad b ;Point to file type field.
- shld cmfcb2
- mvi e,9H ;Say we've gotten nine.
- jmp cmifi1 ;Get the next char.
-
-cmifi3: cpi ':'
- jnz cmifi4
- inr e
- mov a,e
- cpi 2H ;Is it in the right place for a drive?
- jnz cmifi9 ;If not, complain.
- lhld cmfcb2
- dcx h ;Point to previous character.
- mov a,m ;Get the drive name.
- sui '@' ;Get the drive number.
- shld cmfcb2 ;Save pointer to beginning of name field.
- mvi m,space ;[obs] restore a space in FCB
- dcx h ;Point to drive number.
- mov m,a ;Put it in the fcb.
- mvi e,0 ;Start character count over.
- jmp cmifi1
-
-cmifi4: cpi '*'
- jnz cmifi7
- lda cmfwld ;Wildcards allowed?
- cpi 0
- jz cmif11 ;No,complain
- mov a,e
- cpi 8H ;Is this in the name or type field?
- jz cmifi9 ;If its where the dot should be give up.
- jp cmifi5 ;Type.
- mvi b,8H ;Eight chars.
- jmp cmifi6
-
-cmifi5: mvi b,0CH ;Three chars.
-cmifi6: lhld cmfcb2 ;Get a pointer into the FCB.
- mvi a,'?'
- mov m,a ;Put a question mark in.
- inx h
- shld cmfcb2
- inr e
- mov a,e
- cmp b
- jm cmifi6 ;Go fill in another.
- jmp cmifi1 ;Get the next char.
-
-cmifi7: cpi '!' ;[pcc007] control chr or space?
- jm cmifi9 ;[pcc007] yes, illegal
- mov h,a ;[5] stash input char for a bit
- lda ffussy ;[5] while we check the fussy flag
- ora a ;[5] set the flags accordingly
- mov a,h ;[5] restore the input character
- jz cmif7a ;[5] if ffussy=0, allow <>.,;:?*[]
-;[5] So far, we've eliminated "action characters" (including question),
-;[5] period, colon, asterisk, control characters, and space.
-;[5] That leaves us %(),/;<=>[\]_| to check for.
- cpi '%' ;[5]
- jz cmifi9 ;[5]
- cpi '(' ;[5]
- jz cmifi9 ;[5]
- cpi ')' ;[5]
- jz cmifi9 ;[5]
- cpi ',' ;[pcc007] weed out comma
- jz cmifi9 ;[pcc007]
- cpi '/' ;[5]
- jz cmifi9 ;[5]
- cpi '9'+1 ;[pcc007] anything else 21H-39H is ok
- jm cmifi8 ;[pcc007] except '*' never gets here
- cpi '@' ;[pcc007] all of 3AH-3FH is illegal
- jm cmifi9 ;[pcc007]
- cpi '[' ;[pcc007] [\] also illegal
- jm cmifi8 ;[pcc007]
- cpi ']'+1 ;[pcc007]
- jm cmifi9 ;[pcc007]
- cpi '_' ;[5]
- jz cmifi9 ;[5] (If I was doing CP/M, I would have
- cpi '|' ;[5] just eliminated all them funny chars
- jz cmifi9 ;[5] instead of a random selection)
-cmif7a: ;[5]
- cpi 'a' ;[pcc007] if not lower case its ok
- jm cmifi8 ;[pcc007] (DEL never gets here)
- cpi 'z'+1 ;[pcc007] only convert letters
- jp cmifi8 ;[pcc007]
- ani 137O ;Capitalize.
-cmifi8: lhld cmfcb2 ;Get the pointer into the FCB.
- mov m,a ;Put the char there.
- inx h
- shld cmfcb2
- inr e
- jmp cmifi1
-
-cmifi9: lda cmstat
- cpi cmifin ;"silent"?
- jz r ;Yes,let him go w/o check
- lxi d,cmer02
-cmif10: mvi c,prstr
- call bdos
- ret
-
-cmif11: lxi d,cmer03 ;Complain about wildcards.
- jmp cmif10
-
-;
-
-; copy filename from buffer
-; called with HL = destination, A = position (0-3) in buffer
-; called by: cmifil
-
-fspcop: push psw ;Save A.
- lxi d,buff ;Get the right offset in the buffer.
- rlc
- rlc
- rlc
- rlc
- rlc
- add e
- inr a ;Bypass drive spec.
- mov e,a
- mvi b,11 ;Copy file name.
-fspcp1: ldax d
- inx d
- mov m,a
- inx h
- dcr b
- jnz fspcp1
- pop psw ;Restore A.
- ret
-
-; append character in A to command buffer
-; called by: cmifil
-
-cmfput: push h ;Save H.
- lhld cmcptr ;Get buffer pointer.
- mov m,a ;Store in buffer.
- inx h
- shld cmcptr
- lxi h,cmccnt ;Count it.
- inr m
- pop h ;Restore H.
- ret
-;
-; Read characters from the command buffer.
-; called by: cmtext, cmcfrm, cmkeyw, cmifil
-
-cmgtch: push h
- push b
-cmgtc1: lda cmaflg
- ora a ;Is it set.
- cz cminbf ;If the action char flag is not set get more.
- lhld cmdptr ;Get a pointer into the buffer.
- mov a,m ;Get the next char.
- inx h
- shld cmdptr
- cpi ' ' ;Is it a space?
- jz cmgtc2
- cpi tab ;Or a tab?
- jnz cmgtc3
-cmgtc2: lda cmsflg ;Get the space flag.
- ora a ;Was the last char a space?
- jnz cmgtc1 ;Yes, get another char.
- mvi a,0FFH ;Set the space flag.
- sta cmsflg
- mvi a,' '
- pop b
- pop h
- jmp cmgtc5
-
-cmgtc3: push psw
- xra a
- sta cmsflg ;Zero the space flag.
- pop psw
- pop b
- pop h
- cpi esc
- jz cmgtc5
- cpi '?' ;Is the user curious?
- jz cmgtc4
- cpi cr
- jz cmgtc4
- cpi lf
- jz cmgtc4
- cpi ff
- rnz ;Not an action char, just return.
-cmgtc4: push h
- lhld cmdptr
- dcx h
- shld cmdptr
- pop h
-cmgtc5: ori 80H ;Make the char negative to indicate it is
- ret ;a terminator.
-;
-; Read characters from console into command buffer, processing
-; editing characters (^H, ^M, ^J, ^L, ^U, ^X, ?, del).
-; called by: comnd, cmgtch
-
-cminbf: push psw
- push d
- push h
- lda cmaflg ;Is the action char flag set?
- ora a
- jnz cminb9 ;If so get no more chars.
-cminb1: lxi h,cmccnt ;Increment the char count.
- inr m
- mvi c,conin ;Get a char.
- lda cmqflg ;[MF]but do we want it echoed?
- ora a ;[MF]...
- jz cmin1b ;[MF]Yup, proceed normally
-cmin1c: mvi e,0ffH ;[MF]Nope, do it with Direct
- mvi c,dconio ;[MF]Console I/O
- call bdos ;[MF]...
- ora a ;[MF]Did the user type anything?
- jz cmin1c ;[MF]No, don't go on until he/she does.
- jmp cmin1a ;[MF]We got a character
-cmin1b: call bdos
-cmin1a: lhld cmcptr ;Get the pointer into the buffer.
- mov m,a ;Put it in the buffer.
- inx h
- shld cmcptr
- cpi 25O ;Is it a ^U?
- jz cmnb12 ;Yes.
- cpi 30O ;Is it a ^X?
- jnz cminb2
-cmnb12: call clrlin ;Clear the line.
- call prprmp ;Print the prompt [Toad Hall]
- lxi h,cmdbuf
- shld cmcptr ;Reset the point to the start.
- lxi h,cmccnt ;Zero the count.
- mvi m,0
- jmp repars ;Go start over.
-
-cminb2: cpi 10O ;Backspace?
- jz cminb3
- cpi del ;or Delete?
- jnz cminb4
- lda cmqflg ;[MF]If we are echoing characters,
- ora a ;[MF]...
- cz delchr ;Print the delete string. [MF]
-cminb3: lda cmccnt ;Decrement the char count by two.
- dcr a
- dcr a
- ora a ;Have we gone too far?
- jp cmnb32 ;If not proceed.
- mvi c,conout ;Ring the bell.
- mvi e,bell
- call bdos
- jmp cmnb12 ;Go reprint prompt and reparse.
-
-cmnb32: sta cmccnt ;Save the new char count.
- lda cmqflg ;[MF]Echoing characters?
- ora a ;[MF]If we are, then
- cz clrspc ;Erase the character. [MF]
- lhld cmcptr ;Get the pointer into the buffer.
- dcx h ;Back up in the buffer.
- dcx h
- shld cmcptr
- jmp repars ;Go reparse everything.
-
-cminb4: cpi '?' ;Is it a question mark.
- jz cminb6
- cpi esc ;Is it an escape?
- jz cminb6
- cpi cr ;Is it a carriage return?
- jz cminb5
- cpi lf ;Is it a line feed?
- jz cminb5
- cpi ff ;Is it a formfeed?
- jnz cminb8 ;no - just store it and
- ;test if buffer overflowing, else get another character.
- call clrtop
-cminb5: lda cmbflg ;[MF]Allowing initial blank word (<cr>)?
- ora a ;[MF]...
- jnz cminb6 ;[MF]Yes
- lda cmccnt ;Have we parsed any chars yet?
- cpi 1
- jz prserr ;If not, just start over.
-cminb6: mvi a,0FFH ;Set the action flag.
- sta cmaflg
- jmp cminb9
-
-cminb8:
- lda cmccnt ; get the command character count
- cpi cmbufl ; check for comand buffer length
- jm cminb1 ; if less, then all ok
- mvi e,bell ; else beep at user
- call outcon ; send it to the console
- lda cmccnt ; back up one character
- dcr a
- sta cmccnt
- lhld cmcptr ; ditto pointer
- dcx h
- shld cmcptr ; save it again
- jmp cminb1 ; and try again
-
-cminb9: pop h
- pop d
- pop psw
- ret
-;
-;Little utility to print the prompt. (We do a LOT of these.) [Toad Hall]
-;Enters with nothing.
-;Destroys HL (and I suppose B and DE and A).
-
-prprmp: mvi e,cr ; do a cr first
- mvi c,dconio
- call bdos
- lhld cmprmp ;Get the prompt.
- xchg
- call prtstr
- ret
-
-; Little code to allow some expansion of code without changing
-; every futher address, only up to the end of this file.
-; TO BE REMOVED FOR RELEASE!
-
-; org ($+100h) AND 0FF00H
-
-
-IF lasm
-LINK CPSUTL
-ENDIF ;lasm [Toad Hall]
+; CPSCMD.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+;
+; This file provides a user oriented way of parsing commands.
+; It is similar to that of the COMND JSYS in TOPS-20.
+;
+; revision history (latest first):
+;
+;edit 13, 17-Jan-1991 by MF. Modified "cmifil" routine to zero the entire
+; fcb (not just the extent) to fix a bug in the COPY command which
+; prevented successive COPY commands from working properly.
+;edit 12, 16-Jan-1991 by MF. Modified routine "cmkeyw" to ignore leading
+; spaces/tabs before a keyword. This apparently was the intent in
+; "prompt" and "repars" (at least for command-lines) as the variable
+; "cmsflg "is set upon command parse and reparse. The intent was ,
+; subverted, however, as "cmkeyw" did not reset the flag to ignore
+; leading white space for each search thru the key tables (even though
+; the buffer pointer to the keyword entered was reset). The fix was
+; to reset the "spaces seen" flag (cmsflg) after "cmkey2" so that
+; it is reset each time a new table entry is compared to the text
+; the user has entered from the keyboard/TAKE-file etc. The upshot
+; of all this is that the kluge code in "cminbf" at "cminb0" designed
+; to force Kermit to ignore leading white space on command-lines in
+; TAKE-files and on the CP/M command-line is no longer needed and,
+; therefore, has been eliminated. Also modify "comnd" to expect leading
+; spaces for functions other than "get keyword".
+;edit 11, 26-Dec-1990 by MF. Modified routines to ignore leading white space
+; in lines from TAKE-files as well as during input from the CP/M
+; command-line (form-feeds are now considered white space under these
+; circumstances).
+;edit 10, 8-Sep-1990 by Mike Freeman. Modified routines to ignore leading
+; spaces/tabs when processing Kermit commands from the CP/M
+; command-line.
+; Added flag CMBFLG to allow initial word on a command-line
+; to be blank (useful for Remote commands such as Remote CWD etc).
+; Added flag cmqflg to prevent character-echoing while entering
+; commands so Remote CWD etc can have nonechoing password entry.
+; edit 9, 15 June, 1987 by OBSchou. Bug fixing to allow a second filename
+; (quiet) be entered as d:<blank>. Previous revision put the drive name
+; in first character of FCB, I put that character back to a space.
+;
+; edit 8, 12 June, 1987 by OBSchou. Addedin code in cmkeyw to print
+; 20 lines of help, then pause for a key from the user befor
+; proceeding with help.
+;
+; edit 7, 11 March, 1987 by OBSchou for Richard Russell, BBC. He writes:
+; Bug in cmtext which prevented use of octal characters (\nnn) fixed.
+;
+; edit 6, 18 June, 1986 by OBSchou, Loughborough University, Leics. UK
+; added code to parse a number from user input. Added check to make
+; sure the input command buffer does not overflow the limit.
+;
+; edit 5a: 7 March, 1986. OBSchou. Added stuff rom MJ Carter. He writes:
+; 7th May 85, MJ Carter [majoc], Nottingham University
+; Code in cmifil() put one too many spaces in the FCB; this caused
+; the BDOS of the British Micro Mimi to search for exteny 32,
+; rather than extent 0, so era() always said "can't find file"
+; Puttig a null at the point in question ought to fix 9 it.
+;
+; edit 5: 6-Feb-85 by Charles Carvalho
+; Make ffussy a runtime (rather than assembly-time) switch, to
+; eliminate conditional assembly in system-independent module.
+; Don't allow _%|()/\ in filenames if ffussy set; my CP/M manual
+; disallows those, too.
+;
+; edit 4: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
+;
+;pcc006 2-jan-85 VJC modules:cp4cmd,cp4utl
+; Problems with "?" in filespecs. On reparse, may cause action
+; flag to be reset at wrong point, requiring multiple <CR>'s
+; to terminate the line or other weird stuff. Also need to
+; check flag and complain if wild-cards illegal.
+
+;pcc007 2-Jan-85 vjc modules:cp4def,cp4cmd
+; Cmifil is too fussy about what characters to accept in a
+; filespec. My CP/M manual says any printable character is ok
+; except <>.,;:?*[], and lower case. In practice, even those work
+; sometimes. Kermit itself uses '&' if file warning is on,
+; and then won't let you reference the file. Allow all
+; printable characters except those above. Add conditional
+; ffussy, so that if not ffussy, all special characters will be
+; allowed, just convert lower to upper-case.
+
+; edit 3: July 8, 1984 (CJC)
+; integrate Toad Hall changes for LASM compatibility: CP4CPM is linked
+; by CP4WLD, and links CP4UTL.
+;
+; edit 2: June 5, 1984 (CJC)
+; formatting and documentation; delete unnecessary code at cminb7; add
+; module version string.
+;
+; edit 1: May, 1984 (CJC)
+; extracted from CPMBASE.M80 version 3.9; modifications are described in
+; the accompanying .UPD file.
+
+cmdver: db 'CPSCMD.ASM (13) 17-Jan-1991$' ; name, edit number, date
+
+; This routine prints the prompt in DE and specifies the reparse
+; address.
+; called by: kermit
+
+prompt: pop h ;Get the return address.
+ push h ;Put it on the stack again.
+ shld cmrprs ;Save it as the address to go to on reparse.
+ lxi h,0 ;Clear out hl pair.
+ dad sp ;Get the present stack pointer.
+ shld cmostp ;Save for later restoral.
+ xchg ;Save the pointer to the prompt.
+ shld cmprmp
+ xchg
+ lxi h,cmdbuf
+ shld cmcptr ;Initialize the command pointer.
+ shld cmdptr
+ xra a
+ sta cmaflg ;Zero the flags.
+ sta cmccnt
+; mvi a,0FFH ;Try it this way (Daphne.)
+; sta cmsflg
+ call prcrlf ;Print a CR/LF [Toad Hall]
+ jmp prprmp ;Print the prompt. [Toad Hall]
+;
+; This address is jumped to on reparse.
+; here from: cmcfrm, cmkeyw, cmifil, cminbf
+
+repars: lhld cmostp ;Get the old stack pointer.
+ sphl ;Make it the present one.
+ lxi h,cmdbuf
+ shld cmdptr
+; mvi a,0FFH ;Try it this way (Daphne.)
+; sta cmsflg
+ lhld cmrprs ;Get the reparse address.
+ pchl ;Go there.
+
+; This address can be jumped to on a parsing error.
+; here from: cmkeyw, cminbf
+
+prserr: lhld cmostp ;Get the old stack pointer.
+ sphl ;Make it the present one.
+ lxi h,cmdbuf
+ shld cmcptr ;Initialize the command pointer.
+ shld cmdptr
+ xra a
+ sta cmaflg ;Zero the flags.
+ sta cmccnt
+; mvi a,0FFH ;Try it this way (Daphne.)
+; sta cmsflg
+ call prcrlf ;Print a CR/LF [Toad Hall]
+ call prprmp ;Print the prompt [Toad Hall]
+;* Instead return to before the prompt call.
+ lhld cmrprs
+ pchl
+;
+; This routine parses the specified function in A. Any additional
+; information is in DE and HL.
+; Returns +1 on success
+; +4 on failure (assumes a JMP follows the call)
+; called by: log, setcom, read, send, xmit, dir, era, keycmd, cfmcmd
+; and CPSREM
+
+comnd: sta cmstat ;Save what we are presently parsing.
+ call cminbf ;Get chars until an action or a erase char.
+ push psw ;[MF]Save function
+ mvi a,0ffh ;[MF]Expect leading spaces
+ sta cmsflg ;[MF]...
+ pop psw ;[MF]Restore function
+ cpi cmcfm ;Parse a confirm?
+ jz cmcfrm ;Go get one.
+ cpi cmkey ;Parse a keyword?
+ jz cmkeyw ;Try and get one.
+ cpi cmifi ;Parse an input file spec?
+ jz cmifil ;Go get one.
+ cpi cmifin ;Input file-spec silent?
+ jz cmifil ;do as he wishes
+ cpi cmofi ;Output file spec?
+ jz cmofil ;Go get one.
+ cpi cmtxt ;Parse arbitrary text?
+ jz cmtext ;Go do it.
+ cpi cmnum ;[7] Parse a number?
+ jz cmnumb ;[7] go do it
+ lxi d,cmer00 ;"?Unrecognized COMND call"
+ call prtstr
+ ret
+;
+; This routine parses arbitrary text up to a CR.
+; Accepts DE: address to put text
+; Returns in A: number of chars in text (may be 0)
+; DE: updated pointer
+; called by: comnd
+
+cmtext: xra a ; clear counters erc for slashes etc
+ sta slshsn ; if we are in a slash sequence
+ sta slashn ; the octal number being entered
+ sta slashc ; number of characters entered
+
+ xchg ;Put the pointer to the dest in HL.
+ shld cmptab ;Save the pointer.
+ mvi b,0 ;Init the char count
+cmtxt1: call cmgtch ;Get a char.
+ ora a ;Terminator?
+ jp cmtx3 ;No, put in user space. [rtr] was cmtx5
+ ani 7FH ;Turn off minus bit.
+ cpi esc ;An escape?
+ jnz cmtxt2 ;No.
+ mvi c,conout
+ mvi e,bell ;Get a bell.
+ call bdos
+ xra a
+ sta cmaflg ;Turn off the action flag.
+ lhld cmcptr ;Move the pointer to before the escape.
+ dcx h
+ shld cmcptr
+ shld cmdptr
+ lxi h,cmccnt ;Get the char count.
+ dcr m ;Decrement it by one.
+ jmp cmtxt1 ;Try again.
+
+cmtxt2: cpi '?' ;Is it a question mark?
+ jz cmtxt4 ;If so put it in the text. [rtr] was cmtx3
+ cpi ff ;Is it a formfeed?
+ cz clrtop ;If so blank the screen.
+ mov a,b ;Return the count.
+ lhld cmptab ;Return updated pointer in HL.
+ xchg
+ jmp rskp ;Return success.
+
+cmtx3: cpi '\' ; slash?
+ jnz cmtx3a ; nope, so try something else
+ lda slshsn ; a slash already entered?
+ ana a
+ cma ;[rtr]
+ jnz cmtx3a ; yes, so assume its a valid slash to enter
+ sta slshsn ; make sure the flag is set for next time routnd
+ jmp cmtxt1 ; get another character
+
+cmtx3a:
+; lxi h,cmaflg ;Point to the action flag.
+; mvi m,0 ;Set it to zero.
+ mov e,a ; save it in case we are interpreting a slash
+ lda slshsn ; slash already entered?
+ ana a ; test flag
+ mov a,e ; restore it in case...
+ jz cmtx5 ; not a slash seen, so enter as a normal character
+ cpi '\'
+ jnz cmtx3b ; \\ not detected
+ lda slashn ; else get number
+ jmp cmtx5b ; and enter it ( in the case of \n or \nn)
+ ; here if an octal number of 1 or 2 digits
+ ; entered instead of 3, followed by \ again
+
+cmtx3b:
+ sui 30h ; else it should be an octal number
+ jm cmtxt6 ; if not a digit complain
+ cpi 8 ; ditto
+ jp cmtxt6 ;[rtr] was cmtxt
+ mov e,a ; else add it to the number already entered
+ lda slashn
+ add a
+ add a
+ add a ; multiply by 8
+ add e
+ sta slashn
+ lda slashc ; get the count
+ inr a
+ sta slashc ; plus one. If three then a number entered
+ cpi 3
+ lda slashn ; get the number in case...
+ jz cmtx5
+ jmp cmtxt1 ; else loop
+
+cmtxt4: lhld cmdptr ;[rtr] Get a pointer into the buffer
+ inx h ;[rtr] Bump past '?'
+ shld cmdptr ;[rtr]
+cmtx5: call cmtx5c
+ jmp cmtxt1 ; put this into a subroutine
+
+cmtx5b:
+ call cmtx5c ; here if we see \n\ or \nn\ rather than \nnn\
+ mvi a,'\' ; so send slash number to buffer,
+ sta slshsn ; re-store a slash seen
+ jmp cmtxt1 ; try next one
+
+cmtx5c:
+ inr b ;Increment the count.
+ lhld cmptab ;Get the pointer.
+ mov m,a ;Put the char in the array.
+ inx h
+ shld cmptab ;Save the updated pointer.
+ xra a ; clear slash counters etc
+ sta slashc
+ sta slashn
+ sta slshsn
+ ret ; and exit
+
+cmtxt6: lxi d,cmer05 ; complain - not a valid \ parameter
+ call prtstr
+ jmp kermit ; and try another command
+ ds 20h ; for debugging
+;
+; This routine gets a number from user input.
+; Called by: comnd
+;
+cmnumb: lxi h,0 ; make sure the number is zero to start with
+ shld number
+cmnum0: call cmgtch ; get another character
+ ora a ; if negative then its an action
+ jp cmnum1 ; nope, so (possibly) valid input
+ ani 7fh ; else lets see what it is...
+ cpi esc ; do not know what to do with this one...
+ cpi ' ' ; if it is a space then either a return or more
+ jnz cmnum2 ; else
+ jmp rskp ; space is a deliminter
+ dw 0 ; set three bytes aside for a jump/call
+ dw 0 ; and then another three just in case...
+ dw 0 ; making 6 bytes
+cmnum2: cpi '?' ; user is curious
+ jz gnum2
+ cpi cr ; end of input?
+ jz cmnumx
+gnum1: jmp prserr ; did not under stand this, so error
+cmnumx: dw 0
+ dw 0
+ jmp rskp ; return ok
+
+gnum2: lhld number ; get the number.. if at all entered
+ mov a,l
+ ora h ; if hl = 0 then possibly no number entered
+ lxi d,cmin02 ; say confirm...or more on line
+ jnz gnum21 ; else say enter a return
+ lxi d,cmin01 ; say enter a number
+gnum21: call prtstr ; say it
+ call prcrlf ; do a lf
+ call prprmp ; another reprompt
+ lhld cmdptr ; get pointer of string already entered
+ mvi m,'$' ; dollar it to set end of line
+ lhld cmcptr
+ dcx h ; decrement and save the buffer pointer
+ shld cmcptr
+ lxi d,cmdbuf
+ call prtstr ; print what has already been entered
+ xra a
+ sta cmaflg ; turn the action flag off
+ jmp repars ; and try again
+
+ mvi a,cmcfm ; parse a confirm
+dw 0
+dw 0
+dw 0
+dw 0
+dw 0 ; some space to patch...
+dw 0
+
+cmnum1: ani 7fh ; here for a (potentially) valid number
+ sui '0' ; less ascii bias
+ jc gnum3
+ cpi 10 ; if 10 or more its still bad
+ jnc gnum3
+ cmc
+ lhld number ; now multiply number by ten and add the new value
+ push h
+ pop d
+ dad h ; hl = hl * 2
+ dad h ; * 4
+ dad d ; * 5
+ dad h ; * 10
+ mvi d,0
+ mov e,a ; add de to hl...
+ dad d
+ shld number
+ jmp cmnum0
+;
+gnum3: lxi d,cmer04 ; invalid number...
+ call prtstr
+ jmp rskp
+;
+
+;
+; This routine gets a confirm.
+; called by: comnd
+
+cmcfrm: call cmgtch ;Get a char.
+ ora a ;Is it negative (a terminator;a space or
+ ;a tab will not be returned here as they
+ ;will be seen as leading white space.)
+ rp ;If not, return failure.
+ ani 7FH ;Turn off the minus bit.
+ cpi esc ;Is it an escape?
+ jnz cmcfr2
+ mvi c,conout
+ mvi e,bell ;Get a bell.
+ call bdos
+ xra a
+ sta cmaflg ;Turn off the action flag.
+ lhld cmcptr ;Move the pointer to before the escape.
+ dcx h
+ shld cmcptr
+ shld cmdptr
+ lxi h,cmccnt ;Get the char count.
+ dcr m ;Decrement it by one.
+ jmp cmcfrm ;Try again.
+
+cmcfr2: cpi '?' ;Curious?
+ jnz cmcfr3
+ lxi d,cmin00 ;Print something useful.
+ call prtstr
+ call prcrlf ;Print a crlf. [Toad Hall]
+ call prprmp ;Reprint the prompt [Toad Hall]
+ lhld cmdptr ;Get the pointer into the buffer.
+ mvi a,'$' ;Put a $ there for printing.
+ mov m,a
+ lhld cmcptr
+ dcx h ;Decrement and save the buffer pointer.
+ shld cmcptr
+ lxi d,cmdbuf
+ call prtstr
+ xra a ;Turn off the action flag.
+ sta cmaflg
+ jmp repars ;Reparse everything.
+
+cmcfr3: cpi ff ;Is it a form feed?
+ cz clrtop ;If so blank the screen.
+ jmp rskp
+;
+; This routine parses a keyword from the table pointed
+; to in DE. The format of the table is as follows:
+;
+; addr: db n ;Where n is the # of entries in the table.
+; db m ;M is the size of the keyword.
+; db 'string$' ;Where string is the keyword.
+; db a,b ;Where a & b are pieces of data
+; ;to be returned. (Must be two of them.)
+;
+; The keywords must be in alphabetical order.
+;**** Note: The data value a is returned in registers A and E. The
+;**** data value b is returned in register D. This allows the two data
+; bytes to be stored as:
+; dw xxx
+; and result in a correctly formatted 16-bit value in register pair
+; DE.
+; called by: comnd
+
+cmkeyw: shld cmhlp ;Save the help.
+ xchg ;Get the address of the table.
+ shld cmptab ;Save the beginning of keyword tab for '?'.
+ mov b,m ;Get the number of entries in the table.
+ inx h
+ shld cmkptr
+ lhld cmdptr ;Save the command pointer.
+ shld cmsptr
+cmkey2: mov a,b ;Get the number of entries left.
+ ora a ;Any left?
+ rz ;If not we failed.
+ mvi a,0ffh ;[MF]Make sure we ignore leading spaces
+ sta cmsflg ;[MF]...
+ lhld cmkptr
+ mov e,m ;Get the length of the keyword.
+ inx h
+cmkey3: dcr e ;Decrement the number of chars left.
+ mov a,e
+ cpi 0FFH ;Have we passed the end?
+ jm cmkey5 ;If so go to the next.
+ call cmgtch ;Get a char.
+ ora a ;Is it a terminator?
+ jp cmkey4 ;If positive, it is not.
+ ani 7FH ;Turn off the minus bit.
+ cpi '?'
+ jnz cmky31
+ xra a
+ sta cmaflg ;Turn off the action flag.
+ lxi h,cmccnt ;Decrement the char count.
+ dcr m
+;* Must go through the keyword table and print them.
+ lhld cmhlp ;For now print the help text.
+ xchg
+ call p20ln ;[8] print at most 20 lines then pause
+; call prtstr
+ call prcrlf ;Print a crlf [Toad Hall]
+ call prprmp ;Reprint the prompt [Toad Hall]
+ lhld cmdptr ;Get the pointer into the buffer.
+ mvi a,'$' ;Put a $ there for printing.
+ mov m,a
+ lhld cmcptr
+ dcx h ;Decrement and save the buffer pointer.
+ shld cmcptr
+ lxi d,cmdbuf
+ call prtstr
+ jmp repars ;Reparse everything.
+
+cmky31: cpi esc ;Is it an escape?
+ jnz cmky35
+ xra a
+ sta cmaflg ;Turn off the action flag.
+ push d
+ push b
+ push h
+ call cmambg
+ jmp cmky32 ;Not ambiguous.
+ mvi c,conout
+ mvi e,bell
+ call bdos ;Ring the bell.
+ lhld cmcptr ;Move the pointer to before the escape.
+ dcx h
+ shld cmcptr
+ shld cmdptr
+ lxi h,cmccnt ;Get the char count.
+ dcr m ;Decrement it by one.
+ pop h
+ pop b
+ pop d
+ inr e ;Increment the left to parse char count.
+ jmp cmkey3
+
+cmky32: lhld cmcptr ;Pointer into buffer.
+ dcx h ;Backup to the escape.
+ xchg
+ pop h
+ push h
+cmky33: mov a,m ;Get the next char.
+ cpi '$' ;Finished?
+ jz cmky34
+ inx h
+ xchg
+ mov m,a ;Move it into the buffer.
+ inx h
+ xchg
+ lda cmccnt ;Increment the char count.
+ inr a
+ sta cmccnt
+ jmp cmky33
+
+cmky34: lda cmccnt ;Get the character count.
+ inr a ;Increment and save it.
+ sta cmccnt
+ xchg ;Put the command buffer pointer in HL.
+ mvi a,' ' ;Get a blank.
+ mov m,a ;Put it in the command buffer.
+ inx h ;Increment the pointer
+ shld cmcptr ;Save the updated pointer.
+ shld cmdptr
+ pop h
+ push h
+ xchg
+ call prtstr ;Print the rest of the keyword.
+ mvi c,conout
+ mvi e,' '
+ call bdos ;Print a blank.
+ pop h
+ pop b
+ pop d
+ jmp cmky37
+
+cmky35: push h
+ push d
+ call cmambg
+ jmp cmky36
+ lxi d,cmer01
+ call prtstr ;Say its ambiguous.
+ jmp prserr ;Give up.
+
+cmky36: pop d
+ pop h
+cmky37: inr e ;Add one incase it is negative.
+ mvi d,0
+ dad d ;Increment past the keyword.
+ inx h ;Past the $.
+ mov e,m ;Get the data.
+ inx h
+ mov d,m
+ mov a,e
+ jmp rskp
+
+cmkey4: cpi 'a' ;Is it less than a?
+ jm cmky41 ;If so don't capitalize it.
+ cpi 'z'+1 ;Is it more than z?
+ jp cmky41 ;If so don't capitalize it.
+ ani 137O ;Capitalize it.
+cmky41: mov d,m ;Get the next char of the keyword.
+ inx h
+ cmp d ;Match?
+ jz cmkey3 ;If so get the next letter.
+
+cmkey5: mvi d,0
+ mov a,e ;Get the number of chars left.
+ ora a ;Is it negative?
+ jp cmky51
+ mvi d,0FFH ;If so, sign extend.
+cmky51: dad d ;Increment past the keyword.
+ lxi d,0003H ;Plus the $ and data.
+ dad d
+ shld cmkptr
+ dcr b ;Decrement the number of entries left.
+ lhld cmsptr ;Get the old cmdptr.
+ shld cmdptr ;Restore it.
+;* check so we don't pass it.
+ jmp cmkey2 ;Go check the next keyword.
+;
+; Test keyword for ambiguity.
+; returns: nonskip if ambiguous, skip if OK.
+; called by: cmkeyw
+
+cmambg: dcr b ;Decrement the number of entries left.
+ rm ;If none left then it is not ambiguous.
+ inr e ;This is off by one;adjust.
+ mov c,e ;Save the char count.
+ mov a,e
+ ora a ;Any chars left?
+ rz ;No, it can't be ambiguous.
+ mvi d,0
+ dad d ;Increment past the keyword.
+ mvi e,3 ;Plus the $ and data.
+ dad d
+ mov b,m ;Get the length of the keyword.
+ inx h
+ xchg
+ lhld cmkptr ;Get pointer to keyword entry.
+ mov a,m ;Get the length of the keyword.
+ sub c ;Subtract how many left.
+ mov c,a ;Save the count.
+ cmp b
+ jz cmamb0
+ rp ;If larger than the new word then not amb.
+cmamb0: lhld cmsptr ;Get the pointer to what parsed.
+cmamb1: dcr c ;Decrement the count.
+ jm rskp ;If we are done then it is ambiguous.
+ xchg ;Exchange the pointers.
+ mov b,m ;Get the next char of the keyword
+ inx h
+ xchg ;Exchange the pointers.
+ mov a,m ;Get the next parsed char.
+ inx h
+ cpi 'a' ;Is it less than a?
+ jm cmamb2 ;If so don't capitalize it.
+ cpi 'z'+1 ;Is it more than z?
+ jp cmamb2 ;If so don't capitalize it.
+ ani 137O
+cmamb2: cmp b ;Are they equal?
+ rnz ;If not then its not ambiguous.
+ jmp cmamb1 ;Check the next char.
+;
+; cmofil - parse output filespec
+; cmifil - parse input filespec
+; here from: comnd
+
+cmofil: mvi a,0 ;Don't allow wildcards.
+; jmp cmifil ;For now, the same as CMIFI.
+cmifil: sta cmfwld ;Set wildcard flag
+ xchg ;Get the fcb address.
+ shld cmfcb ;Save it.
+ mvi e,0 ;Initialize char count.
+ mvi m,0 ;Set the drive to default to current.
+ inx h
+ shld cmfcb2
+ xra a ;Initialize counter.
+cmifi0: mvi m,' ' ;Blank the FCB.
+ inx h
+ inr a
+; cpi 0CH ;Twelve? [5a dont use this]
+ cpi 0Bh ; [majoc 850585] Eleven?
+ jm cmifi0
+cmif0a: ;[MF]Zero entire fcb, not just the extent
+ mvi m,0 ; [majoc 850507] Specify extent 0
+ inx h ;[MF]Increment fcb byte pointer
+ inr a ;[MF]Increment fcb byte count
+ cpi 32 ;[MF]Done with fcb?
+ jm cmif0a ;[MF]No, zero until done
+cmifi1: call cmgtch ;Get another char.
+ ora a ;Is it an action character?
+ jp cmifi2
+ ani 7FH ;Turn off the action bit.
+ cpi '?' ;A question mark?
+ jnz cmif12
+ lda cmfwld ;[pcc006] Wildcards allowed?
+ ora a ;[pcc006]
+ jz cmif11 ;[pcc006] complain if not
+ lhld cmdptr ;[jd] Increment buffer pointer
+ inx h ;[jd] that was decremented in cmgtch
+ shld cmdptr ;[jd] since we want this chr
+ lda cmcptr ;[pcc006] get lsb of real input pointer
+ cmp l ;[pcc006] is this the last chr input?
+ jnz cmif1a ;[pcc006] no, don't reset action flag
+ xra a ;[pcc006] yes, reset action flag
+ sta cmaflg ;[pcc006]
+cmif1a: mvi a,'?' ;[pcc006] get it back in A
+ jmp cmifi8 ;Treat like any other character
+
+cmif12: cpi esc ;An escape?
+ jnz cmif13
+;Try to recognize file-spec a'la TOPS-20
+ xra a
+ sta cmaflg ;Turn off the action flag.
+ lhld cmcptr ;Move the pointer to before the escape.
+ dcx h
+ shld cmcptr
+ shld cmdptr
+ lxi h,cmccnt ;Get the char count.
+ dcr m ;Decrement it by one.
+ mov a,e ;Save character count up to now.
+ sta temp1
+ cpi 9 ;Past '.'?
+ jm cmfrec ;No.
+ dcr a ;Yes, don't count point.
+cmfrec: lhld cmfcb2 ;Fill the rest with CP/M wildcards.
+cmfrc1: cpi 11 ;Done?
+ jp cmfrc2 ;Yes.
+ mvi m,'?'
+ inx h
+ inr a
+ jmp cmfrc1
+
+cmfrc2: mvi c,sfirst ;Find first matching file?
+ lhld cmfcb
+ xchg
+ call bdos
+ cpi 0FFH
+ jz cmfrc9 ;No, lose.
+ lxi h,fcbblk ;Copy first file spec.
+ call fspcop
+ lxi h,fcbblk+10H ;Get another copy (in case not ambiguous).
+ call fspcop
+ mvi c,snext ;More matching specs?
+ lhld cmfcb
+ xchg
+ call bdos
+ cpi 0FFH
+ jz cmfrc3 ;Only one.
+ lxi h,fcbblk+10H ;Copy second file spec.
+ call fspcop
+cmfrc3: lxi d,fcbblk ;Start comparing file names.
+ lxi h,fcbblk+10H
+ lda temp1 ;Bypass characters typed.
+ cpi 9 ;Past '.'?
+ jm cmfrc4 ;No.
+ dcr a ;Yes, don't count point.
+cmfrc4: mvi c,0
+cmfrl1: cmp c ;Bypassed?
+ jz cmfrl2 ;Yes.
+ inx d
+ inx h
+ inr c
+ jmp cmfrl1 ;Repeat.
+
+cmfrl2: mov a,c ;Get file name characters processed.
+ cpi 11 ;All done?
+ jz cmfrc5 ;Yes.
+ cpi 8 ;End of file name?
+ jnz cmfrl3 ;No.
+ lda temp1 ;Exactly at point?
+ cpi 9
+ jz cmfrl3 ;Yes, don't output a second point.
+ mvi a,'.' ;Output separator.
+ call cmfput
+cmfrl3: ldax d ;Get a character from first file spec.
+ inx d
+ mov b,m ;Get from second file spec.
+ inx h
+ cmp b ;Compare.
+ jnz cmfrc5 ;Ambiguous.
+ inr c ;Same, count.
+ cpi ' ' ;Blank?
+ jz cmfrl2 ;Yes, don't output.
+ call cmfput ;Put character into buffer.
+ jmp cmfrl2 ;Repeat.
+
+cmfrc5: mov a,c ;Get count of characters processed.
+ sta temp1 ;Save it.
+ mvi a,'$' ;Get terminator.
+ call cmfput ;Put it into buffer.
+ lhld cmdptr ;Output recognized characters.
+ xchg
+ mvi c,prstr
+ call bdos
+ lhld cmcptr ;Remove terminator from buffer.
+ dcx h
+ shld cmcptr
+ lxi h,cmccnt
+ dcr m
+ lda temp1 ;Characters processed.
+ cpi 11 ;Complete file name.
+ jz repars ;Yes, don't beep.
+
+cmfrc9: mvi c,conout
+ mvi e,bell
+ call bdos ;Ring the bell.
+ jmp repars
+;
+; Continue file spec parsing.
+
+cmif13: mov a,e ;It must be a terminator.
+ ora a ;Test the length of the file name.
+ jz cmifi9 ;If zero complain.
+ cpi 0DH
+ jp cmifi9 ;If too long complain.
+ jmp rskp ;Otherwise we have succeeded.
+
+cmifi2: cpi '.'
+ jnz cmifi3
+ inr e
+ mov a,e
+ cpi 1H ;Any chars yet?
+ jz cmifi9 ;No, give error.
+ cpi 0AH ;Tenth char?
+ jp cmifi9 ;Past it, give an error.
+ mvi c,9H
+ mvi b,0
+ lhld cmfcb
+ dad b ;Point to file type field.
+ shld cmfcb2
+ mvi e,9H ;Say we've gotten nine.
+ jmp cmifi1 ;Get the next char.
+
+cmifi3: cpi ':'
+ jnz cmifi4
+ inr e
+ mov a,e
+ cpi 2H ;Is it in the right place for a drive?
+ jnz cmifi9 ;If not, complain.
+ lhld cmfcb2
+ dcx h ;Point to previous character.
+ mov a,m ;Get the drive name.
+ sui '@' ;Get the drive number.
+ shld cmfcb2 ;Save pointer to beginning of name field.
+ mvi m,space ;[obs] restore a space in FCB
+ dcx h ;Point to drive number.
+ mov m,a ;Put it in the fcb.
+ mvi e,0 ;Start character count over.
+ jmp cmifi1
+
+cmifi4: cpi '*'
+ jnz cmifi7
+ lda cmfwld ;Wildcards allowed?
+ cpi 0
+ jz cmif11 ;No,complain
+ mov a,e
+ cpi 8H ;Is this in the name or type field?
+ jz cmifi9 ;If its where the dot should be give up.
+ jp cmifi5 ;Type.
+ mvi b,8H ;Eight chars.
+ jmp cmifi6
+
+cmifi5: mvi b,0CH ;Three chars.
+cmifi6: lhld cmfcb2 ;Get a pointer into the FCB.
+ mvi a,'?'
+ mov m,a ;Put a question mark in.
+ inx h
+ shld cmfcb2
+ inr e
+ mov a,e
+ cmp b
+ jm cmifi6 ;Go fill in another.
+ jmp cmifi1 ;Get the next char.
+
+cmifi7: cpi '!' ;[pcc007] control chr or space?
+ jm cmifi9 ;[pcc007] yes, illegal
+ mov h,a ;[5] stash input char for a bit
+ lda ffussy ;[5] while we check the fussy flag
+ ora a ;[5] set the flags accordingly
+ mov a,h ;[5] restore the input character
+ jz cmif7a ;[5] if ffussy=0, allow <>.,;:?*[]
+;[5] So far, we've eliminated "action characters" (including question),
+;[5] period, colon, asterisk, control characters, and space.
+;[5] That leaves us %(),/;<=>[\]_| to check for.
+ cpi '%' ;[5]
+ jz cmifi9 ;[5]
+ cpi '(' ;[5]
+ jz cmifi9 ;[5]
+ cpi ')' ;[5]
+ jz cmifi9 ;[5]
+ cpi ',' ;[pcc007] weed out comma
+ jz cmifi9 ;[pcc007]
+ cpi '/' ;[5]
+ jz cmifi9 ;[5]
+ cpi '9'+1 ;[pcc007] anything else 21H-39H is ok
+ jm cmifi8 ;[pcc007] except '*' never gets here
+ cpi '@' ;[pcc007] all of 3AH-3FH is illegal
+ jm cmifi9 ;[pcc007]
+ cpi '[' ;[pcc007] [\] also illegal
+ jm cmifi8 ;[pcc007]
+ cpi ']'+1 ;[pcc007]
+ jm cmifi9 ;[pcc007]
+ cpi '_' ;[5]
+ jz cmifi9 ;[5] (If I was doing CP/M, I would have
+ cpi '|' ;[5] just eliminated all them funny chars
+ jz cmifi9 ;[5] instead of a random selection)
+cmif7a: ;[5]
+ cpi 'a' ;[pcc007] if not lower case its ok
+ jm cmifi8 ;[pcc007] (DEL never gets here)
+ cpi 'z'+1 ;[pcc007] only convert letters
+ jp cmifi8 ;[pcc007]
+ ani 137O ;Capitalize.
+cmifi8: lhld cmfcb2 ;Get the pointer into the FCB.
+ mov m,a ;Put the char there.
+ inx h
+ shld cmfcb2
+ inr e
+ jmp cmifi1
+
+cmifi9: lda cmstat
+ cpi cmifin ;"silent"?
+ jz r ;Yes,let him go w/o check
+ lxi d,cmer02
+cmif10: mvi c,prstr
+ call bdos
+ ret
+
+cmif11: lxi d,cmer03 ;Complain about wildcards.
+ jmp cmif10
+
+;
+
+; copy filename from buffer
+; called with HL = destination, A = position (0-3) in buffer
+; called by: cmifil
+
+fspcop: push psw ;Save A.
+ lxi d,buff ;Get the right offset in the buffer.
+ rlc
+ rlc
+ rlc
+ rlc
+ rlc
+ add e
+ inr a ;Bypass drive spec.
+ mov e,a
+ mvi b,11 ;Copy file name.
+fspcp1: ldax d
+ inx d
+ mov m,a
+ inx h
+ dcr b
+ jnz fspcp1
+ pop psw ;Restore A.
+ ret
+
+; append character in A to command buffer
+; called by: cmifil
+
+cmfput: push h ;Save H.
+ lhld cmcptr ;Get buffer pointer.
+ mov m,a ;Store in buffer.
+ inx h
+ shld cmcptr
+ lxi h,cmccnt ;Count it.
+ inr m
+ pop h ;Restore H.
+ ret
+;
+; Read characters from the command buffer.
+; called by: cmtext, cmcfrm, cmkeyw, cmifil
+
+cmgtch: push h
+ push b
+cmgtc1: lda cmaflg
+ ora a ;Is it set.
+ cz cminbf ;If the action char flag is not set get more.
+ lhld cmdptr ;Get a pointer into the buffer.
+ mov a,m ;Get the next char.
+ inx h
+ shld cmdptr
+ cpi ' ' ;Is it a space?
+ jz cmgtc2
+ cpi tab ;Or a tab?
+ jnz cmgtc3
+cmgtc2: lda cmsflg ;Get the space flag.
+ ora a ;Was the last char a space?
+ jnz cmgtc1 ;Yes, get another char.
+ mvi a,0FFH ;Set the space flag.
+ sta cmsflg
+ mvi a,' '
+ pop b
+ pop h
+ jmp cmgtc5
+
+cmgtc3: push psw
+ xra a
+ sta cmsflg ;Zero the space flag.
+ pop psw
+ pop b
+ pop h
+ cpi esc
+ jz cmgtc5
+ cpi '?' ;Is the user curious?
+ jz cmgtc4
+ cpi cr
+ jz cmgtc4
+ cpi lf
+ jz cmgtc4
+ cpi ff
+ rnz ;Not an action char, just return.
+cmgtc4: push h
+ lhld cmdptr
+ dcx h
+ shld cmdptr
+ pop h
+cmgtc5: ori 80H ;Make the char negative to indicate it is
+ ret ;a terminator.
+;
+; Read characters from console into command buffer, processing
+; editing characters (^H, ^M, ^J, ^L, ^U, ^X, ?, del).
+; called by: comnd, cmgtch
+
+cminbf: push psw
+ push d
+ push h
+ lda cmaflg ;Is the action char flag set?
+ ora a
+ jnz cminb9 ;If so get no more chars.
+cminb1: lxi h,cmccnt ;Increment the char count.
+ inr m
+ mvi c,conin ;Get a char.
+ lda cmqflg ;[MF]but do we want it echoed?
+ ora a ;[MF]...
+ jz cmin1b ;[MF]Yup, proceed normally
+cmin1c: mvi e,0ffH ;[MF]Nope, do it with Direct
+ mvi c,dconio ;[MF]Console I/O
+ call bdos ;[MF]...
+ ora a ;[MF]Did the user type anything?
+ jz cmin1c ;[MF]No, don't go on until he/she does.
+ jmp cmin1a ;[MF]We got a character
+cmin1b: call bdos
+cmin1a: lhld cmcptr ;Get the pointer into the buffer.
+ mov m,a ;Put it in the buffer.
+ inx h
+ shld cmcptr
+ cpi 25O ;Is it a ^U?
+ jz cmnb12 ;Yes.
+ cpi 30O ;Is it a ^X?
+ jnz cminb2
+cmnb12: call clrlin ;Clear the line.
+ call prprmp ;Print the prompt [Toad Hall]
+ lxi h,cmdbuf
+ shld cmcptr ;Reset the point to the start.
+ lxi h,cmccnt ;Zero the count.
+ mvi m,0
+ jmp repars ;Go start over.
+
+cminb2: cpi 10O ;Backspace?
+ jz cminb3
+ cpi del ;or Delete?
+ jnz cminb4
+ lda cmqflg ;[MF]If we are echoing characters,
+ ora a ;[MF]...
+ cz delchr ;Print the delete string. [MF]
+cminb3: lda cmccnt ;Decrement the char count by two.
+ dcr a
+ dcr a
+ ora a ;Have we gone too far?
+ jp cmnb32 ;If not proceed.
+ mvi c,conout ;Ring the bell.
+ mvi e,bell
+ call bdos
+ jmp cmnb12 ;Go reprint prompt and reparse.
+
+cmnb32: sta cmccnt ;Save the new char count.
+ lda cmqflg ;[MF]Echoing characters?
+ ora a ;[MF]If we are, then
+ cz clrspc ;Erase the character. [MF]
+ lhld cmcptr ;Get the pointer into the buffer.
+ dcx h ;Back up in the buffer.
+ dcx h
+ shld cmcptr
+ jmp repars ;Go reparse everything.
+
+cminb4: cpi '?' ;Is it a question mark.
+ jz cminb6
+ cpi esc ;Is it an escape?
+ jz cminb6
+ cpi cr ;Is it a carriage return?
+ jz cminb5
+ cpi lf ;Is it a line feed?
+ jz cminb5
+ cpi ff ;Is it a formfeed?
+ jnz cminb8 ;no - just store it and
+ ;test if buffer overflowing, else get another character.
+ call clrtop
+cminb5: lda cmbflg ;[MF]Allowing initial blank word (<cr>)?
+ ora a ;[MF]...
+ jnz cminb6 ;[MF]Yes
+ lda cmccnt ;Have we parsed any chars yet?
+ cpi 1
+ jz prserr ;If not, just start over.
+cminb6: mvi a,0FFH ;Set the action flag.
+ sta cmaflg
+ jmp cminb9
+
+cminb8:
+ lda cmccnt ; get the command character count
+ cpi cmbufl ; check for comand buffer length
+ jm cminb1 ; if less, then all ok
+ mvi e,bell ; else beep at user
+ call outcon ; send it to the console
+ lda cmccnt ; back up one character
+ dcr a
+ sta cmccnt
+ lhld cmcptr ; ditto pointer
+ dcx h
+ shld cmcptr ; save it again
+ jmp cminb1 ; and try again
+
+cminb9: pop h
+ pop d
+ pop psw
+ ret
+;
+;Little utility to print the prompt. (We do a LOT of these.) [Toad Hall]
+;Enters with nothing.
+;Destroys HL (and I suppose B and DE and A).
+
+prprmp: mvi e,cr ; do a cr first
+ mvi c,dconio
+ call bdos
+ lhld cmprmp ;Get the prompt.
+ xchg
+ call prtstr
+ ret
+
+; Little code to allow some expansion of code without changing
+; every futher address, only up to the end of this file.
+; TO BE REMOVED FOR RELEASE!
+
+; org ($+100h) AND 0FF00H
+
+
+IF lasm
+LINK CPSUTL
+ENDIF ;lasm [Toad Hall]
diff --git a/cpscom.asm b/cpscom.asm
index 7f2a57a..a74df7e 100644
--- a/cpscom.asm
+++ b/cpscom.asm
@@ -1,1371 +1,1371 @@
-; CPSCOM.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains some of the main loop commands, all SET xxx and
-; status routines. File split from CPSMIT.ASM as that file
-; was getting too big.
-;
-; revision history:
-;
-;edit 13, 25-Mar-1991 by MF. Require confirmation if a STAY command
-; (code at "noexit") is given and a question-mark is entered.
-;edit 12, 21-Mar-1991 by MF. Change SET COLLISSION REPLACE to
-; SET COLLISION OVERWRITE to conform with C-Kermit. Modify SET COLLISION
-; help text slightly.
-
-;edit 11, 27-Feb-1991 by MF. Show Kermit version in VERSION command
-; ("shover").
-;edit 10, 12-Feb-1991 by MF. Modified OUTPUT command to get a "confirm"
-; after accepting the string to be output so that the OUTPUT command
-; doesn't immediately execute if a terminator other than <cr> is typed
-; (immediate execution confuses some users new to Kermit). This
-; situation should seldom, if ever, occur, as the OUTPUT command
-; is most likely to be executed in a TAKE-file but one should
-; protect oneself, shouldn't one?
-; Also commented out case-sensivity code as it is unlikely to be used.
-;edit 9, 4-Dec-1990 by MF. Add "stautr" routine to display Autoreceive
-; status in SHOW/STATUS/<ESC>S commands.
-;edit 8, 30-Nov-1990 by MF. Modify routine "statvt" (terminal status) to
-; display setting of "quiet" switch. Although I presume that Mr.
-; Schou thought the code would accommodate display of QUIET or
-; REGULAR, the code does not in fact allow this since the emulation
-; flag is not involved in the "quiet" setting.
-; Also fix SET TERMINAL's help text a bit.
-;edit 7, 8-Nov-1990 by MF. In SET {RECEIVE/SEND} PACKET-LENGTH routines,
-; call utility routine subbc from CPSUTL.ASM to do 16-bit subtraction
-; rather than doing it in-line to save a few bytes. Eliminate
-; commented-out instructions.
-;edit 6, 1-Nov-1990 by MF. Changed SET BAUD-RATE to SET SPEED in the quest
-; for uniformity of nomenclature (per request of FDC).
-;edit 5, 17-Oct-1990 by MF. Change SET {RECEIVE SEND} PACKET-SIZE to
-; SET {RECEIVE SEND} PACKET-LENGTH to conform with the nomenclature
-; suggested in Chapter 10 of the 6th edition of the Kermit Protocol
-; Manual.
-;edit 4, 14-Sep-1990 by MF. Implemented SET FILE-COLLISION (SET COLLISION)
-; command (except for SET COLLISION ASK and SET COLLISION APPEND).
-; How one APPENDs to a CP/M file depends upon whether it's ASCII or
-; BINARY -- something we may not know.
-; Also implemented SET INCOMPLETE-FILE command.
-; Let's also restore SET FILE-MODE DEFAULT: I never use it but if
-; we leave the DEFAULT code, as Version 4.09 does, the user is entitled
-; to be able to select it if he/she wishes (I'd favor getting rid
-; of it altogether but as soon as I did that, someone'd come out
-; of the woodwork and complain vehemently that he/she **likes**
-; SET FILE-MODE DEFAULT and would the so-and-so who took it out
-; please put it back in. Such is life. In any case, the user can
-; always set the file-mode from a take-file.
-;edit 3, 9-Sep-1990 by MF. Implemented setting of packet sizes for
-; packets up thru length 94 characters for SEND and RECEIVE. Even
-; for standard-length packets, variable sizes are useful.
-; Correct 16-bit subtraction in stspks/strpks to set carry if needed
-; Also corrected bug in routine getnp wherein a JMP KERMIT
-; instruction was left out after trying to parse a confirm, thus
-; skipping loading of number into HL.
-; Fixed bug in PRTSTR wherein BC/HL were not saved under certain
-; conditions, thus causing garbage to appear when PRTSTR was
-; called with QUIETD set.
-; edit 2, September 10, 1987, by OBSchou. Changed SET IBM to reset the
-; flow control flag. IBMs use 13h as a turnaround character (so they
-; say) so no flow control. Anybody willing to add comments etsc, as I
-; have NO IDEA what IBMs do or need.
-; Also removed the SET FILE-MODE DEFAULT option, as it always causes
-; so much trouble. Assume the default mode to be ASCII. Moved a test
-; for key pressed from the status routine to the CPSUTL file.
-;
-; edit 1, April 8th, 1987.
-; Hived off the SET command etc from CPSMIT.ASM to
-; make a more manageable file
-
-
-comver: db 'CPSCOM.ASM (13) 25-Mar-1991$' ;name, edit no. and date
-;
-;
-; This is the SET command.
-
-setcom: lxi d,settab ;Parse a keyword from the set table.
- lxi h,sethlp
- call keycmd
- xchg ; Get result (dispatch address) into HL
- pchl ; Dispatch.
-
-settab: db 26 ;[pcc013] 16 entries [Toad Hall] [9], now 17
- ;[11] removed XMIT and added CASE and FLOW-CTL
- ; Value is address of processing routine.
- ;[14] removed SET CASE-SENSITIVE for now
- ;[DRJ] Added SET USER. settab = 22
- ;[OBS] Added SET AUTORECEIVE.
- ; and SET NO-EXIT. settab = 24
- ;[MF]Added SET COLLISION, settab=25
- ;[MF]Added Set Incomplete settab=26
- db 11, 'AUTORECEIVE$'
- dw setaut
- db 16, 'BLOCK-CHECK-TYPE$'
- dw blkset
- db 11, 'BUFFER-SIZE$'
- dw setbuf
-; db 14, 'CASE-SENSITIVE$' ;[10]
-; dw setcase ;[10]
- db 9,'COLLISION$' ;[MF]
- dw setcol ;[MF]
- db 5, 'DEBUG$'
- dw setdbg
- db 12, 'DEFAULT-DISK$'
- dw setdisk
- db 19, 'DIRECTORY-FILE-SIZE$'
- dw hidef
- db 6, 'ESCAPE$'
- dw escape
- db 9, 'FILE-MODE$'
- dw setcpm
- db 12, 'FLOW-CONTROL$' ;[10]
- dw setflo ;[10]
- db 3, 'IBM$'
- dw ibmset
- db 16,'INCOMPLETE-FILES$'
- dw setinc ;[MF]Set Incomplete
- db 10, 'LOCAL-ECHO$'
- dw locall
- db 7, 'LOGGING$' ;[pcc013]
- dw setlog ;[pcc013]
- db 7, 'NO-EXIT$'
- dw noexit
- db 6, 'PARITY$'
- dw parset
- db 4, 'PORT$'
- dw prtset
- db 7, 'PRINTER$'
- dw setprn
- db 7, 'RECEIVE$' ;[gnn]
- dw setrec ;[gnn]
- db 4, 'SEND$' ;[gnn]
- dw setsnd ;[gnn]
- db 5, 'SPEED$';[MF]
- dw baud
- db 7, 'TACTRAP$'
- dw settac
- db 8, 'TERMINAL$'
- dw vt52em
- db 5, 'TIMER$'
- dw settim
- db 4, 'USER$' ;[DJR]
- dw user ;[DJR]
- db 7, 'WARNING$'
- dw filwar
-
-; help message for SET command. Caps indicate keywords
-
-sethlp: db cr,lf,'AUTORECEIVE to automatically re-receive files'
- db cr,lf,'BLOCK-CHECK-TYPE for error detection'
- db cr,lf,'BUFFER-SIZE for multi-sector buffering'
-; db cr,lf,'CASE-SENSITIVE to equate lower and upper case' ;[10]
- db cr,lf,'COLLISION to specify action for filename conflicts'
- db cr,lf,'DEBUG message control'
- db cr,lf,'DEFAULT-DISK to receive data'
- db cr,lf,'DIRECTORY-FILE-SIZE when displaying directories'
- db cr,lf,'ESCAPE character during CONNECT'
- db cr,lf,'FILE-MODE for outgoing files'
- db cr,lf,'FLOW-CONTROL to set XON/XOFF flow control' ;[10]
- db cr,lf,'IBM mode: parity and turn around handling'
- db cr,lf,'INCOMPLETE-FILE disposition'
- db cr,lf,'LOCAL-ECHO (half-duplex)'
- db cr,lf,'LOGGING of terminal sessions' ;[pcc013]
- db cr,lf,'NO-EXIT to prevent exit to CP/M after a command tail'
- db cr,lf,'PARITY for communication line'
- db cr,lf,'PORT to communicate on'
- db cr,lf,'PRINTER copy control'
- db cr,lf,'RECEIVE parameters' ;not all currently implemented
- db cr,lf,'SEND parameters' ;Ditto
- db cr,lf,'SPEED of communication line'
- db cr,lf,'TAC interface support'
- db cr,lf,'TERMINAL to set a terminal type'
- db cr,lf,'TIMER control'
- db cr,lf,'USER to set a user number' ;[DJR]
- db cr,lf,'WARNING for filename conflicts'
- db '$'
-
-;
-; SET AUTORECEIVE on/off command
-setaut: call onoff ; set it either on or off
- sta autorc ; and save the flag
- jmp kermit ; and do next command
-
-;SET BLOCK-CHECK-TYPE command.
-
-blkset: lxi d,blktab ;Get the address of the block-check table
- lxi h,blkhlp ;And the address of the help text
- call chkkey ;Go check input (val returns in A).
- sta chktyp ;Save desired checksum type
- jmp kermit ;Go get another command
-
-blktab: db 3 ;Three entries.
- db 20, '1-CHARACTER-CHECKSUM$', '1','1'
- db 20, '2-CHARACTER-CHECKSUM$', '2','2'
- db 21, '3-CHARACTER-CRC-CCITT$', '3','3'
-
-blkhlp: db cr,lf,'1-CHARACTER-CHECKSUM'
- db cr,lf,'2-CHARACTER-CHECKSUM'
- db cr,lf,'3-CHARACTER-CRC-CCITT$'
-
-;
-; This is the SET BUFFER-SIZE command.
-; Sets to maximum number of sectors to use for multiple sector
-; buffering. Sorts a lot f problems on some slow disc-access machines..
-setbuf: mvi a,cmnum ; get a number from the user
- call comnd
- jmp kermit ; error if nothing
- lhld number ; get the value
- mov a,h
- ana a
- jnz setbu1 ; if number greater than 255 then error
- lda maxbsc ; get maximum no sectors allowed by system
- cmp l ; set flags from a-l
- jm setbu1 ; if l > a then error
- mov a,l ; only ls bits used
- sta bufsec
- jmp kermit
-
-setbu1: lxi d,erms25
- call prtstr
- jmp kermit
-
-
-;SET DEFAULT DISK command
-
-setdisk:lxi d,fcb
- mvi a,cmifin ;get "file-spec" silently
- call comnd
- jmp setdi1
-setdi1: lda fcb
- ora a ;Was a drive specified? (if zero, no)
- jnz setdi2 ;he typed a drive-spec
- lda curdsk ;he didn't - give him default
-setdi2: sta curdsk
- mvi c,inbdos ;reset disks
- call bdos
- lda curdsk
- dcr a ;LOGDSK is relative 0
- mov e,a
- mvi c,logdsk
- call bdos ;and "LOG" it
- jmp kermit ;all done
-;
-;SET SEND command. Sort of supported
-
-setsnd: lxi d,stsntb ;Parse a keyword from the set send table.
- lxi h,stshlp
- call keycmd
- xchg ; Get dispatch address into HL
- pchl ; Go for it.
-
-stsntb: db 4 ;Two entries. four entries
- db 8, 'PAD-CHAR$'
- dw stspac
- db 7, 'PADDING$'
- dw stspad
- db 15, 'START-OF-PACKET$' ;[gnn]
- dw stssop ;[gnn]
- db 13,'PACKET-LENGTH$' ;
- dw stspks ;
-; db 9,'CHECKTYPE$' ;
-; dw stsckt ;
-
-stshlp: db cr,lf,'PAD-CHAR to define the pad character to use'
- db cr,lf,'PADDING to define the number of PAD-CHAR to use'
- db cr,lf,'START-OF-PACKET to define the start of packet character' ;[gnn]
- db cr,lf,'PACKET-LENGTH for the length of transmitted packet';
-; db cr,lf,'CHECKTYPE to define the check-type to use';[21]
- db '$' ;[gnn]
-
-; SET SEND START-OF-PACKET [gnn]
-stssop: call cfmcmd
- lxi d,sopmes
- call prtstr
- mvi c,conin
- call bdos
- sta sndsop
- jmp kermit
-
-; SET SEND PADDING command. does nothing. get value to dspad
-stspad: call getnp ; get the number of padding characters
- sta dspad ; save ad default send no. pad characters
- jmp kermit
-
-; SET SEND PAD-CHAR command. does nothing. gets char to dspadc
-stspac: call getpad ; get the character to use
- sta dspadc ; save as default send pad character
- jmp kermit
-
-; SET SEND PACKET-LENGTH command. Max 95, but could be more for long pkts...
-stspks: call getnp ; get number into hl
- lxi b,(maxpkt-1) ;[MF] One below upper limit of packet-size
- push h ;[MF] Save number
- call subbc ;[MF] Do 16-bit subtraction, even though
- ;[MF] getnp puts low-order bits in a,
- ;[MF] in case long packets are
- ;[MF] implemented
- pop h ;[MF] Restore number
- lxi d,erms26 ; packet length to long error
- jnc stspk1
- mov a,l
- sta spsiz ;[MF] Save as default send packet length
- jmp kermit
-stspk1: call prtstr
- jmp kermit ; error exit
-
-; SET SEND CHECKTYPE command. Accepts 1,2 or 3
-stsckt: call getnp ; get a number
- cpi 4 ; if more than 3 then error
- jnz stsck1
-stsck2: lxi d,erms27 ; checktype wrong
- jmp kermit
-stsck1: cpi 0 ; error also for null
- jz stsck2
- adi 30h ; make it printable
- sta sdckt ; save as default send checktype
- jmp kermit
-
-
-;SET RECEIVE command. [gnn]
-setrec: lxi d,strctb ;Parse a keyword from the set rec table.
- lxi h,stshlp ; use same help for send and receive
- call keycmd
- xchg ; Get dispatch address into HL
- pchl ; Go for it.
-
-strctb: db 4 ; Three entries. four entries
- db 8, 'PAD-CHAR$'
- dw strpac ; use dummy entry of set send
- db 7, 'PADDING$'
- dw strpad ; use dummy entry of set send
- db 15,'START-OF-PACKET$'
- dw strsop
- db 13,'PACKET-LENGTH$' ;
- dw strpks ;
-; db 9,'CHECKTYPE$' ;
-; dw strckt ;
-
-; SET RECEIVE START-OF-PACKET
-strsop: call cfmcmd
- lxi d,sopmes
- call prtstr
- mvi c,conin
- call bdos
- sta rcvsop
- jmp kermit
-
-; SET RECEIVE PADDING
-strpad: mvi a,cmnum ; go parse a number
- call comnd ; get it
- jmp kermit ; duff entry, so die
- mvi a,cmcfm ; ask to confirm
- call comnd
- lhld number ; get the number of padding charaters
- mov a,l ; assume 255 or less
- sta dspad ; save ad default send no. pad characters
-
-; SET SEND RECEIVE routines
-getpad: call cfmcmd
- lxi d,padcms ; tell user we want the pad character
- call prtstr
- mvi c,conin ; get it verbatum
- call bdos
- ret
-
-; SET RECEIVE PAD-CHAR routine
-strpac: call getpad ; get the character to use
- sta drpadc ; save it
- jmp kermit
-
-; SET RECEIVE PACKET-LENGTH. Max 95, but could be more for long pkts...
-strpks: call getnp ; get number into hl
- lxi b,(maxpkt-1) ;[MF] One below upper limit of packet-size
- push h ;[MF] Save number
- call subbc ;[MF] Do 16-bit subtraction, even though
- ;[MF] getnp puts low-order bits in a,
- ;[MF] in case long packets are
- ;[MF] implemented
- pop h ;[MF] Restore number
- lxi d,erms26 ; packet length to long error
- jnc strpk1
- mov a,l
- sta rpsiz ;[MF] Save as default receive packet-length
- jmp kermit
-strpk1: call prtstr
- jmp kermit ; error exit
-
-
-; SET RECEIVE CHECKTYPE
-strckt: call getnp ; get a number
- cpi 4 ; if more than 3 then error
- jnz strck1
-strck2: lxi d,erms27 ; checktype wrong
- jmp kermit
-strck1: cpi 0 ; error also for null
- jz strck2
- adi 30h ; make it printable
- sta rdckt ; save as default receive checktype
- jmp kermit
-
-getnp: mvi a,cmnum ; go parse a number
- call comnd ; get it
- jmp kermit ; duff entry, so die
- mvi a,cmcfm ; ask to confirm
- call comnd
- jmp kermit ;[MF] Die!
- lhld number ; get the number of padding charaters
- mov a,l ; assume 255 or less
- ret ; return to caller
-
-
-; SET NO-EXIT on/off. Sets a flag to prevent automatically dropping
-; back to CPM after a command tail has been "done". No other use.
-noexit: call cfmcmd ;[MF]Get a "confirm" in case here via STAY
- xra a
- sta nexitf ; no exit to CP/M
- jmp kermit
-
-;[pcc013]
-; This is the SET LOGGING ON/OFF subcommand
-
-setlog: call onoff ;[pcc013] Get on/off
- sta logflg ;[pcc013] Store flag
- jmp kermit
-;
-; This is the SET ESCAPE character subcommand.
-
-escape: call cfmcmd
- lxi d,escmes ;Get the address of the escape message.
- call prtstr
- mvi c,conin ;Get the char.
- call bdos
- sta escchr ;Store the new escape character.
- jmp kermit
-
-; This is the SET LOCAL-ECHO subcommand.
-
-locall: call onoff ;Get on/off setting [Toad Hall]
- sta ecoflg ;Store local echo flag.
- jmp kermit
-
-; This is the SET PRINTER ON/OFF subcommand
-
-setprn: call onoff ;Get on/off setting [Toad Hall]
- sta prnflg ;Store printer flag
- jmp kermit
-
-; This is the SET DEBUG ON/OFF subcommand
-
-setdbg: call onoff ;Get on/off setting [Toad Hall]
- sta dbgflg ;Store debug flag
- jmp kermit
-
-;[jd] this is the SET TIMER subcommand
-
-settim: call onoff ;Get on/off setting [Toad Hall]
- sta timflg ;Store timer flag value
- jmp kermit
-
-;This is the SET FILE-WARNING subcommand
-
-filwar: call onoff ;Get on/off setting [Toad Hall]
- sta flwflg ;Store file-warning flag.
- jmp kermit
-
-;[MF]This is the SET COLLISION subcommand
-;[MF]First, the requisite tables:
-;
-coltab: db 4 ;[MF]4 entries
- db 6,'BACKUP$',02h,02h
- db 7,'DISCARD$',03h,03h
- db 9,'OVERWRITE$',00h,00h
- db 6,'RENAME$',01h,01h
-;
-colhlp: db cr,lf,'BACKUP (rename) existing files'
- db cr,lf,'DISCARD new versions of existing files'
- db cr,lf,'OVERWRITE existing files'
- db cr,lf,'RENAME new versions of existing files'
- db '$'
-;
-;[MF]Now the routine proper
-;
-setcol: lxi d,coltab ;[MF]Table address
- lxi h,colhlp ;[MF]Help address
- call chkkey ;[MF]Get user's answer
- sta flwflg ;[MF]and remember it
- jmp kermit ;[MF]Back to main loop
-
-;[10] This is the SET FLOW-CONTROL subcommand.
-setflo: call onoff ;is it on or off
- sta floctl ; store flow contol flag
- jmp kermit
-
-;[10] SET CASE-SENSITIVE on or off
-;setcase:
-; call onoff ; set it on or off
-; sta casens ; save it
-; jmp kermit
-
-; SET FILE-SIZE on or off. If on, then show file size during DIR
-;
-hidef: call onoff ; see if on or off
- sta hidefs
- jmp kermit
-
-;
-; This is the SET IBM command.
-;
-; If SET IBM ON, we should do
-; 1) Flow Control = off
-; 2) Parity = mark
-; 3) Local echo = on
-; 4) Timer = on
-;
-; If SET IBM OF, we should assume (& do)
-; 1) Flow control = off (default)
-; 2) Parity = none
-; 3) Local Echo = off
-; 4) Timer = off
-
-
-ibmset: call onoff ;Get on/off setting [Toad Hall]
- sta ibmflg ;Store IBM flag.
- ora a ;Is it turned on?
- jz ibmst1 ;If not, set parity to the default.
-;
-; SET IBM ON code
- mvi a,ibmpar ;Get the IBM parity.
- sta parity
- mvi a,1 ;Set local echo on.
- sta ecoflg
- sta timflg ; also set timer on
- xra a ; no flow control
- sta floctl
- jmp ibmst2 ; exit
-;
-; SET IBM OFF code
-
-ibmst1: mvi a,defpar ; set default parity (none)
- sta parity
- xra a ;Set local echo off.
- sta ecoflg
- sta timflg ;[jd] timer is same as local echo
- sta floctl ;[obs] set flow control off
-ibmst2: jmp kermit ; exit from here
-
-;
-; SET FILE-MODE command.
-;[OBS] assume only ascii and binary, no default.
-
-setcpm: lxi d,typtab
- lxi h,typhlp
- call chkkey ;Get and confirm keyword, or die trying
- sta cpmflg ;Set the CPM flag.
- jmp kermit
-
-typtab: db 3 ;Three entries, now two entries
- ;[MF]Now 3 again!
- db 5, 'ASCII$', 01H,01H
- db 6, 'BINARY$', 02H,02H
- db 7, 'DEFAULT$', 00H,00H ; Default
-
-typhlp: db cr,lf,'ASCII BINARY DEFAULT'
- db '$'
-;
-;setinc - Set Incomplete-file [MF]
-;
-setinc: lxi d,inctab ;[MF]Point to tables
- lxi h,inchlp ;[MF]...
- call chkkey ;[MF]Get user's answer or croak
- sta incflg ;[MF]Remember the answer
- jmp kermit ;[MF]We are done.
-;
-inctab: db 2 ;two entries
- db 7,'DISCARD$'
- db 00h,00h ;Discard incomplete files
- db 4,'KEEP$'
- db 01h,01h ;Keep incomplete files
-;
-inchlp: db cr,lf,'DISCARD KEEP'
- db '$'
-
-; This is the SET PARITY subcommand.
-
-parset: lxi d,partab
- lxi h,parhlp
- call chkkey ;Get and confirm keyword, or die trying
- sta parity ;Set the parity flag.
- jmp kermit
-
-partab: db 5 ;Five entries.
- db 4, 'EVEN$', parevn,parevn
- db 4, 'MARK$', parmrk,parmrk
- db 4, 'NONE$', parnon,parnon
- db 3, 'ODD$', parodd,parodd
- db 5, 'SPACE$', parspc,parspc
-
-parhlp: db cr,lf,'EVEN MARK NONE ODD SPACE$'
-
-; This is the SET TACTRAP subcommand.
-; options are ON, OFF, or CHARACTER. (for CHARACTER, we request the
-; new TAC Intercept character, and turn the TACtrap on)
-
-settac: lxi d,tactab
- lxi h,tachlp
- call chkkey ;Get and confirm keyword
- ora a ;Was it "OFF" (zero)?
- jz settc2 ;If so, go disable TACtrap.
- cpi 1 ;Was it "ON"?
- jz settc1 ;If so, go enable TACtrap.
- lxi d,tacmes ;"CHARACTER". request new TAC Intercept char.
- call prtstr
- mvi c,conin ;Get the char.
- call bdos
- sta tacchr ;Store the new TAC Intercept character.
-settc1: lda tacchr ;Copy tacchr to tacflg to enable TACtrap.
-settc2: sta tacflg ;Enable/disable TACtrap
- jmp kermit
-
-tactab: db 3 ;Three entries.
- db 9, 'CHARACTER$', 02H,02H
- db 3, 'OFF$', 00H,00H
- db 2, 'ON$', 01H,01H
-
-tachlp: db cr,lf,'ON to enable TAC trap'
- db cr,lf,'OFF to disable TAC trap'
- db cr,lf,'CHARACTER to enable TAC trap and'
- db ' specify intercept character$'
-
-; This is the SET VT52-EMULATION subcommand.
-; Now SET TERMINAL xxx
-;vt52em: lda vtflg ;get the flag value
-; cpi 0ffH ;0ffH means not allowed -
-; jz notimp ; say it's not implemented.
-; call onoff ;Get keyword (ON or OFF)
-; sta vtflg ;Set the VT52 emulation flag.
-; jmp kermit
-vt52em: lxi d,sttert ; set terminal type
- lxi h,stterh ; help table
- call chkkey ; get it
- mov a,d ; value returned in DE
- cpi vtdefe ; was it selecting an external terminal?
- jnz vt52e1 ; no, so save new value
- lhld extern+1 ; if external, lets see if one is in place
- mov a,h
- ora l
- mvi a,vtdefe ; restore external flag
- jnz vt52e1 ; we have one, so we can save value
- call prcrlf
- lxi d,inms11 ; load up sorry message
- call prtstr
- jmp kermit
-
-vt52e1: cpi 40h ; are we to have a quiet display?
- jnz vt52e2
- sta quietd ; store it
- jmp kermit
-
-vt52e2: cpi 80h ; are we to be a noisy display?
- jnz vt52e3
- xra a
- sta quietd
- jmp kermit
-
-vt52e3: sta vtflg ; else save new set parameter..
- jmp kermit ; and exit
-
-; tabe with string entry, and the returned value as two identical bytes.
-sttert: db 6 ; six types
- db 4,'DUMB$',vtdefd,vtdefd ; assume our terminal is thick
- db 8,'EXTERNAL$',vtdefe,vtdefe ; assume off, but terminal is in dep. code
- db 5,'QUIET$',40h,40h ; display quiet
- db 7,'REGULAR$',80h,80h ; display loud
- db 3,'OFF$',vtdefo,vtdefo ; assume our terminal does everything
- db 4,'VT52$',vtdefv,vtdefv ; VT52 as before
-
-stterh: db cr,lf,'DUMB - only printable characters passed to terminal'
- db cr,lf,'EXTERNAL - with emulation code system specific'
- db cr,lf,'OFF - all characters passed to terminal'
- db cr,lf,'QUIET - display nothing during transfers'
- db cr,lf,'REGULAR - normal display for transfers'
- db cr,lf,'VT52 - assume Kermit can emulate a VT52'
- db '$'
-
-;
-; Note: For the SET BAUD and SET PORT commands, which might not be
-; supported for the current system, the command tables are stored in
-; the overlay. We locate them through pointers in the linkage area:
-; spdtab for SET BAUD, prttab for SET PORT. The contents of spdtab
-; (or prttab) is the address of the beginning of the table (the table
-; does NOT begin at spdtab). If the address is zero, the command is
-; not supported. If the table address is nonzero, then there is a
-; corresponding help message pointed to by (NOT starting at) spdhlp
-; or prthlp.
-
-; This is the SET BAUD command
-
-baud: lhld spdtab ; get pointer to speed table
- mov a,h
- ora l ; test for NULL (zero)
- jz notimp ; if so, say it's not implemented
- xchg ; move speed table address to DE
- lhld spdhlp ; get pointer to speed help text
- call keycmd
- push d ; save selected speed
- call cfmcmd ; confirm...
- pop h ; restore speed to HL
- shld speed ; save all 16 bits of speed value
- xchg ; move speed to DE
- call sysspd ; do system-dependent speed setting.
- jmp kermit ; return to command level
-
-; This is the SET PORT command
-
-prtset: lhld prttab ; get pointer to port table
- mov a,h
- ora l ; test for NULL
- jz notimp ; not supported if pointer was null.
- xchg ; move port table address to DE
- lhld prthlp ; get pointer to port help text
- call keycmd
- push d ; save selected port entry
- call cfmcmd ; confirm...
- pop h ; restore table address to HL
- shld port ;[hh] save all 16 bits of port value
- call sysprt ; go do port stuff
- jmp kermit
-;
-; Subroutines for SET subcommands
-
-; ontab - command table for onoff.
-; onhlp - help text for onoff.
-; onoff - accept "ON" or "OFF" keyword.
-; returns:
-; success: value in A (non-zero = ON)
-; error: no return to caller. print error message and return to
-; main loop.
-ontab: db 2 ;Two entries.
- db 3, 'OFF$', 00H,00H
- db 2, 'ON$', 01H,01H
-
-onhlp: db cr,lf,'OFF ON$'
-
-onoff: lxi d,ontab
- lxi h,onhlp
- ;Fall through to check input. [Toad Hall]
-
-; chkkey - parse and confirm keyword.
-; called with:
-; DE/ address of keyword table
-; HL/ address of help text
-; returns:
-; success: low byte of keyword value (from table) in A.
-; error: no return to caller. print error message and return to
-; main loop. (Since the main loop reloads the stack pointer,
-; we don't have to attempt to clean up the stack here)
-
-chkkey: call keycmd ; Parse a keyword (might not return)
- sta temp1 ; Save the parsed value
- call cfmcmd ; Request confirmation (might not return)
- lda temp1 ; Get saved value
- ret ; Return
-
-;[hh] fndkyw - find a keyword string from a table using
-; it's associated value
-; called with:
-; HL/ address of keyword table
-; A/ value associated with keyword string
-; returns:
-; success: HL points to first byte of keyword string
-; CY flag is cleared
-; error: HL points to error string (?Not found)
-; CY flag is set
-
-fndkyw: mov d,m ;get count of entries
- inx h ;advance over count value
-fndkw1: mov b,m ;get string length
- inr b ;account for $
- inx h ;advance over length value
- shld temp1 ;save string pointer
-fndkw2: inx h ;loop over string
- dcr b
- jnz fndkw2
- mov c,m ;get keyword value from table
- cmp c ;do they match?
- jz fndkw3 ;Yup
- inx h ;bump to next keyword
- inx h ;
- dcr d ;decrement entry count
- jnz fndkw1 ;check the remaining keywords
- lxi h,kywdnf ;point to not found message
- stc ;give calling routine a not found flag
- ret
-fndkw3: ora a ;clear CY to tell caller we succeeded
- lhld temp1 ;restore the saved string pointer
- ret
-
-kywdnf: db cr,lf,'?Not found$' ;not found message
-
-;
-; This is the SHOW command.
-
-show: call cfmcmd
-;* Reconcile this and status.
- call clrtop ;[hh] Clear screen first
- call stat01 ;For now just cop out.
- jmp kermit
-
-; This is the STATUS command.
-
-status: call cfmcmd
- call clrtop ;[hh] Clear screen first
- call stat01
- jmp kermit
-
-; processor for SHOW, STATUS and <escape>S commands
-; called by: show, status, intchr
-
-stat01: lda fileio ;Are we in transmit?
- ora a
- jz sta01b ;No
- lxi d,xmtst ;Yes,say so
- call prtstr
-
-; The following block of code - down to RET - re-ordered by [DJR]
-; DJR January 1987 to get SHOW/STATUS output in the same [DJR]
-; (alphabetical) order as SET's HELP. [DJR]
-sta01b:
- call stautr ;[MF]Show AUTORECEIVE state
- call stabcc ; Tell current block check type
- call stabsz ; Tell user about multi-sector buffers
- call stacol ;[MF]COLLISION state
- call stadbg ; [DJR] Debug mode
- call stacurd ; [DJR] Current disk
- call stahfs ; Tell user if file sizez are hidden during DIR
- call staesc ; Tell current escape character
- call stafil ; Tell about file type
- call staflo ;[10] Tell about flow control
- call staibm ; Tell about IBM flag
- call stainc ;[MF]Tell about incomplete file disposition
-;
-; Ask user to press a key before continuing
-;
- call pausit ; wait for a while till user presses a key
-;
- call staeco ; Tell about local echo flag
- call stalog ; [pcc003] Tell about log file status
- call stapar ; Tell about parity
- lhld prttab ;[hh] Got a port table? (is pointer nonzero?)
- mov a,h ;[hh]
- ora l ;[hh]
- cnz stapor ;[hh] If so, tell which port we're using
- call stalpt ; Tell about printer copy flag
- call starps ;[MF]Show receive packet length
- call starsp ;[gnn] tell rec. start-of-pkt char
- call stasps ;[MF]Show send packet length
- call stassp ;[gnn] tell send start-of-pkt char
- lhld spdtab ; Got a speed table? (is pointer nonzero?)
- mov a,h
- ora l
- cnz staspd ; If so, tell what speed we're running.
- call statac ; Tell about TAC flag/intercept character.
- call statim ; Tell about timer flag
- call stusr ;[7] Tell about user
- call statvt ; Tell about what emulation we are doing
- call stawrn ; Tell about file-warning flag
- ret
-
-; stautr - Show Autoreceive setting [MF]
-;
-stautr: lxi d,autrst ;[MF]Point to "Autoreceive" string
- call prtstr ;[MF]and print it
- lda autorc ;[MF]Get Autoreceive flag
- jmp staton ;[MF]Say "on" or "off" and return
-
-; Show the value of the LOCAL-ECHO flag (On or Off).
-
-staeco: lxi d,locst ;Get the address of the local echo string.
- call prtstr
- lda ecoflg ;Get the local echo flag.
- jmp staton ;Say ON or OFF, and return
-
-; Show the value of the VT52-EMULATION flag (On, Off, or Not Supported).
-; Also show terminal display mode (regular, quiet)
-
-statvt: lxi d,vtdpst ;[MF]Get address of terminal display string
- call prtstr ;[MF]Print it
- lxi d,vtdpsr ;[MF]Assume a regular (loud) display
- lda quietd ;[MF]Get "quiet" flag
- ora a ;[MF]a quiet display?
- jz statva ;[MF]No, print "regular" message
- lxi d,vtdpsq ;[MF]Yes, point to "quiet" string
-statva: call prtstr ;[MF]and print it
- lxi d,vtemst ; Get the address of the VT52 emulation string.
- call prtstr
- lda vtflg ; Get the VT52 emulation flag.
- cpi 0ffh ; isterminal emulation possible?
- jnz statv0 ; yes, maybe
- lxi h,inms11 ; ... no, load up not implemented message ...
- jmp prvtv ; so tell user
-
-
-statv0: mov c,a ; save it to C
- lxi h,sttert ; get table listing what we can do
- mov b,m ; get number of terminal types to b
-statv1: inx h ; point to first entry
- mov e,m ; get length of entry
- mvi d,0
- inx h ; point to text part of entry
- xchg ; save address in de
- dad d ; start + length
- inx h ;... + 1 for the dollar...
- inx h ; plus point to seconcd copy of ter. type value
- cmp m ; is it the one we want?
- jz prvtv ; yes, then print the terminal type value
- dcr b ; have we completed?
- rz ; yes, then just exit back to status
- jmp statv1 ; else try next entry. HL points to next -1
-
-prvtv: jmp prtstr ; print string from DE
- ;[MF]and return
-
-; Show the value of the FILE-MODE flag (ASCII, Binary, or Default).
-
-stafil: lxi d,cpmst ; Get the address of the file mode message.
- call prtstr
- lda cpmflg ; Get the file mode flag.
- lxi d,defstr ; Assume Default (0).
- ora a ; Is it?
- jz prtstr ; If so, say so, and return.
- lxi d,ascstr ; Not default, assume ASCII
- cpi 1 ; Is it ASCII?
- jz prtstr ; Say ASCII, and return
- lxi d,binstr ; Not default or ASCII, must be binary
- jmp prtstr ; Print type, and return.
-;
-;Show current disposition for incomplete files [MF]
-;
-stainc: lxi d,incst ;[MF]Announce what's to be shown
- call prtstr ;[MF]...
- lxi d,dscstr ;[MF]Assume "discard"
- lda incflg ;[MF]Get flag
- ora a ;[MF]Really discarding incomplete files?
- jz prtstr ;[MF]Yes, say so and return
- lxi d,kepstr ;[MF]No, say we're keeping incomplete files
- jmp prtstr ;[MF]and return
-
-; show if file sizes are hidden during DIR (Would have thought this
-; obvious, but its in for completeness
-stahfs: lxi d,hfsod ; get hide file size on dir
- call prtstr
- lda hidefs
- jmp staton ; say if on or off
-
-; Show the value of the IBM-MODE flag (On or Off).
-
-staibm: lxi d,ibmst ;IBM string.
- call prtstr
- lda ibmflg ; Get IBM flag.
- jmp staton ; Print its value and return
-
-; Show the value of the FILE-WARNING flag (On or Off).
-
-stawrn: lxi d,filst ; File warning string.
- call prtstr
- lda flwflg ; File warning flag.
- jmp staton ; Say ON or OFF
-
-; Show the value of the PRINTER flag (On or Off).
-
-stalpt: lxi d,prst ;Printer copy string
- call prtstr
- lda prnflg ;Printer ON/OFF flag
- jmp staton ; Say ON or OFF
-
-
-; Show status of log file
-stalog: lxi d,logst ;[pcc003] Logging lead-in message
- call prtstr ;[pcc003]
-; name of logging file
-; Code derived from [JD's] code for GET, and uses his FNBUF [DJR]
- lxi d,fnbuf ;[DJR] point to destination
- lxi h,lognam ;[DJR] source of filespec
- mov a,m ;[DJR] get drive byte
- ora a ;[DJR] zero = default disc
- jnz stalg1 ;[DJR] if drive has been specified
- lda curdsk ;[DJR] otherwise get the default
-stalg1: adi 'A'-1 ;[DJR] make it printable
- stax d ;[DJR] into dest block
- inx d ;[DJR]
- mvi a,':' ;[DJR] colon after drive
- stax d ;[DJR]
- inx d ;[DJR]
-
- mvi c,8 ;[DJR] length of name part
- lxi h,lognam+1 ;[DJR] start of name
- mvi b,0 ;[DJR] first-time-thru flag
-stalga: mov a,m ;[DJR] get a char from the name
- inx h ;[DJR] pass it
- cpi ' ' ;[DJR] end of this part of name?
- jz stalgb ;[DJR] yes, skip rest...
- stax d ;[DJR] else drop char into dest
- inx d ;[DJR] increment dest ptr
- dcr c ;[DJR] decrement count
- jnz stalga ;[DJR] and continue if more to go
-
-stalgb: mov a,b ;[DJR]
- ora a ;[DJR] first time thru?
- jnz stalgc ;[DJR] no, no period
- mvi a,'.' ;[DJR] period between parts
- stax d ;[DJR]
- inx d ;[DJR]
- mvi b,0ffh ;[DJR] not first time thru anymore
- mvi c,3 ;[DJR] length of ext part
- lxi h,lognam+9 ;[DJR] start of extension
- jmp stalga ;[DJR] keep copying
-
-stalgc: mvi a,'$'
- stax d ;[DJR] end the name string
- lxi d,fnbuf ;[DJR] Print the file name
- call prtstr ;[DJR]
-
- lxi d,logst2 ;[DJR] second part of message
- call prtstr ;[DJR]
-
-; Show status of logging
- lda logflg ;[pcc003] get the flag
- ani 7FH ;[pcc003] ignore open flag
- cpi 2 ;[pcc003] is it suspended?
- jnz staton ;[pcc003] no, must be on or off
- lxi d,susstr ;[pcc003] suspended
- jp prtstr ;[pcc003] print and return
-
-; Show the value of the PARITY flag (Odd, Even, Mark, Space, or None).
-
-stapar: lxi d,parst ;Parity string.
- call prtstr
- lda parity ;Get the parity setting.
- lxi d,pnonst ;Assume parity is NONE
- cpi parnon ;Were we right?
- jz prtstr ;Yep, go say None, and return
- lxi d,pmrkst ;Get ready to say Mark
- cpi parmrk ;Is it mark?
- jz prtstr ;Yep, go say Mark, and return
- lxi d,pspcst ;Get ready to say Space
- cpi parspc ;Is it space?
- jz prtstr ;Yep, go say Space, and return
- lxi d,poddst ;Get ready to say Odd
- cpi parodd ;Is it odd?
- jz prtstr ;Yep, go say Odd, and return
- lxi d,pevnst ;Must be Even.
- jmp prtstr ;Say Even, and return.
-
-; [gnn] Show start of packet characters
-stassp: lxi d,sspmsg ;message of send s-o-p
- call prtstr
- lda sndsop
- adi 'A'-1 ;convert to printable character
- mov e,a
- mvi c,conout
- jmp bdos ;and print it
-starsp: lxi d,rspmsg ;rec. s-o-p message
- call prtstr
- lda rcvsop
- adi 'A'-1 ;convert to printable character
- mov e,a
- mvi c,conout
- jmp bdos ;and print it
-;
-;[MF]Show receive packet length
-;
-starps: lxi d,rpsmsg ;[MF]Point to message
- call prtstr ;[MF]and print it
- lda rpsiz ;[MF]Get receive packet length
- mov l,a ;[MF]Put in HL
- mvi h,0 ;[MF]...
- jmp nout ;[MF]Print receive packet length in decimal
-;
-;[MF]stasps - Print send packet length
-;
-stasps: lxi d,spsmsg ;[MF]Point to message
- call prtstr ;[MF]and print it
- lda spsiz ;[MF]Get send packet length
- mov l,a ;[MF]into HL
- mvi h,0 ;[MF]...
- jmp nout ;[MF]and print in decimal
-
-;[hh] Show the current port (if known).
-
-stapor: lxi d,porst ;[hh]
- call prtstr ;[hh]
- lda port ;[hh] Get current port value
- lxi h,spdust ;[hh] Assume undefined (this error msg is fine)
- cpi 0FFH ;[hh] Is it?
- jz stat73 ;[hh] Yup. Say so
- lhld prttab ;[hh] Address of port keyword table
- call fndkyw ;[hh] Look for correct keyword string
- jnc stpr1 ;[hh] Found a match
- lxi h,spdust ;[hh] No match found - say it's undefined
-stpr1: jmp stat73 ;[hh] Print it and return
-
-; Show the current line speed (if known).
-
-staspd: lxi d,spdst
- call prtstr
- lda speed ;Get current speed.
- lxi h,spdust ;Assume undefined.
- cpi 0FFH ;Is it?
- jz stat73 ;Yes.
- lhld spdtab ;Start scanning keyword table.
- mov d,m ; get count of entries
- inx h ; advance over it.
-stat70: mov b,m ;Get string length.
- inr b ;Account for $.
- inx h
- shld temp1 ;Save string pointer.
-stat71: inx h ;Loop over string.
- dcr b
- jnz stat71
- mov c,m ;Get speed value
- cmp c ;Match?
- jz stat72 ;Yes.
- inx h ;Bump to next keyword.
- inx h
- dcr d ; decrement entry count
- jnz stat70 ; if more left, check them.
- lxi h,spdust ; can't find it. say it's undefined.
- jmp stat73 ; print the message.
-
-stat72: lhld temp1 ;Restore saved string pointer.
- xchg ;[MF] Set into DE for display
- call prtstr ;[MF] Print speed
- lxi h,spdst2 ;[MF] Point to "bps" message
-stat73: xchg ;Set into DE for display.
- jmp prtstr ; print it, and return.
-
-; Show the current BLOCK-CHECK-TYPE (1-, 2-, or 3-character).
-
-stabcc: lxi d,bckst ;Get the string
- call prtstr ;Print "Block check type: "
- lda chktyp ;Get the type (character 1, 2, or 3)
- mov e,a ;Put into E
- mvi c,conout ;Want to print it
- call BDOS ;Do so
- lxi d,bckst1 ;Get rest of text ("-character")
- jmp prtstr ;Print it and return
-;
-;[MF]stacol - Print "SET COLLISION" state
-;
-stacol: lxi d,collst ;[MF]Get message
- call prtstr ;[MF]Print it
- lxi h,coltab ;[MF]Point to COLLISION keywords
- lda flwflg ;[MF]Get COLLISION state
- call fndkyw ;[MF]Get COLLISION state
- ;[MF](Since user doesn't control flwflg
- ;[MF]directly, no need to check for errors
- xchg ;[MF]Prepare for printing
- jmp prtstr ;[MF]Print COLLISION state and return
-
-; Print the current escape character
-
-staesc: lxi d,escst ;Escape string.
- call prtstr
- call escpr ;Print the escape char.
-; jmp prcrlf ;removed [DJR] Print CR/LF and return [Toad Hall]
- ret ;[DJR] added
-
-; Show number proportion of buffers used in multiple sector buffering
-stabsz: lxi d,bufsz1
- call prtstr ; do first bit of string
- lxi h,0
- lda bufsec
- mov l,a ; get size used...
- call nout ;... to screen
- lxi d,bufsz2 ; and then say max value
- call prtstr
- lxi h,0
- lda maxbsc ; get max for this system
- mov l,a
- call nout ;.. thence to screen
-; jmp prcrlf ; removed [DJR] cr lf and out
- ret ;[DJR]
-
-;
-; Show the value of the TIMER flag
-statim: lxi d,timmsg ;[jd]
- call prtstr ;[jd]
- lda timflg
- jmp staton ;Tell whether it's on or off.
-
-; Show internal versions (edit strings)
-shover: call cfmcmd
- call prcrlf
- lxi d,version ;[MF]Point to Kermit version
- call prtstr ;[MF]and show it
- lxi d,modmsg ;[MF]Continue the message
- call prtstr ;[MF]...
- call prcrlf ;[MF]End the line
- lxi h,vertab ; Get address of version list
-shovr1: mov e,m ; Get next word from list
- inx h
- mov d,m ; Next version string is in DE
- inx h
- mov a,d ; Test for zero (end of list)
- ora e
- jz shovr2 ; Done with list if zero
- push h ; Save position in list
- call prtstr ; Not zero. Print it.
- call prcrlf ; Follow with crlf
- pop h ; Restore position in list
- jmp shovr1 ; and go see if there are any more.
-
-shovr2: lhld ovlver ; Get overlay version string
- xchg ; into DE
- call prtstr ; Print it
- call prcrlf ; Output crlf
- lhld family ;[11] New entry in overlay. Get string of
- xchg ;[11] family of machines (eg apple) and print
- call prtstr ;[11] it. For "common" m/c do a $ only.
- jmp kermit ; Return to main loop.
-
-; table of pointers to version strings.
-vertab: dw mitver ; CPSMIT
- dw comver ; CPSCOM
- dw pk1ver ; CPSPK1
- dw pk2ver ; CPSPK2
- dw remver ; CPSREM
- dw server ; CPSSER
- dw ttver ; CPSTT
- dw cpmver ; CPSCPM
- dw wldver ; CPSWLD
- dw cmdver ; CPSCMD
- dw utlver ; CPSUTL
- dw datver ; CPSDAT
- dw 0 ; end of list
-
-; Show TACTrap status (On or Off, and intercept character)
-statac: lxi d,tacst ;"Current TACTrap status/char: "
- call prtstr
- lxi d,offstr ;Assume set off
- lda tacflg ;Get the TACTrap char/flag
- ora a ;Is it off?
- jz prtstr ;Yep, go print OFF...
- mvi c,conout ;Display...
- mov e,a ;...the current intercept char
- call bdos
- jmp prcrlf
-
-; Show if flow control is set on or off
-staflo: lxi d,flost ; Flow control string
- call prtstr
- lda floctl ; get the flag
- jmp staton
-
-; Show if Case sensitvity is on or off
-;stasens:
-; lxi d,senst ; case sensitivity string
-; call prtstr ;
-; lda casens
-; jmp staton ; say if its on or off
-
-
-; Show the current user. (Should do this under directory...)
-stusr:
- mvi c,usrcod
- mvi e,0ffh ;[9] get the current user
- call bdos
- mov l,a ;[9] print hl as a number...
- mvi h,0
- push h ;[9] got the user number
- lxi d,usrst ;[9] tell the user number
- call prtstr
- pop h ;[9] now do number
- call nout ;[6] using routine for writing packet nos.
- ret
-
-;
-;
-; [DJR] Show debug mode
-stadbg:
- lxi d,dbgst ;[DJR] Display string
- call prtstr ;[DJR]
- lda dbgflg ;[DJR] load flag
- jmp staton ;[DJR]
-
-
-; [DJR] Show default disk
-stacurd:
- lxi d,curdst ;[DJR]
- call prtstr ;[DJR]
- lda curdsk ;[DJR]
- adi 'A'-1 ;[DJR]
- mov e,a ;[DJR]
- mvi c,conout ;[DJR]
- jmp bdos ;[DJR]
-
-;
-; Display current state of a boolean flag.
-; called with A/ value (zero = Off, non-zero = On)
-
-staton: lxi d,onstr ; Assume it's on.
- ora a ; Is it on?
- jnz prtstr ; If so, say so, then return.
- lxi d,offstr ; No, say off.
- jmp prtstr ; Print the string, then return.
-
-; STRING command
-; get a string from the user and send it to the host.
-string: mvi a,cmtxt ; get the text
- lxi d,stbuff ; where to put it
- call comnd
- jmp kermit ; if we cannot do it, then back to command level
- sta strcnt ; save the string count
- ana a ; if it is zero, then do nowt
- jz kermit
- call cfmcmd ;[MF]Otherwise, get a "confirm"
- call selmdm ; then select the modem
- lxi d,stbuff ; where to get the string
-stlop: ldax d ; get byte
- inx d ; pointer plus one
- push d ; update pointer, and save de, and the character
- call setpar ; set whatever parity
- mov e,a ; outmdm wants character in e
- call outmdm ; send character in a to line
- pop d
- lda strcnt ; get the count
- dcr a
- sta strcnt ; less one
- jnz stlop ; else still looping
- call selcon ; re-select the console
- jmp kermit
-
-; Print "(not implemented)".
-; here from vt52em, baud, prtset, stavt
-
-notimp: lxi d,inms12 ; Say it's not implemented.
- call prtstr
- jmp kermit ; Return to main loop.
-
-; Little code to allow some expansion of code without changing
-; every futher address, only up to the end of this file.
-; TO BE REMOVED FRO RELEASE!
-
-; org ($+100h) AND 0FF00H
-
-IF lasm ; If using LASM, chain to the next file.
- LINK CPSPK1 ;[obs] break down them big files...
-ENDIF;lasm
+; CPSCOM.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains some of the main loop commands, all SET xxx and
+; status routines. File split from CPSMIT.ASM as that file
+; was getting too big.
+;
+; revision history:
+;
+;edit 13, 25-Mar-1991 by MF. Require confirmation if a STAY command
+; (code at "noexit") is given and a question-mark is entered.
+;edit 12, 21-Mar-1991 by MF. Change SET COLLISSION REPLACE to
+; SET COLLISION OVERWRITE to conform with C-Kermit. Modify SET COLLISION
+; help text slightly.
+
+;edit 11, 27-Feb-1991 by MF. Show Kermit version in VERSION command
+; ("shover").
+;edit 10, 12-Feb-1991 by MF. Modified OUTPUT command to get a "confirm"
+; after accepting the string to be output so that the OUTPUT command
+; doesn't immediately execute if a terminator other than <cr> is typed
+; (immediate execution confuses some users new to Kermit). This
+; situation should seldom, if ever, occur, as the OUTPUT command
+; is most likely to be executed in a TAKE-file but one should
+; protect oneself, shouldn't one?
+; Also commented out case-sensivity code as it is unlikely to be used.
+;edit 9, 4-Dec-1990 by MF. Add "stautr" routine to display Autoreceive
+; status in SHOW/STATUS/<ESC>S commands.
+;edit 8, 30-Nov-1990 by MF. Modify routine "statvt" (terminal status) to
+; display setting of "quiet" switch. Although I presume that Mr.
+; Schou thought the code would accommodate display of QUIET or
+; REGULAR, the code does not in fact allow this since the emulation
+; flag is not involved in the "quiet" setting.
+; Also fix SET TERMINAL's help text a bit.
+;edit 7, 8-Nov-1990 by MF. In SET {RECEIVE/SEND} PACKET-LENGTH routines,
+; call utility routine subbc from CPSUTL.ASM to do 16-bit subtraction
+; rather than doing it in-line to save a few bytes. Eliminate
+; commented-out instructions.
+;edit 6, 1-Nov-1990 by MF. Changed SET BAUD-RATE to SET SPEED in the quest
+; for uniformity of nomenclature (per request of FDC).
+;edit 5, 17-Oct-1990 by MF. Change SET {RECEIVE SEND} PACKET-SIZE to
+; SET {RECEIVE SEND} PACKET-LENGTH to conform with the nomenclature
+; suggested in Chapter 10 of the 6th edition of the Kermit Protocol
+; Manual.
+;edit 4, 14-Sep-1990 by MF. Implemented SET FILE-COLLISION (SET COLLISION)
+; command (except for SET COLLISION ASK and SET COLLISION APPEND).
+; How one APPENDs to a CP/M file depends upon whether it's ASCII or
+; BINARY -- something we may not know.
+; Also implemented SET INCOMPLETE-FILE command.
+; Let's also restore SET FILE-MODE DEFAULT: I never use it but if
+; we leave the DEFAULT code, as Version 4.09 does, the user is entitled
+; to be able to select it if he/she wishes (I'd favor getting rid
+; of it altogether but as soon as I did that, someone'd come out
+; of the woodwork and complain vehemently that he/she **likes**
+; SET FILE-MODE DEFAULT and would the so-and-so who took it out
+; please put it back in. Such is life. In any case, the user can
+; always set the file-mode from a take-file.
+;edit 3, 9-Sep-1990 by MF. Implemented setting of packet sizes for
+; packets up thru length 94 characters for SEND and RECEIVE. Even
+; for standard-length packets, variable sizes are useful.
+; Correct 16-bit subtraction in stspks/strpks to set carry if needed
+; Also corrected bug in routine getnp wherein a JMP KERMIT
+; instruction was left out after trying to parse a confirm, thus
+; skipping loading of number into HL.
+; Fixed bug in PRTSTR wherein BC/HL were not saved under certain
+; conditions, thus causing garbage to appear when PRTSTR was
+; called with QUIETD set.
+; edit 2, September 10, 1987, by OBSchou. Changed SET IBM to reset the
+; flow control flag. IBMs use 13h as a turnaround character (so they
+; say) so no flow control. Anybody willing to add comments etsc, as I
+; have NO IDEA what IBMs do or need.
+; Also removed the SET FILE-MODE DEFAULT option, as it always causes
+; so much trouble. Assume the default mode to be ASCII. Moved a test
+; for key pressed from the status routine to the CPSUTL file.
+;
+; edit 1, April 8th, 1987.
+; Hived off the SET command etc from CPSMIT.ASM to
+; make a more manageable file
+
+
+comver: db 'CPSCOM.ASM (13) 25-Mar-1991$' ;name, edit no. and date
+;
+;
+; This is the SET command.
+
+setcom: lxi d,settab ;Parse a keyword from the set table.
+ lxi h,sethlp
+ call keycmd
+ xchg ; Get result (dispatch address) into HL
+ pchl ; Dispatch.
+
+settab: db 26 ;[pcc013] 16 entries [Toad Hall] [9], now 17
+ ;[11] removed XMIT and added CASE and FLOW-CTL
+ ; Value is address of processing routine.
+ ;[14] removed SET CASE-SENSITIVE for now
+ ;[DRJ] Added SET USER. settab = 22
+ ;[OBS] Added SET AUTORECEIVE.
+ ; and SET NO-EXIT. settab = 24
+ ;[MF]Added SET COLLISION, settab=25
+ ;[MF]Added Set Incomplete settab=26
+ db 11, 'AUTORECEIVE$'
+ dw setaut
+ db 16, 'BLOCK-CHECK-TYPE$'
+ dw blkset
+ db 11, 'BUFFER-SIZE$'
+ dw setbuf
+; db 14, 'CASE-SENSITIVE$' ;[10]
+; dw setcase ;[10]
+ db 9,'COLLISION$' ;[MF]
+ dw setcol ;[MF]
+ db 5, 'DEBUG$'
+ dw setdbg
+ db 12, 'DEFAULT-DISK$'
+ dw setdisk
+ db 19, 'DIRECTORY-FILE-SIZE$'
+ dw hidef
+ db 6, 'ESCAPE$'
+ dw escape
+ db 9, 'FILE-MODE$'
+ dw setcpm
+ db 12, 'FLOW-CONTROL$' ;[10]
+ dw setflo ;[10]
+ db 3, 'IBM$'
+ dw ibmset
+ db 16,'INCOMPLETE-FILES$'
+ dw setinc ;[MF]Set Incomplete
+ db 10, 'LOCAL-ECHO$'
+ dw locall
+ db 7, 'LOGGING$' ;[pcc013]
+ dw setlog ;[pcc013]
+ db 7, 'NO-EXIT$'
+ dw noexit
+ db 6, 'PARITY$'
+ dw parset
+ db 4, 'PORT$'
+ dw prtset
+ db 7, 'PRINTER$'
+ dw setprn
+ db 7, 'RECEIVE$' ;[gnn]
+ dw setrec ;[gnn]
+ db 4, 'SEND$' ;[gnn]
+ dw setsnd ;[gnn]
+ db 5, 'SPEED$';[MF]
+ dw baud
+ db 7, 'TACTRAP$'
+ dw settac
+ db 8, 'TERMINAL$'
+ dw vt52em
+ db 5, 'TIMER$'
+ dw settim
+ db 4, 'USER$' ;[DJR]
+ dw user ;[DJR]
+ db 7, 'WARNING$'
+ dw filwar
+
+; help message for SET command. Caps indicate keywords
+
+sethlp: db cr,lf,'AUTORECEIVE to automatically re-receive files'
+ db cr,lf,'BLOCK-CHECK-TYPE for error detection'
+ db cr,lf,'BUFFER-SIZE for multi-sector buffering'
+; db cr,lf,'CASE-SENSITIVE to equate lower and upper case' ;[10]
+ db cr,lf,'COLLISION to specify action for filename conflicts'
+ db cr,lf,'DEBUG message control'
+ db cr,lf,'DEFAULT-DISK to receive data'
+ db cr,lf,'DIRECTORY-FILE-SIZE when displaying directories'
+ db cr,lf,'ESCAPE character during CONNECT'
+ db cr,lf,'FILE-MODE for outgoing files'
+ db cr,lf,'FLOW-CONTROL to set XON/XOFF flow control' ;[10]
+ db cr,lf,'IBM mode: parity and turn around handling'
+ db cr,lf,'INCOMPLETE-FILE disposition'
+ db cr,lf,'LOCAL-ECHO (half-duplex)'
+ db cr,lf,'LOGGING of terminal sessions' ;[pcc013]
+ db cr,lf,'NO-EXIT to prevent exit to CP/M after a command tail'
+ db cr,lf,'PARITY for communication line'
+ db cr,lf,'PORT to communicate on'
+ db cr,lf,'PRINTER copy control'
+ db cr,lf,'RECEIVE parameters' ;not all currently implemented
+ db cr,lf,'SEND parameters' ;Ditto
+ db cr,lf,'SPEED of communication line'
+ db cr,lf,'TAC interface support'
+ db cr,lf,'TERMINAL to set a terminal type'
+ db cr,lf,'TIMER control'
+ db cr,lf,'USER to set a user number' ;[DJR]
+ db cr,lf,'WARNING for filename conflicts'
+ db '$'
+
+;
+; SET AUTORECEIVE on/off command
+setaut: call onoff ; set it either on or off
+ sta autorc ; and save the flag
+ jmp kermit ; and do next command
+
+;SET BLOCK-CHECK-TYPE command.
+
+blkset: lxi d,blktab ;Get the address of the block-check table
+ lxi h,blkhlp ;And the address of the help text
+ call chkkey ;Go check input (val returns in A).
+ sta chktyp ;Save desired checksum type
+ jmp kermit ;Go get another command
+
+blktab: db 3 ;Three entries.
+ db 20, '1-CHARACTER-CHECKSUM$', '1','1'
+ db 20, '2-CHARACTER-CHECKSUM$', '2','2'
+ db 21, '3-CHARACTER-CRC-CCITT$', '3','3'
+
+blkhlp: db cr,lf,'1-CHARACTER-CHECKSUM'
+ db cr,lf,'2-CHARACTER-CHECKSUM'
+ db cr,lf,'3-CHARACTER-CRC-CCITT$'
+
+;
+; This is the SET BUFFER-SIZE command.
+; Sets to maximum number of sectors to use for multiple sector
+; buffering. Sorts a lot f problems on some slow disc-access machines..
+setbuf: mvi a,cmnum ; get a number from the user
+ call comnd
+ jmp kermit ; error if nothing
+ lhld number ; get the value
+ mov a,h
+ ana a
+ jnz setbu1 ; if number greater than 255 then error
+ lda maxbsc ; get maximum no sectors allowed by system
+ cmp l ; set flags from a-l
+ jm setbu1 ; if l > a then error
+ mov a,l ; only ls bits used
+ sta bufsec
+ jmp kermit
+
+setbu1: lxi d,erms25
+ call prtstr
+ jmp kermit
+
+
+;SET DEFAULT DISK command
+
+setdisk:lxi d,fcb
+ mvi a,cmifin ;get "file-spec" silently
+ call comnd
+ jmp setdi1
+setdi1: lda fcb
+ ora a ;Was a drive specified? (if zero, no)
+ jnz setdi2 ;he typed a drive-spec
+ lda curdsk ;he didn't - give him default
+setdi2: sta curdsk
+ mvi c,inbdos ;reset disks
+ call bdos
+ lda curdsk
+ dcr a ;LOGDSK is relative 0
+ mov e,a
+ mvi c,logdsk
+ call bdos ;and "LOG" it
+ jmp kermit ;all done
+;
+;SET SEND command. Sort of supported
+
+setsnd: lxi d,stsntb ;Parse a keyword from the set send table.
+ lxi h,stshlp
+ call keycmd
+ xchg ; Get dispatch address into HL
+ pchl ; Go for it.
+
+stsntb: db 4 ;Two entries. four entries
+ db 8, 'PAD-CHAR$'
+ dw stspac
+ db 7, 'PADDING$'
+ dw stspad
+ db 15, 'START-OF-PACKET$' ;[gnn]
+ dw stssop ;[gnn]
+ db 13,'PACKET-LENGTH$' ;
+ dw stspks ;
+; db 9,'CHECKTYPE$' ;
+; dw stsckt ;
+
+stshlp: db cr,lf,'PAD-CHAR to define the pad character to use'
+ db cr,lf,'PADDING to define the number of PAD-CHAR to use'
+ db cr,lf,'START-OF-PACKET to define the start of packet character' ;[gnn]
+ db cr,lf,'PACKET-LENGTH for the length of transmitted packet';
+; db cr,lf,'CHECKTYPE to define the check-type to use';[21]
+ db '$' ;[gnn]
+
+; SET SEND START-OF-PACKET [gnn]
+stssop: call cfmcmd
+ lxi d,sopmes
+ call prtstr
+ mvi c,conin
+ call bdos
+ sta sndsop
+ jmp kermit
+
+; SET SEND PADDING command. does nothing. get value to dspad
+stspad: call getnp ; get the number of padding characters
+ sta dspad ; save ad default send no. pad characters
+ jmp kermit
+
+; SET SEND PAD-CHAR command. does nothing. gets char to dspadc
+stspac: call getpad ; get the character to use
+ sta dspadc ; save as default send pad character
+ jmp kermit
+
+; SET SEND PACKET-LENGTH command. Max 95, but could be more for long pkts...
+stspks: call getnp ; get number into hl
+ lxi b,(maxpkt-1) ;[MF] One below upper limit of packet-size
+ push h ;[MF] Save number
+ call subbc ;[MF] Do 16-bit subtraction, even though
+ ;[MF] getnp puts low-order bits in a,
+ ;[MF] in case long packets are
+ ;[MF] implemented
+ pop h ;[MF] Restore number
+ lxi d,erms26 ; packet length to long error
+ jnc stspk1
+ mov a,l
+ sta spsiz ;[MF] Save as default send packet length
+ jmp kermit
+stspk1: call prtstr
+ jmp kermit ; error exit
+
+; SET SEND CHECKTYPE command. Accepts 1,2 or 3
+stsckt: call getnp ; get a number
+ cpi 4 ; if more than 3 then error
+ jnz stsck1
+stsck2: lxi d,erms27 ; checktype wrong
+ jmp kermit
+stsck1: cpi 0 ; error also for null
+ jz stsck2
+ adi 30h ; make it printable
+ sta sdckt ; save as default send checktype
+ jmp kermit
+
+
+;SET RECEIVE command. [gnn]
+setrec: lxi d,strctb ;Parse a keyword from the set rec table.
+ lxi h,stshlp ; use same help for send and receive
+ call keycmd
+ xchg ; Get dispatch address into HL
+ pchl ; Go for it.
+
+strctb: db 4 ; Three entries. four entries
+ db 8, 'PAD-CHAR$'
+ dw strpac ; use dummy entry of set send
+ db 7, 'PADDING$'
+ dw strpad ; use dummy entry of set send
+ db 15,'START-OF-PACKET$'
+ dw strsop
+ db 13,'PACKET-LENGTH$' ;
+ dw strpks ;
+; db 9,'CHECKTYPE$' ;
+; dw strckt ;
+
+; SET RECEIVE START-OF-PACKET
+strsop: call cfmcmd
+ lxi d,sopmes
+ call prtstr
+ mvi c,conin
+ call bdos
+ sta rcvsop
+ jmp kermit
+
+; SET RECEIVE PADDING
+strpad: mvi a,cmnum ; go parse a number
+ call comnd ; get it
+ jmp kermit ; duff entry, so die
+ mvi a,cmcfm ; ask to confirm
+ call comnd
+ lhld number ; get the number of padding charaters
+ mov a,l ; assume 255 or less
+ sta dspad ; save ad default send no. pad characters
+
+; SET SEND RECEIVE routines
+getpad: call cfmcmd
+ lxi d,padcms ; tell user we want the pad character
+ call prtstr
+ mvi c,conin ; get it verbatum
+ call bdos
+ ret
+
+; SET RECEIVE PAD-CHAR routine
+strpac: call getpad ; get the character to use
+ sta drpadc ; save it
+ jmp kermit
+
+; SET RECEIVE PACKET-LENGTH. Max 95, but could be more for long pkts...
+strpks: call getnp ; get number into hl
+ lxi b,(maxpkt-1) ;[MF] One below upper limit of packet-size
+ push h ;[MF] Save number
+ call subbc ;[MF] Do 16-bit subtraction, even though
+ ;[MF] getnp puts low-order bits in a,
+ ;[MF] in case long packets are
+ ;[MF] implemented
+ pop h ;[MF] Restore number
+ lxi d,erms26 ; packet length to long error
+ jnc strpk1
+ mov a,l
+ sta rpsiz ;[MF] Save as default receive packet-length
+ jmp kermit
+strpk1: call prtstr
+ jmp kermit ; error exit
+
+
+; SET RECEIVE CHECKTYPE
+strckt: call getnp ; get a number
+ cpi 4 ; if more than 3 then error
+ jnz strck1
+strck2: lxi d,erms27 ; checktype wrong
+ jmp kermit
+strck1: cpi 0 ; error also for null
+ jz strck2
+ adi 30h ; make it printable
+ sta rdckt ; save as default receive checktype
+ jmp kermit
+
+getnp: mvi a,cmnum ; go parse a number
+ call comnd ; get it
+ jmp kermit ; duff entry, so die
+ mvi a,cmcfm ; ask to confirm
+ call comnd
+ jmp kermit ;[MF] Die!
+ lhld number ; get the number of padding charaters
+ mov a,l ; assume 255 or less
+ ret ; return to caller
+
+
+; SET NO-EXIT on/off. Sets a flag to prevent automatically dropping
+; back to CPM after a command tail has been "done". No other use.
+noexit: call cfmcmd ;[MF]Get a "confirm" in case here via STAY
+ xra a
+ sta nexitf ; no exit to CP/M
+ jmp kermit
+
+;[pcc013]
+; This is the SET LOGGING ON/OFF subcommand
+
+setlog: call onoff ;[pcc013] Get on/off
+ sta logflg ;[pcc013] Store flag
+ jmp kermit
+;
+; This is the SET ESCAPE character subcommand.
+
+escape: call cfmcmd
+ lxi d,escmes ;Get the address of the escape message.
+ call prtstr
+ mvi c,conin ;Get the char.
+ call bdos
+ sta escchr ;Store the new escape character.
+ jmp kermit
+
+; This is the SET LOCAL-ECHO subcommand.
+
+locall: call onoff ;Get on/off setting [Toad Hall]
+ sta ecoflg ;Store local echo flag.
+ jmp kermit
+
+; This is the SET PRINTER ON/OFF subcommand
+
+setprn: call onoff ;Get on/off setting [Toad Hall]
+ sta prnflg ;Store printer flag
+ jmp kermit
+
+; This is the SET DEBUG ON/OFF subcommand
+
+setdbg: call onoff ;Get on/off setting [Toad Hall]
+ sta dbgflg ;Store debug flag
+ jmp kermit
+
+;[jd] this is the SET TIMER subcommand
+
+settim: call onoff ;Get on/off setting [Toad Hall]
+ sta timflg ;Store timer flag value
+ jmp kermit
+
+;This is the SET FILE-WARNING subcommand
+
+filwar: call onoff ;Get on/off setting [Toad Hall]
+ sta flwflg ;Store file-warning flag.
+ jmp kermit
+
+;[MF]This is the SET COLLISION subcommand
+;[MF]First, the requisite tables:
+;
+coltab: db 4 ;[MF]4 entries
+ db 6,'BACKUP$',02h,02h
+ db 7,'DISCARD$',03h,03h
+ db 9,'OVERWRITE$',00h,00h
+ db 6,'RENAME$',01h,01h
+;
+colhlp: db cr,lf,'BACKUP (rename) existing files'
+ db cr,lf,'DISCARD new versions of existing files'
+ db cr,lf,'OVERWRITE existing files'
+ db cr,lf,'RENAME new versions of existing files'
+ db '$'
+;
+;[MF]Now the routine proper
+;
+setcol: lxi d,coltab ;[MF]Table address
+ lxi h,colhlp ;[MF]Help address
+ call chkkey ;[MF]Get user's answer
+ sta flwflg ;[MF]and remember it
+ jmp kermit ;[MF]Back to main loop
+
+;[10] This is the SET FLOW-CONTROL subcommand.
+setflo: call onoff ;is it on or off
+ sta floctl ; store flow contol flag
+ jmp kermit
+
+;[10] SET CASE-SENSITIVE on or off
+;setcase:
+; call onoff ; set it on or off
+; sta casens ; save it
+; jmp kermit
+
+; SET FILE-SIZE on or off. If on, then show file size during DIR
+;
+hidef: call onoff ; see if on or off
+ sta hidefs
+ jmp kermit
+
+;
+; This is the SET IBM command.
+;
+; If SET IBM ON, we should do
+; 1) Flow Control = off
+; 2) Parity = mark
+; 3) Local echo = on
+; 4) Timer = on
+;
+; If SET IBM OF, we should assume (& do)
+; 1) Flow control = off (default)
+; 2) Parity = none
+; 3) Local Echo = off
+; 4) Timer = off
+
+
+ibmset: call onoff ;Get on/off setting [Toad Hall]
+ sta ibmflg ;Store IBM flag.
+ ora a ;Is it turned on?
+ jz ibmst1 ;If not, set parity to the default.
+;
+; SET IBM ON code
+ mvi a,ibmpar ;Get the IBM parity.
+ sta parity
+ mvi a,1 ;Set local echo on.
+ sta ecoflg
+ sta timflg ; also set timer on
+ xra a ; no flow control
+ sta floctl
+ jmp ibmst2 ; exit
+;
+; SET IBM OFF code
+
+ibmst1: mvi a,defpar ; set default parity (none)
+ sta parity
+ xra a ;Set local echo off.
+ sta ecoflg
+ sta timflg ;[jd] timer is same as local echo
+ sta floctl ;[obs] set flow control off
+ibmst2: jmp kermit ; exit from here
+
+;
+; SET FILE-MODE command.
+;[OBS] assume only ascii and binary, no default.
+
+setcpm: lxi d,typtab
+ lxi h,typhlp
+ call chkkey ;Get and confirm keyword, or die trying
+ sta cpmflg ;Set the CPM flag.
+ jmp kermit
+
+typtab: db 3 ;Three entries, now two entries
+ ;[MF]Now 3 again!
+ db 5, 'ASCII$', 01H,01H
+ db 6, 'BINARY$', 02H,02H
+ db 7, 'DEFAULT$', 00H,00H ; Default
+
+typhlp: db cr,lf,'ASCII BINARY DEFAULT'
+ db '$'
+;
+;setinc - Set Incomplete-file [MF]
+;
+setinc: lxi d,inctab ;[MF]Point to tables
+ lxi h,inchlp ;[MF]...
+ call chkkey ;[MF]Get user's answer or croak
+ sta incflg ;[MF]Remember the answer
+ jmp kermit ;[MF]We are done.
+;
+inctab: db 2 ;two entries
+ db 7,'DISCARD$'
+ db 00h,00h ;Discard incomplete files
+ db 4,'KEEP$'
+ db 01h,01h ;Keep incomplete files
+;
+inchlp: db cr,lf,'DISCARD KEEP'
+ db '$'
+
+; This is the SET PARITY subcommand.
+
+parset: lxi d,partab
+ lxi h,parhlp
+ call chkkey ;Get and confirm keyword, or die trying
+ sta parity ;Set the parity flag.
+ jmp kermit
+
+partab: db 5 ;Five entries.
+ db 4, 'EVEN$', parevn,parevn
+ db 4, 'MARK$', parmrk,parmrk
+ db 4, 'NONE$', parnon,parnon
+ db 3, 'ODD$', parodd,parodd
+ db 5, 'SPACE$', parspc,parspc
+
+parhlp: db cr,lf,'EVEN MARK NONE ODD SPACE$'
+
+; This is the SET TACTRAP subcommand.
+; options are ON, OFF, or CHARACTER. (for CHARACTER, we request the
+; new TAC Intercept character, and turn the TACtrap on)
+
+settac: lxi d,tactab
+ lxi h,tachlp
+ call chkkey ;Get and confirm keyword
+ ora a ;Was it "OFF" (zero)?
+ jz settc2 ;If so, go disable TACtrap.
+ cpi 1 ;Was it "ON"?
+ jz settc1 ;If so, go enable TACtrap.
+ lxi d,tacmes ;"CHARACTER". request new TAC Intercept char.
+ call prtstr
+ mvi c,conin ;Get the char.
+ call bdos
+ sta tacchr ;Store the new TAC Intercept character.
+settc1: lda tacchr ;Copy tacchr to tacflg to enable TACtrap.
+settc2: sta tacflg ;Enable/disable TACtrap
+ jmp kermit
+
+tactab: db 3 ;Three entries.
+ db 9, 'CHARACTER$', 02H,02H
+ db 3, 'OFF$', 00H,00H
+ db 2, 'ON$', 01H,01H
+
+tachlp: db cr,lf,'ON to enable TAC trap'
+ db cr,lf,'OFF to disable TAC trap'
+ db cr,lf,'CHARACTER to enable TAC trap and'
+ db ' specify intercept character$'
+
+; This is the SET VT52-EMULATION subcommand.
+; Now SET TERMINAL xxx
+;vt52em: lda vtflg ;get the flag value
+; cpi 0ffH ;0ffH means not allowed -
+; jz notimp ; say it's not implemented.
+; call onoff ;Get keyword (ON or OFF)
+; sta vtflg ;Set the VT52 emulation flag.
+; jmp kermit
+vt52em: lxi d,sttert ; set terminal type
+ lxi h,stterh ; help table
+ call chkkey ; get it
+ mov a,d ; value returned in DE
+ cpi vtdefe ; was it selecting an external terminal?
+ jnz vt52e1 ; no, so save new value
+ lhld extern+1 ; if external, lets see if one is in place
+ mov a,h
+ ora l
+ mvi a,vtdefe ; restore external flag
+ jnz vt52e1 ; we have one, so we can save value
+ call prcrlf
+ lxi d,inms11 ; load up sorry message
+ call prtstr
+ jmp kermit
+
+vt52e1: cpi 40h ; are we to have a quiet display?
+ jnz vt52e2
+ sta quietd ; store it
+ jmp kermit
+
+vt52e2: cpi 80h ; are we to be a noisy display?
+ jnz vt52e3
+ xra a
+ sta quietd
+ jmp kermit
+
+vt52e3: sta vtflg ; else save new set parameter..
+ jmp kermit ; and exit
+
+; tabe with string entry, and the returned value as two identical bytes.
+sttert: db 6 ; six types
+ db 4,'DUMB$',vtdefd,vtdefd ; assume our terminal is thick
+ db 8,'EXTERNAL$',vtdefe,vtdefe ; assume off, but terminal is in dep. code
+ db 5,'QUIET$',40h,40h ; display quiet
+ db 7,'REGULAR$',80h,80h ; display loud
+ db 3,'OFF$',vtdefo,vtdefo ; assume our terminal does everything
+ db 4,'VT52$',vtdefv,vtdefv ; VT52 as before
+
+stterh: db cr,lf,'DUMB - only printable characters passed to terminal'
+ db cr,lf,'EXTERNAL - with emulation code system specific'
+ db cr,lf,'OFF - all characters passed to terminal'
+ db cr,lf,'QUIET - display nothing during transfers'
+ db cr,lf,'REGULAR - normal display for transfers'
+ db cr,lf,'VT52 - assume Kermit can emulate a VT52'
+ db '$'
+
+;
+; Note: For the SET BAUD and SET PORT commands, which might not be
+; supported for the current system, the command tables are stored in
+; the overlay. We locate them through pointers in the linkage area:
+; spdtab for SET BAUD, prttab for SET PORT. The contents of spdtab
+; (or prttab) is the address of the beginning of the table (the table
+; does NOT begin at spdtab). If the address is zero, the command is
+; not supported. If the table address is nonzero, then there is a
+; corresponding help message pointed to by (NOT starting at) spdhlp
+; or prthlp.
+
+; This is the SET BAUD command
+
+baud: lhld spdtab ; get pointer to speed table
+ mov a,h
+ ora l ; test for NULL (zero)
+ jz notimp ; if so, say it's not implemented
+ xchg ; move speed table address to DE
+ lhld spdhlp ; get pointer to speed help text
+ call keycmd
+ push d ; save selected speed
+ call cfmcmd ; confirm...
+ pop h ; restore speed to HL
+ shld speed ; save all 16 bits of speed value
+ xchg ; move speed to DE
+ call sysspd ; do system-dependent speed setting.
+ jmp kermit ; return to command level
+
+; This is the SET PORT command
+
+prtset: lhld prttab ; get pointer to port table
+ mov a,h
+ ora l ; test for NULL
+ jz notimp ; not supported if pointer was null.
+ xchg ; move port table address to DE
+ lhld prthlp ; get pointer to port help text
+ call keycmd
+ push d ; save selected port entry
+ call cfmcmd ; confirm...
+ pop h ; restore table address to HL
+ shld port ;[hh] save all 16 bits of port value
+ call sysprt ; go do port stuff
+ jmp kermit
+;
+; Subroutines for SET subcommands
+
+; ontab - command table for onoff.
+; onhlp - help text for onoff.
+; onoff - accept "ON" or "OFF" keyword.
+; returns:
+; success: value in A (non-zero = ON)
+; error: no return to caller. print error message and return to
+; main loop.
+ontab: db 2 ;Two entries.
+ db 3, 'OFF$', 00H,00H
+ db 2, 'ON$', 01H,01H
+
+onhlp: db cr,lf,'OFF ON$'
+
+onoff: lxi d,ontab
+ lxi h,onhlp
+ ;Fall through to check input. [Toad Hall]
+
+; chkkey - parse and confirm keyword.
+; called with:
+; DE/ address of keyword table
+; HL/ address of help text
+; returns:
+; success: low byte of keyword value (from table) in A.
+; error: no return to caller. print error message and return to
+; main loop. (Since the main loop reloads the stack pointer,
+; we don't have to attempt to clean up the stack here)
+
+chkkey: call keycmd ; Parse a keyword (might not return)
+ sta temp1 ; Save the parsed value
+ call cfmcmd ; Request confirmation (might not return)
+ lda temp1 ; Get saved value
+ ret ; Return
+
+;[hh] fndkyw - find a keyword string from a table using
+; it's associated value
+; called with:
+; HL/ address of keyword table
+; A/ value associated with keyword string
+; returns:
+; success: HL points to first byte of keyword string
+; CY flag is cleared
+; error: HL points to error string (?Not found)
+; CY flag is set
+
+fndkyw: mov d,m ;get count of entries
+ inx h ;advance over count value
+fndkw1: mov b,m ;get string length
+ inr b ;account for $
+ inx h ;advance over length value
+ shld temp1 ;save string pointer
+fndkw2: inx h ;loop over string
+ dcr b
+ jnz fndkw2
+ mov c,m ;get keyword value from table
+ cmp c ;do they match?
+ jz fndkw3 ;Yup
+ inx h ;bump to next keyword
+ inx h ;
+ dcr d ;decrement entry count
+ jnz fndkw1 ;check the remaining keywords
+ lxi h,kywdnf ;point to not found message
+ stc ;give calling routine a not found flag
+ ret
+fndkw3: ora a ;clear CY to tell caller we succeeded
+ lhld temp1 ;restore the saved string pointer
+ ret
+
+kywdnf: db cr,lf,'?Not found$' ;not found message
+
+;
+; This is the SHOW command.
+
+show: call cfmcmd
+;* Reconcile this and status.
+ call clrtop ;[hh] Clear screen first
+ call stat01 ;For now just cop out.
+ jmp kermit
+
+; This is the STATUS command.
+
+status: call cfmcmd
+ call clrtop ;[hh] Clear screen first
+ call stat01
+ jmp kermit
+
+; processor for SHOW, STATUS and <escape>S commands
+; called by: show, status, intchr
+
+stat01: lda fileio ;Are we in transmit?
+ ora a
+ jz sta01b ;No
+ lxi d,xmtst ;Yes,say so
+ call prtstr
+
+; The following block of code - down to RET - re-ordered by [DJR]
+; DJR January 1987 to get SHOW/STATUS output in the same [DJR]
+; (alphabetical) order as SET's HELP. [DJR]
+sta01b:
+ call stautr ;[MF]Show AUTORECEIVE state
+ call stabcc ; Tell current block check type
+ call stabsz ; Tell user about multi-sector buffers
+ call stacol ;[MF]COLLISION state
+ call stadbg ; [DJR] Debug mode
+ call stacurd ; [DJR] Current disk
+ call stahfs ; Tell user if file sizez are hidden during DIR
+ call staesc ; Tell current escape character
+ call stafil ; Tell about file type
+ call staflo ;[10] Tell about flow control
+ call staibm ; Tell about IBM flag
+ call stainc ;[MF]Tell about incomplete file disposition
+;
+; Ask user to press a key before continuing
+;
+ call pausit ; wait for a while till user presses a key
+;
+ call staeco ; Tell about local echo flag
+ call stalog ; [pcc003] Tell about log file status
+ call stapar ; Tell about parity
+ lhld prttab ;[hh] Got a port table? (is pointer nonzero?)
+ mov a,h ;[hh]
+ ora l ;[hh]
+ cnz stapor ;[hh] If so, tell which port we're using
+ call stalpt ; Tell about printer copy flag
+ call starps ;[MF]Show receive packet length
+ call starsp ;[gnn] tell rec. start-of-pkt char
+ call stasps ;[MF]Show send packet length
+ call stassp ;[gnn] tell send start-of-pkt char
+ lhld spdtab ; Got a speed table? (is pointer nonzero?)
+ mov a,h
+ ora l
+ cnz staspd ; If so, tell what speed we're running.
+ call statac ; Tell about TAC flag/intercept character.
+ call statim ; Tell about timer flag
+ call stusr ;[7] Tell about user
+ call statvt ; Tell about what emulation we are doing
+ call stawrn ; Tell about file-warning flag
+ ret
+
+; stautr - Show Autoreceive setting [MF]
+;
+stautr: lxi d,autrst ;[MF]Point to "Autoreceive" string
+ call prtstr ;[MF]and print it
+ lda autorc ;[MF]Get Autoreceive flag
+ jmp staton ;[MF]Say "on" or "off" and return
+
+; Show the value of the LOCAL-ECHO flag (On or Off).
+
+staeco: lxi d,locst ;Get the address of the local echo string.
+ call prtstr
+ lda ecoflg ;Get the local echo flag.
+ jmp staton ;Say ON or OFF, and return
+
+; Show the value of the VT52-EMULATION flag (On, Off, or Not Supported).
+; Also show terminal display mode (regular, quiet)
+
+statvt: lxi d,vtdpst ;[MF]Get address of terminal display string
+ call prtstr ;[MF]Print it
+ lxi d,vtdpsr ;[MF]Assume a regular (loud) display
+ lda quietd ;[MF]Get "quiet" flag
+ ora a ;[MF]a quiet display?
+ jz statva ;[MF]No, print "regular" message
+ lxi d,vtdpsq ;[MF]Yes, point to "quiet" string
+statva: call prtstr ;[MF]and print it
+ lxi d,vtemst ; Get the address of the VT52 emulation string.
+ call prtstr
+ lda vtflg ; Get the VT52 emulation flag.
+ cpi 0ffh ; isterminal emulation possible?
+ jnz statv0 ; yes, maybe
+ lxi h,inms11 ; ... no, load up not implemented message ...
+ jmp prvtv ; so tell user
+
+
+statv0: mov c,a ; save it to C
+ lxi h,sttert ; get table listing what we can do
+ mov b,m ; get number of terminal types to b
+statv1: inx h ; point to first entry
+ mov e,m ; get length of entry
+ mvi d,0
+ inx h ; point to text part of entry
+ xchg ; save address in de
+ dad d ; start + length
+ inx h ;... + 1 for the dollar...
+ inx h ; plus point to seconcd copy of ter. type value
+ cmp m ; is it the one we want?
+ jz prvtv ; yes, then print the terminal type value
+ dcr b ; have we completed?
+ rz ; yes, then just exit back to status
+ jmp statv1 ; else try next entry. HL points to next -1
+
+prvtv: jmp prtstr ; print string from DE
+ ;[MF]and return
+
+; Show the value of the FILE-MODE flag (ASCII, Binary, or Default).
+
+stafil: lxi d,cpmst ; Get the address of the file mode message.
+ call prtstr
+ lda cpmflg ; Get the file mode flag.
+ lxi d,defstr ; Assume Default (0).
+ ora a ; Is it?
+ jz prtstr ; If so, say so, and return.
+ lxi d,ascstr ; Not default, assume ASCII
+ cpi 1 ; Is it ASCII?
+ jz prtstr ; Say ASCII, and return
+ lxi d,binstr ; Not default or ASCII, must be binary
+ jmp prtstr ; Print type, and return.
+;
+;Show current disposition for incomplete files [MF]
+;
+stainc: lxi d,incst ;[MF]Announce what's to be shown
+ call prtstr ;[MF]...
+ lxi d,dscstr ;[MF]Assume "discard"
+ lda incflg ;[MF]Get flag
+ ora a ;[MF]Really discarding incomplete files?
+ jz prtstr ;[MF]Yes, say so and return
+ lxi d,kepstr ;[MF]No, say we're keeping incomplete files
+ jmp prtstr ;[MF]and return
+
+; show if file sizes are hidden during DIR (Would have thought this
+; obvious, but its in for completeness
+stahfs: lxi d,hfsod ; get hide file size on dir
+ call prtstr
+ lda hidefs
+ jmp staton ; say if on or off
+
+; Show the value of the IBM-MODE flag (On or Off).
+
+staibm: lxi d,ibmst ;IBM string.
+ call prtstr
+ lda ibmflg ; Get IBM flag.
+ jmp staton ; Print its value and return
+
+; Show the value of the FILE-WARNING flag (On or Off).
+
+stawrn: lxi d,filst ; File warning string.
+ call prtstr
+ lda flwflg ; File warning flag.
+ jmp staton ; Say ON or OFF
+
+; Show the value of the PRINTER flag (On or Off).
+
+stalpt: lxi d,prst ;Printer copy string
+ call prtstr
+ lda prnflg ;Printer ON/OFF flag
+ jmp staton ; Say ON or OFF
+
+
+; Show status of log file
+stalog: lxi d,logst ;[pcc003] Logging lead-in message
+ call prtstr ;[pcc003]
+; name of logging file
+; Code derived from [JD's] code for GET, and uses his FNBUF [DJR]
+ lxi d,fnbuf ;[DJR] point to destination
+ lxi h,lognam ;[DJR] source of filespec
+ mov a,m ;[DJR] get drive byte
+ ora a ;[DJR] zero = default disc
+ jnz stalg1 ;[DJR] if drive has been specified
+ lda curdsk ;[DJR] otherwise get the default
+stalg1: adi 'A'-1 ;[DJR] make it printable
+ stax d ;[DJR] into dest block
+ inx d ;[DJR]
+ mvi a,':' ;[DJR] colon after drive
+ stax d ;[DJR]
+ inx d ;[DJR]
+
+ mvi c,8 ;[DJR] length of name part
+ lxi h,lognam+1 ;[DJR] start of name
+ mvi b,0 ;[DJR] first-time-thru flag
+stalga: mov a,m ;[DJR] get a char from the name
+ inx h ;[DJR] pass it
+ cpi ' ' ;[DJR] end of this part of name?
+ jz stalgb ;[DJR] yes, skip rest...
+ stax d ;[DJR] else drop char into dest
+ inx d ;[DJR] increment dest ptr
+ dcr c ;[DJR] decrement count
+ jnz stalga ;[DJR] and continue if more to go
+
+stalgb: mov a,b ;[DJR]
+ ora a ;[DJR] first time thru?
+ jnz stalgc ;[DJR] no, no period
+ mvi a,'.' ;[DJR] period between parts
+ stax d ;[DJR]
+ inx d ;[DJR]
+ mvi b,0ffh ;[DJR] not first time thru anymore
+ mvi c,3 ;[DJR] length of ext part
+ lxi h,lognam+9 ;[DJR] start of extension
+ jmp stalga ;[DJR] keep copying
+
+stalgc: mvi a,'$'
+ stax d ;[DJR] end the name string
+ lxi d,fnbuf ;[DJR] Print the file name
+ call prtstr ;[DJR]
+
+ lxi d,logst2 ;[DJR] second part of message
+ call prtstr ;[DJR]
+
+; Show status of logging
+ lda logflg ;[pcc003] get the flag
+ ani 7FH ;[pcc003] ignore open flag
+ cpi 2 ;[pcc003] is it suspended?
+ jnz staton ;[pcc003] no, must be on or off
+ lxi d,susstr ;[pcc003] suspended
+ jp prtstr ;[pcc003] print and return
+
+; Show the value of the PARITY flag (Odd, Even, Mark, Space, or None).
+
+stapar: lxi d,parst ;Parity string.
+ call prtstr
+ lda parity ;Get the parity setting.
+ lxi d,pnonst ;Assume parity is NONE
+ cpi parnon ;Were we right?
+ jz prtstr ;Yep, go say None, and return
+ lxi d,pmrkst ;Get ready to say Mark
+ cpi parmrk ;Is it mark?
+ jz prtstr ;Yep, go say Mark, and return
+ lxi d,pspcst ;Get ready to say Space
+ cpi parspc ;Is it space?
+ jz prtstr ;Yep, go say Space, and return
+ lxi d,poddst ;Get ready to say Odd
+ cpi parodd ;Is it odd?
+ jz prtstr ;Yep, go say Odd, and return
+ lxi d,pevnst ;Must be Even.
+ jmp prtstr ;Say Even, and return.
+
+; [gnn] Show start of packet characters
+stassp: lxi d,sspmsg ;message of send s-o-p
+ call prtstr
+ lda sndsop
+ adi 'A'-1 ;convert to printable character
+ mov e,a
+ mvi c,conout
+ jmp bdos ;and print it
+starsp: lxi d,rspmsg ;rec. s-o-p message
+ call prtstr
+ lda rcvsop
+ adi 'A'-1 ;convert to printable character
+ mov e,a
+ mvi c,conout
+ jmp bdos ;and print it
+;
+;[MF]Show receive packet length
+;
+starps: lxi d,rpsmsg ;[MF]Point to message
+ call prtstr ;[MF]and print it
+ lda rpsiz ;[MF]Get receive packet length
+ mov l,a ;[MF]Put in HL
+ mvi h,0 ;[MF]...
+ jmp nout ;[MF]Print receive packet length in decimal
+;
+;[MF]stasps - Print send packet length
+;
+stasps: lxi d,spsmsg ;[MF]Point to message
+ call prtstr ;[MF]and print it
+ lda spsiz ;[MF]Get send packet length
+ mov l,a ;[MF]into HL
+ mvi h,0 ;[MF]...
+ jmp nout ;[MF]and print in decimal
+
+;[hh] Show the current port (if known).
+
+stapor: lxi d,porst ;[hh]
+ call prtstr ;[hh]
+ lda port ;[hh] Get current port value
+ lxi h,spdust ;[hh] Assume undefined (this error msg is fine)
+ cpi 0FFH ;[hh] Is it?
+ jz stat73 ;[hh] Yup. Say so
+ lhld prttab ;[hh] Address of port keyword table
+ call fndkyw ;[hh] Look for correct keyword string
+ jnc stpr1 ;[hh] Found a match
+ lxi h,spdust ;[hh] No match found - say it's undefined
+stpr1: jmp stat73 ;[hh] Print it and return
+
+; Show the current line speed (if known).
+
+staspd: lxi d,spdst
+ call prtstr
+ lda speed ;Get current speed.
+ lxi h,spdust ;Assume undefined.
+ cpi 0FFH ;Is it?
+ jz stat73 ;Yes.
+ lhld spdtab ;Start scanning keyword table.
+ mov d,m ; get count of entries
+ inx h ; advance over it.
+stat70: mov b,m ;Get string length.
+ inr b ;Account for $.
+ inx h
+ shld temp1 ;Save string pointer.
+stat71: inx h ;Loop over string.
+ dcr b
+ jnz stat71
+ mov c,m ;Get speed value
+ cmp c ;Match?
+ jz stat72 ;Yes.
+ inx h ;Bump to next keyword.
+ inx h
+ dcr d ; decrement entry count
+ jnz stat70 ; if more left, check them.
+ lxi h,spdust ; can't find it. say it's undefined.
+ jmp stat73 ; print the message.
+
+stat72: lhld temp1 ;Restore saved string pointer.
+ xchg ;[MF] Set into DE for display
+ call prtstr ;[MF] Print speed
+ lxi h,spdst2 ;[MF] Point to "bps" message
+stat73: xchg ;Set into DE for display.
+ jmp prtstr ; print it, and return.
+
+; Show the current BLOCK-CHECK-TYPE (1-, 2-, or 3-character).
+
+stabcc: lxi d,bckst ;Get the string
+ call prtstr ;Print "Block check type: "
+ lda chktyp ;Get the type (character 1, 2, or 3)
+ mov e,a ;Put into E
+ mvi c,conout ;Want to print it
+ call BDOS ;Do so
+ lxi d,bckst1 ;Get rest of text ("-character")
+ jmp prtstr ;Print it and return
+;
+;[MF]stacol - Print "SET COLLISION" state
+;
+stacol: lxi d,collst ;[MF]Get message
+ call prtstr ;[MF]Print it
+ lxi h,coltab ;[MF]Point to COLLISION keywords
+ lda flwflg ;[MF]Get COLLISION state
+ call fndkyw ;[MF]Get COLLISION state
+ ;[MF](Since user doesn't control flwflg
+ ;[MF]directly, no need to check for errors
+ xchg ;[MF]Prepare for printing
+ jmp prtstr ;[MF]Print COLLISION state and return
+
+; Print the current escape character
+
+staesc: lxi d,escst ;Escape string.
+ call prtstr
+ call escpr ;Print the escape char.
+; jmp prcrlf ;removed [DJR] Print CR/LF and return [Toad Hall]
+ ret ;[DJR] added
+
+; Show number proportion of buffers used in multiple sector buffering
+stabsz: lxi d,bufsz1
+ call prtstr ; do first bit of string
+ lxi h,0
+ lda bufsec
+ mov l,a ; get size used...
+ call nout ;... to screen
+ lxi d,bufsz2 ; and then say max value
+ call prtstr
+ lxi h,0
+ lda maxbsc ; get max for this system
+ mov l,a
+ call nout ;.. thence to screen
+; jmp prcrlf ; removed [DJR] cr lf and out
+ ret ;[DJR]
+
+;
+; Show the value of the TIMER flag
+statim: lxi d,timmsg ;[jd]
+ call prtstr ;[jd]
+ lda timflg
+ jmp staton ;Tell whether it's on or off.
+
+; Show internal versions (edit strings)
+shover: call cfmcmd
+ call prcrlf
+ lxi d,version ;[MF]Point to Kermit version
+ call prtstr ;[MF]and show it
+ lxi d,modmsg ;[MF]Continue the message
+ call prtstr ;[MF]...
+ call prcrlf ;[MF]End the line
+ lxi h,vertab ; Get address of version list
+shovr1: mov e,m ; Get next word from list
+ inx h
+ mov d,m ; Next version string is in DE
+ inx h
+ mov a,d ; Test for zero (end of list)
+ ora e
+ jz shovr2 ; Done with list if zero
+ push h ; Save position in list
+ call prtstr ; Not zero. Print it.
+ call prcrlf ; Follow with crlf
+ pop h ; Restore position in list
+ jmp shovr1 ; and go see if there are any more.
+
+shovr2: lhld ovlver ; Get overlay version string
+ xchg ; into DE
+ call prtstr ; Print it
+ call prcrlf ; Output crlf
+ lhld family ;[11] New entry in overlay. Get string of
+ xchg ;[11] family of machines (eg apple) and print
+ call prtstr ;[11] it. For "common" m/c do a $ only.
+ jmp kermit ; Return to main loop.
+
+; table of pointers to version strings.
+vertab: dw mitver ; CPSMIT
+ dw comver ; CPSCOM
+ dw pk1ver ; CPSPK1
+ dw pk2ver ; CPSPK2
+ dw remver ; CPSREM
+ dw server ; CPSSER
+ dw ttver ; CPSTT
+ dw cpmver ; CPSCPM
+ dw wldver ; CPSWLD
+ dw cmdver ; CPSCMD
+ dw utlver ; CPSUTL
+ dw datver ; CPSDAT
+ dw 0 ; end of list
+
+; Show TACTrap status (On or Off, and intercept character)
+statac: lxi d,tacst ;"Current TACTrap status/char: "
+ call prtstr
+ lxi d,offstr ;Assume set off
+ lda tacflg ;Get the TACTrap char/flag
+ ora a ;Is it off?
+ jz prtstr ;Yep, go print OFF...
+ mvi c,conout ;Display...
+ mov e,a ;...the current intercept char
+ call bdos
+ jmp prcrlf
+
+; Show if flow control is set on or off
+staflo: lxi d,flost ; Flow control string
+ call prtstr
+ lda floctl ; get the flag
+ jmp staton
+
+; Show if Case sensitvity is on or off
+;stasens:
+; lxi d,senst ; case sensitivity string
+; call prtstr ;
+; lda casens
+; jmp staton ; say if its on or off
+
+
+; Show the current user. (Should do this under directory...)
+stusr:
+ mvi c,usrcod
+ mvi e,0ffh ;[9] get the current user
+ call bdos
+ mov l,a ;[9] print hl as a number...
+ mvi h,0
+ push h ;[9] got the user number
+ lxi d,usrst ;[9] tell the user number
+ call prtstr
+ pop h ;[9] now do number
+ call nout ;[6] using routine for writing packet nos.
+ ret
+
+;
+;
+; [DJR] Show debug mode
+stadbg:
+ lxi d,dbgst ;[DJR] Display string
+ call prtstr ;[DJR]
+ lda dbgflg ;[DJR] load flag
+ jmp staton ;[DJR]
+
+
+; [DJR] Show default disk
+stacurd:
+ lxi d,curdst ;[DJR]
+ call prtstr ;[DJR]
+ lda curdsk ;[DJR]
+ adi 'A'-1 ;[DJR]
+ mov e,a ;[DJR]
+ mvi c,conout ;[DJR]
+ jmp bdos ;[DJR]
+
+;
+; Display current state of a boolean flag.
+; called with A/ value (zero = Off, non-zero = On)
+
+staton: lxi d,onstr ; Assume it's on.
+ ora a ; Is it on?
+ jnz prtstr ; If so, say so, then return.
+ lxi d,offstr ; No, say off.
+ jmp prtstr ; Print the string, then return.
+
+; STRING command
+; get a string from the user and send it to the host.
+string: mvi a,cmtxt ; get the text
+ lxi d,stbuff ; where to put it
+ call comnd
+ jmp kermit ; if we cannot do it, then back to command level
+ sta strcnt ; save the string count
+ ana a ; if it is zero, then do nowt
+ jz kermit
+ call cfmcmd ;[MF]Otherwise, get a "confirm"
+ call selmdm ; then select the modem
+ lxi d,stbuff ; where to get the string
+stlop: ldax d ; get byte
+ inx d ; pointer plus one
+ push d ; update pointer, and save de, and the character
+ call setpar ; set whatever parity
+ mov e,a ; outmdm wants character in e
+ call outmdm ; send character in a to line
+ pop d
+ lda strcnt ; get the count
+ dcr a
+ sta strcnt ; less one
+ jnz stlop ; else still looping
+ call selcon ; re-select the console
+ jmp kermit
+
+; Print "(not implemented)".
+; here from vt52em, baud, prtset, stavt
+
+notimp: lxi d,inms12 ; Say it's not implemented.
+ call prtstr
+ jmp kermit ; Return to main loop.
+
+; Little code to allow some expansion of code without changing
+; every futher address, only up to the end of this file.
+; TO BE REMOVED FRO RELEASE!
+
+; org ($+100h) AND 0FF00H
+
+IF lasm ; If using LASM, chain to the next file.
+ LINK CPSPK1 ;[obs] break down them big files...
+ENDIF;lasm
diff --git a/cpscpm.asm b/cpscpm.asm
index 49df54f..230f147 100644
--- a/cpscpm.asm
+++ b/cpscpm.asm
@@ -1,932 +1,932 @@
-; CPSCPM.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file duplicates the CP/M DIR and ERA functions so we don't have
-; to exit.
-;
-; revision history:
-;
-;edit 14, 1-Apr-1991 by MF. Correct a bug which crept in with edit 13 which
-; caused any control-key other than ^Y or ^Z to act like ^X after a key
-; had been depressed to halt output of the TYPE/PRINT commands.
-;edit 13, 25-Mar-1991 by MF. Make the TYPE command always abort to Kermit
-; command-level if ^C is entered on the console even if multiple files
-; are being typed via wild-cards. Make ^X typed on the console abort
-; typeout of the current file and begin typeout of the next file,
-; if any, otherwise go back to Kermit command-level.
-; The foregoing also applies to the PRINT command.
-;edit 12, 14-Feb-1991 by MF. Call "clrtop" in TYPE command at "type1"
-; rather than sending a <ff> directly to the terminal as some
-; terminals don't respond to <ff> characters. Thus the screen will be
-; cleared (if the terminal allows) before each file is typed.
-; Also use "getfil" rather than the bdos "openf" call to open
-; files for typing (label "type2"). This tightens up the code.
-; Zero "fcbcnt" before starting to type files (label "type0b").
-; This apparently fixes a phantom bug which caused incorrect lookup (and
-; hence garbage typeout) of files occassionally after a new disk
-; was inserted and a SET DEFAULT-DISK was performed to reset the disk
-; system. (It looked like parts of other files were being typed, as
-; if the directory had been misread or had not been reset.)
-;edit 11, 8-Feb-1991 by MF. Cause the bdos call for direct console input
-; in "ckchr" **not** to go thru the bdos trap but to call bdos at 0005h
-; directly. This corrects a bug wherein if commands such as INPUT
-; (which check to see if a keyboard key has been pressed) were executed
-; from a TAKE-file, the character following the terminator of such
-; commands was being interpreted as that keyboard input, thus causing
-; the next command in the TAKE-file to be unrecognized since its
-; first character had been eaten as a result of the keyboard check.
-; This bug **may** be the cause of a report received by Dr. Martin
-; J. Carter of Nottingham University in the U.K. in which Kermit
-; was reported to have read a character beyond a command terminator
-; in a TAKE-file, making the subsequent command unrecognizable since
-; its first character was missing.
-;edit 10, 29-Jan-1991 by MF. Use the big buffer for TYPE/PRINT commands.
-; Thus, edit 9 has been superseded.
-;edit 9, 29-Jan-1991 by MF. Corrected EOF check in TYPE command routine
-; following label "type20". a READF call, if successful, gives A=0
-; (not A=0FFH) and A not zero if failure. Thus the "INR A" instruction
-; checking for EOF was **always** nonzero. The reason the TYPE command
-; worked is that CP/M text files indicate the text end-of-file with a
-; Control-Z, in which case the TYPE routine branched correctly. In
-; other words, this edit is more for aesthetic purposes to satisfy
-; purists than something brought about by dire necessity!
-;edit 8, 28-Jan-1991 by MF. Added code courtesy of Dr. Martin J. Carter
-; of Nottingham University, UK, to use the big buffer for the COPY
-; command.
-;edit 7, 18-Sep-1990 by MF. Added RENAME routine to implement the
-; RENAME (FRENAME) command to rename a CP/M file.
-; Modified COPY routine to explicitly reject wild-carded filenames
-; by using COMND function CMOFI rather than functions CMIFI and
-; CMIFIN to get input and output filenames.
-; Modified ERA and COPY routines to not act upon the respective
-; commands until a "confirm" is typed. This prevents these
-; routines from taking off upon recognition of action characters
-; like "?", which can be quite annoying if one is an inexperienced user.
-; edit 6, March 11, 1987 by OBSchou. Added in the TYPE and PRINT commands
-; Both type to the screen, print also echoes to printer.
-;
-; edit 5 20 June, 1986. Added support for multiple file FCB buffering.
-;
-; edit 4: June 16, 1986 OBSchou at Loughborough University, UK
-; added in a test to prevent a DIR command issued from a TAKE command
-; being interruped by the next character in the take command buffer.
-; Also added code for USER nn. (Well, its OS related,is it not?)
-;
-; edit 3: July 8, 1984 (CJC)
-; Merge modifications from Toad Hall: support LASM (linked by CPSTT,
-; links to CPSWLD), use prcrlf where appropriate.
-;
-; edit 2: June 5, 1984 (CJC)
-; documentation and formatting; delete unused code (dir13); add module
-; version string.
-;
-; edit 1: May, 1984 (CJC)
-; extracted from CPMBASE.M80 version 3.9; modifications are described in
-; the accompanying .UPD file.
-;
-cpmver: db 'CPSCPM.ASM (14) 1-Apr-1991$' ; name, edit number, date
-
-npl EQU 04H ;Number of names per line for dir command.
-
-; This is the DIR command. Display the name and size of all files
-; matching the filespec.
-; here from: kermit
-;
-; Note: This is abstracted from Keith Peterson's DIRF.ASM
-; directory print function. Thanks again Keith.
-;
-;
-dir: lxi d,fcb ;Where to put the data, if any.
- mvi a,cmifin
- call comnd ;Parse a full or piece of file-spec
- jmp dir2 ;Didn't get a FULL file-spec
- jmp dir4 ;lets do it
-;
-;
-;Make FCB all '?' to match any file
-dir2: lda fcb
- cpi ' ' ;CMIFIN leaves that as ' '
- jnz dir2a ;he typed at least x:
- xra a
- sta fcb ;default drive
-dir2a: lxi h,fcb+1
- mvi b,11 ;FN+FT count.
-
-dir3: mvi m,'?' ;Store '?'s in FCB.
- inx h
- dcr b
- jnz dir3
-;Print signon message and drive name
-dir4: call getun ; get current user number
- lda fcb
- ora a ;if not zero, get default
- jnz dir4a
- lda curdsk ;get default
-dir4a: adi 'A'-1 ;Asciize it
- sta dnam14+2 ;[4] add in user no, and Save it in message.
- lda temp1+1 ;[4] most sig. user number
- cpi '0' ;[4] if zero set space
- jnz dir4b
- mvi a,' ' ;[4] space
-dir4b: sta dnam14 ;[4]
- lda temp1
- sta dnam14+1 ;[4] ls user number digit
- call prcrlf
- lxi d,inms14 ;Point to message
- call prtstr
-;
-;Initialize number of names per line counter
- mvi a,npl ;Nr. names per line.
- sta nnams ;Init counter.
- lda hidefs ; are we doing file size?
- ana a
- jnz dir4c ; we are not showing file size,
- lda nnams
- inr a
- sta nnams ; so we can show another name per line
-
-dir4c: xra a ; clear the flags ready for multi-sector buffering
- sta fcbcnt ; clear fcb counter
- sta mfflg1
- sta mfflg2
- sta mfflg3
- lxi h,fcb0 ; reset pointer for fcb save space
- shld xfcbptr
-;
- call dir26 ;Get disk parameters
- xra a ;[5] say first time round, so no spare fcbs
- sta fcbcnt ;[5]
-dir5: call mfname ;get some names
- jnc dir6 ;got one
- jmp dir17 ;got none - do summary
-
-dir6: ;Check for console break
- lda takflg ;[4] ... but not if issued from TAKE....
- ana a ;[4]
- jnz dir6a ;[4] we do the lot regardless.
-
- mvi c,consta ;Ck status of kbd.
- call bdos
- ora a ;Any key pressed?
- jz dir6a ;nope, keep going
- mvi c,conin
- call bdos ;gobble key
- jmp dir17 ;and print summary only
-
-;Print an entry
-dir6a:
- lxi h,fcb+1 ;point to Filename
- mvi b,8 ;File name length.
- call dir11 ;Type filename.
- mvi a,'.' ;Period after FN.
- call dir10
- mvi b,3 ;Get the filetype.
- call dir11
- call dir25 ;print size
- lxi h,nnams ;Point to names counter.
- dcr m ;One less on this line.
- push psw
- cnz dir7 ;No cr-lf needed, do fence.
- pop psw
- cz dir12 ;Cr-lf needed.
- jmp dir5
-
-;Print space, fence character, then space
-dir7: call dir9
- mvi a,':' ;Fence character.
- call dir10
- jmp dir9
-
-; dir8 - Print two spaces
-; dir9 - Print one space
-; dir10 - Type char in A register
-dir8: call dir9
-dir9: mvi a,' '
-dir10: push b
- push d
- push h
- mov e,a ;Char to E for CP/M.
- mvi c,conout ;Write char to console function.
- call bdos
- pop h
- pop d
- pop b
- ret
-
-;Type (B) characters from memory (HL)
-dir11: mov a,m
- ani 7FH ;Remove CP/M 2.x attributes.
- call dir10
- inx h
- dcr b
- jnz dir11
- ret
-
-;CR-LF routine. HL=NNAMS upon entry
-dir12: push b
- push d
- push h
- call prcrlf ;Print CR/LF [Toad Hall]
- pop h ;(did use call to dir10, but slooow)
- pop d
- pop b
- mvi m,npl ;Number of names per line.
- lda hidefs ; are we showing file size?
- ana a
- rnz ; no, so all ok
- inr m ; else show another file per line
- ret
-
-;Exit - All done, return via jmp (as for all main commands)
-dir16: call prcrlf
- lda curdsk
- dcr a ;relative to 0
- mov e,a
- mvi c,logdsk
- call bdos ;back to "logged in" disk
- jmp kermit ;...and return to kermit.
-
-;
-;Determines free space remaining
-;
-dir17: xra a
- sta mfflg1 ;clean up MFNAME
- sta mfflg2
- lda fcb ; get drive number from FCB
- ora a
- jz dir18 ; default?
- dcr a ; no, make requested drive current drive.
- mov e,a
- mvi c,logdsk
- call bdos
-dir18: call sysspc ; get space available for current drive
- push h
- lxi d,inms15 ;"Drive "
- call prtstr
- lda fcb ;If no drive, get
- ora a ;logged in drive
- jnz dir24
- mvi c,rddrv
- call bdos
- inr a
-dir24: adi 'A'-1
- sta inms16
- lxi d,inms16 ;"x has "
- call prtstr
- pop h ;Get number of bytes available
- call nout
- lxi d,inms17 ;"K bytes free"
- call prtstr
- jmp dir16 ;all done
-
-;Compute the size of the file
-
-dir25: lda hidefs ; do we show file size?
- ana a ; if non zero, we dont.
- rz ; so just return
- mvi c,cflsz ;get file-size
- lxi d,fcb
- call bdos
- lda fcbrno ;shift least sign. part
- lxi b,0 ;init bc
- mov l,a
- ani 7
- jz dir250 ;even K
- lxi b,1 ;save for later
-dir250: push b ;save 0 or 1 to add to size
- mvi b,3 ;shift 3 bits
-dir25a: xra a ;clear sign
- lda fcbrno+1 ;get most sig byte
- rar ;shift right
- sta fcbrno+1 ;put back
- lda fcbrno ;get least sig part
- rar
- sta fcbrno
- dcr b ;loop 3 times
- jnz dir25a
- mov l,a ;size in HL
- lda fcbrno+1
- mov h,a
- pop b ;get 0 or 1
- dad b ;round up to KB used
- lda bmask ;get (sectors/block)-1
- rrc
- rrc ;get (K/block)-1
- rrc
- ani 1FH
- mov c,a
- dad b ;add (K/block)-1 to size to round up
- cma ;make a mask
- ana l ;truncate after rounding up
- mov l,a
- push h
- lxi b,-10 ;subtract 10
- dad b
- jc dir25d ;>= 10
- call dir8 ; print a leading space
- jmp dir25e
-
-dir25d: pop h ;get size again
- push h
- lxi b,-100 ;subtract 100
- dad b
- jc dir25e ;>= 100
- call dir9 ; print another leading space
-dir25e: call dir9 ;a space
- pop h ;get size back
- call nout ;..go print it
- mvi a,'k' ;..and follow with K size
- call dir10
- ret
-
-dir26: mvi c,gtdpar ;current DISK PARAMETER BLOCK
- call bdos
- inx h
- inx h
- mov a,m ;Get Block Shift Factor
- sta bshiftf
- inx h ;Bump to Block Mask
- mov a,m ;get it
- sta bmask
- inx h
- inx h
- mov e,m ;Get Max Block number
- inx h
- mov d,m
- xchg
- shld bmax ;Put it away
- ret
-;
-; ERA command - erase a CP/M file
-; here from: kermit
-
-era: mvi a,cmifi ;Parse a file-spec
- lxi d,fcb ;into FCB
- call comnd
- jmp kermit ;bad parse
- mvi a,cmcfm ;[MF]Get a confirm from the user
- call comnd ;[MF]...
- jmp kermit ;[MF]NO? try another command
- lxi d,fcb
- mvi c,sfirst ;check if valid
- call bdos
- inr a ;0 if FILE not found
- jnz era1 ;found at least one
- lxi d,erms15 ;"unable to find file"
- call prtstr
- jmp kermit
-
-era1: lxi d,fcb
- mvi c,delf
- call bdos
- lxi d,inms18 ;" File(s) erased"
- call prtstr
- jmp kermit
-
-; USER - select a new user. This is an unusual routine in that the user
-; enters a number. The others take on/off or filename (except
-; set escape
-;
-user: mvi a,cmnum ; go parse a number
- call comnd
- jmp kermit ; if we can not do it, quit to command loop
- mvi a,cmcfm ; get a confirm from the user
- call comnd
- jmp kermit ; if no, then try another command
- lhld number ; else get the number...
- xchg ; until a non valid digit is typed (eg cr)
- lxi h,-32 ; if a carry, then ok
- dad d ; ... else its above 32
- jc user1
- xchg ; restor number in hl again
- mov a,l ; Lets save it
- sta curusr ; as current user number
- mov e,l ; get user no to e...
- mvi c,usrcod
- call bdos
- call getun ; get user number to temp1 and temp2
- lda temp2
- cpi '0'
- jnz user0 ; dont do ms digit if a zero
- mvi a,' '
-user0: sta kerm1 ; save into string etc
- sta dnam14 ; also for dir command
- lda temp1
- sta kerm1+1
- sta dnam14+1 ; also for dir command
- jmp kermit
-
-user1: lxi d,erms23 ; tell user sorry
- call prtstr
- jmp kermit
-
-
-;
-; TYPE - type a file or files to the console.
-;
-; This utility also used by print, where the characters printed to
-; the console are also copied to the printer if the prnfl flag
-; is non-zero. Uses mfname to type (print) multiple names.
-; Each file is preceeded with a formfeed character (usually clears
-; the screen on a VDU)
-;
-
-type: mvi a,cmifi ; parse a file name
- lxi d,fcb ; let the parser know where the FCB is
- call comnd
- jmp type02 ; if error say so
-
-type0b:
- xra a ; clear some flags for mfname
- sta mfflg1
- sta mfflg2
- sta mfflg3
- sta fcbcnt ;[12]...
- lxi h,fcb0 ; reset the fcb pointers etc
- shld fcbptr
- call mfname
- jc type02 ; match not found
-
-;[MF][10]The following code to type a file using a 1-sector buffer has
-;[MF][10]been replaced by code to use the "big buffer" -- 30-Jan-1991
-;type1: lxi d,buff ; point to the default DMA address
-; mvi c,setdma
-; call bdos ; tell bdos where to put the dma address
-; mvi a,ff ; do a form feed
-; call typit
-; xra a ; clear the character count
-; sta chrcnt
-;
-;type2: mvi c,openf ; open the file for reading
-; lxi d,fcb
-; xra a ; but first clear bits of fcb...
-; sta fcb+12
-; sta fcb+14
-; sta fcb+15
-; sta fcb+32
-; call bdos ; NOW open the file
-;
-;type20: mvi c,readf ; open up the file and read first sector
-; lxi d,fcb
-; call bdos
-;;[MF][9]Correct EOF test below (next two instructions)
-;; inr a ; if 0ffh returned, error. Assume EOF
-;; jz typex ; so exit from here
-; ora a ;[MF][9]If error, assume EOF
-; jnz typex ;[MF][9]so exit
-; lxi h,0 ; else clear the pointer into the file
-; shld typptr
-;
-;
-;type2a: lxi d,buff ;ok, so lets get the byte to print
-; lhld typptr
-; dad d ; add offset to the DMA base
-; mov a,m ; and get character to type (print)
-; ani 7fh ; make sure it is printable
-; cpi 20h ; is it a control character?
-; jp type3
-; cpi 09h ; if its a tab, then expand it
-; jnz type2b
-;
-;type2c: mvi a,' ' ; send a space
-; call typit ; type it
-; lda chrcnt ; get the number of chrs so far
-; ani 7h ; see of an 8th pos?
-; jnz type2c ; loop until all spaces done, then exit
-; jmp type4
-;
-;type2b: cpi cr ; is it a cr or lf?
-; jnz type2d
-; call typit ; do a cr
-; xra a
-; sta chrcnt ; cr of lf => clear character count
-; jmp type4 ; and exit
-;
-;type2d: cpi lf
-; jnz type2e
-; call typit ; print the character
-; xra a
-; sta chrcnt ; cr or lf clears the character count
-; jmp type4
-;
-;type2e: cpi cntlz ; is it end of file?
-; jnz type2f
-; jmp typex ; yes, so close and try for another file
-;
-;type2f: push psw ; control char - save the character
-; mvi a,'^' ; send control chars as ^A, for ex.
-; call typit
-; pop psw
-;
-;type3: call typit
-;
-;
-;type4: lhld typptr ; get the pointer
-; inx h
-; shld typptr ; up it by one character, and save it.
-; mov a,l ; lets see if the sector has been typed
-; ana a
-; jm type20 ; if 80h => read new sector
-; jmp type2a ; else just continue along
-
-;[MF][10]The following code uses the "big buffer" to read the file
-;[MF][10]which is to be typed
-;[12]Clear the screen explicitly as some terminals don't respond
-;[12]to the <ff> character.
-;type1: mvi a,ff ; do a form feed
-; call typit
-type1: call clrtop ;[12] Clear the screen
- xra a ; clear the character count
- sta temp1 ;[MF]alias column counter
-
-type2:
-;[12]Eliminate call to openf in favor of call to "getfil"
-; mvi c,openf ; open the file for reading
- lxi d,fcb
-; xra a ; but first clear bits of fcb...
-; sta fcb+12
-; sta fcb+14
-; sta fcb+15
-; sta fcb+32
-; call bdos ; NOW open the file
- call getfil ;[12] NOW open the file
-
-type20: call inbuf ;[MF]Fill input buffers
- jmp typex ;[MF]Tru end-of-file reached
- jmp type21 ;[MF]Begin typing/printing characters
-
-type2a: lda chrcnt ;[MF]Get buffer character counter
- dcr a ;[MF]and decrement it
- jm type20 ;[MF]Get more characters if needed
-type21: sta chrcnt ;[MF]else remember new buffer character counter
- lhld bufpnt ;[MF]Now get character pointer
- mov a,m ; and get character to type (print)
- inx h ;[MF]Increment the pointer
- shld bufpnt ;[MF]and remember it
- ani 7fh ; make sure character is printable
- cpi 20h ; is it a control character?
- jp type3
- cpi 09h ; if its a tab, then expand it
- jnz type2b
-
-type2c: mvi a,' ' ; send a space
- call typit ; type it
- lda temp1 ;[MF]Get the number of characters so far
- ani 7h ; see if an 8th pos?
- jnz type2c ; loop until all spaces done, then exit
- jmp type2a ;[MF]and continue
-
-type2b: cpi cr ; is it a cr or lf?
- jnz type2d
- call typit ; do a cr
- xra a
- sta temp1 ; cr or lf => clear character count
- jmp type2a ;[MF]and continue
-
-type2d: cpi lf
- jnz type2e
- call typit ; print the character
- xra a
- sta temp1 ; cr or lf clears the character count
- jmp type2a ;[MF]and continue
-
-type2e: cpi cntlz ; is it end of file?
- jnz type2f
- jmp typex ; yes, so close and try for another file
-
-type2f: push psw ; control char - save the character
- mvi a,'^' ; send control chars as ^A, for ex.
- call typit
- pop psw
-
-type3: call typit
- jmp type2a ; and continue along
-
-typex: mvi c,closf
- lxi d,fcb
- call bdos ; close the file
- mvi a,cr ; send cr lf to screen/printer to clear buffers
- call typit
- mvi a,lf
- call typit
- call mfname ; and see if there are other files to type
- jnc type1 ; yup, so go do it
- xra a ; make sure the flag is reset
- sta prnfl
- jmp kermit ; then exit.
-
-typex0: mvi c,closf ;[MF]Close the file
- lxi d,fcb ;[MF]...
- call bdos ;[MF]...
- mvi a,cr ;[MF]Clear buffers
- call typit ;[MF]...
- mvi a,lf ;[MF]...
- call typit ;[MF]...
- xra a ;[MF]Clear flag
- sta prnfl ;[MF]...
- lda takflg ;[MF]See if we're TAKEing commands
- ani 1 ;[MF]from a file
- cnz closet ;[MF]If we are, abort TAKE-file processing
- jmp kermit ;[MF]Back to Kermit command-level
-
-; error for file not found for type
-type02: lxi d,nofile ; say no file name (its invalid)
- call prtstr
- xra a
- sta prnfl ; clear the flag
- jmp kermit ; so abort
-
-
-typit: mov e,a
- call ckqtyp ; see if a cntl-c or other character from user
- jmp typit2 ;[MF] Control-C entered, abort
- jc typit1 ; CNTL-X entered, so abort file [MF]
- push d ; save for a bit
- call outcon ; send it to the console
- lda temp1 ; update the number of characters sent[MF]
- inr a
- sta temp1 ;[MF]
- pop d
- lda prnfl ; see if we have to print it too
- ana a
- rz
- call outprn ; send character to printer (buffer)
- ret
-
-typit1: pop d ; adjust stack again
- jmp typex ; and say we are done (for this file)
-
-typit2: pop d ;[MF] Adjust the stack
- jmp typex0 ;[MF] and abort file typeout completely
-
-
-; CKQTYP - CHeck for requested Quiet TYPe (ie hang on a second)
-; Routine sees if the user has typed ANY key. If a key HAS been pressed
-; see if its a Control-c. If so, flag for an abort, else wait for
-; a second entry from the user. If its a Control C, flag an abort
-; else continue with the print.
-; note: only the DE registers maintained. All others destroyed.
-; **NOTE** CKQTYP now gives a nonskip return if Control-C is typed,
-; a skip-return with carry set if a Control-X is typed and a skip-return
-; with carry clear if any other character is typed as the second
-; character.
-
-ckqtyp: push d ; save the character to be printed
- call ckchr ; see if user entered a character
- ani 7fh ; strip parity etc
- jz ckqty3 ; nothing entered, so go on as usual (See below)
- cpi ctrlc ; control c?
- jz ckqt1a ;[MF] Yup, give nonskip return
- cpi 'X'-100o ;[MF] If Control-X,
- jz ckqty1 ; yup, set carry and exit
-ckqty2: call ckchr ; another character to wait for (ie pause)
- ani 7fh
- jz ckqty2 ; wait until some input
- cpi ctrlc ; if control c, abort
- jz ckqt1a ;[MF] ...
- cpi 'X'-100o ;[MF] Control-X?
- jz ckqty1 ; yuss, so flag abort file [MF]
-ckqty3: pop d ; else restore the character to be typed [MF]
-; ret ; no, so continue with type/print
- stc ;[MF]Set carry
- cmc ;[MF]Then clear it
- jmp rskp ;[MF] Continue with type/print (skip ret)
-
-ckqty1: pop d ; restore stack again
- stc ; set carry and return
-; ret
- jmp rskp ;[MF] ...
-
-ckqt1a: pop d ;[MF] Adjust stack
- ret ;[MF] and return
-
-;[MF][14]No longer need these lines
-;ckqty3: pop d ; restore stack again
-;; ret
-; stc ;[MF] Clear carry
-; cmc ;[MF] ...
-; jmp rskp ;[MF] and give skip return
-
-ckchr: call selcon ; make sure we are talking to the console
- mvi e,0ffh ; see if user has any input for us
- mvi c,dconio
-; call bdos ;[11]Don't go thru bdos trap
- call 0005h ;[11]Call bdos directly
- ret ; This routine does not care what comes back
-
-
-;
-; COPY - routine to copy from a source file to a destination file
-; from the Kermit command state.
-;
-; Note. This could be tricky, as there are several forms of copy
-; copy d:source.ext d:dest.ext (Easy one)
-; copy d:source.ext d: (File to another drive)
-; copy d:source.??? d: (several files)
-; copy d:*.* d: (Several files)
-;
-; Initially, lets make it top one, and see how we go, ok?
-;
-;
-;Things to do for copy:
-; 1) get source name
-; 2) get target name
-; 3) if both source and destination = abort
-; 4) if source does not exist abort
-; 5) attempt to delete destination file if it exists
-; 6) open source and destination files
-; 7) copy file across
-; 8) close all files
-; 9) return to command mode
-;
-copy: ; Here goes...
-; 1) get source file name
- mvi a,cmofi ; go parse a file name
- ;[MF]Nonwild
- lxi d,cfcbs ; use the source for copy FCB (Allows copy
- call comnd ; from a TAKE file etc)
- jmp kermit ; if error, abort
-
-; 2) get target name
- mvi a,cmofi ; go parse a target file name
- ;[MF]Again, nonwild
- lxi d,cfcbd ; use destination fcb
- call comnd ; get it
- jmp kermit ;[MF]Couldn't.
- mvi a,cmcfm ;[MF]Get a confirm from the user
- call comnd ;[MF]...
- jmp kermit ;[MF]No? try another command
-
-; 3) see if both target and source are equal
-copy0: mvi b,12 ; we are gonna test drive, file and extention
- lxi d,cfcbs ; from source file name...
- lxi h,cfcbd ; to destination file name
- xra a ; clear flag for difference found
- sta equflg
-copy1: ldax d ; get source file name character
- cmp m ; test with targer file name
- jz copy2 ; if equal, do nothing
- lda equflg ; else update flage (ie files are different)
- inr a
- sta equflg
-copy2: inx h
- inx d
- dcr b
- jnz copy1 ; up pointers and test for next char
-
- lda equflg ; if still null, then its a daft thing to do
- ana a
- jnz copy3 ; its not a daft thing to do
- lxi d,samems ; load up "File source and destination the same"
- call prtstr ; tell user
- jmp kermit ; and try again
-
-; 4) If source does not exist, abort. Assume we have a full file name.
-copy3:
- lxi d,cfcbs ; load up source fcb
- mvi c,openf ; open file
- call bdos
- inr a ; error on open?
- jnz copy4
- lxi d,nofile ; assume file not found
- call prtstr
- jmp kermit ; and die
-
-copy4: lxi d,cfcbd ; load up destination fcb
- mvi c,delf ; destroy target name if it exists
- call bdos ; ignore error messages
- lxi d,cfcbd ; load up destination fcb
- mvi c,makef ; make a file
- call bdos
- inr a ; make error?
- jnz copy4a
- lxi d,erms12 ; no directory space
- call prtstr
- jmp copy7 ; close source file
-
-copy4a: lxi d,cfcbd ; load up destination fcb...
- mvi c,openf ; for open
- call bdos
- inr a ; error on open?
- jnz copy5 ; could do with better error detection...
- lxi d,erms15 ;... but assume its a disk full
- call prtstr
- jmp copy7 ; close source file and jmp kermit
-
-;copy5: lxi d,buff ; set default dma address to 80h
-; mvi c,setdma
-; call bdos
-;
-;copy6: lxi d,cfcbs ; copy routine proper.. get a sector
-; mvi c,readf
-; call bdos
-; ana a ; error reading the file?
-; jnz copy8 ; yes, then cope with it (could be EOF)
-; [MaJoC 910128] The above code, which reads single logical sectors,
-; is grossly inefficient with systems (most of them) with larger physical
-; disk blocks and a single shared read/write buffer. Use of INBUF below
-; is functionally equivalent at this level, but does actual disk reads
-; by the Big Buffer-ful.
-copy5:
- xra a ; Initialise INBUF, to force reading of
- sta seccnt ; the first Big Buffer-ful. Redundant
- sta endsts ; if file opened by GETFIL (or variant).
- sta eoflag ;[MF]...
- lxi h,cfcbs ;[MF]Copy source fcb to default fcb
- lxi d,fcb ;[MF]since INBUF uses the default fcb
- lxi b,33 ;[MF]...
- call mover ;[MF]...
-copy6:
-; INBUF returns a pointer to the next logical bufferful via bufpnt, filling
-; the Big Buffer as necessary, with skip return for success and nonskip on
-; error or EOF.
- call inbuf ; Start of copy proper: get bufferful.
- jmp copy8 ; Nonskip return: treat as EOF.
- lhld bufpnt ; Skip return => OK: pick up buffer pointer.
- xchg
- mvi c, setdma ; Tell system where to write from.
- call bdos
-; [majoc 910128: end]
- lxi d,cfcbd ; send sector to destination
- mvi c,writef
- call bdos
- ana a ; error on write (disk full?)
- jz copy6 ; no error, so do another sector.
- lxi d,erms17 ; say disk is full
- call prtstr
- lxi d,cfcbd ; close the output file...
- mvi c,closf
- call bdos
- lxi d,cfcbd ; ... and then delete it
- mvi c,delf
- call bdos ; ... and then drop through to...
-
-copy7: lxi d,cfcbs ; here to close the source FCB
- mvi c,closf
- call bdos
- jmp kermit
-
-copy8: lxi d,cfcbd ; orderly close of destination file
- mvi c,closf
- call bdos
- jmp copy7 ; now close the source file as well.
-
-;
-;[MF]RENAME - Rename a file
-;
-rename: mvi a,cmofi ;[MF]Get nonwild filename
- lxi d,cfcbs ;[MF]Use "COPY" fcb's
- call comnd ;[MF]...
- jmp kermit ;[MF]Couldn't get it.
- mvi a,cmofi ;[MF]Get filespec to rename it to
- lxi d,cfcbd ;[MF]...
- call comnd ;[MF]...
- jmp kermit ;[MF]Couldn't.
-renam0: lxi d,cfcbs ;[MF]See if file to be renamed exists
- mvi c,openf ;[MF]by trying to open it
- call bdos ;[MF]...
- inr a ;[MF]Does the file exist?
- jnz renam1 ;[MF]Yes
- lxi d,nofile ;[MF]No, inform the user
- call prtstr ;[MF]...
- jmp kermit ;[MF]and bomb
-renam1: lxi d,cfcbd ;[MF]Point to rename filespec
- mvi c,openf ;[MF]Set function code to
- call bdos ;[MF]See if rename file exists
- inr a ;[MF]Does it?
- jz renam2 ;[MF]No
- lxi d,erms31 ;[MF]Yes, complain
- call prtstr ;[MF]...
- jmp kermit ;[MF]and depart with tail between legs
-renam2: lxi h,cfcbd ;[MF]Now get rename filespec again
- lxi d,cfcbs+16 ;[MF]and where to copy it to
- lxi b,16 ;[MF]We copy drive, filename, filetype, extent
- call mover ;[MF]...
- lxi d,cfcbs ;[MF]Point to fcb for rename
- mvi c,renam ;[MF]Get rename function
- call bdos ;[MF]Try to rename the file
- inr a ;[MF]Did we succeed?
- jnz kermit ;[MF]Yes, done
- lxi d,erms16 ;[MF]No, complain
- call prtstr ;[MF]...
- jmp kermit ;[MF]and start over
-
-
-IF lasm
- LINK CPSWLD
-ENDIF;lasm [Toad Hall]
+; CPSCPM.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file duplicates the CP/M DIR and ERA functions so we don't have
+; to exit.
+;
+; revision history:
+;
+;edit 14, 1-Apr-1991 by MF. Correct a bug which crept in with edit 13 which
+; caused any control-key other than ^Y or ^Z to act like ^X after a key
+; had been depressed to halt output of the TYPE/PRINT commands.
+;edit 13, 25-Mar-1991 by MF. Make the TYPE command always abort to Kermit
+; command-level if ^C is entered on the console even if multiple files
+; are being typed via wild-cards. Make ^X typed on the console abort
+; typeout of the current file and begin typeout of the next file,
+; if any, otherwise go back to Kermit command-level.
+; The foregoing also applies to the PRINT command.
+;edit 12, 14-Feb-1991 by MF. Call "clrtop" in TYPE command at "type1"
+; rather than sending a <ff> directly to the terminal as some
+; terminals don't respond to <ff> characters. Thus the screen will be
+; cleared (if the terminal allows) before each file is typed.
+; Also use "getfil" rather than the bdos "openf" call to open
+; files for typing (label "type2"). This tightens up the code.
+; Zero "fcbcnt" before starting to type files (label "type0b").
+; This apparently fixes a phantom bug which caused incorrect lookup (and
+; hence garbage typeout) of files occassionally after a new disk
+; was inserted and a SET DEFAULT-DISK was performed to reset the disk
+; system. (It looked like parts of other files were being typed, as
+; if the directory had been misread or had not been reset.)
+;edit 11, 8-Feb-1991 by MF. Cause the bdos call for direct console input
+; in "ckchr" **not** to go thru the bdos trap but to call bdos at 0005h
+; directly. This corrects a bug wherein if commands such as INPUT
+; (which check to see if a keyboard key has been pressed) were executed
+; from a TAKE-file, the character following the terminator of such
+; commands was being interpreted as that keyboard input, thus causing
+; the next command in the TAKE-file to be unrecognized since its
+; first character had been eaten as a result of the keyboard check.
+; This bug **may** be the cause of a report received by Dr. Martin
+; J. Carter of Nottingham University in the U.K. in which Kermit
+; was reported to have read a character beyond a command terminator
+; in a TAKE-file, making the subsequent command unrecognizable since
+; its first character was missing.
+;edit 10, 29-Jan-1991 by MF. Use the big buffer for TYPE/PRINT commands.
+; Thus, edit 9 has been superseded.
+;edit 9, 29-Jan-1991 by MF. Corrected EOF check in TYPE command routine
+; following label "type20". a READF call, if successful, gives A=0
+; (not A=0FFH) and A not zero if failure. Thus the "INR A" instruction
+; checking for EOF was **always** nonzero. The reason the TYPE command
+; worked is that CP/M text files indicate the text end-of-file with a
+; Control-Z, in which case the TYPE routine branched correctly. In
+; other words, this edit is more for aesthetic purposes to satisfy
+; purists than something brought about by dire necessity!
+;edit 8, 28-Jan-1991 by MF. Added code courtesy of Dr. Martin J. Carter
+; of Nottingham University, UK, to use the big buffer for the COPY
+; command.
+;edit 7, 18-Sep-1990 by MF. Added RENAME routine to implement the
+; RENAME (FRENAME) command to rename a CP/M file.
+; Modified COPY routine to explicitly reject wild-carded filenames
+; by using COMND function CMOFI rather than functions CMIFI and
+; CMIFIN to get input and output filenames.
+; Modified ERA and COPY routines to not act upon the respective
+; commands until a "confirm" is typed. This prevents these
+; routines from taking off upon recognition of action characters
+; like "?", which can be quite annoying if one is an inexperienced user.
+; edit 6, March 11, 1987 by OBSchou. Added in the TYPE and PRINT commands
+; Both type to the screen, print also echoes to printer.
+;
+; edit 5 20 June, 1986. Added support for multiple file FCB buffering.
+;
+; edit 4: June 16, 1986 OBSchou at Loughborough University, UK
+; added in a test to prevent a DIR command issued from a TAKE command
+; being interruped by the next character in the take command buffer.
+; Also added code for USER nn. (Well, its OS related,is it not?)
+;
+; edit 3: July 8, 1984 (CJC)
+; Merge modifications from Toad Hall: support LASM (linked by CPSTT,
+; links to CPSWLD), use prcrlf where appropriate.
+;
+; edit 2: June 5, 1984 (CJC)
+; documentation and formatting; delete unused code (dir13); add module
+; version string.
+;
+; edit 1: May, 1984 (CJC)
+; extracted from CPMBASE.M80 version 3.9; modifications are described in
+; the accompanying .UPD file.
+;
+cpmver: db 'CPSCPM.ASM (14) 1-Apr-1991$' ; name, edit number, date
+
+npl EQU 04H ;Number of names per line for dir command.
+
+; This is the DIR command. Display the name and size of all files
+; matching the filespec.
+; here from: kermit
+;
+; Note: This is abstracted from Keith Peterson's DIRF.ASM
+; directory print function. Thanks again Keith.
+;
+;
+dir: lxi d,fcb ;Where to put the data, if any.
+ mvi a,cmifin
+ call comnd ;Parse a full or piece of file-spec
+ jmp dir2 ;Didn't get a FULL file-spec
+ jmp dir4 ;lets do it
+;
+;
+;Make FCB all '?' to match any file
+dir2: lda fcb
+ cpi ' ' ;CMIFIN leaves that as ' '
+ jnz dir2a ;he typed at least x:
+ xra a
+ sta fcb ;default drive
+dir2a: lxi h,fcb+1
+ mvi b,11 ;FN+FT count.
+
+dir3: mvi m,'?' ;Store '?'s in FCB.
+ inx h
+ dcr b
+ jnz dir3
+;Print signon message and drive name
+dir4: call getun ; get current user number
+ lda fcb
+ ora a ;if not zero, get default
+ jnz dir4a
+ lda curdsk ;get default
+dir4a: adi 'A'-1 ;Asciize it
+ sta dnam14+2 ;[4] add in user no, and Save it in message.
+ lda temp1+1 ;[4] most sig. user number
+ cpi '0' ;[4] if zero set space
+ jnz dir4b
+ mvi a,' ' ;[4] space
+dir4b: sta dnam14 ;[4]
+ lda temp1
+ sta dnam14+1 ;[4] ls user number digit
+ call prcrlf
+ lxi d,inms14 ;Point to message
+ call prtstr
+;
+;Initialize number of names per line counter
+ mvi a,npl ;Nr. names per line.
+ sta nnams ;Init counter.
+ lda hidefs ; are we doing file size?
+ ana a
+ jnz dir4c ; we are not showing file size,
+ lda nnams
+ inr a
+ sta nnams ; so we can show another name per line
+
+dir4c: xra a ; clear the flags ready for multi-sector buffering
+ sta fcbcnt ; clear fcb counter
+ sta mfflg1
+ sta mfflg2
+ sta mfflg3
+ lxi h,fcb0 ; reset pointer for fcb save space
+ shld xfcbptr
+;
+ call dir26 ;Get disk parameters
+ xra a ;[5] say first time round, so no spare fcbs
+ sta fcbcnt ;[5]
+dir5: call mfname ;get some names
+ jnc dir6 ;got one
+ jmp dir17 ;got none - do summary
+
+dir6: ;Check for console break
+ lda takflg ;[4] ... but not if issued from TAKE....
+ ana a ;[4]
+ jnz dir6a ;[4] we do the lot regardless.
+
+ mvi c,consta ;Ck status of kbd.
+ call bdos
+ ora a ;Any key pressed?
+ jz dir6a ;nope, keep going
+ mvi c,conin
+ call bdos ;gobble key
+ jmp dir17 ;and print summary only
+
+;Print an entry
+dir6a:
+ lxi h,fcb+1 ;point to Filename
+ mvi b,8 ;File name length.
+ call dir11 ;Type filename.
+ mvi a,'.' ;Period after FN.
+ call dir10
+ mvi b,3 ;Get the filetype.
+ call dir11
+ call dir25 ;print size
+ lxi h,nnams ;Point to names counter.
+ dcr m ;One less on this line.
+ push psw
+ cnz dir7 ;No cr-lf needed, do fence.
+ pop psw
+ cz dir12 ;Cr-lf needed.
+ jmp dir5
+
+;Print space, fence character, then space
+dir7: call dir9
+ mvi a,':' ;Fence character.
+ call dir10
+ jmp dir9
+
+; dir8 - Print two spaces
+; dir9 - Print one space
+; dir10 - Type char in A register
+dir8: call dir9
+dir9: mvi a,' '
+dir10: push b
+ push d
+ push h
+ mov e,a ;Char to E for CP/M.
+ mvi c,conout ;Write char to console function.
+ call bdos
+ pop h
+ pop d
+ pop b
+ ret
+
+;Type (B) characters from memory (HL)
+dir11: mov a,m
+ ani 7FH ;Remove CP/M 2.x attributes.
+ call dir10
+ inx h
+ dcr b
+ jnz dir11
+ ret
+
+;CR-LF routine. HL=NNAMS upon entry
+dir12: push b
+ push d
+ push h
+ call prcrlf ;Print CR/LF [Toad Hall]
+ pop h ;(did use call to dir10, but slooow)
+ pop d
+ pop b
+ mvi m,npl ;Number of names per line.
+ lda hidefs ; are we showing file size?
+ ana a
+ rnz ; no, so all ok
+ inr m ; else show another file per line
+ ret
+
+;Exit - All done, return via jmp (as for all main commands)
+dir16: call prcrlf
+ lda curdsk
+ dcr a ;relative to 0
+ mov e,a
+ mvi c,logdsk
+ call bdos ;back to "logged in" disk
+ jmp kermit ;...and return to kermit.
+
+;
+;Determines free space remaining
+;
+dir17: xra a
+ sta mfflg1 ;clean up MFNAME
+ sta mfflg2
+ lda fcb ; get drive number from FCB
+ ora a
+ jz dir18 ; default?
+ dcr a ; no, make requested drive current drive.
+ mov e,a
+ mvi c,logdsk
+ call bdos
+dir18: call sysspc ; get space available for current drive
+ push h
+ lxi d,inms15 ;"Drive "
+ call prtstr
+ lda fcb ;If no drive, get
+ ora a ;logged in drive
+ jnz dir24
+ mvi c,rddrv
+ call bdos
+ inr a
+dir24: adi 'A'-1
+ sta inms16
+ lxi d,inms16 ;"x has "
+ call prtstr
+ pop h ;Get number of bytes available
+ call nout
+ lxi d,inms17 ;"K bytes free"
+ call prtstr
+ jmp dir16 ;all done
+
+;Compute the size of the file
+
+dir25: lda hidefs ; do we show file size?
+ ana a ; if non zero, we dont.
+ rz ; so just return
+ mvi c,cflsz ;get file-size
+ lxi d,fcb
+ call bdos
+ lda fcbrno ;shift least sign. part
+ lxi b,0 ;init bc
+ mov l,a
+ ani 7
+ jz dir250 ;even K
+ lxi b,1 ;save for later
+dir250: push b ;save 0 or 1 to add to size
+ mvi b,3 ;shift 3 bits
+dir25a: xra a ;clear sign
+ lda fcbrno+1 ;get most sig byte
+ rar ;shift right
+ sta fcbrno+1 ;put back
+ lda fcbrno ;get least sig part
+ rar
+ sta fcbrno
+ dcr b ;loop 3 times
+ jnz dir25a
+ mov l,a ;size in HL
+ lda fcbrno+1
+ mov h,a
+ pop b ;get 0 or 1
+ dad b ;round up to KB used
+ lda bmask ;get (sectors/block)-1
+ rrc
+ rrc ;get (K/block)-1
+ rrc
+ ani 1FH
+ mov c,a
+ dad b ;add (K/block)-1 to size to round up
+ cma ;make a mask
+ ana l ;truncate after rounding up
+ mov l,a
+ push h
+ lxi b,-10 ;subtract 10
+ dad b
+ jc dir25d ;>= 10
+ call dir8 ; print a leading space
+ jmp dir25e
+
+dir25d: pop h ;get size again
+ push h
+ lxi b,-100 ;subtract 100
+ dad b
+ jc dir25e ;>= 100
+ call dir9 ; print another leading space
+dir25e: call dir9 ;a space
+ pop h ;get size back
+ call nout ;..go print it
+ mvi a,'k' ;..and follow with K size
+ call dir10
+ ret
+
+dir26: mvi c,gtdpar ;current DISK PARAMETER BLOCK
+ call bdos
+ inx h
+ inx h
+ mov a,m ;Get Block Shift Factor
+ sta bshiftf
+ inx h ;Bump to Block Mask
+ mov a,m ;get it
+ sta bmask
+ inx h
+ inx h
+ mov e,m ;Get Max Block number
+ inx h
+ mov d,m
+ xchg
+ shld bmax ;Put it away
+ ret
+;
+; ERA command - erase a CP/M file
+; here from: kermit
+
+era: mvi a,cmifi ;Parse a file-spec
+ lxi d,fcb ;into FCB
+ call comnd
+ jmp kermit ;bad parse
+ mvi a,cmcfm ;[MF]Get a confirm from the user
+ call comnd ;[MF]...
+ jmp kermit ;[MF]NO? try another command
+ lxi d,fcb
+ mvi c,sfirst ;check if valid
+ call bdos
+ inr a ;0 if FILE not found
+ jnz era1 ;found at least one
+ lxi d,erms15 ;"unable to find file"
+ call prtstr
+ jmp kermit
+
+era1: lxi d,fcb
+ mvi c,delf
+ call bdos
+ lxi d,inms18 ;" File(s) erased"
+ call prtstr
+ jmp kermit
+
+; USER - select a new user. This is an unusual routine in that the user
+; enters a number. The others take on/off or filename (except
+; set escape
+;
+user: mvi a,cmnum ; go parse a number
+ call comnd
+ jmp kermit ; if we can not do it, quit to command loop
+ mvi a,cmcfm ; get a confirm from the user
+ call comnd
+ jmp kermit ; if no, then try another command
+ lhld number ; else get the number...
+ xchg ; until a non valid digit is typed (eg cr)
+ lxi h,-32 ; if a carry, then ok
+ dad d ; ... else its above 32
+ jc user1
+ xchg ; restor number in hl again
+ mov a,l ; Lets save it
+ sta curusr ; as current user number
+ mov e,l ; get user no to e...
+ mvi c,usrcod
+ call bdos
+ call getun ; get user number to temp1 and temp2
+ lda temp2
+ cpi '0'
+ jnz user0 ; dont do ms digit if a zero
+ mvi a,' '
+user0: sta kerm1 ; save into string etc
+ sta dnam14 ; also for dir command
+ lda temp1
+ sta kerm1+1
+ sta dnam14+1 ; also for dir command
+ jmp kermit
+
+user1: lxi d,erms23 ; tell user sorry
+ call prtstr
+ jmp kermit
+
+
+;
+; TYPE - type a file or files to the console.
+;
+; This utility also used by print, where the characters printed to
+; the console are also copied to the printer if the prnfl flag
+; is non-zero. Uses mfname to type (print) multiple names.
+; Each file is preceeded with a formfeed character (usually clears
+; the screen on a VDU)
+;
+
+type: mvi a,cmifi ; parse a file name
+ lxi d,fcb ; let the parser know where the FCB is
+ call comnd
+ jmp type02 ; if error say so
+
+type0b:
+ xra a ; clear some flags for mfname
+ sta mfflg1
+ sta mfflg2
+ sta mfflg3
+ sta fcbcnt ;[12]...
+ lxi h,fcb0 ; reset the fcb pointers etc
+ shld fcbptr
+ call mfname
+ jc type02 ; match not found
+
+;[MF][10]The following code to type a file using a 1-sector buffer has
+;[MF][10]been replaced by code to use the "big buffer" -- 30-Jan-1991
+;type1: lxi d,buff ; point to the default DMA address
+; mvi c,setdma
+; call bdos ; tell bdos where to put the dma address
+; mvi a,ff ; do a form feed
+; call typit
+; xra a ; clear the character count
+; sta chrcnt
+;
+;type2: mvi c,openf ; open the file for reading
+; lxi d,fcb
+; xra a ; but first clear bits of fcb...
+; sta fcb+12
+; sta fcb+14
+; sta fcb+15
+; sta fcb+32
+; call bdos ; NOW open the file
+;
+;type20: mvi c,readf ; open up the file and read first sector
+; lxi d,fcb
+; call bdos
+;;[MF][9]Correct EOF test below (next two instructions)
+;; inr a ; if 0ffh returned, error. Assume EOF
+;; jz typex ; so exit from here
+; ora a ;[MF][9]If error, assume EOF
+; jnz typex ;[MF][9]so exit
+; lxi h,0 ; else clear the pointer into the file
+; shld typptr
+;
+;
+;type2a: lxi d,buff ;ok, so lets get the byte to print
+; lhld typptr
+; dad d ; add offset to the DMA base
+; mov a,m ; and get character to type (print)
+; ani 7fh ; make sure it is printable
+; cpi 20h ; is it a control character?
+; jp type3
+; cpi 09h ; if its a tab, then expand it
+; jnz type2b
+;
+;type2c: mvi a,' ' ; send a space
+; call typit ; type it
+; lda chrcnt ; get the number of chrs so far
+; ani 7h ; see of an 8th pos?
+; jnz type2c ; loop until all spaces done, then exit
+; jmp type4
+;
+;type2b: cpi cr ; is it a cr or lf?
+; jnz type2d
+; call typit ; do a cr
+; xra a
+; sta chrcnt ; cr of lf => clear character count
+; jmp type4 ; and exit
+;
+;type2d: cpi lf
+; jnz type2e
+; call typit ; print the character
+; xra a
+; sta chrcnt ; cr or lf clears the character count
+; jmp type4
+;
+;type2e: cpi cntlz ; is it end of file?
+; jnz type2f
+; jmp typex ; yes, so close and try for another file
+;
+;type2f: push psw ; control char - save the character
+; mvi a,'^' ; send control chars as ^A, for ex.
+; call typit
+; pop psw
+;
+;type3: call typit
+;
+;
+;type4: lhld typptr ; get the pointer
+; inx h
+; shld typptr ; up it by one character, and save it.
+; mov a,l ; lets see if the sector has been typed
+; ana a
+; jm type20 ; if 80h => read new sector
+; jmp type2a ; else just continue along
+
+;[MF][10]The following code uses the "big buffer" to read the file
+;[MF][10]which is to be typed
+;[12]Clear the screen explicitly as some terminals don't respond
+;[12]to the <ff> character.
+;type1: mvi a,ff ; do a form feed
+; call typit
+type1: call clrtop ;[12] Clear the screen
+ xra a ; clear the character count
+ sta temp1 ;[MF]alias column counter
+
+type2:
+;[12]Eliminate call to openf in favor of call to "getfil"
+; mvi c,openf ; open the file for reading
+ lxi d,fcb
+; xra a ; but first clear bits of fcb...
+; sta fcb+12
+; sta fcb+14
+; sta fcb+15
+; sta fcb+32
+; call bdos ; NOW open the file
+ call getfil ;[12] NOW open the file
+
+type20: call inbuf ;[MF]Fill input buffers
+ jmp typex ;[MF]Tru end-of-file reached
+ jmp type21 ;[MF]Begin typing/printing characters
+
+type2a: lda chrcnt ;[MF]Get buffer character counter
+ dcr a ;[MF]and decrement it
+ jm type20 ;[MF]Get more characters if needed
+type21: sta chrcnt ;[MF]else remember new buffer character counter
+ lhld bufpnt ;[MF]Now get character pointer
+ mov a,m ; and get character to type (print)
+ inx h ;[MF]Increment the pointer
+ shld bufpnt ;[MF]and remember it
+ ani 7fh ; make sure character is printable
+ cpi 20h ; is it a control character?
+ jp type3
+ cpi 09h ; if its a tab, then expand it
+ jnz type2b
+
+type2c: mvi a,' ' ; send a space
+ call typit ; type it
+ lda temp1 ;[MF]Get the number of characters so far
+ ani 7h ; see if an 8th pos?
+ jnz type2c ; loop until all spaces done, then exit
+ jmp type2a ;[MF]and continue
+
+type2b: cpi cr ; is it a cr or lf?
+ jnz type2d
+ call typit ; do a cr
+ xra a
+ sta temp1 ; cr or lf => clear character count
+ jmp type2a ;[MF]and continue
+
+type2d: cpi lf
+ jnz type2e
+ call typit ; print the character
+ xra a
+ sta temp1 ; cr or lf clears the character count
+ jmp type2a ;[MF]and continue
+
+type2e: cpi cntlz ; is it end of file?
+ jnz type2f
+ jmp typex ; yes, so close and try for another file
+
+type2f: push psw ; control char - save the character
+ mvi a,'^' ; send control chars as ^A, for ex.
+ call typit
+ pop psw
+
+type3: call typit
+ jmp type2a ; and continue along
+
+typex: mvi c,closf
+ lxi d,fcb
+ call bdos ; close the file
+ mvi a,cr ; send cr lf to screen/printer to clear buffers
+ call typit
+ mvi a,lf
+ call typit
+ call mfname ; and see if there are other files to type
+ jnc type1 ; yup, so go do it
+ xra a ; make sure the flag is reset
+ sta prnfl
+ jmp kermit ; then exit.
+
+typex0: mvi c,closf ;[MF]Close the file
+ lxi d,fcb ;[MF]...
+ call bdos ;[MF]...
+ mvi a,cr ;[MF]Clear buffers
+ call typit ;[MF]...
+ mvi a,lf ;[MF]...
+ call typit ;[MF]...
+ xra a ;[MF]Clear flag
+ sta prnfl ;[MF]...
+ lda takflg ;[MF]See if we're TAKEing commands
+ ani 1 ;[MF]from a file
+ cnz closet ;[MF]If we are, abort TAKE-file processing
+ jmp kermit ;[MF]Back to Kermit command-level
+
+; error for file not found for type
+type02: lxi d,nofile ; say no file name (its invalid)
+ call prtstr
+ xra a
+ sta prnfl ; clear the flag
+ jmp kermit ; so abort
+
+
+typit: mov e,a
+ call ckqtyp ; see if a cntl-c or other character from user
+ jmp typit2 ;[MF] Control-C entered, abort
+ jc typit1 ; CNTL-X entered, so abort file [MF]
+ push d ; save for a bit
+ call outcon ; send it to the console
+ lda temp1 ; update the number of characters sent[MF]
+ inr a
+ sta temp1 ;[MF]
+ pop d
+ lda prnfl ; see if we have to print it too
+ ana a
+ rz
+ call outprn ; send character to printer (buffer)
+ ret
+
+typit1: pop d ; adjust stack again
+ jmp typex ; and say we are done (for this file)
+
+typit2: pop d ;[MF] Adjust the stack
+ jmp typex0 ;[MF] and abort file typeout completely
+
+
+; CKQTYP - CHeck for requested Quiet TYPe (ie hang on a second)
+; Routine sees if the user has typed ANY key. If a key HAS been pressed
+; see if its a Control-c. If so, flag for an abort, else wait for
+; a second entry from the user. If its a Control C, flag an abort
+; else continue with the print.
+; note: only the DE registers maintained. All others destroyed.
+; **NOTE** CKQTYP now gives a nonskip return if Control-C is typed,
+; a skip-return with carry set if a Control-X is typed and a skip-return
+; with carry clear if any other character is typed as the second
+; character.
+
+ckqtyp: push d ; save the character to be printed
+ call ckchr ; see if user entered a character
+ ani 7fh ; strip parity etc
+ jz ckqty3 ; nothing entered, so go on as usual (See below)
+ cpi ctrlc ; control c?
+ jz ckqt1a ;[MF] Yup, give nonskip return
+ cpi 'X'-100o ;[MF] If Control-X,
+ jz ckqty1 ; yup, set carry and exit
+ckqty2: call ckchr ; another character to wait for (ie pause)
+ ani 7fh
+ jz ckqty2 ; wait until some input
+ cpi ctrlc ; if control c, abort
+ jz ckqt1a ;[MF] ...
+ cpi 'X'-100o ;[MF] Control-X?
+ jz ckqty1 ; yuss, so flag abort file [MF]
+ckqty3: pop d ; else restore the character to be typed [MF]
+; ret ; no, so continue with type/print
+ stc ;[MF]Set carry
+ cmc ;[MF]Then clear it
+ jmp rskp ;[MF] Continue with type/print (skip ret)
+
+ckqty1: pop d ; restore stack again
+ stc ; set carry and return
+; ret
+ jmp rskp ;[MF] ...
+
+ckqt1a: pop d ;[MF] Adjust stack
+ ret ;[MF] and return
+
+;[MF][14]No longer need these lines
+;ckqty3: pop d ; restore stack again
+;; ret
+; stc ;[MF] Clear carry
+; cmc ;[MF] ...
+; jmp rskp ;[MF] and give skip return
+
+ckchr: call selcon ; make sure we are talking to the console
+ mvi e,0ffh ; see if user has any input for us
+ mvi c,dconio
+; call bdos ;[11]Don't go thru bdos trap
+ call 0005h ;[11]Call bdos directly
+ ret ; This routine does not care what comes back
+
+
+;
+; COPY - routine to copy from a source file to a destination file
+; from the Kermit command state.
+;
+; Note. This could be tricky, as there are several forms of copy
+; copy d:source.ext d:dest.ext (Easy one)
+; copy d:source.ext d: (File to another drive)
+; copy d:source.??? d: (several files)
+; copy d:*.* d: (Several files)
+;
+; Initially, lets make it top one, and see how we go, ok?
+;
+;
+;Things to do for copy:
+; 1) get source name
+; 2) get target name
+; 3) if both source and destination = abort
+; 4) if source does not exist abort
+; 5) attempt to delete destination file if it exists
+; 6) open source and destination files
+; 7) copy file across
+; 8) close all files
+; 9) return to command mode
+;
+copy: ; Here goes...
+; 1) get source file name
+ mvi a,cmofi ; go parse a file name
+ ;[MF]Nonwild
+ lxi d,cfcbs ; use the source for copy FCB (Allows copy
+ call comnd ; from a TAKE file etc)
+ jmp kermit ; if error, abort
+
+; 2) get target name
+ mvi a,cmofi ; go parse a target file name
+ ;[MF]Again, nonwild
+ lxi d,cfcbd ; use destination fcb
+ call comnd ; get it
+ jmp kermit ;[MF]Couldn't.
+ mvi a,cmcfm ;[MF]Get a confirm from the user
+ call comnd ;[MF]...
+ jmp kermit ;[MF]No? try another command
+
+; 3) see if both target and source are equal
+copy0: mvi b,12 ; we are gonna test drive, file and extention
+ lxi d,cfcbs ; from source file name...
+ lxi h,cfcbd ; to destination file name
+ xra a ; clear flag for difference found
+ sta equflg
+copy1: ldax d ; get source file name character
+ cmp m ; test with targer file name
+ jz copy2 ; if equal, do nothing
+ lda equflg ; else update flage (ie files are different)
+ inr a
+ sta equflg
+copy2: inx h
+ inx d
+ dcr b
+ jnz copy1 ; up pointers and test for next char
+
+ lda equflg ; if still null, then its a daft thing to do
+ ana a
+ jnz copy3 ; its not a daft thing to do
+ lxi d,samems ; load up "File source and destination the same"
+ call prtstr ; tell user
+ jmp kermit ; and try again
+
+; 4) If source does not exist, abort. Assume we have a full file name.
+copy3:
+ lxi d,cfcbs ; load up source fcb
+ mvi c,openf ; open file
+ call bdos
+ inr a ; error on open?
+ jnz copy4
+ lxi d,nofile ; assume file not found
+ call prtstr
+ jmp kermit ; and die
+
+copy4: lxi d,cfcbd ; load up destination fcb
+ mvi c,delf ; destroy target name if it exists
+ call bdos ; ignore error messages
+ lxi d,cfcbd ; load up destination fcb
+ mvi c,makef ; make a file
+ call bdos
+ inr a ; make error?
+ jnz copy4a
+ lxi d,erms12 ; no directory space
+ call prtstr
+ jmp copy7 ; close source file
+
+copy4a: lxi d,cfcbd ; load up destination fcb...
+ mvi c,openf ; for open
+ call bdos
+ inr a ; error on open?
+ jnz copy5 ; could do with better error detection...
+ lxi d,erms15 ;... but assume its a disk full
+ call prtstr
+ jmp copy7 ; close source file and jmp kermit
+
+;copy5: lxi d,buff ; set default dma address to 80h
+; mvi c,setdma
+; call bdos
+;
+;copy6: lxi d,cfcbs ; copy routine proper.. get a sector
+; mvi c,readf
+; call bdos
+; ana a ; error reading the file?
+; jnz copy8 ; yes, then cope with it (could be EOF)
+; [MaJoC 910128] The above code, which reads single logical sectors,
+; is grossly inefficient with systems (most of them) with larger physical
+; disk blocks and a single shared read/write buffer. Use of INBUF below
+; is functionally equivalent at this level, but does actual disk reads
+; by the Big Buffer-ful.
+copy5:
+ xra a ; Initialise INBUF, to force reading of
+ sta seccnt ; the first Big Buffer-ful. Redundant
+ sta endsts ; if file opened by GETFIL (or variant).
+ sta eoflag ;[MF]...
+ lxi h,cfcbs ;[MF]Copy source fcb to default fcb
+ lxi d,fcb ;[MF]since INBUF uses the default fcb
+ lxi b,33 ;[MF]...
+ call mover ;[MF]...
+copy6:
+; INBUF returns a pointer to the next logical bufferful via bufpnt, filling
+; the Big Buffer as necessary, with skip return for success and nonskip on
+; error or EOF.
+ call inbuf ; Start of copy proper: get bufferful.
+ jmp copy8 ; Nonskip return: treat as EOF.
+ lhld bufpnt ; Skip return => OK: pick up buffer pointer.
+ xchg
+ mvi c, setdma ; Tell system where to write from.
+ call bdos
+; [majoc 910128: end]
+ lxi d,cfcbd ; send sector to destination
+ mvi c,writef
+ call bdos
+ ana a ; error on write (disk full?)
+ jz copy6 ; no error, so do another sector.
+ lxi d,erms17 ; say disk is full
+ call prtstr
+ lxi d,cfcbd ; close the output file...
+ mvi c,closf
+ call bdos
+ lxi d,cfcbd ; ... and then delete it
+ mvi c,delf
+ call bdos ; ... and then drop through to...
+
+copy7: lxi d,cfcbs ; here to close the source FCB
+ mvi c,closf
+ call bdos
+ jmp kermit
+
+copy8: lxi d,cfcbd ; orderly close of destination file
+ mvi c,closf
+ call bdos
+ jmp copy7 ; now close the source file as well.
+
+;
+;[MF]RENAME - Rename a file
+;
+rename: mvi a,cmofi ;[MF]Get nonwild filename
+ lxi d,cfcbs ;[MF]Use "COPY" fcb's
+ call comnd ;[MF]...
+ jmp kermit ;[MF]Couldn't get it.
+ mvi a,cmofi ;[MF]Get filespec to rename it to
+ lxi d,cfcbd ;[MF]...
+ call comnd ;[MF]...
+ jmp kermit ;[MF]Couldn't.
+renam0: lxi d,cfcbs ;[MF]See if file to be renamed exists
+ mvi c,openf ;[MF]by trying to open it
+ call bdos ;[MF]...
+ inr a ;[MF]Does the file exist?
+ jnz renam1 ;[MF]Yes
+ lxi d,nofile ;[MF]No, inform the user
+ call prtstr ;[MF]...
+ jmp kermit ;[MF]and bomb
+renam1: lxi d,cfcbd ;[MF]Point to rename filespec
+ mvi c,openf ;[MF]Set function code to
+ call bdos ;[MF]See if rename file exists
+ inr a ;[MF]Does it?
+ jz renam2 ;[MF]No
+ lxi d,erms31 ;[MF]Yes, complain
+ call prtstr ;[MF]...
+ jmp kermit ;[MF]and depart with tail between legs
+renam2: lxi h,cfcbd ;[MF]Now get rename filespec again
+ lxi d,cfcbs+16 ;[MF]and where to copy it to
+ lxi b,16 ;[MF]We copy drive, filename, filetype, extent
+ call mover ;[MF]...
+ lxi d,cfcbs ;[MF]Point to fcb for rename
+ mvi c,renam ;[MF]Get rename function
+ call bdos ;[MF]Try to rename the file
+ inr a ;[MF]Did we succeed?
+ jnz kermit ;[MF]Yes, done
+ lxi d,erms16 ;[MF]No, complain
+ call prtstr ;[MF]...
+ jmp kermit ;[MF]and start over
+
+
+IF lasm
+ LINK CPSWLD
+ENDIF;lasm [Toad Hall]
diff --git a/cpsdat.asm b/cpsdat.asm
index 729ca52..b8f3f66 100644
--- a/cpsdat.asm
+++ b/cpsdat.asm
@@ -1,648 +1,648 @@
-; CPSDAT.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; Pure and impure data areas. Previously of CPSUTL.ASM
-;
-; revision history:
-;
-;edit 19, 29-Mar-1991 by MF. Add flag "initak" (nonzero) which is cleared
-; after the initial automatic TAKE attempt of KERMIT.INI to allow
-; "unable to find file" complaints if not doing that initial TAKE.
-;edit 18, 21-Mar-1991 by MF. Renamed parameter vermin to revno (revision
-; level) since verno is already known as the "minor version number".
-;edit 17, 27-Feb-1991 by MF. Corrected typeo in "inms19" and commented out
-; "typptr" pointer as the TYPE command now uses the big buffer.
-; Also provided for a "minor version number" (1-26=A-Z) and message to
-; facilitate display of Kermit version in VERSION command (modmsg)
-;edit 16, 12-Feb-1991 by MF. Eliminated storage (message and variable)
-; for case sensitivity by commenting it out.
-;edit 15, 9-Dec-1990 by MF. Modified message for "directory file size"
-; status report to make it clearer when spoken by a speech synthesizer.
-;edit 14, 4-Dec-1990 by MF. Added message for Autoreceive status report.
-;edit 13, 30-Nov-1990 by MF. Added messages to display regular/quiet status
-; of terminal in SHOW and STATUS commands.
-;edit 12, 8-Nov-1990 by MF. Added a new message for Set Autoreceive.
-;edit 11, 2-Nov-1990 by MF. Moved overlay address to 7000H -- I didn't
-; realize I was **that** close to the limit until I made a couple of
-; cosmetic changes and REM CD bombed. This is still ver. 4.10 as it
-; hasn''t been released yet.
-;edit 10, 1-Nov-1990 by MF. Changed message at "spdst" to conform with
-; the change of "SET BAUD-RATE" to "SET SPEED".
-; Also added message "sdpst2" for speed status (staspd) routine
-;edit 9, 17-Oct-1990 by MF. Changed "packet-size" messages to use the
-; word "length" to conform with the nomenclature suggested in the
-; 6th edition of the Kermit Protocol Manual.
-;edit 8, 19-Sep-1990 by MF. Added error message for FRENAME command.
-;edit 7, 14-Sep-1990 by MF. Added storage/strings for SET COLLISION command.
-; Also added strings/storage for SET INCOMPLETE-FILE command.
-;edit 6, 9-Sep-1990 by MF. Added messages and storage for Remote commands.
-; and display of packet sizes
-; Moved overlay address to 06C00H for Version 4.10.
-; edit 5, 8 April, 1987 by OBSchou. Added new entry in jump table to call
-; code for an external terminal type. Added some new error messages
-; and added more to the packet space.
-;
-; edit 4, 30 March by OBSchou. Added in space for autoreceive.
-;
-; edit 3, 19 March, 1987 by OBSchou. Added some more strings etc, and
-; increased the stack space fro 32 entries to 64.
-;
-; edit 2, 11 March, 1987 by OBSchou.
-; Added in some more data and strings and things. Nothing special
-;
-; edit 1, 28 January, 1987 by OBSchou
-; Following file the data section of CPSUTL.ASM. This part of the
-; CPSUTL.ASM file now seperate as it ws getting too larg. Link to here
-; from CPSUTL.ASM (which now has only the utlity routines).
-; Also added in bits submitted by Dave Roberts of Leicester:
-; DJR 18th January 1987 - David J. Roberts.
-; Support for cosmetic changes in CPSMIT:
-; New strings DBGST and CURDST
-; CRLF in front of TIMMSG
-; LOGST changed, and new LOGST2
-;
-;
-datver: db 'CPSDAT.ASM (19) 29-Mar-1991$'
-
-
-
-;
-
-version:db 'Kermit-80 v4.'
- db (verno/10) + '0' ; tenth's digit of version number
- db (verno MOD 10) + '0' ; hundredth's digit
-IF revno ;[MF]If a revision level,
- db revno+'@' ;[MF]put it in (range 1-26=A-Z)
-ENDIF ;revno [MF]
- db ' $'
-modmsg: db ' has been built from the following modules:$';[MF]
-kerm: db 'Kermit-80 '
-kerm1: db 'nnx:>$' ;'x' filled in at startup with DRIVE name
- ;'nn filled at startup and user with user number
-crlf: db cr,lf,'$'
-ermes1: db cr,lf,'?Unrecognized command$'
-ermes3: db cr,lf,'?Not confirmed$'
-ermes4: db '?Unable to receive initiate',cr,lf,'$'
-ermes5: db '?Unable to receive file name',cr,lf,'$'
-ermes6: db '?Unable to receive end of file',cr,lf,'$'
-erms10: db '?Unable to receive data',cr,lf,'$'
-erms11: db '?Disk full',cr,lf,'$'
-erms12: db '?Directory full',cr,lf,'$'
-erms14: db '?Unable to receive an acknowledgement from the host',cr,lf,'$'
-erms15: db cr,lf,'?Unable to find file',cr,lf,'$'
-erms16: db '?Unable to rename file$'
-erms17: db cr,lf,'?Disk full$'
-erms18: db cr,lf,'?Unable to tell host that the session is finished$'
-erms19: db cr,lf,'?Unable to tell host to logout$'
-erms20: db cr,lf,'?Kermit has not been configured for a target system$'
-erms21: db cr,lf,'?Consistency check on configuration failed$'
-erms22: db cr,lf,'?Error writing to log file',cr,lf,'$' ;[pcc005]
-erms23: db cr,lf,'?Invalid user number$'
-erms24: db cr,lf,'?Invalid Pause parameter$'
-erms25: db cr,lf,'?Invalid BUFFER-SIZE parameter$'
-erms26: db cr,lf,'?Invalid packet length (too long)$'
-erms27: db cr,lf,'?Invalid Checktype$'
-erms28: db cr,lf,'?Too many retries$'
-erms29: db cr,lf,'?Failed to exchange parameters$'
-erms30: db cr,lf,'?Failed to receive input string in alloted time$'
-erms31: db cr,lf,'?File already exists$' ;[MF]
-
-infms3: db bell,'Completed$'
-infms4: db bell,'Failed$'
-infms5: db '%Renaming file to $'
-infms6: db cr,lf,'[Closing the log file]$'
-infms7: db cr,lf,'[Connected to remote host. Type $'
-infms8: db 'C to return;',cr,lf,' type $'
-inms8a: db '? for command list]',cr,lf,'$'
-infms9: db cr,lf,'[Connection closed, back at micro]$'
-inms10: db 'Control-$'
-inms11: db ' Not implemented.$'
-inms12: db ' (Not implemented)',cr,lf,'$'
-inms13: db bell,'Interrupted$'
-inms14: db TAB,TAB,' Directory for drive '
-dnam14: db 'nnx:',cr,lf,'$' ;filled in by dir routine.
-inms15: DB CR,LF,TAB,TAB,'Drive $'
-inms16: DB ' has $';filled in by summary code with drive letter
-inms17: DB 'K bytes free',CR,LF,'$'
-inms18: DB CR,LF,'File(s) erased$',CR,LF
-inms19: db cr,lf,'[Transmitting file to host:'
- db cr,lf,' 1. Lines automatically sent, and wait for possible reply'
- db cr,lf,' 2. CONTROL-C aborts transfer'
- db cr,lf,' 3. If transfer hangs, try a return to continue'
- db cr,lf,' 4. on exit, you will be placed in CONNECT state.'
- db cr,lf,'$'
-inms20: db 'R to send the same line again,'
- db cr,lf,' or type $'
-inms21: db 'C to abort transmission.]',cr,lf,'$'
-inms22: db cr,lf,'[Transmission done. Connected normally '
- db 'to remote host,'
- db cr,lf,' type $'
-inms23: db 'Sending...$'
-inms24: db 'Receiving...$'
-inms25: db bell,'Warning: eighth bit cannot be sent$'
-inms26: db cr,lf,'For help, type ? at any point in a command$'
-inms27: db cr,lf,'[Logging suspended]',cr,lf,'$' ;[pcc003]
-inms28: db cr,lf,'[Logging resumed]',cr,lf,'$' ;[pcc003]
-inms29: db cr,lf,'[Transmission Aborted. Connected normally '
- db 'to remote host,'
- db cr,lf,' type $'
-autmes: db cr,lf,cr,lf,'[Automatically receiving; type ^C to abort]'
- db cr,lf,cr,lf,'$' ;[MF]
-anymes: db cr,lf,cr,lf,' * * * Press any key to continue * * * '
- db cr,lf,cr,lf,'$'
-escmes: db cr,lf,'Type the new escape character: $'
-tacmes: db cr,lf,'Type the new TAC intercept character: $'
-sopmes: db cr,lf,'Give the start-of-packet character: $' ;[gnn]
-padcms: db cr,lf,'Type the new padding character: $' ;[obs]
-xmthlp: db cr,lf,'R Send the same line again$'
-loghlp: db cr,lf,'Q Suspend logging' ;[pcc003]
- db cr,lf,'R Resume logging$' ;[pcc003]
-inthlp: db cr,lf,'? This message'
- db cr,lf,'C Close the connection'
- db cr,lf,'0 (zero) Transmit a NULL'
- db cr,lf,'P Toggle printer on/off' ;[pcc002]
- db cr,lf,'S Status of the connection$'
-inhlp1: db cr,lf,'Typing another $'
-inhlp2: db ' will send it to the host'
- db cr,lf,cr,lf,'Command>$'
-
-xmtst: db cr,lf,'Transmitting a file$'
-autrst: db cr,lf,'Autoreceive is$'
-locst: db cr,lf,'Local echo$'
-onstr: db ' on$'
-offstr: db ' off$'
-flost: db cr,lf,'Flow control$'
-;senst: db cr,lf,'Case sensetivity$'
-vtdpst: db cr,lf,'Terminal display is $'
-vtdpsr: db 'REGULAR$'
-vtdpsq: db 'QUIET$'
-vtemst: db cr,lf,'Terminal emulation is $'
-cpmst: db cr,lf,'File Mode$'
-defstr: db ' default$'
-ascstr: db ' ASCII$'
-binstr: db ' binary$'
-hfsod: db cr,lf,'Display file size on DIRECTORY command$'
-ibmst: db cr,lf,'IBM flag$'
-incst: db cr,lf,'Disposition for incomplete files is$'
-dscstr: db ' discard$'
-kepstr: db ' keep$'
-filst: db cr,lf,'File warning$'
-prst: db cr,lf,'Printer copy$'
-logst: db cr,lf,'Logging to $' ;[pcc003][DJR]
-logst2: db ' is$' ;[DJR]
-susstr: db ' suspended$' ;[pcc003]
-sspmsg: db cr,lf,'SEND start-of-pkt char ^$' ;[gnn]
-rspmsg: db cr,lf,'RECEIVE start-of-pkt char ^$' ;[gnn]
-spsmsg: db cr,lf,'SEND packet length $' ;[MF]
-rpsmsg: db cr,lf,'RECEIVE packet length $' ;[MF]
-escst: db cr,lf,'Escape char: $'
-bufsz1: db cr,lf,'Multi-sector buffering at $'
-bufsz2: db ' of a maximum of $'
-xmitst: db cr,lf,'Transmit protocol char: $'
-bckst: db cr,lf,'Block check type: $'
-bckst1: db '-character$'
-collst: db cr,lf,'File COLLISION: $';[MF]
-parst: db cr,lf,'Parity: $'
-pnonst: db 'none$'
-pmrkst: db 'mark$'
-pspcst: db 'space$'
-poddst: db 'odd$'
-pevnst: db 'even$'
-porst: db cr,lf,'Port in use is: $'
-spdst: db cr,lf,'Current speed is: $'
-spdst2: db ' bps$' ;[MF]
-spdust: db 'indeterminate (not SET)$'
-timmsg: db cr,lf,'Timer$' ;[DJR] Added CRLF like the others
-tacst: db cr,lf,'Current TACTrap Status/Intercept Character: $'
-usrst: db cr,lf,'Current user number: $'
-dbgst: db cr,lf,'Debugging$' ;[DJR]
-curdst: db cr,lf,'Current default disk: $' ;[DJR]
-spac15: db ' $' ; *** 15 spaces ***
-samems: db cr,lf,'?Source and destination files the same$'
-nofile: db cr,lf,'?File not found$'
-cmer00: db cr,lf,'?Program error: Invalid COMND call$'
-cmer01: db cr,lf,'?Ambiguous$'
-cmer02: db cr,lf,'?Illegal CP/M file specification$'
-cmer03: db cr,lf,'?Wild-cards not allowed in file specification$' ;[pcc006]
-cmer04: db cr,lf,'?Invalid user number$'
-cmer05: db cr,lf,'?Invalid \ parameter$'
-cmin00: db ' Confirm with carriage return$'
-cmin01: db ' Enter a number$'
-cmin02: db ' Confirm with carriage return or enter more$'
-
-; Diagnostic messages
-sstatm: db '<SState:> ',0
-rstatm: db '<RState:> ',0
-spackm: db '<Data transmitted> ',0
-rpackm: db '<Data received > ',0
-princr: db cr,lf,0
-;
-; Remote command messages [MF]
-;
-newfms: db cr,lf,'New file: $'
-pswdms: db cr,lf,'Password: $'
-acctms: db cr,lf,'Account: $'
-newnms: db cr,lf,'New name: $'
-msgms: db cr,lf,'Message: $'
-optms: db cr,lf,'Options: $'
-
-;
- ;Impure data
-
-;COMND storage
-
-comchr: ds 1 ;[8] save space
-floctl: db 0 ;[8] flow control on/off flag
-;casens: db 0 ;[8] Upper/lower case sensitive
-cmstat: ds 1 ;What is presently being parsed.
-cmaflg: ds 1 ;Non-zero when an action char has been found.
-cmbflg: ds 1 ;[MF]Nonzero to allow a blank initial keyword
-cmqflg: ds 1 ;[MF]Nonzero to prevent character echoing
- ;[MF]when entering commands
-cmccnt: ds 1 ;Non-zero if a significant char is found.
-cmsflg: ds 1 ;Non-zero when the last char was a space.
-cmostp: ds 2 ;Old stack pointer for reparse.
-cmrprs: ds 2 ;Address to go to on reparse.
-cmprmp: ds 2 ;Address of prompt.
-cmptab: ds 2 ;Address of present keyword table.
-cmhlp: ds 2 ;Address of present help.
-cmdbuf: ds 80H ;Buffer for command parsing.
-cmbufl equ $-cmdbuf-3 ; set a limit on the command buffer
-cmfcb: ds 2 ;Pointer to FCB.
-cmfcb2: ds 2 ;Pointer to position in FCB.
-cmfwld: ds 1 ;Wildcard flag
-cmcptr: ds 2 ;Pointer for next char input.
-cmdptr: ds 2 ;Pointer into the command buffer.
-cmkptr: ds 2 ;Pointer to keyword.
-cmsptr: ds 2 ;Place to save a pointer.
-slshsn: db 0 ; slash seen in command line
-slashc: db 0 ; count for number of characters in slash sequence
-slashn: db 0 ; number to be built for \xxx
-;
-oldsp: ds 2 ;Room for old system stack.
- ds 80H ;Room for 64 levels of calls.[obs]
-stack: ds 2
-eoflag: ds 1 ;EOF flag;non-zero on EOF.
-curdsk: db 0 ;holds "logged" disk
-curusr: db 0 ;[8] holds "user" number
-rcvsop: db SOH ;[gnn] receive start-of-packet
-sndsop: db SOH ;[gnn] send start-of-packet
-prtcnt: db 0 ;[pcc008] prtchr fairness count
-timflg: db 0 ;[jd] timer flag: 0 -> no timer
-timval: dw 0 ;[jd] timer value
-wrn8: db 0 ;[jd] non-zero if 8-bit-lost warning sent
-qbchr: db '&' ;[jd] binary quote character.
-quot8: db 0 ;[jd] non-zero if doing 8-bit quoting
-logflg: db 0 ;Flag for a log file.
- ;[pcc005] 0 = no log
- ;[pcc005] x1 = logging on
- ;[pcc005] x2 = suspended
- ;[pcc005] 8xH (bit 7) = file open
-lognam: db 0 ;[pcc013] File to use for session logging
- db 'KERMIT ' ;[pcc013]
- db 'LOG' ;[pcc013]
-nexitf: db 0 ; set to 1 for exit to CPM after command tail
-takflg: db 0 ;[8] TAKE flag.
- ; Bit zero = 1 for take file in progress
- ; bit 4 = 1 if command line present/in progress
- ; Note: Take has priority over command line.
-initak: db 0ffh ;[MF]Cleared after initial TAKE (KERMIT.INI)
-taknam: db 0 ;[8] use default drive
- db 'KERMIT '
- db 'INI' ;[8] Inital file to TAKE KERMIT.INI
-takptr: ds 2 ;[8] Pointer to position in TAKE file input
-takfcb: ds 12 ;[8] fcb space for take file
- dw 0 ;[8] fill up extents etc with 00
- dw 0
- ds 16 ;[8] used by dos
- dw 0
- dw 0
-takdma: ds 128 ;[8]space to read TAKE file...
-prnbuf: ds 1 ; printer buffer. Output pointer
- ds 1 ; input offset pointer
- ds 256 ; give a large buffer
- ds 10 ; and a little spare
-;
-;
-;
-; Transmit space
-;
-repcnt: db 0 ; repeat counter
-starc: db 0 ; star count
-rexbfl: db 0 ; retransmit flag (1=> retransmit)
-rexcnt: db 0 ; retransmit character count
-rexbuf: ds 128 ; max retransmit line length 128 characters
-xmtbuff:
- ds 128 ; 128 byte sector buffer
-xmtptr: db 0 ; offset pointer to xmtbuff above
-xmtfcb: ds 36 ; fcb for transmit file.
-;
-;INPUT and STRING space
-strlen: db 0 ; length of the string from INPUT and STRING
-
-; Assorted other space
-errorc: db 0 ; error level set to xxx
-errorl: db 0 ; error level to test against
-
-remtxt: db 0 ; set <> 0 if D packets to screen
-
-hosths: ds 1 ; have we told the host to xoff? (is this duplicated)
-stbuff: ds 80h ; some space or the string buffer
-waitp: ds 2 ; wait command timer
-waitp1: ds 2 ; wait/input timer (copy of waitp)
-prntmp: ds 1 ; temporary space to put the caracter to print
-prnfl: db 0 ; printer flag. Used by TYPE/PRINT
-;[MF][17]Following line no longer needed as TYPE uses the big buffer
-;typptr: ds 2 ; pointer used by TYPE/PRINT
-equflg: db 0 ; set to non zero if copy files same
-nquiet: db 0 ; If non zero print from NOUT to display
-
-escflg: db 0 ;Escape flag (start off).
-fileio: db 0 ;Line-by-line from file (default off).
-xofflg: db 0 ;X-OFF (=^S) received from COMM-line
- ;X-ON (=^Q) received resets this
-clkbit: dw 0 ; 32 bit pseudo clock
- dw 0 ; MS bits of clock
-number: ds 2 ; Number in binary form from user input
-initflg:db 0 ; set to non zero when system initialised
-maxbsc: ds 1 ; save space to know how big system allows
- ; for multi-sector buffering. (Usually 8k?)
-;
-; Multiple FCB storage space. Used for the DIR command
-; Later on, I want to shift this into space after the system
-; dependent stuff, but then it becomes messy with pointers
-; to pointers etc... [OBS]
-;
-xfcbptr:
- ds 2 ; pointer to current fcb space
-fcbcnt: ds 1 ; Number of valid fcbs in space
-;
-fcb0: ds 12 ; 36 bytes requred for a single fcb
-fcblen EQU $-fcb0 ; length of a single fcb
- ds maxfcb*fcblen ; space for maximum fcbs + 1
-;
-hidefs: db 0ffh ; flag <> 0 if we show file size in DIR
-
-; FCB sapce for COPY command
-cfcbs: ds 33 ; source fcb for copy file ops.
- ;[MF]and FRENAME ops.
-cfcbd: ds 33 ; destination fcb for copy ops.
- ;[MF]and FRENAME ops.
-
-colfcb: ds 33 ;[MF]Rename fcb for SET COLLISION
-
-; Command tail data space etc
-cbptr: db 2 ; command tail pointer (0= length of tail)
-cbuff: ds 128 ; temp. space for potential command tail
-
-strcnt: db 0 ; string count for string operations...
-
-vtyval: ds 1 ; holds row number for VT52 cursor positioning
-chrcnt: ds 1 ;Number of chars in the file buffer.
-
-; Various packet variables etc
-bytes: dw 0 ; 4 byte 'byte count' space
- dw 0
-filcnt: ds 1 ;Number of chars left to fill.
-outpnt: ds 2 ;Position in packet.
-bufpnt: ds 2 ;Position in file buffer.
-fcbptr: ds 2 ;Position in FCB.
-datptr: ds 2 ;Position in packet data buffer.
-cbfptr: ds 2 ;Position in character buffer.
-pktptr: ds 2 ;Position in receive packet.
-size: ds 1 ;Size of data from gtchr.
-curchk: ds 1 ;Current checksum type
-inichk: ds 1 ;Agreed upon checksum type
-czseen: ds 1 ;Flag that control-Z was typed
-dscflg: ds 1 ;[MF]Discard file if nonzero
-pktnum: ds 1 ;Packet number.
-numpkt: ds 2 ;Total number of packets sent.
-numrtr: ds 2 ;Total number of retries.
-numtry: ds 1 ;Number of tries on this packet.
-oldtry: ds 1 ;Number of tries on previous packet.
-state: ds 1 ;Present state of the automaton.
-;*** start of new flags. Do not assume that just because these flags are
-; present that the feature is available. I simply put them in 'for future use'
-rcapas:
-rcap1: db 0 ; receive capabilties byte 0
-rcap2: db 0 ; receive cpabilities byte 1
-scapas:
-scap1: db 0 ; send capabilities byte 0
-scap2: db 0 ; send capabilities byte 1
-rtimeo: db 0 ; receive timeout
-stimeo: db 0 ; send timeout
-rpadc: db 0 ; receive pad character
-spadc: db 0 ; send pad character
-rrept: db 0 ; receive repeat prefix
-srept: db 0 ; send repeat prefix
-rwindo: db 0 ; receive window size
-swindo: db 0 ; send window size
-rdpkt:
-rlpkt: dw 0 ; receive long packet length
-sdpkt:
-slpkt: dw 0 ; send long packet length
-sdckt: db 0 ; send default checktype
-rdckt: db 0 ; receive checktype (should be same as sdckt)
-;*** end of new flags
-sohchr: db 1 ;Default Start-of-header chr is cntl-a
-; Kermit packet starts here
-; Byte 0 = start of packe character
-; 1 = length of packet
-; 2 = packet number
-; 3 = packet type (S R I Z E B etc)
-packet: ds 4 ;Packet (data is part of it).
-; Data part of packet (variable length - include checksum)
-data: ds 5AH ;Data and checksum field of packet.
-recpkt: ds 65H ;Receive packet storage (use the following).
-recpkx: db cr,'$' ;= = = buffer limit
-filbuf: ds 65H ;Character buffer.
-fnbuf: ds 20h ;[jd] file name buffer
-autorc: db 0 ;[obs] set to ON for autoreceive
-
-; Temporary data space. Sometimes accesses as 16 bits (eg temp1/2)
-;** Temp 1 & 2 must be in order
-lstchr: ;Last console input character.
-temp1: ds 1 ;Temporary storage.
-temp2: ds 1
-lincnt: ; used for counting lines in p20ln
-temp3: ds 1
-temp4: ds 1
-temp5: ds 1
-temp6: ds 1
-temp7: ds 1
-temp8: ds 1
-temp9: ds 1
-temp10: ds 1
-temp11: ds 1
-
-
-getrxflg:
- ds 1 ;[obs 22]
-quietd: db 0 ;loud display during file transfers
-argblk: ds 20H ;Used for subroutine arguments
-
-maxfil EQU 2 ; currently, only two names used.
-fcbblk: ds maxfil*10H ;Used for a list of FCB's
-
-; [gnn] secondary filename storage (remote on send, local on get)
-remnam: ds 60 ;[gnn]
-remlen: ds 1 ;[gnn] length of name
-
-; Bookkeeping storage for multiple-sector buffering. The actual buffer
-; is somewhere in the system-dependent overlay. (at the end, I hope).
-nxtbuf: ds 2 ; Pointer to next sector
-seccnt: ds 1 ; Number of sectors buffered
-endsts: ds 1 ; Status for last read into buffer
-;
-;
-; [MF] Storage for Remote Command processing
-;
-;
-rdl: ds 1 ;[MF]Holds accumulated length of remote data
-;
-rcl: ds 1 ;[MF]Holds length of Remote command line arg
-;
-remdat: ds 95 ;[MF]Packet data buffer (plenty big)
-;
-rcom: ds 1 ;[MF] Remote Command type
-;
-rprmpt: dw 0 ;[MF]Address of prompt strings
-;
-rptr: dw 0 ;[MF]Remote command packet data pointer
-;
-rscode: ds 3 ;[MF]Holds Remote Set command ASCII code
-;
-;
- org 7000h ; address for Kermit 4.11
-; ORG ($ + 0ffH) AND 0ff00H ; move to start of next page
-
-;
-; hooks for system-dependent routines:
-; This area is overwritten by the system-dependent overlay.
-;
-lnkflg: dw 0 ; linkage information for consistency check.
-lnkent: dw 0 ; more of the same.
-ovlver: dw 0 ; pointer to overlay's version string
-family: dw 0 ;*NEW* [10] address of the family overlay (not CPSSYS)
-;
-; Input/output routines. Note that outmdm and outcon may actually be the
-; same routine if selmdm and selcon do anything. (the same is true
-; of inpmdm and inpcon).
-;
-selmdm: jmp $-$ ; select modem for I/O
-outmdm: jmp $-$ ; output character in E to modem
-inpmdm: jmp $-$ ; read character from modem. return character or 0 in A.
-flsmdm: jmp $-$ ; flush pending input from modem
-selcon: jmp $-$ ; select console for I/O
-outcon: jmp $-$ ; output character in E to console
-inpcon: jmp $-$ ; read char from console. return character or 0 in A
-outlpt: jmp $-$ ; output character in E to printer
-lptstat:jmp $-$ ;*NEW*[10] see if printer ready to print a character
- ; If 0ffh then ok, if 0h then not ok.
-extern: jmp $-$ ;*NEW for 4.09* If $-$ is not zero, then its a jump to
- ; a routine to emulate any terminal type the user
- ; wants to implement.
-xbdos: jmp 0 ;*NEW* address of the bdos trap in this section
- ; of code. It is filled in initialisation.
-;
-; screen formatting routines
-clrlin: jmp $-$ ; erase current line
-clrspc: jmp $-$ ; erase current position (after backspace)
-delchr: jmp $-$ ; make delete look like backspace
-clrtop: jmp $-$ ; erase screen and go home
-;
-; these routines are called to display a field on the screen.
-scrend: jmp $-$ ; move to prompt field
-screrr: jmp $-$ ; move to error message field
-scrfln: jmp $-$ ; move to filename field
-scrnp: jmp $-$ ; move to packet count field
-scrnrt: jmp $-$ ; move to retry count field
-scrst: jmp $-$ ; move to status field
-rppos: jmp $-$ ; move to receive packet field (debug)
-sppos: jmp $-$ ; move to send packet field (debug)
-;
-sysinit: jmp $-$ ; program initialization
-sysexit: jmp $-$ ; program termination
-syscon: jmp $-$ ; remote session initialization
-syscls: jmp $-$ ; return to local command level
-sysinh: jmp $-$ ; help text for interrupt (escape) extensions
-sysint: jmp $-$ ; interrupt (escape) extensions, including break
-sysflt: jmp $-$ ; filter for incoming characters.
- ; called with character in E.
-sysbye: jmp $-$ ; terminate remote session
-sysspd: jmp $-$ ; baud rate change routine.
- ; called with value from table in DE
-sysprt: jmp $-$ ; port change routine.
- ; called with value from table in HL
-sysscr: jmp $-$ ; screen setup for file transfer
- ; called with Kermit's version string in DE
-csrpos: jmp $-$ ; move cursor to row B, column C
-sysspc: jmp $-$ ; calculate free space for current disk
-mover: jmp $-$ ; block move
-prtstr: jmp $-$ ; *** NEW *** prtstr moved to overlay
-;
-; Data initialized by system-dependent overlay:
-;
-pttab: ds 2 ; points to local equivalents to VT52 escape sequences
-spdtab: ds 2 ; address of baud rate command table, or zero
-spdhlp: ds 2 ; address of baud rate help table, or zero
-prttab: ds 2 ; address of port command table, or zero
-prthlp: ds 2 ; address of port help table, or zero
-timout: ds 2 ; Initial value for fuzzy timeout
-vtflg: ds 1 ; VT52 emulation flag
-escchr: ds 1 ; Storage for the escape character.
-speed: ds 2 ; storage for the baud rate
-port: ds 2 ; storage for port value
-prnflg: ds 1 ;[hh] printer copy flag (overlay may need it)
-dbgflg: ds 1 ; debugging flag
-ecoflg: ds 1 ; Local echo flag (default off).
-flwflg: ds 1 ; File warning flag (default on).
-ibmflg: ds 1 ; IBM flag (default off).
-cpmflg: ds 1 ; File mode flag (ascii/binary/default)
-incflg: ds 1 ;[MF]Incomplete flag (keep/discard)
- ;[MF](default discard)
-parity: ds 1 ; Current parity.
-spsiz: ds 1 ; Send packet size.
-rpsiz: ds 1 ; Receive packet size.
-stime: ds 1 ; Send time out.
-rtime: ds 1 ; Receive time out.
-spad: ds 1 ; Send padding.
-rpad: ds 1 ; Receive padding.
-spadch: ds 1 ; Send padding char.
-rpadch: ds 1 ; Receive padding char.
-seol: ds 1 ; Send EOL char.
-reol: ds 1 ; Receive EOL char.
-squote: ds 1 ; Send quote char.
-rquote: ds 1 ; Receive quote char.
-chktyp: ds 1 ; Checksum type desired
-tacflg: ds 1 ; TACTrap flag (zero=off, nonzero=on; when non-zero,
- ; contains current TAC intercept character)
-tacchr: ds 1 ; TAC intercept character
-bufadr: ds 2 ; Pointer to big buffer for multiple-sector I/O
-bufsec: ds 1 ; Number of sectors big buffer can hold (0 means 256)
-ffussy: ds 1 ; if nonzero, don't permit <>.,;?*[] in CP/M filespec.
-; space used by directory command; here because space calculation is
-; (operating) system-dependent
-bmax: ds 2 ; highest block number on drive
-bmask: ds 1 ; (records/block)-1
-bshiftf: ds 1 ; number of shifts to multiply by rec/block
-nnams: ds 1 ; counter for filenames per line
-
-lnksiz equ $-lnkflg ; length of linkage section, for consistency check.
-
- END START
+; CPSDAT.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; Pure and impure data areas. Previously of CPSUTL.ASM
+;
+; revision history:
+;
+;edit 19, 29-Mar-1991 by MF. Add flag "initak" (nonzero) which is cleared
+; after the initial automatic TAKE attempt of KERMIT.INI to allow
+; "unable to find file" complaints if not doing that initial TAKE.
+;edit 18, 21-Mar-1991 by MF. Renamed parameter vermin to revno (revision
+; level) since verno is already known as the "minor version number".
+;edit 17, 27-Feb-1991 by MF. Corrected typeo in "inms19" and commented out
+; "typptr" pointer as the TYPE command now uses the big buffer.
+; Also provided for a "minor version number" (1-26=A-Z) and message to
+; facilitate display of Kermit version in VERSION command (modmsg)
+;edit 16, 12-Feb-1991 by MF. Eliminated storage (message and variable)
+; for case sensitivity by commenting it out.
+;edit 15, 9-Dec-1990 by MF. Modified message for "directory file size"
+; status report to make it clearer when spoken by a speech synthesizer.
+;edit 14, 4-Dec-1990 by MF. Added message for Autoreceive status report.
+;edit 13, 30-Nov-1990 by MF. Added messages to display regular/quiet status
+; of terminal in SHOW and STATUS commands.
+;edit 12, 8-Nov-1990 by MF. Added a new message for Set Autoreceive.
+;edit 11, 2-Nov-1990 by MF. Moved overlay address to 7000H -- I didn't
+; realize I was **that** close to the limit until I made a couple of
+; cosmetic changes and REM CD bombed. This is still ver. 4.10 as it
+; hasn''t been released yet.
+;edit 10, 1-Nov-1990 by MF. Changed message at "spdst" to conform with
+; the change of "SET BAUD-RATE" to "SET SPEED".
+; Also added message "sdpst2" for speed status (staspd) routine
+;edit 9, 17-Oct-1990 by MF. Changed "packet-size" messages to use the
+; word "length" to conform with the nomenclature suggested in the
+; 6th edition of the Kermit Protocol Manual.
+;edit 8, 19-Sep-1990 by MF. Added error message for FRENAME command.
+;edit 7, 14-Sep-1990 by MF. Added storage/strings for SET COLLISION command.
+; Also added strings/storage for SET INCOMPLETE-FILE command.
+;edit 6, 9-Sep-1990 by MF. Added messages and storage for Remote commands.
+; and display of packet sizes
+; Moved overlay address to 06C00H for Version 4.10.
+; edit 5, 8 April, 1987 by OBSchou. Added new entry in jump table to call
+; code for an external terminal type. Added some new error messages
+; and added more to the packet space.
+;
+; edit 4, 30 March by OBSchou. Added in space for autoreceive.
+;
+; edit 3, 19 March, 1987 by OBSchou. Added some more strings etc, and
+; increased the stack space fro 32 entries to 64.
+;
+; edit 2, 11 March, 1987 by OBSchou.
+; Added in some more data and strings and things. Nothing special
+;
+; edit 1, 28 January, 1987 by OBSchou
+; Following file the data section of CPSUTL.ASM. This part of the
+; CPSUTL.ASM file now seperate as it ws getting too larg. Link to here
+; from CPSUTL.ASM (which now has only the utlity routines).
+; Also added in bits submitted by Dave Roberts of Leicester:
+; DJR 18th January 1987 - David J. Roberts.
+; Support for cosmetic changes in CPSMIT:
+; New strings DBGST and CURDST
+; CRLF in front of TIMMSG
+; LOGST changed, and new LOGST2
+;
+;
+datver: db 'CPSDAT.ASM (19) 29-Mar-1991$'
+
+
+
+;
+
+version:db 'Kermit-80 v4.'
+ db (verno/10) + '0' ; tenth's digit of version number
+ db (verno MOD 10) + '0' ; hundredth's digit
+IF revno ;[MF]If a revision level,
+ db revno+'@' ;[MF]put it in (range 1-26=A-Z)
+ENDIF ;revno [MF]
+ db ' $'
+modmsg: db ' has been built from the following modules:$';[MF]
+kerm: db 'Kermit-80 '
+kerm1: db 'nnx:>$' ;'x' filled in at startup with DRIVE name
+ ;'nn filled at startup and user with user number
+crlf: db cr,lf,'$'
+ermes1: db cr,lf,'?Unrecognized command$'
+ermes3: db cr,lf,'?Not confirmed$'
+ermes4: db '?Unable to receive initiate',cr,lf,'$'
+ermes5: db '?Unable to receive file name',cr,lf,'$'
+ermes6: db '?Unable to receive end of file',cr,lf,'$'
+erms10: db '?Unable to receive data',cr,lf,'$'
+erms11: db '?Disk full',cr,lf,'$'
+erms12: db '?Directory full',cr,lf,'$'
+erms14: db '?Unable to receive an acknowledgement from the host',cr,lf,'$'
+erms15: db cr,lf,'?Unable to find file',cr,lf,'$'
+erms16: db '?Unable to rename file$'
+erms17: db cr,lf,'?Disk full$'
+erms18: db cr,lf,'?Unable to tell host that the session is finished$'
+erms19: db cr,lf,'?Unable to tell host to logout$'
+erms20: db cr,lf,'?Kermit has not been configured for a target system$'
+erms21: db cr,lf,'?Consistency check on configuration failed$'
+erms22: db cr,lf,'?Error writing to log file',cr,lf,'$' ;[pcc005]
+erms23: db cr,lf,'?Invalid user number$'
+erms24: db cr,lf,'?Invalid Pause parameter$'
+erms25: db cr,lf,'?Invalid BUFFER-SIZE parameter$'
+erms26: db cr,lf,'?Invalid packet length (too long)$'
+erms27: db cr,lf,'?Invalid Checktype$'
+erms28: db cr,lf,'?Too many retries$'
+erms29: db cr,lf,'?Failed to exchange parameters$'
+erms30: db cr,lf,'?Failed to receive input string in alloted time$'
+erms31: db cr,lf,'?File already exists$' ;[MF]
+
+infms3: db bell,'Completed$'
+infms4: db bell,'Failed$'
+infms5: db '%Renaming file to $'
+infms6: db cr,lf,'[Closing the log file]$'
+infms7: db cr,lf,'[Connected to remote host. Type $'
+infms8: db 'C to return;',cr,lf,' type $'
+inms8a: db '? for command list]',cr,lf,'$'
+infms9: db cr,lf,'[Connection closed, back at micro]$'
+inms10: db 'Control-$'
+inms11: db ' Not implemented.$'
+inms12: db ' (Not implemented)',cr,lf,'$'
+inms13: db bell,'Interrupted$'
+inms14: db TAB,TAB,' Directory for drive '
+dnam14: db 'nnx:',cr,lf,'$' ;filled in by dir routine.
+inms15: DB CR,LF,TAB,TAB,'Drive $'
+inms16: DB ' has $';filled in by summary code with drive letter
+inms17: DB 'K bytes free',CR,LF,'$'
+inms18: DB CR,LF,'File(s) erased$',CR,LF
+inms19: db cr,lf,'[Transmitting file to host:'
+ db cr,lf,' 1. Lines automatically sent, and wait for possible reply'
+ db cr,lf,' 2. CONTROL-C aborts transfer'
+ db cr,lf,' 3. If transfer hangs, try a return to continue'
+ db cr,lf,' 4. on exit, you will be placed in CONNECT state.'
+ db cr,lf,'$'
+inms20: db 'R to send the same line again,'
+ db cr,lf,' or type $'
+inms21: db 'C to abort transmission.]',cr,lf,'$'
+inms22: db cr,lf,'[Transmission done. Connected normally '
+ db 'to remote host,'
+ db cr,lf,' type $'
+inms23: db 'Sending...$'
+inms24: db 'Receiving...$'
+inms25: db bell,'Warning: eighth bit cannot be sent$'
+inms26: db cr,lf,'For help, type ? at any point in a command$'
+inms27: db cr,lf,'[Logging suspended]',cr,lf,'$' ;[pcc003]
+inms28: db cr,lf,'[Logging resumed]',cr,lf,'$' ;[pcc003]
+inms29: db cr,lf,'[Transmission Aborted. Connected normally '
+ db 'to remote host,'
+ db cr,lf,' type $'
+autmes: db cr,lf,cr,lf,'[Automatically receiving; type ^C to abort]'
+ db cr,lf,cr,lf,'$' ;[MF]
+anymes: db cr,lf,cr,lf,' * * * Press any key to continue * * * '
+ db cr,lf,cr,lf,'$'
+escmes: db cr,lf,'Type the new escape character: $'
+tacmes: db cr,lf,'Type the new TAC intercept character: $'
+sopmes: db cr,lf,'Give the start-of-packet character: $' ;[gnn]
+padcms: db cr,lf,'Type the new padding character: $' ;[obs]
+xmthlp: db cr,lf,'R Send the same line again$'
+loghlp: db cr,lf,'Q Suspend logging' ;[pcc003]
+ db cr,lf,'R Resume logging$' ;[pcc003]
+inthlp: db cr,lf,'? This message'
+ db cr,lf,'C Close the connection'
+ db cr,lf,'0 (zero) Transmit a NULL'
+ db cr,lf,'P Toggle printer on/off' ;[pcc002]
+ db cr,lf,'S Status of the connection$'
+inhlp1: db cr,lf,'Typing another $'
+inhlp2: db ' will send it to the host'
+ db cr,lf,cr,lf,'Command>$'
+
+xmtst: db cr,lf,'Transmitting a file$'
+autrst: db cr,lf,'Autoreceive is$'
+locst: db cr,lf,'Local echo$'
+onstr: db ' on$'
+offstr: db ' off$'
+flost: db cr,lf,'Flow control$'
+;senst: db cr,lf,'Case sensetivity$'
+vtdpst: db cr,lf,'Terminal display is $'
+vtdpsr: db 'REGULAR$'
+vtdpsq: db 'QUIET$'
+vtemst: db cr,lf,'Terminal emulation is $'
+cpmst: db cr,lf,'File Mode$'
+defstr: db ' default$'
+ascstr: db ' ASCII$'
+binstr: db ' binary$'
+hfsod: db cr,lf,'Display file size on DIRECTORY command$'
+ibmst: db cr,lf,'IBM flag$'
+incst: db cr,lf,'Disposition for incomplete files is$'
+dscstr: db ' discard$'
+kepstr: db ' keep$'
+filst: db cr,lf,'File warning$'
+prst: db cr,lf,'Printer copy$'
+logst: db cr,lf,'Logging to $' ;[pcc003][DJR]
+logst2: db ' is$' ;[DJR]
+susstr: db ' suspended$' ;[pcc003]
+sspmsg: db cr,lf,'SEND start-of-pkt char ^$' ;[gnn]
+rspmsg: db cr,lf,'RECEIVE start-of-pkt char ^$' ;[gnn]
+spsmsg: db cr,lf,'SEND packet length $' ;[MF]
+rpsmsg: db cr,lf,'RECEIVE packet length $' ;[MF]
+escst: db cr,lf,'Escape char: $'
+bufsz1: db cr,lf,'Multi-sector buffering at $'
+bufsz2: db ' of a maximum of $'
+xmitst: db cr,lf,'Transmit protocol char: $'
+bckst: db cr,lf,'Block check type: $'
+bckst1: db '-character$'
+collst: db cr,lf,'File COLLISION: $';[MF]
+parst: db cr,lf,'Parity: $'
+pnonst: db 'none$'
+pmrkst: db 'mark$'
+pspcst: db 'space$'
+poddst: db 'odd$'
+pevnst: db 'even$'
+porst: db cr,lf,'Port in use is: $'
+spdst: db cr,lf,'Current speed is: $'
+spdst2: db ' bps$' ;[MF]
+spdust: db 'indeterminate (not SET)$'
+timmsg: db cr,lf,'Timer$' ;[DJR] Added CRLF like the others
+tacst: db cr,lf,'Current TACTrap Status/Intercept Character: $'
+usrst: db cr,lf,'Current user number: $'
+dbgst: db cr,lf,'Debugging$' ;[DJR]
+curdst: db cr,lf,'Current default disk: $' ;[DJR]
+spac15: db ' $' ; *** 15 spaces ***
+samems: db cr,lf,'?Source and destination files the same$'
+nofile: db cr,lf,'?File not found$'
+cmer00: db cr,lf,'?Program error: Invalid COMND call$'
+cmer01: db cr,lf,'?Ambiguous$'
+cmer02: db cr,lf,'?Illegal CP/M file specification$'
+cmer03: db cr,lf,'?Wild-cards not allowed in file specification$' ;[pcc006]
+cmer04: db cr,lf,'?Invalid user number$'
+cmer05: db cr,lf,'?Invalid \ parameter$'
+cmin00: db ' Confirm with carriage return$'
+cmin01: db ' Enter a number$'
+cmin02: db ' Confirm with carriage return or enter more$'
+
+; Diagnostic messages
+sstatm: db '<SState:> ',0
+rstatm: db '<RState:> ',0
+spackm: db '<Data transmitted> ',0
+rpackm: db '<Data received > ',0
+princr: db cr,lf,0
+;
+; Remote command messages [MF]
+;
+newfms: db cr,lf,'New file: $'
+pswdms: db cr,lf,'Password: $'
+acctms: db cr,lf,'Account: $'
+newnms: db cr,lf,'New name: $'
+msgms: db cr,lf,'Message: $'
+optms: db cr,lf,'Options: $'
+
+;
+ ;Impure data
+
+;COMND storage
+
+comchr: ds 1 ;[8] save space
+floctl: db 0 ;[8] flow control on/off flag
+;casens: db 0 ;[8] Upper/lower case sensitive
+cmstat: ds 1 ;What is presently being parsed.
+cmaflg: ds 1 ;Non-zero when an action char has been found.
+cmbflg: ds 1 ;[MF]Nonzero to allow a blank initial keyword
+cmqflg: ds 1 ;[MF]Nonzero to prevent character echoing
+ ;[MF]when entering commands
+cmccnt: ds 1 ;Non-zero if a significant char is found.
+cmsflg: ds 1 ;Non-zero when the last char was a space.
+cmostp: ds 2 ;Old stack pointer for reparse.
+cmrprs: ds 2 ;Address to go to on reparse.
+cmprmp: ds 2 ;Address of prompt.
+cmptab: ds 2 ;Address of present keyword table.
+cmhlp: ds 2 ;Address of present help.
+cmdbuf: ds 80H ;Buffer for command parsing.
+cmbufl equ $-cmdbuf-3 ; set a limit on the command buffer
+cmfcb: ds 2 ;Pointer to FCB.
+cmfcb2: ds 2 ;Pointer to position in FCB.
+cmfwld: ds 1 ;Wildcard flag
+cmcptr: ds 2 ;Pointer for next char input.
+cmdptr: ds 2 ;Pointer into the command buffer.
+cmkptr: ds 2 ;Pointer to keyword.
+cmsptr: ds 2 ;Place to save a pointer.
+slshsn: db 0 ; slash seen in command line
+slashc: db 0 ; count for number of characters in slash sequence
+slashn: db 0 ; number to be built for \xxx
+;
+oldsp: ds 2 ;Room for old system stack.
+ ds 80H ;Room for 64 levels of calls.[obs]
+stack: ds 2
+eoflag: ds 1 ;EOF flag;non-zero on EOF.
+curdsk: db 0 ;holds "logged" disk
+curusr: db 0 ;[8] holds "user" number
+rcvsop: db SOH ;[gnn] receive start-of-packet
+sndsop: db SOH ;[gnn] send start-of-packet
+prtcnt: db 0 ;[pcc008] prtchr fairness count
+timflg: db 0 ;[jd] timer flag: 0 -> no timer
+timval: dw 0 ;[jd] timer value
+wrn8: db 0 ;[jd] non-zero if 8-bit-lost warning sent
+qbchr: db '&' ;[jd] binary quote character.
+quot8: db 0 ;[jd] non-zero if doing 8-bit quoting
+logflg: db 0 ;Flag for a log file.
+ ;[pcc005] 0 = no log
+ ;[pcc005] x1 = logging on
+ ;[pcc005] x2 = suspended
+ ;[pcc005] 8xH (bit 7) = file open
+lognam: db 0 ;[pcc013] File to use for session logging
+ db 'KERMIT ' ;[pcc013]
+ db 'LOG' ;[pcc013]
+nexitf: db 0 ; set to 1 for exit to CPM after command tail
+takflg: db 0 ;[8] TAKE flag.
+ ; Bit zero = 1 for take file in progress
+ ; bit 4 = 1 if command line present/in progress
+ ; Note: Take has priority over command line.
+initak: db 0ffh ;[MF]Cleared after initial TAKE (KERMIT.INI)
+taknam: db 0 ;[8] use default drive
+ db 'KERMIT '
+ db 'INI' ;[8] Inital file to TAKE KERMIT.INI
+takptr: ds 2 ;[8] Pointer to position in TAKE file input
+takfcb: ds 12 ;[8] fcb space for take file
+ dw 0 ;[8] fill up extents etc with 00
+ dw 0
+ ds 16 ;[8] used by dos
+ dw 0
+ dw 0
+takdma: ds 128 ;[8]space to read TAKE file...
+prnbuf: ds 1 ; printer buffer. Output pointer
+ ds 1 ; input offset pointer
+ ds 256 ; give a large buffer
+ ds 10 ; and a little spare
+;
+;
+;
+; Transmit space
+;
+repcnt: db 0 ; repeat counter
+starc: db 0 ; star count
+rexbfl: db 0 ; retransmit flag (1=> retransmit)
+rexcnt: db 0 ; retransmit character count
+rexbuf: ds 128 ; max retransmit line length 128 characters
+xmtbuff:
+ ds 128 ; 128 byte sector buffer
+xmtptr: db 0 ; offset pointer to xmtbuff above
+xmtfcb: ds 36 ; fcb for transmit file.
+;
+;INPUT and STRING space
+strlen: db 0 ; length of the string from INPUT and STRING
+
+; Assorted other space
+errorc: db 0 ; error level set to xxx
+errorl: db 0 ; error level to test against
+
+remtxt: db 0 ; set <> 0 if D packets to screen
+
+hosths: ds 1 ; have we told the host to xoff? (is this duplicated)
+stbuff: ds 80h ; some space or the string buffer
+waitp: ds 2 ; wait command timer
+waitp1: ds 2 ; wait/input timer (copy of waitp)
+prntmp: ds 1 ; temporary space to put the caracter to print
+prnfl: db 0 ; printer flag. Used by TYPE/PRINT
+;[MF][17]Following line no longer needed as TYPE uses the big buffer
+;typptr: ds 2 ; pointer used by TYPE/PRINT
+equflg: db 0 ; set to non zero if copy files same
+nquiet: db 0 ; If non zero print from NOUT to display
+
+escflg: db 0 ;Escape flag (start off).
+fileio: db 0 ;Line-by-line from file (default off).
+xofflg: db 0 ;X-OFF (=^S) received from COMM-line
+ ;X-ON (=^Q) received resets this
+clkbit: dw 0 ; 32 bit pseudo clock
+ dw 0 ; MS bits of clock
+number: ds 2 ; Number in binary form from user input
+initflg:db 0 ; set to non zero when system initialised
+maxbsc: ds 1 ; save space to know how big system allows
+ ; for multi-sector buffering. (Usually 8k?)
+;
+; Multiple FCB storage space. Used for the DIR command
+; Later on, I want to shift this into space after the system
+; dependent stuff, but then it becomes messy with pointers
+; to pointers etc... [OBS]
+;
+xfcbptr:
+ ds 2 ; pointer to current fcb space
+fcbcnt: ds 1 ; Number of valid fcbs in space
+;
+fcb0: ds 12 ; 36 bytes requred for a single fcb
+fcblen EQU $-fcb0 ; length of a single fcb
+ ds maxfcb*fcblen ; space for maximum fcbs + 1
+;
+hidefs: db 0ffh ; flag <> 0 if we show file size in DIR
+
+; FCB sapce for COPY command
+cfcbs: ds 33 ; source fcb for copy file ops.
+ ;[MF]and FRENAME ops.
+cfcbd: ds 33 ; destination fcb for copy ops.
+ ;[MF]and FRENAME ops.
+
+colfcb: ds 33 ;[MF]Rename fcb for SET COLLISION
+
+; Command tail data space etc
+cbptr: db 2 ; command tail pointer (0= length of tail)
+cbuff: ds 128 ; temp. space for potential command tail
+
+strcnt: db 0 ; string count for string operations...
+
+vtyval: ds 1 ; holds row number for VT52 cursor positioning
+chrcnt: ds 1 ;Number of chars in the file buffer.
+
+; Various packet variables etc
+bytes: dw 0 ; 4 byte 'byte count' space
+ dw 0
+filcnt: ds 1 ;Number of chars left to fill.
+outpnt: ds 2 ;Position in packet.
+bufpnt: ds 2 ;Position in file buffer.
+fcbptr: ds 2 ;Position in FCB.
+datptr: ds 2 ;Position in packet data buffer.
+cbfptr: ds 2 ;Position in character buffer.
+pktptr: ds 2 ;Position in receive packet.
+size: ds 1 ;Size of data from gtchr.
+curchk: ds 1 ;Current checksum type
+inichk: ds 1 ;Agreed upon checksum type
+czseen: ds 1 ;Flag that control-Z was typed
+dscflg: ds 1 ;[MF]Discard file if nonzero
+pktnum: ds 1 ;Packet number.
+numpkt: ds 2 ;Total number of packets sent.
+numrtr: ds 2 ;Total number of retries.
+numtry: ds 1 ;Number of tries on this packet.
+oldtry: ds 1 ;Number of tries on previous packet.
+state: ds 1 ;Present state of the automaton.
+;*** start of new flags. Do not assume that just because these flags are
+; present that the feature is available. I simply put them in 'for future use'
+rcapas:
+rcap1: db 0 ; receive capabilties byte 0
+rcap2: db 0 ; receive cpabilities byte 1
+scapas:
+scap1: db 0 ; send capabilities byte 0
+scap2: db 0 ; send capabilities byte 1
+rtimeo: db 0 ; receive timeout
+stimeo: db 0 ; send timeout
+rpadc: db 0 ; receive pad character
+spadc: db 0 ; send pad character
+rrept: db 0 ; receive repeat prefix
+srept: db 0 ; send repeat prefix
+rwindo: db 0 ; receive window size
+swindo: db 0 ; send window size
+rdpkt:
+rlpkt: dw 0 ; receive long packet length
+sdpkt:
+slpkt: dw 0 ; send long packet length
+sdckt: db 0 ; send default checktype
+rdckt: db 0 ; receive checktype (should be same as sdckt)
+;*** end of new flags
+sohchr: db 1 ;Default Start-of-header chr is cntl-a
+; Kermit packet starts here
+; Byte 0 = start of packe character
+; 1 = length of packet
+; 2 = packet number
+; 3 = packet type (S R I Z E B etc)
+packet: ds 4 ;Packet (data is part of it).
+; Data part of packet (variable length - include checksum)
+data: ds 5AH ;Data and checksum field of packet.
+recpkt: ds 65H ;Receive packet storage (use the following).
+recpkx: db cr,'$' ;= = = buffer limit
+filbuf: ds 65H ;Character buffer.
+fnbuf: ds 20h ;[jd] file name buffer
+autorc: db 0 ;[obs] set to ON for autoreceive
+
+; Temporary data space. Sometimes accesses as 16 bits (eg temp1/2)
+;** Temp 1 & 2 must be in order
+lstchr: ;Last console input character.
+temp1: ds 1 ;Temporary storage.
+temp2: ds 1
+lincnt: ; used for counting lines in p20ln
+temp3: ds 1
+temp4: ds 1
+temp5: ds 1
+temp6: ds 1
+temp7: ds 1
+temp8: ds 1
+temp9: ds 1
+temp10: ds 1
+temp11: ds 1
+
+
+getrxflg:
+ ds 1 ;[obs 22]
+quietd: db 0 ;loud display during file transfers
+argblk: ds 20H ;Used for subroutine arguments
+
+maxfil EQU 2 ; currently, only two names used.
+fcbblk: ds maxfil*10H ;Used for a list of FCB's
+
+; [gnn] secondary filename storage (remote on send, local on get)
+remnam: ds 60 ;[gnn]
+remlen: ds 1 ;[gnn] length of name
+
+; Bookkeeping storage for multiple-sector buffering. The actual buffer
+; is somewhere in the system-dependent overlay. (at the end, I hope).
+nxtbuf: ds 2 ; Pointer to next sector
+seccnt: ds 1 ; Number of sectors buffered
+endsts: ds 1 ; Status for last read into buffer
+;
+;
+; [MF] Storage for Remote Command processing
+;
+;
+rdl: ds 1 ;[MF]Holds accumulated length of remote data
+;
+rcl: ds 1 ;[MF]Holds length of Remote command line arg
+;
+remdat: ds 95 ;[MF]Packet data buffer (plenty big)
+;
+rcom: ds 1 ;[MF] Remote Command type
+;
+rprmpt: dw 0 ;[MF]Address of prompt strings
+;
+rptr: dw 0 ;[MF]Remote command packet data pointer
+;
+rscode: ds 3 ;[MF]Holds Remote Set command ASCII code
+;
+;
+ org 7000h ; address for Kermit 4.11
+; ORG ($ + 0ffH) AND 0ff00H ; move to start of next page
+
+;
+; hooks for system-dependent routines:
+; This area is overwritten by the system-dependent overlay.
+;
+lnkflg: dw 0 ; linkage information for consistency check.
+lnkent: dw 0 ; more of the same.
+ovlver: dw 0 ; pointer to overlay's version string
+family: dw 0 ;*NEW* [10] address of the family overlay (not CPSSYS)
+;
+; Input/output routines. Note that outmdm and outcon may actually be the
+; same routine if selmdm and selcon do anything. (the same is true
+; of inpmdm and inpcon).
+;
+selmdm: jmp $-$ ; select modem for I/O
+outmdm: jmp $-$ ; output character in E to modem
+inpmdm: jmp $-$ ; read character from modem. return character or 0 in A.
+flsmdm: jmp $-$ ; flush pending input from modem
+selcon: jmp $-$ ; select console for I/O
+outcon: jmp $-$ ; output character in E to console
+inpcon: jmp $-$ ; read char from console. return character or 0 in A
+outlpt: jmp $-$ ; output character in E to printer
+lptstat:jmp $-$ ;*NEW*[10] see if printer ready to print a character
+ ; If 0ffh then ok, if 0h then not ok.
+extern: jmp $-$ ;*NEW for 4.09* If $-$ is not zero, then its a jump to
+ ; a routine to emulate any terminal type the user
+ ; wants to implement.
+xbdos: jmp 0 ;*NEW* address of the bdos trap in this section
+ ; of code. It is filled in initialisation.
+;
+; screen formatting routines
+clrlin: jmp $-$ ; erase current line
+clrspc: jmp $-$ ; erase current position (after backspace)
+delchr: jmp $-$ ; make delete look like backspace
+clrtop: jmp $-$ ; erase screen and go home
+;
+; these routines are called to display a field on the screen.
+scrend: jmp $-$ ; move to prompt field
+screrr: jmp $-$ ; move to error message field
+scrfln: jmp $-$ ; move to filename field
+scrnp: jmp $-$ ; move to packet count field
+scrnrt: jmp $-$ ; move to retry count field
+scrst: jmp $-$ ; move to status field
+rppos: jmp $-$ ; move to receive packet field (debug)
+sppos: jmp $-$ ; move to send packet field (debug)
+;
+sysinit: jmp $-$ ; program initialization
+sysexit: jmp $-$ ; program termination
+syscon: jmp $-$ ; remote session initialization
+syscls: jmp $-$ ; return to local command level
+sysinh: jmp $-$ ; help text for interrupt (escape) extensions
+sysint: jmp $-$ ; interrupt (escape) extensions, including break
+sysflt: jmp $-$ ; filter for incoming characters.
+ ; called with character in E.
+sysbye: jmp $-$ ; terminate remote session
+sysspd: jmp $-$ ; baud rate change routine.
+ ; called with value from table in DE
+sysprt: jmp $-$ ; port change routine.
+ ; called with value from table in HL
+sysscr: jmp $-$ ; screen setup for file transfer
+ ; called with Kermit's version string in DE
+csrpos: jmp $-$ ; move cursor to row B, column C
+sysspc: jmp $-$ ; calculate free space for current disk
+mover: jmp $-$ ; block move
+prtstr: jmp $-$ ; *** NEW *** prtstr moved to overlay
+;
+; Data initialized by system-dependent overlay:
+;
+pttab: ds 2 ; points to local equivalents to VT52 escape sequences
+spdtab: ds 2 ; address of baud rate command table, or zero
+spdhlp: ds 2 ; address of baud rate help table, or zero
+prttab: ds 2 ; address of port command table, or zero
+prthlp: ds 2 ; address of port help table, or zero
+timout: ds 2 ; Initial value for fuzzy timeout
+vtflg: ds 1 ; VT52 emulation flag
+escchr: ds 1 ; Storage for the escape character.
+speed: ds 2 ; storage for the baud rate
+port: ds 2 ; storage for port value
+prnflg: ds 1 ;[hh] printer copy flag (overlay may need it)
+dbgflg: ds 1 ; debugging flag
+ecoflg: ds 1 ; Local echo flag (default off).
+flwflg: ds 1 ; File warning flag (default on).
+ibmflg: ds 1 ; IBM flag (default off).
+cpmflg: ds 1 ; File mode flag (ascii/binary/default)
+incflg: ds 1 ;[MF]Incomplete flag (keep/discard)
+ ;[MF](default discard)
+parity: ds 1 ; Current parity.
+spsiz: ds 1 ; Send packet size.
+rpsiz: ds 1 ; Receive packet size.
+stime: ds 1 ; Send time out.
+rtime: ds 1 ; Receive time out.
+spad: ds 1 ; Send padding.
+rpad: ds 1 ; Receive padding.
+spadch: ds 1 ; Send padding char.
+rpadch: ds 1 ; Receive padding char.
+seol: ds 1 ; Send EOL char.
+reol: ds 1 ; Receive EOL char.
+squote: ds 1 ; Send quote char.
+rquote: ds 1 ; Receive quote char.
+chktyp: ds 1 ; Checksum type desired
+tacflg: ds 1 ; TACTrap flag (zero=off, nonzero=on; when non-zero,
+ ; contains current TAC intercept character)
+tacchr: ds 1 ; TAC intercept character
+bufadr: ds 2 ; Pointer to big buffer for multiple-sector I/O
+bufsec: ds 1 ; Number of sectors big buffer can hold (0 means 256)
+ffussy: ds 1 ; if nonzero, don't permit <>.,;?*[] in CP/M filespec.
+; space used by directory command; here because space calculation is
+; (operating) system-dependent
+bmax: ds 2 ; highest block number on drive
+bmask: ds 1 ; (records/block)-1
+bshiftf: ds 1 ; number of shifts to multiply by rec/block
+nnams: ds 1 ; counter for filenames per line
+
+lnksiz equ $-lnkflg ; length of linkage section, for consistency check.
+
+ END START
diff --git a/cpsdef.asm b/cpsdef.asm
index 46e3ba6..4cb4c10 100644
--- a/cpsdef.asm
+++ b/cpsdef.asm
@@ -1,287 +1,287 @@
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains definitions used by both modules of Kermit.
-;
-; revision history:
-;
-;edit 9, 30-Nov-1990 by MF. Make "fairness" count "prfair" be 50 so
-; console gets checked a bit more often.
-; edit 8, 11-Sep-1990 by MF. Make default RECEIVE and SEND packet-size
-; 80 (per Kermit standard) as packet size is adjustable in Version
-; 4.10.
-; edit 7 16-Jun-86 OBSchou. Added cmnum in the command opcodes. This gets a
-; number from the user inot variable number. No checking on overflow.
-;
-; edit 6 13-May-86 OBSchou. BDOS calls trapped to check for console use
-; as we want to substitute in commands from a TAKE file. Trapping
-; means I dont have to go through an check ever BDOS call...
-;
-; edit 5: 22-Apr-86 by Bertil Schou, Loughborough University, UK
-; moved some definitions from the CP4SYS.ASM file to here for
-; Kermit version 4.06
-;
-; edit 4: 6-Feb-85 by Charles Carvalho
-; modify pcc007: replace ffussy assembly switch with runtime test.
-; add "getvnm" - get CP/M version number.
-;
-; edit 3: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
-;
-;pcc007 2-Jan-85 vjc modules:cp4def,cp4cmd
-; Cmifil is too fussy about what characters to accept in a
-; filespec. My CP/M manual says any printable character is ok
-; except <>.,;:?*[], and lower case. In practice, even those work
-; sometimes. Kermit itself uses '&' if file warning is on,
-; and then won't let you reference the file. Allow all
-; printable characters except those above. Add conditional
-; ffussy, so that if not ffussy, all special characters will be
-; allowed, just convert lower to upper-case.
-;
-;pcc008 2-Jan-85 vjc modules:cp4def,cp4tt,cp4utl
-; Keyboard input during CONNECT mode can get locked out if
-; there is enough input from the modem port to keep prtchr
-; busy. This can happen for example, if the printer is running
-; at the same speed as the modem line, leaving you helpless to
-; turn it off or abort the host. Add a fairness count, so that
-; at least every prfair characters we look at console input.
-;
-; edit 2: July 10, 1984 (CJC)
-; Remove defines for TRUE and FALSE, during reorganization for LASM
-; compatibility. If we're using LASM, this file is linked by CP4KER
-; or CP4TYP, and links to CP4MIT or CP4LNK. Also, push comments around
-; a little.
-;
-; edit 1: May, 1984 (CJC)
-; extracted from CPMBASE.M80 version 3.9; modifications are described
-; in the accompanying .UPD file.
-;
-
-;Symbolic Definitions for some ASCII characters
-;
-soh EQU 01O ;ASCII SOH (Control-A)
-cntlc EQU 03O ;ASCII ETX (Control-C)
-ctrlc EQU 03O ;ASCII ETX (Control-C)
-bell EQU 07O ;ASCII BEL (Control-G)
-bs EQU 10O ;ASCII backspace (Control-H)
-tab EQU 11O ;ASCII Tab (Control-I)
-lf EQU 12O ;ASCII Line Feed (CTRL-J)
-ff EQU 14O ;ASCII Form Feed (CTRL-L)
-cr EQU 15O ;ASCII Carriage Return (CTRL-M)
-space EQU 20h ;ASCII Space
-xon EQU 21O ;ASCII XON (Control-Q)
-xoff EQU 23O ;ASCII XOFF (Control-S)
-esc EQU 33O ;ASCII ESCape
-semico EQU 3bh ;ASCII Semicolon
-subt EQU 32O ;ASCII SUB (CTRL-Z)
-cntlz EQU subt ;ASCII SUB (Control-z) [6]
-ctrlz EQU subt ;ASCII SUB (Control-z)
-del EQU 177O ;ASCII DELete (rubout)
-;
-;BDOS calls
-IF NOT cpsker ;[6] If CPSKER is truem then system indep. stuff. We want
- ;to trap BDOS calls and test for console activity
-bdos EQU 0005H ;BDOS entry point, for the following functions:
-ENDIF ;NOT cpsker [6]
-;
-;Function Name Function Input Parameters Output Parameter
-;============= ======== ================ ================
-; (ALL Function Numbers are passed in Register C)
-conin EQU 01H ;Read Console NONE ASCII Char in A
-conout EQU 02H ;Write Console ASCII Char in E NONE
-auxin EQU 03H ;Auxiliary input
-rdrin EQU 03H ;Read Reader NONE ASCII Char in A
-lstout EQU 05H ;Write List ASCII Char in E NONE
-dconio EQU 06H ;Direct Con I/O ASCII Char in E I/O Status in A
- ; if E=0FEH,
- ; Input if E=0FFH
-prstr EQU 09H ;Print String String-Address NONE
- ; in DE (term=$)
-rdstr EQU 0AH ;Read Buffer Buffer-Address Read Buffer filled
-; in DE
-; Read Buffer Byte Function
-; 1 Maximum Buffer Length
-; 2 Current Buffer Length (returned value)
-; 3-n Data (returned values)
-;
-consta EQU 0BH ;Console Stat NONE LSB(A)=1 if char ready
-getvnm EQU 0CH ;Version Number NONE H=0 (CP/M), L=BDOS ver
-inbdos EQU 0DH ;Init BDOS NONE NONE
-logdsk EQU 0EH ;LOG-In disk Value in E NONE
- ; A=0,B=1,...
-openf EQU 0FH ;Open File FCB-Addr in DE Byte Addr.of FCB,
- ; or 0FFH if not
-closf EQU 10H ;Close File FCB-Addr in DE Byte Addr.of FCB,
- ; or 0FFH if not
-sfirst EQU 11H ;Search File FCB-Addr in DE Byte Addr.of FCB(0-3),
- ; or 0FFH if not
-snext EQU 12H ;Search next FCB-Addr in DE Byte Addr.of next FCB,
- ; or 0FFH if not
-delf EQU 13H ;Delete File FCB-Addr in DE Byte Addr.of FCB(0-3),
- ; or 0FFH if not
-readf EQU 14H ;Read Record FCB-Addr in DE 0=successful read
- ; 1=read past EOF
- ; 2=reading random data
-writef EQU 15H ;Write Record FCB-Addr in DE 0=successful write
- ; 1=ERROR extending
- ; 2=End of disk data
- ; 255=No more DIR space
-makef EQU 16H ;Make File FCB-Addr in DE 0-3= success,
- ; 255= no more dir space
-renam EQU 17H ;Rename File FCB-Addr in DE 0-3= success,
- ; 255= file not found
-rdlog EQU 18H ;Ret. Log Code NONE Login Vector in HL
-rddrv EQU 19H ;Read Drive # NONE # of logged in drive in
- ; (A=0,B=1,C=2....)
-setdma EQU 1AH ;Set DMA Addr. Addr. of 128 NONE
- ; byte buffer in DE
-wrtprt EQU 1CH ;Write prot dsk NONE NONE
-getrov EQU 1DH ;Get R/O Vect. NONE HL= R/O Vect. value
-setfat EQU 1EH ;Set File Attr. FCB-Addr.in DE Dir. code in A
-gtdpar EQU 1FH ;Get DSK par. NONE HL=DPB Address
-usrcod EQU 20H ;Get/Set Usr.Cd E=0FFH (get) A=current code (get)
- ; E-code (set) A=no value (set)
-rrand EQU 21H ;Read Random FCB-Addr in DE A=Return code
-wrand EQU 22H ;Write Random FCB-Addr in DE 1=read'g unwritten data
- ; 2=(not used)
- ; 3=can't close curr. ext
- ; 4=seek to unwr. ext.
- ; 5=dir overflow(write)
- ; 6=seek past End of DSK
-cflsz EQU 23H ;Comp File Sz. FCB Addr.in DE Rand.Rec.field set to
- ; File size
-setrar EQU 24H ;Set Rand. Rec. FCB-Addr.in DE Rand.Rec.field set
-
-; CPM 2 only:
-punout EQU 04H ;Write Punch ASCII Char in E NONE
-gtiob EQU 07H ;Get I/O status NONE I/O Status in A
-ptiob EQU 08H ;Put I/O status I/O Status in E NONE
-getalv EQU 1BH ;Get All.Vect. NONE All.Vect in HL
-
-; CPM 3 only:
-auxout EQU 04H ;Auxiliary output
-auxist EQU 07H ;Get AUXIN: status A=FF if character
- ; ready, A=0 if none
-auxost EQU 08H ;Get AUXOUT: status A=FF if ready, A=0
- ; if not ready
-getfs EQU 2EH ;Get free space E=drive # rec free in dma addr
-;
-parevn EQU 00H ;Even parity.
-parmrk EQU 03H ;Mark parity.
-parnon EQU 06H ;No parity (eighth bit is data).
-parodd EQU 09H ;Odd parity.
-parspc EQU 0CH ;Space parity.
-
-defpar EQU parnon ;Default parity.
-ibmpar EQU parmrk ;IBM COMTEN's parity.
-
-fcb EQU 5CH ;Location of File Control Block.
-fcbext equ fcb+12
-fcbrno equ fcb+33
-buff EQU 80H ;Location of file output buffer (DMA).
-bufsiz EQU 80H ;Size of DMA.
-
-maxfcb equ 64 ; maximum of 64 fcbs to be stored in multiple fcb bock
-
-maxpkt EQU '~'-' '+2O;Maximum size of a packet.
-maxtry EQU 05O ; Number of retries on a packet.
-imxtry EQU 20O ; Number of retries send initiate.
-prfair EQU 50 ;[pcc008] Prtchr fairness count
-
-; opcodes for command parser
-cmkey EQU 01H ;Parse a keyword.
-cmifi EQU 02H ;Parse an input file spec (can be wild).
-cmofi EQU 03H ;Parse an output file spec.
-cmcfm EQU 04H ;Parse a confirm.
-cmtxt EQU 05H ;Parse text.
-cmnum EQU 06h ;Parse a number
-cmifin EQU 10H ;Parse an input file spec (but no
- ;Error output
-
-;[4] from CP4SYS.ASM
-;
-;=========================================================================
-; I/O Byte assignments (2-bit fields for 4 devices at loc 3)
-;
-;bits 6+7 LIST field
-; 0 LIST is Teletype device (TTY:)
-; 1 LIST is CRT device (CRT:)
-; 2 LIST is Lineprinter (LPT:)
-; 3 LIST is user defined (UL1:)
-;
-;bits 4+5 PUNCH field
-; 0 PUNCH is Teletype device (TTY:)
-; 1 PUNCH is high speed punch (PUN:)
-; 2 PUNCH is user defined #1 (UP1:)
-; 3 PUNCH is user defined #2 (UP2:)
-;
-;bits 2+3 READER field
-; 0 READER is Teletype device (TTY:)
-; 1 READER is high speed reader (RDR:)
-; 2 READER is user defined #1 (UR1:)
-; 3 READER is user defined #2 (UR2:)
-;
-;bits 0+1 CONSOLE field
-; 0 CONSOLE is console printer (TTY:)
-; 1 CONSOLE is CRT device (CRT:)
-; 2 CONSOLE is in Batch-mode (BAT:);READER = Input,
-; LIST = Output
-; 3 CONSOLE is user defined (UC1:)
-;
-;=========================================================================
-
-iobyte EQU 03H ;Location of I/O byte
-
-;[4] From CP4SYS.ASM
-;
-;
-;
-; Protocol parameters. Some of these can be changed with commands.
-;
-
-drpsiz SET 50H ;Default receive packet size. (maximum is 5EH)
-dspsiz SET 50H ;Default send packet size. (maximum is 5EH)
-dstime SET 08H ;Default send time out interval.
-drtime SET 05 ;Default receive time out interval
-
-dspad EQU 00H ;Default send padding.
-drpad EQU 00H ;Default receive padding.
-dspadc EQU 00H ;Default send padding char.
-drpadc EQU 00H ;Default receive padding char.
-dseol EQU CR ;Default send EOL char.
-dreol EQU CR ;Default receive EOL char.
-dsquot EQU '#' ;Default send quote char.
-drquot EQU '#' ;Default receive quote char.
-dschkt EQU '1' ;Default checksum type
-;
-
-; Define VT or Terminal type values
-vtdefo EQU 0 ;VT52 emulation by terminal itself.
-vtdefv EQU 1 ;VT52 emulation by ttab tables in CPXVDU.ASM etc
-vtdefd EQU 2 ;Dumb Terminal (Just prints)
-vtdefe EQU 3 ;Termianl emulation done outside (in overlay)
-
-
-; If this is being assembled by LASM, we need to LINK to one of two modules;
-; if we're not using LASM, no problem.
-; CPSKER.ASM defines "cpsker" TRUE, and CPXTYP.ASM defines it FALSE, so we can
-; determine what's going on.
-IF lasm AND cpsker ; building CP4KER with LASM?
- LINK CPSMIT ; yes, chain to next piece.
-ENDIF;lasm AND cpsker
-IF lasm AND NOT cpsker ; LASM, but not building CP4KER?
- LINK CPXLNK ; yes, chain to different piece.
-ENDIF;lasm AND NOT cpsker
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains definitions used by both modules of Kermit.
+;
+; revision history:
+;
+;edit 9, 30-Nov-1990 by MF. Make "fairness" count "prfair" be 50 so
+; console gets checked a bit more often.
+; edit 8, 11-Sep-1990 by MF. Make default RECEIVE and SEND packet-size
+; 80 (per Kermit standard) as packet size is adjustable in Version
+; 4.10.
+; edit 7 16-Jun-86 OBSchou. Added cmnum in the command opcodes. This gets a
+; number from the user inot variable number. No checking on overflow.
+;
+; edit 6 13-May-86 OBSchou. BDOS calls trapped to check for console use
+; as we want to substitute in commands from a TAKE file. Trapping
+; means I dont have to go through an check ever BDOS call...
+;
+; edit 5: 22-Apr-86 by Bertil Schou, Loughborough University, UK
+; moved some definitions from the CP4SYS.ASM file to here for
+; Kermit version 4.06
+;
+; edit 4: 6-Feb-85 by Charles Carvalho
+; modify pcc007: replace ffussy assembly switch with runtime test.
+; add "getvnm" - get CP/M version number.
+;
+; edit 3: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
+;
+;pcc007 2-Jan-85 vjc modules:cp4def,cp4cmd
+; Cmifil is too fussy about what characters to accept in a
+; filespec. My CP/M manual says any printable character is ok
+; except <>.,;:?*[], and lower case. In practice, even those work
+; sometimes. Kermit itself uses '&' if file warning is on,
+; and then won't let you reference the file. Allow all
+; printable characters except those above. Add conditional
+; ffussy, so that if not ffussy, all special characters will be
+; allowed, just convert lower to upper-case.
+;
+;pcc008 2-Jan-85 vjc modules:cp4def,cp4tt,cp4utl
+; Keyboard input during CONNECT mode can get locked out if
+; there is enough input from the modem port to keep prtchr
+; busy. This can happen for example, if the printer is running
+; at the same speed as the modem line, leaving you helpless to
+; turn it off or abort the host. Add a fairness count, so that
+; at least every prfair characters we look at console input.
+;
+; edit 2: July 10, 1984 (CJC)
+; Remove defines for TRUE and FALSE, during reorganization for LASM
+; compatibility. If we're using LASM, this file is linked by CP4KER
+; or CP4TYP, and links to CP4MIT or CP4LNK. Also, push comments around
+; a little.
+;
+; edit 1: May, 1984 (CJC)
+; extracted from CPMBASE.M80 version 3.9; modifications are described
+; in the accompanying .UPD file.
+;
+
+;Symbolic Definitions for some ASCII characters
+;
+soh EQU 01O ;ASCII SOH (Control-A)
+cntlc EQU 03O ;ASCII ETX (Control-C)
+ctrlc EQU 03O ;ASCII ETX (Control-C)
+bell EQU 07O ;ASCII BEL (Control-G)
+bs EQU 10O ;ASCII backspace (Control-H)
+tab EQU 11O ;ASCII Tab (Control-I)
+lf EQU 12O ;ASCII Line Feed (CTRL-J)
+ff EQU 14O ;ASCII Form Feed (CTRL-L)
+cr EQU 15O ;ASCII Carriage Return (CTRL-M)
+space EQU 20h ;ASCII Space
+xon EQU 21O ;ASCII XON (Control-Q)
+xoff EQU 23O ;ASCII XOFF (Control-S)
+esc EQU 33O ;ASCII ESCape
+semico EQU 3bh ;ASCII Semicolon
+subt EQU 32O ;ASCII SUB (CTRL-Z)
+cntlz EQU subt ;ASCII SUB (Control-z) [6]
+ctrlz EQU subt ;ASCII SUB (Control-z)
+del EQU 177O ;ASCII DELete (rubout)
+;
+;BDOS calls
+IF NOT cpsker ;[6] If CPSKER is truem then system indep. stuff. We want
+ ;to trap BDOS calls and test for console activity
+bdos EQU 0005H ;BDOS entry point, for the following functions:
+ENDIF ;NOT cpsker [6]
+;
+;Function Name Function Input Parameters Output Parameter
+;============= ======== ================ ================
+; (ALL Function Numbers are passed in Register C)
+conin EQU 01H ;Read Console NONE ASCII Char in A
+conout EQU 02H ;Write Console ASCII Char in E NONE
+auxin EQU 03H ;Auxiliary input
+rdrin EQU 03H ;Read Reader NONE ASCII Char in A
+lstout EQU 05H ;Write List ASCII Char in E NONE
+dconio EQU 06H ;Direct Con I/O ASCII Char in E I/O Status in A
+ ; if E=0FEH,
+ ; Input if E=0FFH
+prstr EQU 09H ;Print String String-Address NONE
+ ; in DE (term=$)
+rdstr EQU 0AH ;Read Buffer Buffer-Address Read Buffer filled
+; in DE
+; Read Buffer Byte Function
+; 1 Maximum Buffer Length
+; 2 Current Buffer Length (returned value)
+; 3-n Data (returned values)
+;
+consta EQU 0BH ;Console Stat NONE LSB(A)=1 if char ready
+getvnm EQU 0CH ;Version Number NONE H=0 (CP/M), L=BDOS ver
+inbdos EQU 0DH ;Init BDOS NONE NONE
+logdsk EQU 0EH ;LOG-In disk Value in E NONE
+ ; A=0,B=1,...
+openf EQU 0FH ;Open File FCB-Addr in DE Byte Addr.of FCB,
+ ; or 0FFH if not
+closf EQU 10H ;Close File FCB-Addr in DE Byte Addr.of FCB,
+ ; or 0FFH if not
+sfirst EQU 11H ;Search File FCB-Addr in DE Byte Addr.of FCB(0-3),
+ ; or 0FFH if not
+snext EQU 12H ;Search next FCB-Addr in DE Byte Addr.of next FCB,
+ ; or 0FFH if not
+delf EQU 13H ;Delete File FCB-Addr in DE Byte Addr.of FCB(0-3),
+ ; or 0FFH if not
+readf EQU 14H ;Read Record FCB-Addr in DE 0=successful read
+ ; 1=read past EOF
+ ; 2=reading random data
+writef EQU 15H ;Write Record FCB-Addr in DE 0=successful write
+ ; 1=ERROR extending
+ ; 2=End of disk data
+ ; 255=No more DIR space
+makef EQU 16H ;Make File FCB-Addr in DE 0-3= success,
+ ; 255= no more dir space
+renam EQU 17H ;Rename File FCB-Addr in DE 0-3= success,
+ ; 255= file not found
+rdlog EQU 18H ;Ret. Log Code NONE Login Vector in HL
+rddrv EQU 19H ;Read Drive # NONE # of logged in drive in
+ ; (A=0,B=1,C=2....)
+setdma EQU 1AH ;Set DMA Addr. Addr. of 128 NONE
+ ; byte buffer in DE
+wrtprt EQU 1CH ;Write prot dsk NONE NONE
+getrov EQU 1DH ;Get R/O Vect. NONE HL= R/O Vect. value
+setfat EQU 1EH ;Set File Attr. FCB-Addr.in DE Dir. code in A
+gtdpar EQU 1FH ;Get DSK par. NONE HL=DPB Address
+usrcod EQU 20H ;Get/Set Usr.Cd E=0FFH (get) A=current code (get)
+ ; E-code (set) A=no value (set)
+rrand EQU 21H ;Read Random FCB-Addr in DE A=Return code
+wrand EQU 22H ;Write Random FCB-Addr in DE 1=read'g unwritten data
+ ; 2=(not used)
+ ; 3=can't close curr. ext
+ ; 4=seek to unwr. ext.
+ ; 5=dir overflow(write)
+ ; 6=seek past End of DSK
+cflsz EQU 23H ;Comp File Sz. FCB Addr.in DE Rand.Rec.field set to
+ ; File size
+setrar EQU 24H ;Set Rand. Rec. FCB-Addr.in DE Rand.Rec.field set
+
+; CPM 2 only:
+punout EQU 04H ;Write Punch ASCII Char in E NONE
+gtiob EQU 07H ;Get I/O status NONE I/O Status in A
+ptiob EQU 08H ;Put I/O status I/O Status in E NONE
+getalv EQU 1BH ;Get All.Vect. NONE All.Vect in HL
+
+; CPM 3 only:
+auxout EQU 04H ;Auxiliary output
+auxist EQU 07H ;Get AUXIN: status A=FF if character
+ ; ready, A=0 if none
+auxost EQU 08H ;Get AUXOUT: status A=FF if ready, A=0
+ ; if not ready
+getfs EQU 2EH ;Get free space E=drive # rec free in dma addr
+;
+parevn EQU 00H ;Even parity.
+parmrk EQU 03H ;Mark parity.
+parnon EQU 06H ;No parity (eighth bit is data).
+parodd EQU 09H ;Odd parity.
+parspc EQU 0CH ;Space parity.
+
+defpar EQU parnon ;Default parity.
+ibmpar EQU parmrk ;IBM COMTEN's parity.
+
+fcb EQU 5CH ;Location of File Control Block.
+fcbext equ fcb+12
+fcbrno equ fcb+33
+buff EQU 80H ;Location of file output buffer (DMA).
+bufsiz EQU 80H ;Size of DMA.
+
+maxfcb equ 64 ; maximum of 64 fcbs to be stored in multiple fcb bock
+
+maxpkt EQU '~'-' '+2O;Maximum size of a packet.
+maxtry EQU 05O ; Number of retries on a packet.
+imxtry EQU 20O ; Number of retries send initiate.
+prfair EQU 50 ;[pcc008] Prtchr fairness count
+
+; opcodes for command parser
+cmkey EQU 01H ;Parse a keyword.
+cmifi EQU 02H ;Parse an input file spec (can be wild).
+cmofi EQU 03H ;Parse an output file spec.
+cmcfm EQU 04H ;Parse a confirm.
+cmtxt EQU 05H ;Parse text.
+cmnum EQU 06h ;Parse a number
+cmifin EQU 10H ;Parse an input file spec (but no
+ ;Error output
+
+;[4] from CP4SYS.ASM
+;
+;=========================================================================
+; I/O Byte assignments (2-bit fields for 4 devices at loc 3)
+;
+;bits 6+7 LIST field
+; 0 LIST is Teletype device (TTY:)
+; 1 LIST is CRT device (CRT:)
+; 2 LIST is Lineprinter (LPT:)
+; 3 LIST is user defined (UL1:)
+;
+;bits 4+5 PUNCH field
+; 0 PUNCH is Teletype device (TTY:)
+; 1 PUNCH is high speed punch (PUN:)
+; 2 PUNCH is user defined #1 (UP1:)
+; 3 PUNCH is user defined #2 (UP2:)
+;
+;bits 2+3 READER field
+; 0 READER is Teletype device (TTY:)
+; 1 READER is high speed reader (RDR:)
+; 2 READER is user defined #1 (UR1:)
+; 3 READER is user defined #2 (UR2:)
+;
+;bits 0+1 CONSOLE field
+; 0 CONSOLE is console printer (TTY:)
+; 1 CONSOLE is CRT device (CRT:)
+; 2 CONSOLE is in Batch-mode (BAT:);READER = Input,
+; LIST = Output
+; 3 CONSOLE is user defined (UC1:)
+;
+;=========================================================================
+
+iobyte EQU 03H ;Location of I/O byte
+
+;[4] From CP4SYS.ASM
+;
+;
+;
+; Protocol parameters. Some of these can be changed with commands.
+;
+
+drpsiz SET 50H ;Default receive packet size. (maximum is 5EH)
+dspsiz SET 50H ;Default send packet size. (maximum is 5EH)
+dstime SET 08H ;Default send time out interval.
+drtime SET 05 ;Default receive time out interval
+
+dspad EQU 00H ;Default send padding.
+drpad EQU 00H ;Default receive padding.
+dspadc EQU 00H ;Default send padding char.
+drpadc EQU 00H ;Default receive padding char.
+dseol EQU CR ;Default send EOL char.
+dreol EQU CR ;Default receive EOL char.
+dsquot EQU '#' ;Default send quote char.
+drquot EQU '#' ;Default receive quote char.
+dschkt EQU '1' ;Default checksum type
+;
+
+; Define VT or Terminal type values
+vtdefo EQU 0 ;VT52 emulation by terminal itself.
+vtdefv EQU 1 ;VT52 emulation by ttab tables in CPXVDU.ASM etc
+vtdefd EQU 2 ;Dumb Terminal (Just prints)
+vtdefe EQU 3 ;Termianl emulation done outside (in overlay)
+
+
+; If this is being assembled by LASM, we need to LINK to one of two modules;
+; if we're not using LASM, no problem.
+; CPSKER.ASM defines "cpsker" TRUE, and CPXTYP.ASM defines it FALSE, so we can
+; determine what's going on.
+IF lasm AND cpsker ; building CP4KER with LASM?
+ LINK CPSMIT ; yes, chain to next piece.
+ENDIF;lasm AND cpsker
+IF lasm AND NOT cpsker ; LASM, but not building CP4KER?
+ LINK CPXLNK ; yes, chain to different piece.
+ENDIF;lasm AND NOT cpsker
diff --git a/cpsker.asm b/cpsker.asm
index 254d056..b3d4831 100644
--- a/cpsker.asm
+++ b/cpsker.asm
@@ -1,315 +1,315 @@
-; CPSKER.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-;
-; This is the header for the system-independent portion of KERMIT, which
-; consists of the following files (in this order):
-;
-; CPSKER.ASM - this file
-; CPSDEF.ASM - definitions for both KERMIT and KERSYS
-; CPSMIT.ASM - \initialization, main loop, miscellaneous commands
-; CPSCOM.ASM - /(BYE, EXIT, LOG, SET, SHOW, and STATUS) (Part1 of 2)
-; CPSPK1.ASM - \the KERMIT protocol handler (SEND, RECEIVE, LOGOUT,
-; CPSPK2.ASM - / and FINISH commands) (In two parts)
-; CPSREM.ASM - REMOTE commands etc
-; CPSSER.ASM - SERVER commands etc (Empty as yet)
-; CPSTT.ASM - the transparent commands (TRANSMIT, CONNECT)
-; CPSCPM.ASM - CP/M commands (DIR, ERA)
-; CPSWLD.ASM - the wildcard handler
-; CPSCMD.ASM - the command parser
-; CPSUTL.ASM - utility routines
-; CPSDAT.ASM - Data space and the overlay link space
-;
-; When building the system-independent part with M80 or MAC80, CPSKER
-; INCLUDEs the other files; when building with LASM, each file LINKs to
-; the next file.
-;
-; For now, the system-dependent routines are all in CPSSYS.ASM, with
-; the actual configuration defined in CPSTYP.ASM.
-;
-; revision history (latest first):
-;
-; Begin CP/M Kermit-80 version 4.11.
-;edit 32, 1-Apr-1991 by MF. Official release of work to date as CP/M Kermit
-; (Kermit-80) Version 4.11.
-; Modified edit level of cpscpm.asm to reflect a bug fix for the TYPE
-; command introduced with edit 13.
-;edit 31, 29-Mar-1991 by MF. Modified edit levels of cpsker.asm,
-; cpscom.asm and cpsdat.asm to reflect rename of parameter vermin to
-; revno (revision level) and change of SET COLLISION REPLACE to
-; SET COLLISION OVERWRITE to conform with C-Kermit. Modified
-; edit level of cpsrem.asm to reflect change from REMOTE SET FILE
-; COLLISION REPLACE to REMOTE SET FILE COLLISION OVERWRITE.
-; Modified edit level of cpsutl.asm to reflect code tightening and
-; edit levels of cpsmit.asm and cpspk2.asm to close any open TAKE-file
-; and abort take-file processing if ^C is typed from the console
-; Also corrected ^Z test in cpsmit.asm in INPUT command ("inp2b")
-; Implement "file not found" complaint if a TAKE command can't find
-; the TAKE-file and it's not the initial TAKE (KERMIT.INI)
-; Modified edit level of cpscpm.asm to reflect modification of the
-; TYPE and PRINT commands to cancel file typeout/printout completely
-; if ^C is entered on the console (either immediately or after a key
-; has been pressed to induce a pause) and to immediately begin
-; typeout/printout of the next file (if the filespec was wild-carded)
-; if ^X is entered (either immediately or after a key has been pressed
-; to induce a pause).
-; Modified edit levels of cpsmit.asm and cpscom.asm to reflect addition
-; of the STAY command as a synonym for SET NO-EXIT.
-;edit 30, 27-Feb-1991 by MF. Modified edit levels of cpscom.asm,
-; cpsmit.asm, cpsutl.asm and cpsdat.asm to reflect provision for
-; a "revision level" field (1-26=A-Z), addition of QUIT as a synonym
-; for the EXIT command, recognition of C, R and S as abbreviations
-; for the CONNECT, RECEIVE and SEND commands, respectively, display
-; of Kermit version in the VERSION command and a fix to the TAKE-file
-; input routine "r1tchr" to prevent semicolons from being interpreted
-; as command separators during TAKE-file execution. This last fix
-; allows such commands as REMOTE DELETE *.*;* to Kermit-32 to
-; operate as expected.
-;edit 29, 14-Feb-1991 by MF. Updated edit levels of cpscom.asm,
-; cpscpm.asm, cpsdat.asm and cpsrem.asm to reflect bug fixes,
-; code tightening and simplified routine "remcli" (in cpsrem.asm)
-; which gets text to be passed on to a remote Kermit in REMOTE
-; Kermit commands.
-;edit 28, 8-Feb-1991 by MF. Changed edit level of cpscpm.asm to reflect
-; a bug fix to make TAKE-files work properly with commands such as
-; INPUT which check the keyboard for input.
-;edit 27, 30-Jan-1991 by MF. Changed edit levels of cpscpm.asm, cpsrem.asm,
-; cpstt.asm and cpsutl.asm to reflect bug fixes and enhancements
-;edit 26, 17-Jan-1991 by MF. Changed edit level of cpscmd.asm to
-; reflect fixes to allow leading spaces/tabs to be ignored when
-; parsing keywords (this was the intent but the code never worked
-; correctly) and to blank the entire fcb in "cmifil" to allow successive
-; COPY commands to function properly. Also changed edit level of
-; cpspk1.asm to reflect further work on "disk full" error reporting.
-;edit 25, 14-Jan-1991 by MF. Incremented edit level of cpspk1.asm to
-; reflect bug fix to "disk full" error reporting code so <cr><lf>
-; is not sent directly to the Remote Kermit. This per a report from
-; Russell Lang of Australia's Monash University.
-;edit 24, 10-Jan-1991 by MF. Modified edit level of cpxtyp.asm to
-; reflect addition of "terminal required" message for some.
-; machines.
-;edit 23, 7-Jan-1991 by MF. Modified edit levels of cpxtyp.asm, cpxswt.asm,
-; cpxbbi.asm to reflect addition of Ampro Little Board support.
-;edit 22, 3-Jan-1991 by MF. Incremented edit levels of cpspk1.asm/cpspk2.asm
-; to reflect further mods to "sdata" and "inchr" routines.
-;edit 21, 2-Jan-1991 by MF. Incremented edit level of cpspk1.asm to reflect
-; code cleanup in "sdata" routine.
-;edit 20, 26-Dec-1990 by MF. Modified edit level of CPSCMD.ASM to reflect
-; fix to allow leading white space to be skipped in lines from
-; TAKE-files as well as from the CP/M command-line tail; this per a
-; phoned-in bug-report to Dr. Martin J. Carter of Nottingham
-; University in the U.K. (PPZMAJOC@vax.ccc.nottingham.ac.uk)
-;edit 19, 14-Dec-1990 by MF. Modified edit level of cpspk2.asm to reflect
-; modification to "gofil" to allow drive specifications in 2nd
-; filename of GET and RECEIVE commands; also modified edit levels of
-; cpspk1.asm and cpsrem.asm to reflect addition of "<<>>" around
-; "X" or "F" packets coming as a reply to a REMOTE command and
-; deletion of an unnecessary instruction before label remc2d
-; in cpsrem.asm.
-;edit 18, 9-Dec-1990 by MF. Modified edit levels for Version 4.10
-; yet another time to reflect changes in CPSDAT.ASM to clarify
-; "File size on DIR" status message.
-;edit 17, 4-Dec-1990 by MF. Adjusted edit levels of cpscom.asm/cpsdat.asm
-; to reflect addition of Autoreceive status to SHOW/STATUS display.
-;edit 16, 30-Nov-1990 by MF. Adjusted edit levels of cpscom.asm/cpsdat.asm
-; to reflect fix to SHOW/STATUS routines to show terminal display
-; mode (quiet/regular). Also adjusted edit level of cpsutl.asm to reflect
-; change to routine "p20ln" to use "pausit" to save code space.
-; Adjusted edit level of cpsdef.asm to reflect change in "fairness"
-; counter prfair from 100 to 50 to make terminal a bit more responsive
-; during CONNECTs.
-;edit 15, 27-Nov-1990 by MF. Adjusted edit level of cpspk1.asm to reflect
-; a bug fix.
-;edit 14, 27-Nov-1990 by MF. Again adjusted edit level of cpspk1.asm to
-; reflect modifications of "disk-full"and SET INCOMPLETE-FILES behavior.
-;edit 13, 23 Nov-1990 by MF. Adjusted edit level of cpspk1.asm to reflect
-; code changes for "disk full" processing.
-;edit 12, 8-Nov-1990 by MF.
-; Adjusted edit levels shown for cpscom.asm/cpspk1.asm/cpsdat.asm to
-; reflect bug fixes and code revisions.
-;edit 11, 5-Nov-1990 by MF.
-; Cosmetic changes for main help text for COPY and RENAME commands.
-; Begin CP/M Kermit-80 version 4.10.
-;edit 10, 2-Nov-1990 by MF. Moved Overlay address to 7000H (cpsdat.asm).
-;edit 9, 1-Nov-1990 by Mike Freeman (BPA). Cosmetic changes (command-name
-; changes: SET BAUD-RATE==>SET SPEED, FCOPY==>COPY, FRENAME==>RENAME,
-; STRING==>OUTPUT, REMOTE CWD==>REMOTE CD per suggestions of FDC
-; to aid in uniformity of nomenclature for various Kermits.
-;edit 8, 30-Oct-1990 by Michael Freeman; 301 N.E. 107th Street;
-; Vancouver, WA 98685 USA; Telephone (206)574-8221.
-; Work: Bonneville Power Administration
-; P.O. Box 491 M/S MORF
-; Vancouver, WA USA 98666
-; Telephone (206)690-2307
-; Implemented FRENAME command to rename a CP/M file.
-; Implemented many Remote commands, variable-length packets up thru
-; 94 characters in length. Fixed a bug in CPSCOM.ASM in the
-; routine "getnp" and a bug in CPSCOM.ASM which caused garbage to appear
-; on the screen when PRTSTR was called with QUIETD flag set.
-; Modified code in module CPSCMD.ASM to skip leading spaces and tabs
-; when getting Kermit commands from the CP/M command line. This also
-; obviates the necessity to type a leading semicolon to separate the
-; Kermit command from the Kermit commands on the CP/M command line.
-; Fixed code in CPSPK2.ASM which handles file collision detection
-; and resulting file rename per my entries in CPKERM.BWR.
-; and included fix by Russell Lang of Dept. of Electrical and Computer
-; Engineering, Monash University, Australia, to prevent renamed
-; files with SET WARNING ON from having the attributes (e.g., R/O)
-; copied from original file. Mr. Lang's E-mail address is:
-; Russell Lang Email: rjl@monu1.cc.monash.edu.au Phone: (03) 565 3460
-; Department of Electrical and Computer Systems Engineering
-; Monash University, Australia
-; Also fixed a bug in CPSPK2.ASM which prevented completion messages
-; from being displayed if terminal was set to QUIET.
-; Implemented most proposed SET FILE-COLLISION (COLLISION) commands.
-; Implemented SET INCOMPLETE file disposition command.
-; Implemented a few of the proposed REMOTE SET commands.
-; Implemented other fixes suggested in CPKERM.BWR.
-; Moved overlay address to 6C00H.
-; Changed location of .printx in this file so LASM doesn't complain.
-; In system-dependent modules, included HP-125 support.
-; Also modified Telcon Zorba code in CPXHEA.ASM to enable setting
-; of baud-rates and sending of a break.
-; Included Russell Lang of Monash Univ. Australia's implementation
-; for the Microbee series of computers (CPXBEE.ASM).
-; Fixed COMPUPRO version of Kermit to compile correctly and to
-; conform to current syntax for setting baud-rate.
-; edit 7, September, 1987. Added files for SERVER and REMOTE
-; modules (CPSSER/CPSREM). SERVER is still empty, and may be
-; only wishfull thinking. I have ideas, but I dont think I
-; will have the time to implement it.
-;
-; edit 6: 30 March, 1987 by OBSchou. Start Kermit-80 V4.09 with the
-; overlay address at 6000h. Also adjusted the INCLUDEs to allow
-; M80 to assmeble these files.
-;
-; edit 5: 20 June, 1986. Have added so much code etc that the overlay had to
-; be moved again.. give it to 5000h. This starts off Kermit-80 V4.08
-;
-; edit 4 22 April 1986
-; Start work on 4.06. This should clear up a couple of bugs, add in
-; a few features, and split the system dependent stuff into
-; smaller units.
-;
-; edit 3a 7 March 86 OBSchou Loughborough england. Minor additions
-; to cpsker.asm, cpscmd.asm and cpspkt.asm.
-;
-; edit 3: February 10, 1985 (CJC)
-; Update for v4.05; add "verno" so CPSUTL doesn't have to change
-; just because some other module did.
-;
-; edit 2: September 10, 1984 (CJC)
-; Update for v4.03.
-;
-; edit 1: July 27, 1984 (CJC)
-; Created to allow assembly of Kermit by LASM as well as MAC80 and M80.
-
-verno EQU 11 ; minor version number
-revno EQU 0 ;[MF]Revision level
- ;[MF]0-26 yields A-Z
-
-; Version 4.10 of Kermit consists of the following edit levels:
-; cpsker.asm edit 32
-; cpsdef.asm edit 9
-; cpsmit.asm edit 30
-; cpscom.asm edit 13
-; cpspk1.asm edit 23
-; cpspk2.asm edit 11
-; cpsrem.asm edit 13
-; cpsser.asm edit 1
-; cpstt.asm edit 12
-; cpscpm.asm edit 14
-; cpswld.asm edit 4
-; cpscmd.asm edit 13
-; cpsutl.asm edit 30
-; cpsdat.asm edit 19
-; cpxlnk.asm edit 8 (cpslnk.asm is not assembled with cpsker, but it
-; defines the linkage area expected by cpsker, and so must
-; match the description in cpsutl.asm)
-; cpxswt.asm edit 10
-;
-; Version 4.10 of Kermit has been tested with the following edit levels of
-; the system-dependent files:
-; cpxtyp.asm edit 34
-; cpxsys.asm edit 40
-; cpxhea.asm edit 4
-; cpxtor.asm edit 4
-; cpxbbi.asm edit 4 (Ampro Little Board)
-;
-; Version 4.10 of Kermit is still to be tested fully against all known systems
-; so far included in the system dependent overlays.
-;
-
-
-FALSE equ 0
-TRUE equ NOT FALSE
-
-cpsker equ TRUE ; building system-independent part
-debug equ FALSE ; set false for running system. True => does some
- ; unusual or unexpected things.
-;
-; Assembler type. Define the appropriate one TRUE, the rest FALSE. (We can't
-; use ASM, because it cannot handle multiple input files)
-mac80 EQU FALSE ; For assembly via MAC80 cross-assembler.
-m80 EQU false ; For assembly via Microsoft's M80.
-lasm EQU true ; For assembly via LASM, a public-domain
- ; assembler.
-;
-; Get the other modules...
-
-IF lasm ; If we're linking, go on to the next file.
- LINK CPSDEF
-ENDIF;lasm
-
-; If we're still here, we must be using M80 or MAC80. M80 doesn't
-; like ENDs inside conditionals, but the END statement has to be
-; in CPSUTL for LASM (otherwise, we'd need a file containing just an
-; END statement). So, we leave off the IF m80 OR mac80 conditional
-; that ought to be around these INCLUDEs. No problem until the next
-; incompatible assembler comes along...
-; Let's first say where we are:
-;
-.printx * CPSKER.ASM (or nearest offer) *
-;
-.printx * CPSDEF.ASM *
- INCLUDE CPSDEF.ASM ; definitions
-.printx * CPSMIT.ASM *
- INCLUDE CPSMIT.ASM ; initialization, main loop, some commands
-.printx * CPSCOM.ASM *
- INCLUDE CPSCOM.ASM ; part of command/status/set etc
-.printx * CPSPK1.ASM *
- INCLUDE CPSPK1.ASM ; KERMIT protocol handler (Part 1)
-.printx * CPSPK2.ASM *
- INCLUDE CPSPK2.ASM ; KERMIT protocol handler (Part 2)
-.printx * CPSREM.ASM *
- INCLUDE CPSREM.ASM ; Kermit REMOTE code (little in it, as yet)
-.printx * CPSSER.ASM *
- INCLUDE CPSSER.ASM ; Kermit SERVER code (As yet, empty)
-.printx * CPSTT.ASM *
- INCLUDE CPSTT.ASM ; transparent communication handler
-.printx * CPSCPM.ASM *
- INCLUDE CPSCPM.ASM ; CP/M command support (DIR, ERA)
-.printx * CPSWLD.ASM *
- INCLUDE CPSWLD.ASM ; wildcard handler
-.printx * CPSCMD.ASM *
- INCLUDE CPSCMD.ASM ; command parser
-.printx * CPSUTL.ASM *
- INCLUDE CPSUTL.ASM ; Various utilities and data, and END [ToadHall]
-.printx * CPSDAT.ASM *
- INCLUDE CPSDAT.ASM
- END ; MAC80 ignores END's in included files...
+; CPSKER.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+;
+; This is the header for the system-independent portion of KERMIT, which
+; consists of the following files (in this order):
+;
+; CPSKER.ASM - this file
+; CPSDEF.ASM - definitions for both KERMIT and KERSYS
+; CPSMIT.ASM - \initialization, main loop, miscellaneous commands
+; CPSCOM.ASM - /(BYE, EXIT, LOG, SET, SHOW, and STATUS) (Part1 of 2)
+; CPSPK1.ASM - \the KERMIT protocol handler (SEND, RECEIVE, LOGOUT,
+; CPSPK2.ASM - / and FINISH commands) (In two parts)
+; CPSREM.ASM - REMOTE commands etc
+; CPSSER.ASM - SERVER commands etc (Empty as yet)
+; CPSTT.ASM - the transparent commands (TRANSMIT, CONNECT)
+; CPSCPM.ASM - CP/M commands (DIR, ERA)
+; CPSWLD.ASM - the wildcard handler
+; CPSCMD.ASM - the command parser
+; CPSUTL.ASM - utility routines
+; CPSDAT.ASM - Data space and the overlay link space
+;
+; When building the system-independent part with M80 or MAC80, CPSKER
+; INCLUDEs the other files; when building with LASM, each file LINKs to
+; the next file.
+;
+; For now, the system-dependent routines are all in CPSSYS.ASM, with
+; the actual configuration defined in CPSTYP.ASM.
+;
+; revision history (latest first):
+;
+; Begin CP/M Kermit-80 version 4.11.
+;edit 32, 1-Apr-1991 by MF. Official release of work to date as CP/M Kermit
+; (Kermit-80) Version 4.11.
+; Modified edit level of cpscpm.asm to reflect a bug fix for the TYPE
+; command introduced with edit 13.
+;edit 31, 29-Mar-1991 by MF. Modified edit levels of cpsker.asm,
+; cpscom.asm and cpsdat.asm to reflect rename of parameter vermin to
+; revno (revision level) and change of SET COLLISION REPLACE to
+; SET COLLISION OVERWRITE to conform with C-Kermit. Modified
+; edit level of cpsrem.asm to reflect change from REMOTE SET FILE
+; COLLISION REPLACE to REMOTE SET FILE COLLISION OVERWRITE.
+; Modified edit level of cpsutl.asm to reflect code tightening and
+; edit levels of cpsmit.asm and cpspk2.asm to close any open TAKE-file
+; and abort take-file processing if ^C is typed from the console
+; Also corrected ^Z test in cpsmit.asm in INPUT command ("inp2b")
+; Implement "file not found" complaint if a TAKE command can't find
+; the TAKE-file and it's not the initial TAKE (KERMIT.INI)
+; Modified edit level of cpscpm.asm to reflect modification of the
+; TYPE and PRINT commands to cancel file typeout/printout completely
+; if ^C is entered on the console (either immediately or after a key
+; has been pressed to induce a pause) and to immediately begin
+; typeout/printout of the next file (if the filespec was wild-carded)
+; if ^X is entered (either immediately or after a key has been pressed
+; to induce a pause).
+; Modified edit levels of cpsmit.asm and cpscom.asm to reflect addition
+; of the STAY command as a synonym for SET NO-EXIT.
+;edit 30, 27-Feb-1991 by MF. Modified edit levels of cpscom.asm,
+; cpsmit.asm, cpsutl.asm and cpsdat.asm to reflect provision for
+; a "revision level" field (1-26=A-Z), addition of QUIT as a synonym
+; for the EXIT command, recognition of C, R and S as abbreviations
+; for the CONNECT, RECEIVE and SEND commands, respectively, display
+; of Kermit version in the VERSION command and a fix to the TAKE-file
+; input routine "r1tchr" to prevent semicolons from being interpreted
+; as command separators during TAKE-file execution. This last fix
+; allows such commands as REMOTE DELETE *.*;* to Kermit-32 to
+; operate as expected.
+;edit 29, 14-Feb-1991 by MF. Updated edit levels of cpscom.asm,
+; cpscpm.asm, cpsdat.asm and cpsrem.asm to reflect bug fixes,
+; code tightening and simplified routine "remcli" (in cpsrem.asm)
+; which gets text to be passed on to a remote Kermit in REMOTE
+; Kermit commands.
+;edit 28, 8-Feb-1991 by MF. Changed edit level of cpscpm.asm to reflect
+; a bug fix to make TAKE-files work properly with commands such as
+; INPUT which check the keyboard for input.
+;edit 27, 30-Jan-1991 by MF. Changed edit levels of cpscpm.asm, cpsrem.asm,
+; cpstt.asm and cpsutl.asm to reflect bug fixes and enhancements
+;edit 26, 17-Jan-1991 by MF. Changed edit level of cpscmd.asm to
+; reflect fixes to allow leading spaces/tabs to be ignored when
+; parsing keywords (this was the intent but the code never worked
+; correctly) and to blank the entire fcb in "cmifil" to allow successive
+; COPY commands to function properly. Also changed edit level of
+; cpspk1.asm to reflect further work on "disk full" error reporting.
+;edit 25, 14-Jan-1991 by MF. Incremented edit level of cpspk1.asm to
+; reflect bug fix to "disk full" error reporting code so <cr><lf>
+; is not sent directly to the Remote Kermit. This per a report from
+; Russell Lang of Australia's Monash University.
+;edit 24, 10-Jan-1991 by MF. Modified edit level of cpxtyp.asm to
+; reflect addition of "terminal required" message for some.
+; machines.
+;edit 23, 7-Jan-1991 by MF. Modified edit levels of cpxtyp.asm, cpxswt.asm,
+; cpxbbi.asm to reflect addition of Ampro Little Board support.
+;edit 22, 3-Jan-1991 by MF. Incremented edit levels of cpspk1.asm/cpspk2.asm
+; to reflect further mods to "sdata" and "inchr" routines.
+;edit 21, 2-Jan-1991 by MF. Incremented edit level of cpspk1.asm to reflect
+; code cleanup in "sdata" routine.
+;edit 20, 26-Dec-1990 by MF. Modified edit level of CPSCMD.ASM to reflect
+; fix to allow leading white space to be skipped in lines from
+; TAKE-files as well as from the CP/M command-line tail; this per a
+; phoned-in bug-report to Dr. Martin J. Carter of Nottingham
+; University in the U.K. (PPZMAJOC@vax.ccc.nottingham.ac.uk)
+;edit 19, 14-Dec-1990 by MF. Modified edit level of cpspk2.asm to reflect
+; modification to "gofil" to allow drive specifications in 2nd
+; filename of GET and RECEIVE commands; also modified edit levels of
+; cpspk1.asm and cpsrem.asm to reflect addition of "<<>>" around
+; "X" or "F" packets coming as a reply to a REMOTE command and
+; deletion of an unnecessary instruction before label remc2d
+; in cpsrem.asm.
+;edit 18, 9-Dec-1990 by MF. Modified edit levels for Version 4.10
+; yet another time to reflect changes in CPSDAT.ASM to clarify
+; "File size on DIR" status message.
+;edit 17, 4-Dec-1990 by MF. Adjusted edit levels of cpscom.asm/cpsdat.asm
+; to reflect addition of Autoreceive status to SHOW/STATUS display.
+;edit 16, 30-Nov-1990 by MF. Adjusted edit levels of cpscom.asm/cpsdat.asm
+; to reflect fix to SHOW/STATUS routines to show terminal display
+; mode (quiet/regular). Also adjusted edit level of cpsutl.asm to reflect
+; change to routine "p20ln" to use "pausit" to save code space.
+; Adjusted edit level of cpsdef.asm to reflect change in "fairness"
+; counter prfair from 100 to 50 to make terminal a bit more responsive
+; during CONNECTs.
+;edit 15, 27-Nov-1990 by MF. Adjusted edit level of cpspk1.asm to reflect
+; a bug fix.
+;edit 14, 27-Nov-1990 by MF. Again adjusted edit level of cpspk1.asm to
+; reflect modifications of "disk-full"and SET INCOMPLETE-FILES behavior.
+;edit 13, 23 Nov-1990 by MF. Adjusted edit level of cpspk1.asm to reflect
+; code changes for "disk full" processing.
+;edit 12, 8-Nov-1990 by MF.
+; Adjusted edit levels shown for cpscom.asm/cpspk1.asm/cpsdat.asm to
+; reflect bug fixes and code revisions.
+;edit 11, 5-Nov-1990 by MF.
+; Cosmetic changes for main help text for COPY and RENAME commands.
+; Begin CP/M Kermit-80 version 4.10.
+;edit 10, 2-Nov-1990 by MF. Moved Overlay address to 7000H (cpsdat.asm).
+;edit 9, 1-Nov-1990 by Mike Freeman (BPA). Cosmetic changes (command-name
+; changes: SET BAUD-RATE==>SET SPEED, FCOPY==>COPY, FRENAME==>RENAME,
+; STRING==>OUTPUT, REMOTE CWD==>REMOTE CD per suggestions of FDC
+; to aid in uniformity of nomenclature for various Kermits.
+;edit 8, 30-Oct-1990 by Michael Freeman; 301 N.E. 107th Street;
+; Vancouver, WA 98685 USA; Telephone (206)574-8221.
+; Work: Bonneville Power Administration
+; P.O. Box 491 M/S MORF
+; Vancouver, WA USA 98666
+; Telephone (206)690-2307
+; Implemented FRENAME command to rename a CP/M file.
+; Implemented many Remote commands, variable-length packets up thru
+; 94 characters in length. Fixed a bug in CPSCOM.ASM in the
+; routine "getnp" and a bug in CPSCOM.ASM which caused garbage to appear
+; on the screen when PRTSTR was called with QUIETD flag set.
+; Modified code in module CPSCMD.ASM to skip leading spaces and tabs
+; when getting Kermit commands from the CP/M command line. This also
+; obviates the necessity to type a leading semicolon to separate the
+; Kermit command from the Kermit commands on the CP/M command line.
+; Fixed code in CPSPK2.ASM which handles file collision detection
+; and resulting file rename per my entries in CPKERM.BWR.
+; and included fix by Russell Lang of Dept. of Electrical and Computer
+; Engineering, Monash University, Australia, to prevent renamed
+; files with SET WARNING ON from having the attributes (e.g., R/O)
+; copied from original file. Mr. Lang's E-mail address is:
+; Russell Lang Email: rjl@monu1.cc.monash.edu.au Phone: (03) 565 3460
+; Department of Electrical and Computer Systems Engineering
+; Monash University, Australia
+; Also fixed a bug in CPSPK2.ASM which prevented completion messages
+; from being displayed if terminal was set to QUIET.
+; Implemented most proposed SET FILE-COLLISION (COLLISION) commands.
+; Implemented SET INCOMPLETE file disposition command.
+; Implemented a few of the proposed REMOTE SET commands.
+; Implemented other fixes suggested in CPKERM.BWR.
+; Moved overlay address to 6C00H.
+; Changed location of .printx in this file so LASM doesn't complain.
+; In system-dependent modules, included HP-125 support.
+; Also modified Telcon Zorba code in CPXHEA.ASM to enable setting
+; of baud-rates and sending of a break.
+; Included Russell Lang of Monash Univ. Australia's implementation
+; for the Microbee series of computers (CPXBEE.ASM).
+; Fixed COMPUPRO version of Kermit to compile correctly and to
+; conform to current syntax for setting baud-rate.
+; edit 7, September, 1987. Added files for SERVER and REMOTE
+; modules (CPSSER/CPSREM). SERVER is still empty, and may be
+; only wishfull thinking. I have ideas, but I dont think I
+; will have the time to implement it.
+;
+; edit 6: 30 March, 1987 by OBSchou. Start Kermit-80 V4.09 with the
+; overlay address at 6000h. Also adjusted the INCLUDEs to allow
+; M80 to assmeble these files.
+;
+; edit 5: 20 June, 1986. Have added so much code etc that the overlay had to
+; be moved again.. give it to 5000h. This starts off Kermit-80 V4.08
+;
+; edit 4 22 April 1986
+; Start work on 4.06. This should clear up a couple of bugs, add in
+; a few features, and split the system dependent stuff into
+; smaller units.
+;
+; edit 3a 7 March 86 OBSchou Loughborough england. Minor additions
+; to cpsker.asm, cpscmd.asm and cpspkt.asm.
+;
+; edit 3: February 10, 1985 (CJC)
+; Update for v4.05; add "verno" so CPSUTL doesn't have to change
+; just because some other module did.
+;
+; edit 2: September 10, 1984 (CJC)
+; Update for v4.03.
+;
+; edit 1: July 27, 1984 (CJC)
+; Created to allow assembly of Kermit by LASM as well as MAC80 and M80.
+
+verno EQU 11 ; minor version number
+revno EQU 0 ;[MF]Revision level
+ ;[MF]0-26 yields A-Z
+
+; Version 4.10 of Kermit consists of the following edit levels:
+; cpsker.asm edit 32
+; cpsdef.asm edit 9
+; cpsmit.asm edit 30
+; cpscom.asm edit 13
+; cpspk1.asm edit 23
+; cpspk2.asm edit 11
+; cpsrem.asm edit 13
+; cpsser.asm edit 1
+; cpstt.asm edit 12
+; cpscpm.asm edit 14
+; cpswld.asm edit 4
+; cpscmd.asm edit 13
+; cpsutl.asm edit 30
+; cpsdat.asm edit 19
+; cpxlnk.asm edit 8 (cpslnk.asm is not assembled with cpsker, but it
+; defines the linkage area expected by cpsker, and so must
+; match the description in cpsutl.asm)
+; cpxswt.asm edit 10
+;
+; Version 4.10 of Kermit has been tested with the following edit levels of
+; the system-dependent files:
+; cpxtyp.asm edit 34
+; cpxsys.asm edit 40
+; cpxhea.asm edit 4
+; cpxtor.asm edit 4
+; cpxbbi.asm edit 4 (Ampro Little Board)
+;
+; Version 4.10 of Kermit is still to be tested fully against all known systems
+; so far included in the system dependent overlays.
+;
+
+
+FALSE equ 0
+TRUE equ NOT FALSE
+
+cpsker equ TRUE ; building system-independent part
+debug equ FALSE ; set false for running system. True => does some
+ ; unusual or unexpected things.
+;
+; Assembler type. Define the appropriate one TRUE, the rest FALSE. (We can't
+; use ASM, because it cannot handle multiple input files)
+mac80 EQU FALSE ; For assembly via MAC80 cross-assembler.
+m80 EQU false ; For assembly via Microsoft's M80.
+lasm EQU true ; For assembly via LASM, a public-domain
+ ; assembler.
+;
+; Get the other modules...
+
+IF lasm ; If we're linking, go on to the next file.
+ LINK CPSDEF
+ENDIF;lasm
+
+; If we're still here, we must be using M80 or MAC80. M80 doesn't
+; like ENDs inside conditionals, but the END statement has to be
+; in CPSUTL for LASM (otherwise, we'd need a file containing just an
+; END statement). So, we leave off the IF m80 OR mac80 conditional
+; that ought to be around these INCLUDEs. No problem until the next
+; incompatible assembler comes along...
+; Let's first say where we are:
+;
+.printx * CPSKER.ASM (or nearest offer) *
+;
+.printx * CPSDEF.ASM *
+ INCLUDE CPSDEF.ASM ; definitions
+.printx * CPSMIT.ASM *
+ INCLUDE CPSMIT.ASM ; initialization, main loop, some commands
+.printx * CPSCOM.ASM *
+ INCLUDE CPSCOM.ASM ; part of command/status/set etc
+.printx * CPSPK1.ASM *
+ INCLUDE CPSPK1.ASM ; KERMIT protocol handler (Part 1)
+.printx * CPSPK2.ASM *
+ INCLUDE CPSPK2.ASM ; KERMIT protocol handler (Part 2)
+.printx * CPSREM.ASM *
+ INCLUDE CPSREM.ASM ; Kermit REMOTE code (little in it, as yet)
+.printx * CPSSER.ASM *
+ INCLUDE CPSSER.ASM ; Kermit SERVER code (As yet, empty)
+.printx * CPSTT.ASM *
+ INCLUDE CPSTT.ASM ; transparent communication handler
+.printx * CPSCPM.ASM *
+ INCLUDE CPSCPM.ASM ; CP/M command support (DIR, ERA)
+.printx * CPSWLD.ASM *
+ INCLUDE CPSWLD.ASM ; wildcard handler
+.printx * CPSCMD.ASM *
+ INCLUDE CPSCMD.ASM ; command parser
+.printx * CPSUTL.ASM *
+ INCLUDE CPSUTL.ASM ; Various utilities and data, and END [ToadHall]
+.printx * CPSDAT.ASM *
+ INCLUDE CPSDAT.ASM
+ END ; MAC80 ignores END's in included files...
diff --git a/cpsmit.asm b/cpsmit.asm
index f41ee70..1bf6a58 100644
--- a/cpsmit.asm
+++ b/cpsmit.asm
@@ -1,834 +1,834 @@
-; CPSMIT.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the system-independent initialization, the main
-; loop, and the commands that don't have any place better to go.
-; All the SET xxx and status routines now in CPSCOM.ASM as CPSMIT.ASM
-; was getting too big.
-;
-; revision history:
-;
-;edit 30, 29-Mar-1991 by MF. When looking up a TAKE-file in a TAKE command
-; and the file is not found, complain if it's not the first TAKE of
-; the current program execution (the automatic TAKE of KERMIT.INI)
-;edit 29, 25-Mar-1991 by MF. Add STAY command as a synonym for SET NO-EXIT
-; command per Martin J. Carter of Nottingham University in the U.K.
-;edit 28, 21-Mar-1991 by MF. Modify code after "inp2a" in INPUT command
-; so a ^C will halt TAKE-file processing
-;edit 27, 27-Feb-1991 by MF. Add QUIT as a synonym for EXIT per code of
-; Dr. Martin J. Carter of Nottingham University, U.K. Recognizing QUIT
-; helps those who forget they're not in MS-Kermit, C-Kermit,
-; Kermit-32 etc. Also add commands so that CONNECT, RECEIVE and SEND may
-; be abbreviated to C, R and S, respectively.
-;edit 26, 5-Nov-1990 by MF. Cosmetic changes to main HELP messages for
-; COPY and RENAME commands.
-;edit 25, 1-Nov-1990 by MF. Made the following command-name changes in the
-; interest of uniformity of nomenclature (per suggestions of FDC):
-; FCOPY to COPY, FRENAME to RENAME and STRING to OUTPUT.
-; This means we'll have to type "CO" for CONNECT and "REC" for
-; RECEIVE but with REMOTE now with us we have to do the latter anyway.
-;edit 24, 18-Sep-1990 by MF. Implemented FRENAME command to rename a
-; CP/M file.
-;edit 23, 9-Sep-1990 by MF. Implemented commands to be sent to a
-; remote Kermit Server (Remote commands).
-; Implemented setting of packet sizes for RECEIVE and SEND.
-; Put DIRECTORY/STRING help texts in proper alphabetical position.
-; edit 22, July 6th, 1987 by OBSchou. Added a dummy Commandline to be
-; loaded for debugging purposes as DDT destroys any command line at 80H
-; Also fixed a bug or two...
-;
-; edit 21, April 8th, 1987.
-; Various bits, including more SET SENDRECEIVE options, and make
-; PADDING and PADCHAR valid options. Have I wasted my time, or
-; there still systems that use padding?? Fixed a bug in the INPUT
-; command so we know how many characters there are to check for. Also
-; hived off the SET commands to make a new file, CPSCOM.ASM thereby
-; reducing the size of CPSMIT.ASM. Also rename COPY command to FCOPY
-; hence retaining a single C to imply connect.
-;
-; edit 20, March 30, 1987 by OBSchou.
-; added code for no exit to CPM if a command tail is done (optional)
-; by the SET NO-EXIT command. Added bits for SET AUTORECEIVE to enable
-; or inhibit automatic receive of several files (if something is coming
-; along from the remote side, do a receive. Toss first packet away.)
-; This is first step to SERVER???
-; Also added back the INPUT command.
-;
-; edit 19, March 16, 1987. Moved the code to check for and execute
-; command tails (See Richard Russells submission below).
-; Added flags to exit to CP/M after executing a command tail.
-; The KERMIT.INI file is taken before the command tail is issued.
-;
-; edit 18, March 11, 1987 by OBSchou.
-; Added in code for TYPE <file> and PRINT <file>. Hope to add COPY
-; later on. Also added in code submitted by Richard Russel, to accept
-; a command tail on entry to kermit (eg KERMIT CONNECT). This facility
-; if used, will replace the automatic TAKE function on loading Kermit.
-; Unfortunately, you will not be dropped back to CP/M after the command
-; In the future, it may be possible to either accept several commands
-; on the command tail, and possibly accept the automatic TAKE facility
-; as well. Low on my list of things to do.
-;
-; edit 17, January 28, 1987 by OBSchou for DJ Roberts of Leicester
-; Also added a couple of fixes [obs]
-;
-; DJR January 1987 David J. Roberts.
-; USER made a SET option
-; STATUS output placed in alphabetical order
-; Report DEBUG mode and default disk
-; Name of LOG file on SHOW/STATUS display
-;
-;
-; edit 16 December 1st, OBSchou. Fixed bug in that if the overlay is not in
-; place or correct then prtstr is not called to print the error message
-; (As prtstr has been moved out of the system independent code)
-;
-; edit 15 November 10, 1986 by OBSchou. Re-inserted Pause and Break
-; commands for release.
-;
-; edit 14 August 29, 1986. Removed PAUSE,BREAK,INPUT and SET CASE as
-; these have not been fully coded or debugged. (For next
-; version of Kermit-80...). Also tidied up a bit.
-;
-; 13 by OBSchou for Godfrey Nix. He writes:
-; edit August 11,1986 Godfrey Nix, Nottingham University [gnn]
-; To insert code for setting the packet start character on
-; both send and receive packets (default is still 01H)
-; and make GET and RECEIVE to be separate;
-; use with edits to CP4PKT, CP4UTL
-;
-; edit 12: 19 June, 1986 by OBSchou. Added PAUSE and BREAK facility.
-; Breaks simulate a call to sysint which tests for a B being passed.
-; Note this is only useful if the system dependent code supports breaks,
-; and an appropriate message is returned if breaks are not possible.
-; Also added is the command entry for INPUT, which waits for a string
-; from the host for a given time. The time is a very variable counter
-; incremented every BDOS call. Trial and error will give a reasonable
-; value. STRING acceps a string from the use and then sends it on
-; to the host. These new commands allow a user to (almost) set up auto
-; log on files, where BREAKS/INPUT/STRING/STRING partially emulate a user
-; (AI LURES OK and all that). Still could do with a test, eg if not a
-; correctly returned string go back n steps. This would make a fairly
-; simple TAKE command a lot more complicated.
-;
-;edit 11: 30 May, 1986 OBSchou. Added in a couple of more routines and such
-;
-;edit 10: 27 May, 1986 OBSchou. Added in support for USER function
-; removed XMIT test and routine, but also added SET FLOW-CONTROL
-; (set for XON/XOFF flow control in both directions) and a
-; SET CASE-SENSITIVE ON/OFF (if on => a # A, if ON => a=A)
-;
-;edit 9: 13 May, 1986 OBSchou, Loughborough University, UK
-; Added in code for SET XMIT character to allow setting of the
-; character to wait for from the host during TRANSMIT. It is
-; a line feed by default. Also added a TAKE command, to take: commands
-; from a named disk file. If a file is TAKEn, then all BDOS calls
-; are trapped and tested for console input. If so, we substitute a
-; character (or buffer) from the TAKE file specified.
-; This may also be used in the future for a CPKERMIT.INI
-; to be evaluated during Kermit initialsation.
-;
-; edit 8: February 6, 1895
-; Add a PORT status/show routine for those machines that have more
-; than one they can talk to. It also required a port storage variable
-; a la SPEED and the necessary code to handle it in the SET routine.
-; [Hal Hostetler]
-;
-; edit 7: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
-;
-;pcc003-pcc005 2-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl
-; These edits must all be installed together and change the way
-; logging is handled. The log file spec is moved to a separate
-; fcb, and not opened until an actual CONNECT command is given.
-; This takes care of a NASTY bug that if you used any other file
-; command between the LOG and CONNECT, the log file would get
-; written over the last file used. This also allows logging to
-; be "permanently" enabled until an CLOSE (new command) for all
-; CONNECT sessions, like most other kermits do. If a log file
-; already exists, it will be appended to. Also add two new
-; CONNECT mode commands <esc>Q to suspend logging and <esc>R to
-; resume. <esc>R means something else during TRANSMIT, but
-; logging is never on then, so there shouldn't be any conflict.
-; I also changed the write code, so that it can handle one more
-; character after the XOFF is send to stop the host. This allows
-; a little "slop" for systems that don't stop immediately (such
-; as TOPS10), but it didn't help much.
-;
-;pcc012 4-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl
-; Use the big buffer for the log file. Move the log file back
-; into the common fcb and only save the drive, name, and
-; extension between connects. Add new routines to cp4utl to
-; create or append to an existing file, and to conditionally
-; advance buffers only if in memory. Remove edit pcc003 that
-; allows one more character after the xoff, since it didn't
-; really work very well and does not fit in well with the way
-; the buffer advancing routines are set up. If someone still
-; thinks this would be useful, it could be put back in with a
-; little more work.
-;
-; While testing this edit, I also noticed another bug that
-; the command parsing routines do not limit or check the
-; length of command lines or file specs, trashing what ever
-; comes after them. Currently because of where the fcb and
-; command buffer are located, this does not usually cause a
-; problem, but could if an extremely long line was typed in,
-; or in the future multiple fcbs defined elsewhere in memory
-; were used. Maybe this should be put on the bug list
-; somewhere.
-;
-;pcc013 8-Jan-85 vjc modules:cp4mit,cp4utl,cp4typ
-; Replace CLOSE command to cancel session logging to SET
-; LOGGING ON/OFF. This seems to fit in with the command
-; structure better. Default the log file to KERMIT.LOG
-; incase no previous LOG command. Logging is also enabled
-; by LOG command, as before.
-;
-; edit 6: September 8, 1984
-; Add VERSION command, to display the internal version strings.
-; Move command tables here from CP4UTL, and translate string
-; lengths in them to decimal (how many fingers do YOU got?).
-; Replace some jump tables with dispatch addresses in tables.
-; Make help text for SET command consistent with top level help text.
-;
-; edit 5: August 21, 1984
-; Add word at 0100H to allow us to exit cleanly from DDT (shifting
-; entry section by two bytes).
-;
-; edit 4: August 3, 1984 (CJC)
-; Remove "mover" from entry section, as it now lives in CP4SYS.
-;
-; edit 3: July 27, 1984 (CJC)
-; Merge LASM support from Toad Hall: most of CP4MIT is now in CP4UTL.
-; When assembling with LASM, CP4MIT is linked by CP4DEF; it links to
-; CP4PKT. Add SET TACTRAP command. Separate out display routines so
-; we can eventually do "SHOW <parameter>". Save both bytes of baud
-; rate in speed, and check both bytes when displaying baud rate. Move
-; header info to CP4KER.ASM. Add onoff and chkkey routines to simplify
-; SET command (Toad Hall)
-;
-; edit 2: June 8, 1984
-; formatting and documentation; delete unreferenced variables and some
-; unnecessary labels; move setpar here from cp4pkt; add module version
-; string; make this version 4.01.
-;
-; edit 1: May, 1984
-; extracted from CPMBASE.M80 version 3.9; modifications are described
-; in the accompanying .UPD file.
-
-;
- ASEG
- ORG 100H
-
-; The CCP invokes programs with a CALL 100H, with the stack pointer set to
-; 100H. When we exit to CP/M, we do so with a RET, avoiding a warm boot.
-; Unfortunately, DDT starts programs with a jump, not a call, so when we
-; attempt to return to CP/M, we blow the stack and use the word at 100H as
-; the new PC. Put a 0 there so we reboot instead of dying horribly.
-; (Fortunately, this happens to be two NOP's).
- dw 0
- jmp start ; Bypass entry section
-
-;
-; Entry section for system-independent part. This contains
-; jumps to routines needed by the system support module.
-;
-entries:
- jmp kermit ; reentry address
- jmp nout ; output HL in decimal
-entsiz equ $-entries ; length of entry section
-;
-; End of entry section. As a consistency check, the expected
-; length of this section is stored by the system-dependent
-; module in the linkage section at the end of Kermit, and
-; tested at initialization.
-
-mitver: db 'CPSMIT.ASM (30) 29-Mar-1991$' ; name, edit number, date
-;
-;
-; Initialization
-;
-start: lxi h,0 ; Clear out hl pair
- dad sp ; and fetch the system stack pointer
- shld oldsp ; and save for later restoral
- lxi sp,stack ; move in our own stack.
- lxi d,version ; print Kermit version
- call prtstx ; before we do too much (Use fudged prtstr)
- mvi c,rddrv ;Get our logged in drive
- call BDOS
- inr a ;relative 1
- sta CURDSK ;and save it for later
-
- lda vtflg ; [OBS] Hangover from VT52 ems not possible...
- cpi 0ffh ; ... if 0ff stored, assume terminal = off
- mvi a,vtdefo
- jnz start0
- sta vtflg ; if 0ffh make it VT52 off
-start0:
-
-
-IF debug
-;vvvvvvvvvvvvvvvv remove this for run time
-; OBS edit 22 - add in a dummy command line to 80H
- lxi h,dcomln ;[22] load up dummy command line
- lxi d,81h ;[22] where to put it
- lxi b,endcoml-dcomln
- mov a,c ; get length to a
- sta 80h ; ... and save as command line length
- call mover ; ... and save rest of line
- jmp starta
-dcomln: db 'set baud 4800',semico
- db 'set dir on',semico
- db 'dir'
- db 0,0 ; just to make up space
-endcoml:
-;^^^^^^^^^^^^^^^^ remove this for run time
-ENDIF ;debug
-
-
-starta:
-;
-; Make sure the overlay is in place...
-;
- lhld lnkflg
- mov a,h
- ora l ; if lnkflg is still zero,
- jz start1 ; the configuration overlay is missing.
- lxi d,-lnksiz ; if it's not equal to lnksiz,
- dad d ; we've probably got the wrong
- mov a,h ; version of the configuration overlay.
- ora l
- jnz start2
- lhld lnkent ; make sure the overlay knows how long
- lxi d,-entsiz ; our entry section is, so they don't miss.
- dad d
- mov a,h
- ora l
- jnz start2
- ; might be ok.
- lxi h,bdos ; set xbdos address to bdos trap in our code.
- shld xbdos+1 ; (they may never use it...)
- call sysinit ; do system-dependent initialization
- lda bufsec ; get the max no of buffers allowed by system
- sta maxbsc ; save for SET BUFFER use to compare
- lxi d,inms26 ; offer some advice on getting help
- call prtstr
- lxi h,buff ;[19] we copy any potential command tail across
- lxi d,cbuff
- lxi b,80h ;[19] copy all 128 bytes. May use none.
- call mover
- lda 80h ; see if there is a command tail...
-
- ana a
-
-
-
-; Remove for runtime use
-; xra a ; make out there is no command tail
-; Runtime => no XRA above
-
- jz startz
- dcr a
- jz startz ; one character tail...
- lda takflg ; if more characters, say we are have tail
- ori 10h ; set bit 4
- sta takflg
- sta nexitf ; exit back to CP/M after command line
-startz:
- mvi a,0ffh ; when here, system basically initiallised,...
- sta initflg ; apart from KERMIT.INI, so say initialised.
-
- call take1 ;[9] take a KERMIT.INI file
- xra a ;[MF] Say we've done it
- sta initak ;[MF] ...
- jmp kermit ; Start main loop.
-
-start1: lxi d,erms20 ; "Kermit has not been configured"
- call prtstx ; print error message (Use bodge for prtstr)
- jmp exit2 ; and exit.
-
-start2: lxi d,erms21 ; "Consistency check on configuration failed"
- call prtstx ; print error message
- jmp exit2 ; and exit.
-;
-;This is the main KERMIT loop. It prompts for and gets the users commands.
-
-kermit: lxi sp,stack ; get new stack pointer, old one might be bad.
- call selcon ; make sure console is selected.
- xra a
- sta mfflg1 ;reset MFNAME
- sta mfflg2 ;ditto
- sta mfflg3
- sta getrxflg ; clear the get/receive flag
- ;0=> receive, non 0 => get
- sta cmbflg ;[MF]Initial keyword must not be blank
- sta cmqflg ;[MF]Allow character-echoing during commands
- sta remtxt ;[MF] Clear remote-text-to-screen flag
- lda curdsk ; update the prompt
- adi 'A'-1
- sta kerm1+2
- call getun ;[11] get the user number into temp1/2
- lda temp1+1 ;[11] get ms value of user number
- cpi '0' ;[11] less than 10 => do a space
- jnz kerm4 ;[11] else do MS digit of user number
- mvi a,' ' ;[11]
-kerm4: sta kerm1 ;[11]
- lda temp1 ;[11] get ls digit of user number
- sta kerm1+1 ;[11] save that
- lda takflg ; are we in TAKE or command line??
- ani 11h ; strip out both bits
- jnz kerm5 ; still in either or both...
- lda nexitf ; if neither, and no-exit-flag set, we quit.
- ana a
- jnz exit ;... back to CP/M, else as you were...
-kerm5:
- lxi d,kerm
- call prompt ;Prompt the user.
-
-kerm7: lxi d,comtab
- lxi h,tophlp
- call keycmd ; Get a keyword
- xchg ; Get result (dispatch address) into HL
- pchl ; Dispatch.
-
-; here from: log, setcom, read, cfmcmd
-kermt3: lxi d,ermes3 ;"Not confirmed"
- call prtstr
- jmp kermit ;Do it again.
-
-; Structure of command table:
-;
-; 1) Number of entries.
-; 2) Each entry is arranged as follows:
-; a) length of command in bytes.
-; b) 'name of command and $-sign'
-; c) address of routine to process command
-;
-; ---> Note this command table is in alphabetic order.
-;
-
-comtab: db 32 ; added remote
- ;[obs] added in COPY command, now called FCOPY
- ;[obs] removed remote simply to issue V4.09
- ;[MF]Make FCOPY/FRENAME COPY/RENAME for
- ;[MF]Version 4.10
- ;[MF]Add QUIT as a synonym for EXIT and
- ;[MF]C, R and S as abbreviations for
- ;[MF]CONNECT, RECEIVE and SEND, respectively
- ;[MF]Add STAY as a synonym for SET NO-EXIT
- db 5, 'BREAK$'
- dw break
- db 3, 'BYE$'
- dw bye
- db 1,'C$'
- dw telnet ;[MF]Abbreviation for CONNECT
- db 7, 'CONNECT$'
- dw telnet
- db 4,'COPY$'
- dw copy
- db 9, 'DIRECTORY$'
- dw dir
- db 5, 'ERASE$'
- dw era
- db 4, 'EXIT$'
- dw exit
- db 6, 'FINISH$'
- dw finish
- db 3, 'GET$'
- dw read ; [gnn] entry for GET
- db 4, 'HELP$'
- dw help
- db 5, 'INPUT$'
- dw input
- db 3, 'LOG$'
- dw log
- db 6, 'LOGOUT$'
- dw logout
- db 6, 'OUTPUT$'
- dw string
- db 5, 'PAUSE$'
- dw pause
- db 5, 'PRINT$'
- dw printf ;[obs] print a file
- db 4,'QUIT$'
- dw exit ;[MF]Synonym for EXIT
- db 1,'R$'
- dw read0 ;[MF]Abbreviation for RECEIVE
- db 7, 'RECEIVE$'
- dw read0 ; [gnn] not same as GET now
- db 6, 'REMOTE$'
- dw remote
- db 6,'RENAME$'
- dw rename ;[MF]
- db 1,'S$'
- dw send ;[MF]Abbreviation for SEND
- db 4, 'SEND$'
- dw send
- db 3, 'SET$'
- dw setcom
- db 4, 'SHOW$'
- dw show
- db 6, 'STATUS$'
- dw status
- db 4,'STAY$'
- dw noexit ;STAY (SET NO-EXIT)
- db 4, 'TAKE$' ;[9]
- dw take
- db 8, 'TRANSMIT$'
- dw xmit
- db 4, 'TYPE$'
- dw type ;[obs] type a file command
- db 7, 'VERSION$'
- dw shover
-; db 4, 'USER$' ; removed [DRJ]
-; dw user ;[10] removed [DRJ]
-; top-level help message. Caps indicate keywords.
-; this text is also printed by the HELP command.
-
-tophlp:
- db cr,lf,'BREAK to send a break to the host'
- db cr,lf,'BYE to host (LOGOUT) and exit to CP/M'
- db cr,lf,'CONNECT to host on selected port'
- db cr,lf,'COPY to copy a CP/M file'
- db cr,lf,'DIRECTORY of current used Micro-disk'
- db cr,lf,'ERASE a CP/M file'
- db cr,lf,'EXIT to CP/M'
- db cr,lf,'FINISH running Kermit on the host'
- db cr,lf,'GET a file from the host'
- db cr,lf,'HELP by giving this message'
- db cr,lf,'INPUT to make the micro wait for a string from the host'
- db cr,lf,'LOG the terminal sessions to a file'
- db cr,lf,'LOGOUT the host'
- db cr,lf,'OUTPUT to send a specified string to the host'
- db cr,lf,'PAUSE to wait for a little time'
- db cr,lf,'PRINT a file to the printer'
- db cr,lf,'QUIT to CP/M'
- db cr,lf,'RECEIVE file from host'
- db cr,lf,'REMOTE to send commands to a remote server'
- db cr,lf,'RENAME to rename a CP/M file'
- db cr,lf,'SEND file to host'
- db cr,lf,'SET a parameter'
- db cr,lf,'SHOW the parameters'
- db cr,lf,'STATUS of Kermit'
- db cr,lf,'STAY at Kermit command-level after a command tail'
- db cr,lf,'TAKE commands from a file' ;[9]
- db cr,lf,'TRANSMIT file to host (in connect state)'
- db cr,lf,'TYPE a file to the console'
- db cr,lf,'VERSION of Kermit running' ;[pcc005]
-; db cr,lf,'USER to set a different user number' ;removed [DJR]
- db '$' ;[obs] added it here to allow for expansion
-
-;
-; This is the BREAK command. It sends a 'B' to the system dependent
-; interrupt routines (test for escape-cokebottle xxx) and do a break
-; if the overlay can. Else, we tell user not to be so silly.
-break: call cfmcmd ; get return
- mvi a,'B' ; were gonna do a break if the overlay can
- call sysint ; try doing it..
- jmp kermit ; if we can do it, else
- lxi d,inms12 ;... say not implemented
- jmp kermit
-
-;
-;
-; This is the BYE command. It tells the remote KERSRV to logout,
-; then exits.
-
-bye: call cfmcmd
- call logo ;Tell the main frame to logout.
- jmp kermit ;If it fails, don't exit.
- call sysbye ; success. do system-dependent cleanup
- jmp exit1 ;Exit Kermit.
-
-; This is the EXIT command. It leaves KERMIT and returns to CP/M.
-; alternate entries: exit1, from BYE command;
-; exit2, from initialization (if it fails)
-
-exit: call cfmcmd ; confirm...
-exit1: call sysexit ; do system-dependent termination
-exit2:
- jmp 0 ; return to CP/M via JUMP instead of RET.
-
-; lhld oldsp ;Get back the system stack
-; sphl ;and restore it.
-; ret ;Then return to system.
-
-; Input command. Syntax:
-; INPUT [Wait period] [string]
-; where
-; Wait period is a time period to wat for
-; string is a string to expect back from the host. Control
-; characters are entered as \ and an octal number.
-;
-; I can see uses for this command from other routines...
-;
-input: mvi a,cmnum ; first get the number
- call comnd ; get it
- jmp kermit ; if we dont understand it...
- lhld number
- shld waitp ; and save as the wait period
- lxi d,stbuff ; where to put the string
- mvi a,cmtxt ; get text
- call comnd
- jmp kermit ; not quite correct...
- sta strcnt ; string count returned in a
- call cfmcmd ; get a confirm
-
- lhld waitp ; multiply the number by
- dad h
- dad h ; ... 4
- dad h ; ... 8
- inx h ; but make sure it is at least 1
- shld waitp ; and save it away again
- shld waitp1 ; save in case we need to reset counter
-
-; Right, now wait for characters comming from the line, within the
-; time allowed (very fuzzy). Compare with STRING buffer
-;
-inp1: xra a
- sta repcnt ; clear the host prompt chars.counter
-inp2: lhld waitp ; have we waited long enough
- dcx h
- shld waitp ; count less one
- mov a,h ; test to see if both zero
- ora l
- jnz inp20 ; nope
- mvi a,3 ; error is three ie total failure
- sta errorc
- jmp inp5 ; take error exit
-
-inp20: call rd1chl ; read a character from the line
- ani 7fh ; set flags
- jnz inp4 ; Not zero => we have a character from host
- call ckchr ; see if *WE* have a character from console
- push psw ; restore to modem
- call selmdm ; reselect the modem port
- pop psw
- ani 7fh ; strip parity (should not be there)
- jnz inp2a ; if a null, try again
- lda strcnt ; if the string length is zero, dont wait.
- ana a
- jnz inp2 ; so loop back again
- jmp kermit ; else drop out
-
-inp2a: cpi cntlc ; do we want to abort?
-;[MF]Change following line
-; jz kermit ; in which case exit back to command loop
- jnz inp2b ;[MF] No
- lda takflg ;[MF] Yes, are we TAKEing
- ani 1 ;[MF] commands from a file?
- cnz closet ;[MF] Yes, close and reset to get
- ;[MF] commands from the command-line
- jmp kermit ;[MF] and exit back to command loop
-inp2b: cpi cntlz ; if control z exit back to command loop
- jz kermit ; else try for other characters [MF]
- jmp inp2
-
-inp4: mov e,a ; save it for a while
- lda repcnt ; see if this character matches with one in buffer
- lxi h,stbuff ; point to string buffer
- add l ; make hl = hl + a
- mov l,a
- mvi a,0 ; ie make hl = hl + character count
- adc h
- mov h,a ; not using xra, as that clears the Carry flag
- mov a,e ; get the character back again
- cmp m ; is it = to what we expect?
- jnz inp1 ; no, clear counter and try again
- lda repcnt ; yes, then update the pointer, and ...
- inr a ; ... see if we have received all ...
- sta repcnt ; ... we should have received
- lhld waitp1 ; get original counter
- shld waitp ; and reset the loop (timer) counter
- mov e,a ; save length into E again
- lda strcnt ; get the length to compare
- sub e ; if (e) > string length, we have it
- jnz inp2 ; else wait for a little longer
-
- xra a ; no errors
- sta errorc
- jmp kermit ; so say nothing
-;else if error...
-
-inp5: lxi d,erms30 ; say message not receive in time...
- call prtstr
- jmp kermit ; have string, so exit
-
-;
-;
-
-; This is the HELP command. It gives a list of the commands.
-
-help: call cfmcmd
- lxi d,tophlp ;The address of the help message.
- call p20ln ;Print at most 20 lines then pause
-; call prtstr
- jmp kermit
-;
-; This is the LOG command. It logs a session to a file.
-
-log: mvi a,cmofi ;[pcc005] Parse an output file spec.
- lxi d,fcb ;[pcc012] where to put it
- call comnd
- jmp kermt3
- call cfmcmd
- lxi h,fcb ;[pcc012] copy file name and ext
- lxi d,lognam ;[pcc012] to a safe place
- lxi b,12 ;[pcc012] 12 bytes
- call mover ;[pcc012] zap ...
- mvi a,1 ;[pcc005] set flag for logging
- sta logflg ;[pcc005]
- jmp kermit ;[pcc005]
-
-;
-; PAUSE [Wait period]. Just wait for a couple of tics...
-pause: mvi a,cmnum ; get the number of the wait period
- call comnd ; get it
- jmp kermit ; we canna do it, so get next command
- lhld number
- xchg ; move to d
- lhld clkbit+1 ; get clock bits 8 to 23
- mov a,h ; strip ms bit so we have space for a possible carry
- ani 7fh
- mov h,a
- dad d ; add the number (ie get the number to wait to
- shld number ; save it somewhere
-;
-; Now, wait for time to be equal to newer NUMBER with Carry
-ploop:
- call clock ; increment clock
- lda takflg ; test if keyboard interrupt.. not for takes
- ana a
- jnz ploop1 ; do nothing for take command files
- mvi c,dconio ; get status from console
- mvi e,0ffh ; just get the character
- call bdos
- ana a ; if non zero return, then quit
- jnz kermit ; we got something, so quit
-ploop1: lhld number
- xchg
- lhld clkbit+1 ; get bits 8 to 23
- mov a,h
- ani 7fh ; make it 15 bits for a carry...
- mov h,a
- mov a,e ; now, do (DE with carry) - HL
- sub l
- mov e,a
- mov a,d
- sbb h
- ora e ; a = OR of result
- jnz ploop
- jmp kermit ; otherwise we are done.
-
-; PRINT - Print a file to the console and printer.
-; This command is active only from the command level, and not
-; from the connect state. Unfortunately, the print command is
-; not going to be a background utility.
-printf: mvi a,0ffh ; set the print flag on
-typent: sta prnfl ; Type file entry. Common for PRINT and TYPE
- call type ; and do the rest of the print via type
- xra a
- sta prnfl ; next clear the print flag
- jmp kermit
-
-; TYPE - Type a file to the console.
-; This command is really the same as the print command, but the output
-; is not copied to the printer.
-typef: xra a ; we want to clear the printer on flag
- jmp typent ; go to the type entry in printfile above
-
-
-;
-; This is the TAKE command. It take input from a file.
-; TAKE1 is the entry for automatically TAKE-ing KERMIT.INI (or whatever
-; the file name at taknam is) from the default drive
-; [18] code added to accept command tails. See note [18] above
-;
-take: mvi a,cmifi ;[9] Get filename from user
- lxi d,takfcb ;[9] Take file fcb space
- call comnd ;[9] get the file spec
- jmp kermit ;[9] User failed to specify a good file spec
- call take2 ;[MF] Now TAKE the file
- jmp kermit ;[MF] Go back to main Kermit command loop
-;
-take1: lxi b,12 ;[9] copy default drive and file name to take fcb
- lxi d,takfcb
- lxi h,taknam
- call mover ;[9] and do it (all other extents etc are zero)
-;[MF][30]No longer need the following line
-; jmp take2 ; got the file name, now take it.
-;
- ;[9] get the file name, now lets open it
-;
-take2:
- lda takflg ; check to see we have not tak-take
- ani 1 ; if set, we are in a take already
-;[MF]We can do the following test/call more efficiently
-; jz take21
-; call closet ; so close current take file
- cnz closet ;[MF] So close current take file
-take21:
- mvi c,setdma
- lxi d,takdma ;[9] tell bdos where to send data
- call BDOS
- xra a ;[9] clear all these extents etc
- sta takfcb+14
- sta takfcb+32
- lxi d,takfcb ;[9] open the file
- mvi c,openf ;[9] open the file
- call BDOS
- inr a ;[9] if FF returned, problems
-;[MF]Complain if failure and not seeking KERMIT.INI
-; jz kermit ;[9] for now, say nowt if no ini file. Else..
- jz ntake ;[9] We'll say file not found
- ;[MF] unless the initial TAKE (KERMIT.INI)
-; jmp take3 ; a test
-; mvi c,readf ;[9] read first bytes from file
-; lxi d,takfcb ;[9]
-; call BDOS
-
-take3: lxi h,0
- shld takptr ;[9] point to first byte of take file
- lda takflg ; get current flag
- ori 1 ;[9] and set flag to tell Kermit we're taking
- sta takflg
-;[MF][30]Redo next lines so can flag initial TAKE of KERMIT.INI
-; call rnsect ;[9] read a sector
-; jmp kermit ;(Should use a ret, but this will do)
- jmp rnsect ;[9] read a sector and return
-
-ntake: lda initak ;[MF]Is this the initial TAKE (KERMIT.INI)?
- ora a ;[MF]...
- rnz ;[MF]Yes, don't complain
- lxi d,erms15 ;[9] Say file not found
- call prtstr
-;[MF][30]Make next line a "jmp" since we've called TAKE2
-; call rstdma ;[9] reset the DMA addres for other files
-; jmp kermit
- jmp rstdma ;[9] reset the DMA addres for other files
- ;[MF] and return
-
-
-; Little code to allow some expansion of code without changing
-; every futher address, only up to the end of this file.
-; TO BE REMOVED FRO RELEASE!
-
-; org ($+100h) AND 0FF00H
-
-IF lasm
- LINK CPSCOM
-ENDIF ;lasm
+; CPSMIT.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the system-independent initialization, the main
+; loop, and the commands that don't have any place better to go.
+; All the SET xxx and status routines now in CPSCOM.ASM as CPSMIT.ASM
+; was getting too big.
+;
+; revision history:
+;
+;edit 30, 29-Mar-1991 by MF. When looking up a TAKE-file in a TAKE command
+; and the file is not found, complain if it's not the first TAKE of
+; the current program execution (the automatic TAKE of KERMIT.INI)
+;edit 29, 25-Mar-1991 by MF. Add STAY command as a synonym for SET NO-EXIT
+; command per Martin J. Carter of Nottingham University in the U.K.
+;edit 28, 21-Mar-1991 by MF. Modify code after "inp2a" in INPUT command
+; so a ^C will halt TAKE-file processing
+;edit 27, 27-Feb-1991 by MF. Add QUIT as a synonym for EXIT per code of
+; Dr. Martin J. Carter of Nottingham University, U.K. Recognizing QUIT
+; helps those who forget they're not in MS-Kermit, C-Kermit,
+; Kermit-32 etc. Also add commands so that CONNECT, RECEIVE and SEND may
+; be abbreviated to C, R and S, respectively.
+;edit 26, 5-Nov-1990 by MF. Cosmetic changes to main HELP messages for
+; COPY and RENAME commands.
+;edit 25, 1-Nov-1990 by MF. Made the following command-name changes in the
+; interest of uniformity of nomenclature (per suggestions of FDC):
+; FCOPY to COPY, FRENAME to RENAME and STRING to OUTPUT.
+; This means we'll have to type "CO" for CONNECT and "REC" for
+; RECEIVE but with REMOTE now with us we have to do the latter anyway.
+;edit 24, 18-Sep-1990 by MF. Implemented FRENAME command to rename a
+; CP/M file.
+;edit 23, 9-Sep-1990 by MF. Implemented commands to be sent to a
+; remote Kermit Server (Remote commands).
+; Implemented setting of packet sizes for RECEIVE and SEND.
+; Put DIRECTORY/STRING help texts in proper alphabetical position.
+; edit 22, July 6th, 1987 by OBSchou. Added a dummy Commandline to be
+; loaded for debugging purposes as DDT destroys any command line at 80H
+; Also fixed a bug or two...
+;
+; edit 21, April 8th, 1987.
+; Various bits, including more SET SENDRECEIVE options, and make
+; PADDING and PADCHAR valid options. Have I wasted my time, or
+; there still systems that use padding?? Fixed a bug in the INPUT
+; command so we know how many characters there are to check for. Also
+; hived off the SET commands to make a new file, CPSCOM.ASM thereby
+; reducing the size of CPSMIT.ASM. Also rename COPY command to FCOPY
+; hence retaining a single C to imply connect.
+;
+; edit 20, March 30, 1987 by OBSchou.
+; added code for no exit to CPM if a command tail is done (optional)
+; by the SET NO-EXIT command. Added bits for SET AUTORECEIVE to enable
+; or inhibit automatic receive of several files (if something is coming
+; along from the remote side, do a receive. Toss first packet away.)
+; This is first step to SERVER???
+; Also added back the INPUT command.
+;
+; edit 19, March 16, 1987. Moved the code to check for and execute
+; command tails (See Richard Russells submission below).
+; Added flags to exit to CP/M after executing a command tail.
+; The KERMIT.INI file is taken before the command tail is issued.
+;
+; edit 18, March 11, 1987 by OBSchou.
+; Added in code for TYPE <file> and PRINT <file>. Hope to add COPY
+; later on. Also added in code submitted by Richard Russel, to accept
+; a command tail on entry to kermit (eg KERMIT CONNECT). This facility
+; if used, will replace the automatic TAKE function on loading Kermit.
+; Unfortunately, you will not be dropped back to CP/M after the command
+; In the future, it may be possible to either accept several commands
+; on the command tail, and possibly accept the automatic TAKE facility
+; as well. Low on my list of things to do.
+;
+; edit 17, January 28, 1987 by OBSchou for DJ Roberts of Leicester
+; Also added a couple of fixes [obs]
+;
+; DJR January 1987 David J. Roberts.
+; USER made a SET option
+; STATUS output placed in alphabetical order
+; Report DEBUG mode and default disk
+; Name of LOG file on SHOW/STATUS display
+;
+;
+; edit 16 December 1st, OBSchou. Fixed bug in that if the overlay is not in
+; place or correct then prtstr is not called to print the error message
+; (As prtstr has been moved out of the system independent code)
+;
+; edit 15 November 10, 1986 by OBSchou. Re-inserted Pause and Break
+; commands for release.
+;
+; edit 14 August 29, 1986. Removed PAUSE,BREAK,INPUT and SET CASE as
+; these have not been fully coded or debugged. (For next
+; version of Kermit-80...). Also tidied up a bit.
+;
+; 13 by OBSchou for Godfrey Nix. He writes:
+; edit August 11,1986 Godfrey Nix, Nottingham University [gnn]
+; To insert code for setting the packet start character on
+; both send and receive packets (default is still 01H)
+; and make GET and RECEIVE to be separate;
+; use with edits to CP4PKT, CP4UTL
+;
+; edit 12: 19 June, 1986 by OBSchou. Added PAUSE and BREAK facility.
+; Breaks simulate a call to sysint which tests for a B being passed.
+; Note this is only useful if the system dependent code supports breaks,
+; and an appropriate message is returned if breaks are not possible.
+; Also added is the command entry for INPUT, which waits for a string
+; from the host for a given time. The time is a very variable counter
+; incremented every BDOS call. Trial and error will give a reasonable
+; value. STRING acceps a string from the use and then sends it on
+; to the host. These new commands allow a user to (almost) set up auto
+; log on files, where BREAKS/INPUT/STRING/STRING partially emulate a user
+; (AI LURES OK and all that). Still could do with a test, eg if not a
+; correctly returned string go back n steps. This would make a fairly
+; simple TAKE command a lot more complicated.
+;
+;edit 11: 30 May, 1986 OBSchou. Added in a couple of more routines and such
+;
+;edit 10: 27 May, 1986 OBSchou. Added in support for USER function
+; removed XMIT test and routine, but also added SET FLOW-CONTROL
+; (set for XON/XOFF flow control in both directions) and a
+; SET CASE-SENSITIVE ON/OFF (if on => a # A, if ON => a=A)
+;
+;edit 9: 13 May, 1986 OBSchou, Loughborough University, UK
+; Added in code for SET XMIT character to allow setting of the
+; character to wait for from the host during TRANSMIT. It is
+; a line feed by default. Also added a TAKE command, to take: commands
+; from a named disk file. If a file is TAKEn, then all BDOS calls
+; are trapped and tested for console input. If so, we substitute a
+; character (or buffer) from the TAKE file specified.
+; This may also be used in the future for a CPKERMIT.INI
+; to be evaluated during Kermit initialsation.
+;
+; edit 8: February 6, 1895
+; Add a PORT status/show routine for those machines that have more
+; than one they can talk to. It also required a port storage variable
+; a la SPEED and the necessary code to handle it in the SET routine.
+; [Hal Hostetler]
+;
+; edit 7: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
+;
+;pcc003-pcc005 2-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl
+; These edits must all be installed together and change the way
+; logging is handled. The log file spec is moved to a separate
+; fcb, and not opened until an actual CONNECT command is given.
+; This takes care of a NASTY bug that if you used any other file
+; command between the LOG and CONNECT, the log file would get
+; written over the last file used. This also allows logging to
+; be "permanently" enabled until an CLOSE (new command) for all
+; CONNECT sessions, like most other kermits do. If a log file
+; already exists, it will be appended to. Also add two new
+; CONNECT mode commands <esc>Q to suspend logging and <esc>R to
+; resume. <esc>R means something else during TRANSMIT, but
+; logging is never on then, so there shouldn't be any conflict.
+; I also changed the write code, so that it can handle one more
+; character after the XOFF is send to stop the host. This allows
+; a little "slop" for systems that don't stop immediately (such
+; as TOPS10), but it didn't help much.
+;
+;pcc012 4-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl
+; Use the big buffer for the log file. Move the log file back
+; into the common fcb and only save the drive, name, and
+; extension between connects. Add new routines to cp4utl to
+; create or append to an existing file, and to conditionally
+; advance buffers only if in memory. Remove edit pcc003 that
+; allows one more character after the xoff, since it didn't
+; really work very well and does not fit in well with the way
+; the buffer advancing routines are set up. If someone still
+; thinks this would be useful, it could be put back in with a
+; little more work.
+;
+; While testing this edit, I also noticed another bug that
+; the command parsing routines do not limit or check the
+; length of command lines or file specs, trashing what ever
+; comes after them. Currently because of where the fcb and
+; command buffer are located, this does not usually cause a
+; problem, but could if an extremely long line was typed in,
+; or in the future multiple fcbs defined elsewhere in memory
+; were used. Maybe this should be put on the bug list
+; somewhere.
+;
+;pcc013 8-Jan-85 vjc modules:cp4mit,cp4utl,cp4typ
+; Replace CLOSE command to cancel session logging to SET
+; LOGGING ON/OFF. This seems to fit in with the command
+; structure better. Default the log file to KERMIT.LOG
+; incase no previous LOG command. Logging is also enabled
+; by LOG command, as before.
+;
+; edit 6: September 8, 1984
+; Add VERSION command, to display the internal version strings.
+; Move command tables here from CP4UTL, and translate string
+; lengths in them to decimal (how many fingers do YOU got?).
+; Replace some jump tables with dispatch addresses in tables.
+; Make help text for SET command consistent with top level help text.
+;
+; edit 5: August 21, 1984
+; Add word at 0100H to allow us to exit cleanly from DDT (shifting
+; entry section by two bytes).
+;
+; edit 4: August 3, 1984 (CJC)
+; Remove "mover" from entry section, as it now lives in CP4SYS.
+;
+; edit 3: July 27, 1984 (CJC)
+; Merge LASM support from Toad Hall: most of CP4MIT is now in CP4UTL.
+; When assembling with LASM, CP4MIT is linked by CP4DEF; it links to
+; CP4PKT. Add SET TACTRAP command. Separate out display routines so
+; we can eventually do "SHOW <parameter>". Save both bytes of baud
+; rate in speed, and check both bytes when displaying baud rate. Move
+; header info to CP4KER.ASM. Add onoff and chkkey routines to simplify
+; SET command (Toad Hall)
+;
+; edit 2: June 8, 1984
+; formatting and documentation; delete unreferenced variables and some
+; unnecessary labels; move setpar here from cp4pkt; add module version
+; string; make this version 4.01.
+;
+; edit 1: May, 1984
+; extracted from CPMBASE.M80 version 3.9; modifications are described
+; in the accompanying .UPD file.
+
+;
+ ASEG
+ ORG 100H
+
+; The CCP invokes programs with a CALL 100H, with the stack pointer set to
+; 100H. When we exit to CP/M, we do so with a RET, avoiding a warm boot.
+; Unfortunately, DDT starts programs with a jump, not a call, so when we
+; attempt to return to CP/M, we blow the stack and use the word at 100H as
+; the new PC. Put a 0 there so we reboot instead of dying horribly.
+; (Fortunately, this happens to be two NOP's).
+ dw 0
+ jmp start ; Bypass entry section
+
+;
+; Entry section for system-independent part. This contains
+; jumps to routines needed by the system support module.
+;
+entries:
+ jmp kermit ; reentry address
+ jmp nout ; output HL in decimal
+entsiz equ $-entries ; length of entry section
+;
+; End of entry section. As a consistency check, the expected
+; length of this section is stored by the system-dependent
+; module in the linkage section at the end of Kermit, and
+; tested at initialization.
+
+mitver: db 'CPSMIT.ASM (30) 29-Mar-1991$' ; name, edit number, date
+;
+;
+; Initialization
+;
+start: lxi h,0 ; Clear out hl pair
+ dad sp ; and fetch the system stack pointer
+ shld oldsp ; and save for later restoral
+ lxi sp,stack ; move in our own stack.
+ lxi d,version ; print Kermit version
+ call prtstx ; before we do too much (Use fudged prtstr)
+ mvi c,rddrv ;Get our logged in drive
+ call BDOS
+ inr a ;relative 1
+ sta CURDSK ;and save it for later
+
+ lda vtflg ; [OBS] Hangover from VT52 ems not possible...
+ cpi 0ffh ; ... if 0ff stored, assume terminal = off
+ mvi a,vtdefo
+ jnz start0
+ sta vtflg ; if 0ffh make it VT52 off
+start0:
+
+
+IF debug
+;vvvvvvvvvvvvvvvv remove this for run time
+; OBS edit 22 - add in a dummy command line to 80H
+ lxi h,dcomln ;[22] load up dummy command line
+ lxi d,81h ;[22] where to put it
+ lxi b,endcoml-dcomln
+ mov a,c ; get length to a
+ sta 80h ; ... and save as command line length
+ call mover ; ... and save rest of line
+ jmp starta
+dcomln: db 'set baud 4800',semico
+ db 'set dir on',semico
+ db 'dir'
+ db 0,0 ; just to make up space
+endcoml:
+;^^^^^^^^^^^^^^^^ remove this for run time
+ENDIF ;debug
+
+
+starta:
+;
+; Make sure the overlay is in place...
+;
+ lhld lnkflg
+ mov a,h
+ ora l ; if lnkflg is still zero,
+ jz start1 ; the configuration overlay is missing.
+ lxi d,-lnksiz ; if it's not equal to lnksiz,
+ dad d ; we've probably got the wrong
+ mov a,h ; version of the configuration overlay.
+ ora l
+ jnz start2
+ lhld lnkent ; make sure the overlay knows how long
+ lxi d,-entsiz ; our entry section is, so they don't miss.
+ dad d
+ mov a,h
+ ora l
+ jnz start2
+ ; might be ok.
+ lxi h,bdos ; set xbdos address to bdos trap in our code.
+ shld xbdos+1 ; (they may never use it...)
+ call sysinit ; do system-dependent initialization
+ lda bufsec ; get the max no of buffers allowed by system
+ sta maxbsc ; save for SET BUFFER use to compare
+ lxi d,inms26 ; offer some advice on getting help
+ call prtstr
+ lxi h,buff ;[19] we copy any potential command tail across
+ lxi d,cbuff
+ lxi b,80h ;[19] copy all 128 bytes. May use none.
+ call mover
+ lda 80h ; see if there is a command tail...
+
+ ana a
+
+
+
+; Remove for runtime use
+; xra a ; make out there is no command tail
+; Runtime => no XRA above
+
+ jz startz
+ dcr a
+ jz startz ; one character tail...
+ lda takflg ; if more characters, say we are have tail
+ ori 10h ; set bit 4
+ sta takflg
+ sta nexitf ; exit back to CP/M after command line
+startz:
+ mvi a,0ffh ; when here, system basically initiallised,...
+ sta initflg ; apart from KERMIT.INI, so say initialised.
+
+ call take1 ;[9] take a KERMIT.INI file
+ xra a ;[MF] Say we've done it
+ sta initak ;[MF] ...
+ jmp kermit ; Start main loop.
+
+start1: lxi d,erms20 ; "Kermit has not been configured"
+ call prtstx ; print error message (Use bodge for prtstr)
+ jmp exit2 ; and exit.
+
+start2: lxi d,erms21 ; "Consistency check on configuration failed"
+ call prtstx ; print error message
+ jmp exit2 ; and exit.
+;
+;This is the main KERMIT loop. It prompts for and gets the users commands.
+
+kermit: lxi sp,stack ; get new stack pointer, old one might be bad.
+ call selcon ; make sure console is selected.
+ xra a
+ sta mfflg1 ;reset MFNAME
+ sta mfflg2 ;ditto
+ sta mfflg3
+ sta getrxflg ; clear the get/receive flag
+ ;0=> receive, non 0 => get
+ sta cmbflg ;[MF]Initial keyword must not be blank
+ sta cmqflg ;[MF]Allow character-echoing during commands
+ sta remtxt ;[MF] Clear remote-text-to-screen flag
+ lda curdsk ; update the prompt
+ adi 'A'-1
+ sta kerm1+2
+ call getun ;[11] get the user number into temp1/2
+ lda temp1+1 ;[11] get ms value of user number
+ cpi '0' ;[11] less than 10 => do a space
+ jnz kerm4 ;[11] else do MS digit of user number
+ mvi a,' ' ;[11]
+kerm4: sta kerm1 ;[11]
+ lda temp1 ;[11] get ls digit of user number
+ sta kerm1+1 ;[11] save that
+ lda takflg ; are we in TAKE or command line??
+ ani 11h ; strip out both bits
+ jnz kerm5 ; still in either or both...
+ lda nexitf ; if neither, and no-exit-flag set, we quit.
+ ana a
+ jnz exit ;... back to CP/M, else as you were...
+kerm5:
+ lxi d,kerm
+ call prompt ;Prompt the user.
+
+kerm7: lxi d,comtab
+ lxi h,tophlp
+ call keycmd ; Get a keyword
+ xchg ; Get result (dispatch address) into HL
+ pchl ; Dispatch.
+
+; here from: log, setcom, read, cfmcmd
+kermt3: lxi d,ermes3 ;"Not confirmed"
+ call prtstr
+ jmp kermit ;Do it again.
+
+; Structure of command table:
+;
+; 1) Number of entries.
+; 2) Each entry is arranged as follows:
+; a) length of command in bytes.
+; b) 'name of command and $-sign'
+; c) address of routine to process command
+;
+; ---> Note this command table is in alphabetic order.
+;
+
+comtab: db 32 ; added remote
+ ;[obs] added in COPY command, now called FCOPY
+ ;[obs] removed remote simply to issue V4.09
+ ;[MF]Make FCOPY/FRENAME COPY/RENAME for
+ ;[MF]Version 4.10
+ ;[MF]Add QUIT as a synonym for EXIT and
+ ;[MF]C, R and S as abbreviations for
+ ;[MF]CONNECT, RECEIVE and SEND, respectively
+ ;[MF]Add STAY as a synonym for SET NO-EXIT
+ db 5, 'BREAK$'
+ dw break
+ db 3, 'BYE$'
+ dw bye
+ db 1,'C$'
+ dw telnet ;[MF]Abbreviation for CONNECT
+ db 7, 'CONNECT$'
+ dw telnet
+ db 4,'COPY$'
+ dw copy
+ db 9, 'DIRECTORY$'
+ dw dir
+ db 5, 'ERASE$'
+ dw era
+ db 4, 'EXIT$'
+ dw exit
+ db 6, 'FINISH$'
+ dw finish
+ db 3, 'GET$'
+ dw read ; [gnn] entry for GET
+ db 4, 'HELP$'
+ dw help
+ db 5, 'INPUT$'
+ dw input
+ db 3, 'LOG$'
+ dw log
+ db 6, 'LOGOUT$'
+ dw logout
+ db 6, 'OUTPUT$'
+ dw string
+ db 5, 'PAUSE$'
+ dw pause
+ db 5, 'PRINT$'
+ dw printf ;[obs] print a file
+ db 4,'QUIT$'
+ dw exit ;[MF]Synonym for EXIT
+ db 1,'R$'
+ dw read0 ;[MF]Abbreviation for RECEIVE
+ db 7, 'RECEIVE$'
+ dw read0 ; [gnn] not same as GET now
+ db 6, 'REMOTE$'
+ dw remote
+ db 6,'RENAME$'
+ dw rename ;[MF]
+ db 1,'S$'
+ dw send ;[MF]Abbreviation for SEND
+ db 4, 'SEND$'
+ dw send
+ db 3, 'SET$'
+ dw setcom
+ db 4, 'SHOW$'
+ dw show
+ db 6, 'STATUS$'
+ dw status
+ db 4,'STAY$'
+ dw noexit ;STAY (SET NO-EXIT)
+ db 4, 'TAKE$' ;[9]
+ dw take
+ db 8, 'TRANSMIT$'
+ dw xmit
+ db 4, 'TYPE$'
+ dw type ;[obs] type a file command
+ db 7, 'VERSION$'
+ dw shover
+; db 4, 'USER$' ; removed [DRJ]
+; dw user ;[10] removed [DRJ]
+; top-level help message. Caps indicate keywords.
+; this text is also printed by the HELP command.
+
+tophlp:
+ db cr,lf,'BREAK to send a break to the host'
+ db cr,lf,'BYE to host (LOGOUT) and exit to CP/M'
+ db cr,lf,'CONNECT to host on selected port'
+ db cr,lf,'COPY to copy a CP/M file'
+ db cr,lf,'DIRECTORY of current used Micro-disk'
+ db cr,lf,'ERASE a CP/M file'
+ db cr,lf,'EXIT to CP/M'
+ db cr,lf,'FINISH running Kermit on the host'
+ db cr,lf,'GET a file from the host'
+ db cr,lf,'HELP by giving this message'
+ db cr,lf,'INPUT to make the micro wait for a string from the host'
+ db cr,lf,'LOG the terminal sessions to a file'
+ db cr,lf,'LOGOUT the host'
+ db cr,lf,'OUTPUT to send a specified string to the host'
+ db cr,lf,'PAUSE to wait for a little time'
+ db cr,lf,'PRINT a file to the printer'
+ db cr,lf,'QUIT to CP/M'
+ db cr,lf,'RECEIVE file from host'
+ db cr,lf,'REMOTE to send commands to a remote server'
+ db cr,lf,'RENAME to rename a CP/M file'
+ db cr,lf,'SEND file to host'
+ db cr,lf,'SET a parameter'
+ db cr,lf,'SHOW the parameters'
+ db cr,lf,'STATUS of Kermit'
+ db cr,lf,'STAY at Kermit command-level after a command tail'
+ db cr,lf,'TAKE commands from a file' ;[9]
+ db cr,lf,'TRANSMIT file to host (in connect state)'
+ db cr,lf,'TYPE a file to the console'
+ db cr,lf,'VERSION of Kermit running' ;[pcc005]
+; db cr,lf,'USER to set a different user number' ;removed [DJR]
+ db '$' ;[obs] added it here to allow for expansion
+
+;
+; This is the BREAK command. It sends a 'B' to the system dependent
+; interrupt routines (test for escape-cokebottle xxx) and do a break
+; if the overlay can. Else, we tell user not to be so silly.
+break: call cfmcmd ; get return
+ mvi a,'B' ; were gonna do a break if the overlay can
+ call sysint ; try doing it..
+ jmp kermit ; if we can do it, else
+ lxi d,inms12 ;... say not implemented
+ jmp kermit
+
+;
+;
+; This is the BYE command. It tells the remote KERSRV to logout,
+; then exits.
+
+bye: call cfmcmd
+ call logo ;Tell the main frame to logout.
+ jmp kermit ;If it fails, don't exit.
+ call sysbye ; success. do system-dependent cleanup
+ jmp exit1 ;Exit Kermit.
+
+; This is the EXIT command. It leaves KERMIT and returns to CP/M.
+; alternate entries: exit1, from BYE command;
+; exit2, from initialization (if it fails)
+
+exit: call cfmcmd ; confirm...
+exit1: call sysexit ; do system-dependent termination
+exit2:
+ jmp 0 ; return to CP/M via JUMP instead of RET.
+
+; lhld oldsp ;Get back the system stack
+; sphl ;and restore it.
+; ret ;Then return to system.
+
+; Input command. Syntax:
+; INPUT [Wait period] [string]
+; where
+; Wait period is a time period to wat for
+; string is a string to expect back from the host. Control
+; characters are entered as \ and an octal number.
+;
+; I can see uses for this command from other routines...
+;
+input: mvi a,cmnum ; first get the number
+ call comnd ; get it
+ jmp kermit ; if we dont understand it...
+ lhld number
+ shld waitp ; and save as the wait period
+ lxi d,stbuff ; where to put the string
+ mvi a,cmtxt ; get text
+ call comnd
+ jmp kermit ; not quite correct...
+ sta strcnt ; string count returned in a
+ call cfmcmd ; get a confirm
+
+ lhld waitp ; multiply the number by
+ dad h
+ dad h ; ... 4
+ dad h ; ... 8
+ inx h ; but make sure it is at least 1
+ shld waitp ; and save it away again
+ shld waitp1 ; save in case we need to reset counter
+
+; Right, now wait for characters comming from the line, within the
+; time allowed (very fuzzy). Compare with STRING buffer
+;
+inp1: xra a
+ sta repcnt ; clear the host prompt chars.counter
+inp2: lhld waitp ; have we waited long enough
+ dcx h
+ shld waitp ; count less one
+ mov a,h ; test to see if both zero
+ ora l
+ jnz inp20 ; nope
+ mvi a,3 ; error is three ie total failure
+ sta errorc
+ jmp inp5 ; take error exit
+
+inp20: call rd1chl ; read a character from the line
+ ani 7fh ; set flags
+ jnz inp4 ; Not zero => we have a character from host
+ call ckchr ; see if *WE* have a character from console
+ push psw ; restore to modem
+ call selmdm ; reselect the modem port
+ pop psw
+ ani 7fh ; strip parity (should not be there)
+ jnz inp2a ; if a null, try again
+ lda strcnt ; if the string length is zero, dont wait.
+ ana a
+ jnz inp2 ; so loop back again
+ jmp kermit ; else drop out
+
+inp2a: cpi cntlc ; do we want to abort?
+;[MF]Change following line
+; jz kermit ; in which case exit back to command loop
+ jnz inp2b ;[MF] No
+ lda takflg ;[MF] Yes, are we TAKEing
+ ani 1 ;[MF] commands from a file?
+ cnz closet ;[MF] Yes, close and reset to get
+ ;[MF] commands from the command-line
+ jmp kermit ;[MF] and exit back to command loop
+inp2b: cpi cntlz ; if control z exit back to command loop
+ jz kermit ; else try for other characters [MF]
+ jmp inp2
+
+inp4: mov e,a ; save it for a while
+ lda repcnt ; see if this character matches with one in buffer
+ lxi h,stbuff ; point to string buffer
+ add l ; make hl = hl + a
+ mov l,a
+ mvi a,0 ; ie make hl = hl + character count
+ adc h
+ mov h,a ; not using xra, as that clears the Carry flag
+ mov a,e ; get the character back again
+ cmp m ; is it = to what we expect?
+ jnz inp1 ; no, clear counter and try again
+ lda repcnt ; yes, then update the pointer, and ...
+ inr a ; ... see if we have received all ...
+ sta repcnt ; ... we should have received
+ lhld waitp1 ; get original counter
+ shld waitp ; and reset the loop (timer) counter
+ mov e,a ; save length into E again
+ lda strcnt ; get the length to compare
+ sub e ; if (e) > string length, we have it
+ jnz inp2 ; else wait for a little longer
+
+ xra a ; no errors
+ sta errorc
+ jmp kermit ; so say nothing
+;else if error...
+
+inp5: lxi d,erms30 ; say message not receive in time...
+ call prtstr
+ jmp kermit ; have string, so exit
+
+;
+;
+
+; This is the HELP command. It gives a list of the commands.
+
+help: call cfmcmd
+ lxi d,tophlp ;The address of the help message.
+ call p20ln ;Print at most 20 lines then pause
+; call prtstr
+ jmp kermit
+;
+; This is the LOG command. It logs a session to a file.
+
+log: mvi a,cmofi ;[pcc005] Parse an output file spec.
+ lxi d,fcb ;[pcc012] where to put it
+ call comnd
+ jmp kermt3
+ call cfmcmd
+ lxi h,fcb ;[pcc012] copy file name and ext
+ lxi d,lognam ;[pcc012] to a safe place
+ lxi b,12 ;[pcc012] 12 bytes
+ call mover ;[pcc012] zap ...
+ mvi a,1 ;[pcc005] set flag for logging
+ sta logflg ;[pcc005]
+ jmp kermit ;[pcc005]
+
+;
+; PAUSE [Wait period]. Just wait for a couple of tics...
+pause: mvi a,cmnum ; get the number of the wait period
+ call comnd ; get it
+ jmp kermit ; we canna do it, so get next command
+ lhld number
+ xchg ; move to d
+ lhld clkbit+1 ; get clock bits 8 to 23
+ mov a,h ; strip ms bit so we have space for a possible carry
+ ani 7fh
+ mov h,a
+ dad d ; add the number (ie get the number to wait to
+ shld number ; save it somewhere
+;
+; Now, wait for time to be equal to newer NUMBER with Carry
+ploop:
+ call clock ; increment clock
+ lda takflg ; test if keyboard interrupt.. not for takes
+ ana a
+ jnz ploop1 ; do nothing for take command files
+ mvi c,dconio ; get status from console
+ mvi e,0ffh ; just get the character
+ call bdos
+ ana a ; if non zero return, then quit
+ jnz kermit ; we got something, so quit
+ploop1: lhld number
+ xchg
+ lhld clkbit+1 ; get bits 8 to 23
+ mov a,h
+ ani 7fh ; make it 15 bits for a carry...
+ mov h,a
+ mov a,e ; now, do (DE with carry) - HL
+ sub l
+ mov e,a
+ mov a,d
+ sbb h
+ ora e ; a = OR of result
+ jnz ploop
+ jmp kermit ; otherwise we are done.
+
+; PRINT - Print a file to the console and printer.
+; This command is active only from the command level, and not
+; from the connect state. Unfortunately, the print command is
+; not going to be a background utility.
+printf: mvi a,0ffh ; set the print flag on
+typent: sta prnfl ; Type file entry. Common for PRINT and TYPE
+ call type ; and do the rest of the print via type
+ xra a
+ sta prnfl ; next clear the print flag
+ jmp kermit
+
+; TYPE - Type a file to the console.
+; This command is really the same as the print command, but the output
+; is not copied to the printer.
+typef: xra a ; we want to clear the printer on flag
+ jmp typent ; go to the type entry in printfile above
+
+
+;
+; This is the TAKE command. It take input from a file.
+; TAKE1 is the entry for automatically TAKE-ing KERMIT.INI (or whatever
+; the file name at taknam is) from the default drive
+; [18] code added to accept command tails. See note [18] above
+;
+take: mvi a,cmifi ;[9] Get filename from user
+ lxi d,takfcb ;[9] Take file fcb space
+ call comnd ;[9] get the file spec
+ jmp kermit ;[9] User failed to specify a good file spec
+ call take2 ;[MF] Now TAKE the file
+ jmp kermit ;[MF] Go back to main Kermit command loop
+;
+take1: lxi b,12 ;[9] copy default drive and file name to take fcb
+ lxi d,takfcb
+ lxi h,taknam
+ call mover ;[9] and do it (all other extents etc are zero)
+;[MF][30]No longer need the following line
+; jmp take2 ; got the file name, now take it.
+;
+ ;[9] get the file name, now lets open it
+;
+take2:
+ lda takflg ; check to see we have not tak-take
+ ani 1 ; if set, we are in a take already
+;[MF]We can do the following test/call more efficiently
+; jz take21
+; call closet ; so close current take file
+ cnz closet ;[MF] So close current take file
+take21:
+ mvi c,setdma
+ lxi d,takdma ;[9] tell bdos where to send data
+ call BDOS
+ xra a ;[9] clear all these extents etc
+ sta takfcb+14
+ sta takfcb+32
+ lxi d,takfcb ;[9] open the file
+ mvi c,openf ;[9] open the file
+ call BDOS
+ inr a ;[9] if FF returned, problems
+;[MF]Complain if failure and not seeking KERMIT.INI
+; jz kermit ;[9] for now, say nowt if no ini file. Else..
+ jz ntake ;[9] We'll say file not found
+ ;[MF] unless the initial TAKE (KERMIT.INI)
+; jmp take3 ; a test
+; mvi c,readf ;[9] read first bytes from file
+; lxi d,takfcb ;[9]
+; call BDOS
+
+take3: lxi h,0
+ shld takptr ;[9] point to first byte of take file
+ lda takflg ; get current flag
+ ori 1 ;[9] and set flag to tell Kermit we're taking
+ sta takflg
+;[MF][30]Redo next lines so can flag initial TAKE of KERMIT.INI
+; call rnsect ;[9] read a sector
+; jmp kermit ;(Should use a ret, but this will do)
+ jmp rnsect ;[9] read a sector and return
+
+ntake: lda initak ;[MF]Is this the initial TAKE (KERMIT.INI)?
+ ora a ;[MF]...
+ rnz ;[MF]Yes, don't complain
+ lxi d,erms15 ;[9] Say file not found
+ call prtstr
+;[MF][30]Make next line a "jmp" since we've called TAKE2
+; call rstdma ;[9] reset the DMA addres for other files
+; jmp kermit
+ jmp rstdma ;[9] reset the DMA addres for other files
+ ;[MF] and return
+
+
+; Little code to allow some expansion of code without changing
+; every futher address, only up to the end of this file.
+; TO BE REMOVED FRO RELEASE!
+
+; org ($+100h) AND 0FF00H
+
+IF lasm
+ LINK CPSCOM
+ENDIF ;lasm
diff --git a/cpspk1.asm b/cpspk1.asm
index 6ea4831..8e2f87c 100644
--- a/cpspk1.asm
+++ b/cpspk1.asm
@@ -1,1904 +1,1904 @@
-; CPSPK1.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the (system-independent) routines that implement
-; the KERMIT protocol, and the commands that use them:
-; RECEIVE, SEND, FINISH, and LOGOUT.
-;
-; revision history:
-;
-;edit 23, 16-Jan-1991 by MF. The bug of (22) was not fixed (although
-; the error described needed to be corrected). Really fixed the bug this:
-; time. changed "lda 'E'" after "ptch9b" to "mvi a,'E'" -- Zilog
-; mnemonic thinking must've addled my brain!
-;edit 22, 14-Jan-1991 by MF. Fix bug in the code which sends an "E" packet
-; to the remote Kermit on encountering "disk full" so that
-; uncontrollified <CR><LF> is not copied to the packet data area (and
-; hence sent to the remote Kermit). This should fix a bug reported
-; by Russell Lang of Monash University in Australia wherein a PC
-; running Kermit in Server mode complained of invalid characters when
-; receiving the "disk full" error packet from CP/M Kermit.
-;edit 21 of 3-Jan-1991 by MF. Reverse part of edit 20 which flushes comm
-; input at EOF send: the problem of multiple copies of packets being
-; sent when a stream of files being sent is partially interrupted with
-; ^X has been fixed by modifying "inchr" in CPSPK2.ASM.
-;edit 20, 2-Jan-1991 by MF. Tightened up code just after "sdata1" and around
-; "sdat14". Added code to flush comm input after user has typed ^X
-; or ^Z to interrupt file sends so that duplicate packets are not
-; sent after the interrupt character (especially ^X) has been typed.
-;edit 19, 14-Dec-1990 by MF. Place "<<>>" around "F" and "X" packets coming
-; as replies to REMOTE commands a la VMS Bliss Kermit.
-; Also type each character of "X" or "F" packet explicitly in case
-; dollar-signs are part of the filename (as in VMS Bliss Kermit
-; when a REMOTE TYPE is given and SET FILE NAMING FULL is in effect).
-; Expanded code is at label rfil3f.
-;edit 18, 27-Nov-1990 by MF. Fix bug introduced with edit 17 which resulted
-; in "E" packet being sent twice when receiving file(s) and disk-full
-; occurred. Sorry about that, folks!
-;edit 17, 27-Nov-1990 by MF. When receiving files, make the decision as to
-; whether to delete a partially-received file on a "disk full"
-; condition subject to the setting of the SET INCOMPLETE-FILES
-; switch in conformity with the behavior of MSDOS Kermit.
-; An "E" packet is still sent to the remote Kermit. Also try to close
-; any incomplete file whether deleting it or not (labels rdat16 and
-; rdat3a). If keeping incomplete files, try to write outstanding
-; buffers to disk, giving an error if the disk is full.
-;edit 16, 23-Nov-1990 by MF. When receiving, cause the file being written
-; to disk to **always** be deleted and an "E" packet to be sent when a
-; "disk full" condition is encountered (per suggestion of
-; RJL@MONU1.CC.MONASH.EDU.AU).
-;edit 15, 15-Nov-1990 by MF. Changed code for the Receive Complete state
-; to always go into RECEIVE if AUTORECEIVE is on. This will happen
-; most of the time anyway as most mainframe Kermits issue a prompt
-; after a single SEND command (wild-carded or not), thus guaranteeing
-; that the modem status check of Kermit-80 ver. 4.09 would **always**
-; have characters ready for input (the mainframe Kermit's prompt),
-; defeating the status check and the Console input check (originally
-; intended to drop the user out of the loop if he/she typed a key with
-; no comm input present). Eliminate "any key" message there also.
-; the user can drop out by hitting ^C.
-; Of course, none of the foregoing applies if the Receive Complete
-; state occurs as the result of a "Get" command where Autoreceive
-; is meaningless and we just drop back to Kermit command-level.
-;edit 14, 1-Oct-1990 by MF. Added code to send an "I" packet before an
-; "R" packet in GET command.
-; Modified routine "sinit" to ignore "E" packets when sending an
-; "i" packet (per KPROTO.DOC).
-;edit 13, 14-Sep-1990 by MF. Added code to implement SET FILE COLLISION
-; and SET INCOMPLETE commands.
-;edit 12, 9-Sep-1990 by MF. Added code to prevent packet counts
-; from being displayed during Remote commands. Fixed
-; AUTORECEIVE code, file colision Rename algorithm and eliminated
-; multiple display of initial messages during GET/RECEIVE.
-; edit 11, 28 July, 1987 by OBSchou. Commented out capas etc support
-; (Long packets etc) as this is not worth the effort coding... but
-; I have left what WAS done for any enthusiast. Also set in a few
-; to NOT write to screen if SET TERMINAL QUIET set. Hopefully speeds
-; up transfers on systems taking forever to update screens.
-;
-; edit 10, 8 April, 1987 by OBSchou. Tarted up all sorts of bits n bobs
-; to cope with all the new aditions for Kermit-80 V 4.09
-; Look for the [10] for most cahnges. spar and rpar largely replaced
-;
-; edit 9, March 30th by OBSchou. Set bits for automatically receiving
-; another file if a remote sender sends files in seperate sessions.
-; The code simply checks the serial line, and if there is some
-; activity, assume its another SEND INIT packet. As there is no
-; simple way to go to receive with the control-a, just ignore the
-; packet. Causes one retry on the sender, but so what. Really
-; should make it a server gizzmo.
-;
-; edit 8: January 28, 1987 by OBSchou
-; Two major issues: firstly split CPSPKT.ASM into CPSPK(1 2).ASM
-; making it far easier to handle this file.
-; Second, some mode to the GET routines to correctly print the file
-; name instead of the fireworks. Trouble was with GET <file> <file>
-; and RECEIVE <file>. However, new bugs discovered...
-;
-; edit 7: August 11, 1986 Godfrey N. Nix [gnn] Nottingham University
-; To ignore echoed packets (ie send 'S' receive 'S' before 'A');
-; To allow character other than SOH for packet header (see also
-; updates to CP4MIT and CP4UTL for other code needed);
-; To permit SEND and RECEIVE to specify a host filename which
-; is of a different structure to that of CP/M.
-;
-; edit 6a: [OBSchou] 7 March, 1985.
-; Edited file with additions from MJ Carter. He writes:
-; 25th September 1985, M J Carter [majoc], Nottingham University
-; Code in gofil() amended, for exactly the same reasons to the
-; alteration to cmifil() in cpscmd.asm. If there is any deep
-; reason why gofil() has to be used instead of a call to comnd(cmofil),
-; I can't see it. The bug (on a British Micro Mimi 803) caused
-; gofil() to overwrite existing files in GET and RECEIVE, even
-; with file warning SET ON.
-;
-;edir 6: November 22, 1984
-; Change SEND's 'Unable to find file' error exit from calling
-; error3 to calling prtstr instead. I don't know about you, but
-; I greatly dislike having messages dumped into pre-existing
-; junk on the screen where I have to spend lots of time hunting
-; for them. [Hal Hostetler]
-;
-; edit 5: September 9, 1984
-; Call flsmdm in init to flush old input when starting transfers.
-; Select console before returning from inpkt.
-; Replace inline code with calls to makfil/clofil to set up for
-; multisector buffering on output.
-; Remove superfluous call to clrlin in error3.
-;
-; edit 4: August 21, 1984 (CJC)
-; Fix comment in inpkt: packet is terminated by NUL on return, not CR.
-; If debugging, display the outgoing packet before putting the EOL
-; character on, so the dumped packet doesn't get overwritten.
-;
-; edit 3: July 27, 1984
-; add link directive for LASM. CP4PKT is linked by CP4MIT, and links
-; to CP4TT. Add Toad Hall TACtrap to permit operations through a TAC.
-;
-; edit 2: June 8, 1984
-; formatting and documentation; remove some unused labels; move setpar
-; to cp4mit.m80; add module version string; make all arithmetic on
-; 'pktnum' modulo 64; apply defaults correctly for missing parameters
-; in send-init packet (and corresponding ack).
-;
-; edit 1: May, 1984
-; extracted from CPMBASE.M80 version 3.9; modifications are described
-; in the accompanying .UPD file.
-;
-pk1ver: db 'CPSPK1.ASM (23) 16-Jan-1991$' ; name, edit number, date
-
-; GET command [gnn]
-; here from: kermit
-
-read: mvi a,0ffh ;[obs 8] we are doing a get
- sta getrxflg ;[obs 8] so set flag
- lxi d,remdat ;Where to put the text (if any.)
- mvi a,cmtxt
- call comnd ;Get either some text or a confirm.
- jmp kermt3 ; Didn't get anything.
- ora a ;Get any chars?
- jz kermt3 ;[gnn] GET must have a filename
- sta rdl ;Store the number of chars.
- xchg ;Get pointer into HL.
- mvi m,'$' ;Put in a dollar sign for printing.
- call init ;Clear the line and initialize the buffers.
- lda quietd ; quiet display?
- ana a
- jz read01 ;[MF]No, go ahead and position cursor
- call prcrlf ;[MF]Yes, keep from overwriting the prompt
- jmp read00 ;[MF]and write filename
-read01: call scrfln ;Position cursor [MF]
-read00: lxi d,remdat ;Print the file name, in either case
- call prtstr
- jmp read0a ;[gnn] go get local name if any
-
-
-; enter here for RECEIVE command [gnn]
-read0: mvi a,0 ;[gnn]
- sta rdl ;[gnn][MF] flag entry as receive, not get
- sta getrxflg ;[obs 8] doing a receive, so reset flag
- call init ;clear line, initialise buffers
-read0a: lxi d,remnam ;[gnn] save local name here
- mvi a,cmtxt ;[gnn]
- call comnd ;[gnn] read second filename if present
- jmp kermt3 ;[gnn] error exit
- sta remlen ;[gnn] save length of name, may be zero
- sta getrxflg ;[obs 8] May also be receive <fnam> so
- ;[obs 8]pretend get for printing filename
- lda rdl ;[gnn] look at first name
- ora a ;[gnn] receive or get?
- jz read1 ;[gnn] receive
-
- mvi a,'I' ;[MF]Set state to send "I" packet
- sta state ;[MF]...
-
-; jmp read12 ;[obs] [gnn] does not want this
-
-read1: ;call init ;Clear the line and initialize the buffers.
-read12: xra a
- sta czseen ;Clear the ^X/^Z flag initially.
- lxi h,0
- shld numpkt ;Set the number of packets to zero.
- shld numrtr ;Set the number of retries to zero.
- sta pktnum ;Set the packet number to zero.
- sta numtry ;Set the number of tries to zero.
- lda quietd ; quiet display?
- ana a
- jnz read13 ; yes, so dont write...
- call scrnrt ;Position cursor
- lxi h,0
- call nout ;Write the number of retries.
-read13: lda rdl ;[MF]Get or receive?
- ora a ;[MF]...
- jnz read2 ;[MF]Get, don't reset state
- mvi a,'R'
- sta state ;Set the state to receive initiate.
- ;...
-;
-;RECEIVE state table switcher.
-
-read2: lda quietd ; noisy display?
- ana a
- jnz read21 ; no, a quiet one
- lda remtxt ;[MF] In Remote command?
- ora a
- jnz read21 ;[MF] Yes, don't write to screen
- call scrnp ;Position cursor
- lhld numpkt
- call nout ;Write the current packet number.
-read21: lda state ;Get the state.
- cpi 'D' ;Are we in the DATA receive state?
- jnz read22
- call rdata
- jmp read2
-
-read22: cpi 'X' ; F packet but not an F packet?
- jnz read3 ; nope, so try next one
- call rfile ; 'get' the filename (but dont open it)
- jmp read2
-
-read3: cpi 'F' ;Are we in the FILE receive state?
- jnz read4
- call rfile ;Call receive file.
- jmp read2
-
-read4: cpi 'R' ;Are we in the Receive-Initiate state?
- jnz read5
- call rinit
- lda state ;[jd] get new state
- cpi 'F' ;[jd] went into receive state?
- jnz read2 ;[jd] no
- lxi d,inms24 ;[jd] yes, get receiving... message
- call finmes ;[jd] go print it
- jmp read2
-
-read5: cpi 'C' ;Are we in the Receive-Complete state?
- jnz read6
- lxi d,infms3 ;Put in "Complete" message.
- lda czseen ;Or was it interrupted?
- ora a ; . . .
- jz read5a ;No.
- xra a ;Yes, clear flag.
- sta czseen ; ...
- lxi d,inms13 ;Issue "interrupted" message.
-read5a: lda remtxt ;[MF] Doing a Remote command?
- ora a
- cz finmes ;Print completion message in right place if not
-;
- lda rdl ;[MF]Receive or Get?
- ora a ;[MF]...
- jnz kermit ;[MF]Get, Autoreceive means nothing.
- lda autorc ; see if we want autoreceives
- ana a
- jz kermit ;[MF]No autoreceives, so drop out
- lxi d,autmes ;[MF]Yes, tell the user what we're doing
- call prtstr ;[MF]...
- jmp read1 ;[MF]Try another Receive (we get one
- ;[MF]retry from the sender as the ^A is lost)
-
-read6: cpi 'Y' ;[MF]Simple ack (from remote command)?
- jz kermit ;[MF]Yes
-
- cpi 'I' ;[MF]Exchanging parameters via info packet?
- jnz read7 ;[MF]No
- call sinit ;[MF]Yes, send the packet
- lda state ;[MF]Now see what happened
- cpi 'X' ;[MF]Did we exchange parameters successfully?
- jz read6a ;[MF]Yes, go send the filespec
- cpi 'A' ;[MF]No, are we in abort state?
- jnz read2 ;[MF]No, try again
- jmp kermit ;[MF]Yes, it's a real disaster, we must stop
-read6a: lda rdl ;[MF]Get length of filespec
- sta argblk+1 ;[MF]as length of packet
- mov c,a ;[MF]We must copy the filespec
- mvi b,0 ;[MF]...
- lxi h,remdat ;[MF]from the temporary buffer
- lxi d,data ;[MF]to the packet data area
- call mover ;[MF]Do it.
-; for GET we must send the name of the file we want [gnn]
-
- mvi a,'1' ;Start with single character checksum
- sta curchk ;Save the type
- xra a ;Start a packet zero.
- sta argblk
- mvi a,'R' ;Receive init packet.
- call spack ;Send the packet.
- jmp kermt3 ; Die!
- xra a
- sta czseen ;Clear the ^X/^Z flag initially.
- lxi h,0
- shld numpkt ;Set the number of packets to zero.
- sta pktnum ;Set the packet number to zero.
- sta numtry ;Set the number of tries to zero.
- mvi a,'R' ;[MF]Set state to Receive-Initiate
- sta state ;[MF]...
- jmp read21 ;[MF]and go around again
- ;[MF]without retyping packet-number
-
-read7: cpi 'A' ;Are we in the Receive-"Abort" state?
- jnz read8
-read8: lxi d,infms4 ;Anything else is equivalent to "abort".
- call finmes
- jmp kermit
-;
-; Receive routines
-
-; Receive init
-; called by: read
-
-rinit: lda numtry ;Get the number of tries.
- cpi imxtry ;Have we reached the maximum number of tries?
- jm rinit2
- lxi d,ermes4
- call error3 ;Move cursor and print an error message.
- jmp abort ;Change the state to abort.
-
-rinit2: inr a ;Increment it.
- sta numtry ;Save the updated number of tries.
- mvi a,'1' ;Reset block check type to single character
- sta curchk ;Store as current type for initialization
- call rpack ;Get a packet.
- jmp nak ; Trashed packet: nak, retry.
- cpi 'S' ;Is it a send initiate packet?
- jnz rinit3 ;If not see if its an error.
-rini2a: lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- xra a
- sta numtry ;Reset the number of tries.
- lda argblk ;Returned packet number. (Synchronize them.)
- call countp
- lda argblk+1 ;Get the number of arguments received.
- lxi h,data ;Get a pointer to the data.
- call spar ;Get the data into the proper variables.
- lxi h,data ;Get a pointer to our data block.
- call rpar ;Set up the receive parameters.
- sta argblk+1 ;Store the returned number of arguments.
- mvi a,'Y' ;Acknowledge packet.
- call spack ;Send the packet.
- jmp abort ; Failed, abort.
- lda inichk ;Now switch to agreed upon check-type
- sta curchk ;For all future packets
- mvi a,'F' ;Set the state to file send.
- sta state
- ret
-
-rinit3: cpi 'E' ;Is it an error packet.
- jnz nak0 ;If not NAK whatever it is.
- call error
- jmp abort
-;
-; Receive file
-; called by: read
-
-rfile: lda numtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm rfile1
- lxi d,ermes5
- call error3 ;Move cursor and print an error message.
- jmp abort ;Change the state to abort.
-
-rfile1: inr a ;Increment it.
- sta numtry ;Save the updated number of tries.
- call rpack ;Get a packet.
- jmp nak ; Trashed packet: nak, retry.
- cpi 'S' ;Is it a send initiate packet?
- jnz rfile2 ; No, try next type.
- lda oldtry ;Get the number of tries.
- cpi imxtry ;Have we reached the maximum number of tries?
- jm rfil12 ;If not proceed.
- lxi d,ermes4
- call error3 ;Move cursor and print an error message.
- jmp abort ;Change the state to abort.
-
-rfil12: inr a ;Increment it.
- sta oldtry ;Save the updated number of tries.
- lda pktnum ;Get the present packet number.
- dcr a ;Decrement
- ani 3FH ; modulo 64
- mov b,a
- lda argblk ;Get the packet's number
- cmp b ;Is the packet's number one less than now?
- jnz nak0 ;No, NAK and try again.
- call updrtr ;Update the retry count.
- xra a
- sta numtry ;Reset the number of tries.
- lxi h,data ;Get a pointer to our data block.
- call rpar ;Set up the parameter information.
- sta argblk+1 ;Save the number of arguments.
- mvi a,'Y' ;Acknowledge packet.
- call spack ;Send the packet.
- jmp abort ; Failed, abort.
- ret
-
-rfile2: cpi 'Z' ;Is it an EOF packet?
- jnz rfile3 ; No, try next type.
- lda oldtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm rfil21 ;If not proceed.
- lxi d,ermes6
- call error3 ;Move cursor and print an error message.
- jmp abort ;Change the state to abort.
-
-rfil21: call tryagn
- ret
-
-rfile3: cpi 'F' ;Start of file?
- jnz rfil3b
- mov c,a ;[MF]Save packet type
- lda remtxt ;[MF]Doing a remote server command?
- ora a ;[MF]...
- mov a,c ;[MF]Restore packet type
- jnz rfil3d ;[MF]If yes, same as x packet
- call compp
- jnz nak0 ;No, NAK it and try again.
- call countp
- mov c,a ;[MF]
- lda remtxt ;[MF]Doing a remote command?
- ora a ;[MF]...
- mov a,c ;[MF]
- jnz rfil3a ;[MF]Yes, don't open a file
- call gofil ;Get a file to write to, and init output buffer.
- jmp abort
-rfil3a: lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- call ackp
- mvi a,'D' ;Set the state to data receive.
- sta state
- lda czseen ;Check if we punted a file
- cpi 'Z' ;and didn't want any more
- rz ;If that was the request, keep telling other end
- xra a ;Otherwise, clear flag (^X is only for one file)
- sta czseen ;And store the flag back
- ret
-
-rfil3b: cpi 'X' ;Start of 'file?' , but not a file?
- jnz rfile4
-rfil3d: call compp
- jnz nak0 ;No, NAK it and try again.
- call countp
-
- call selcon ;[MF]Select Console
- lda argblk+1 ; get length
- ora a ;[MF]Anything to write?
- jz rfil3e ;[MF]No
- push psw ;[MF]Yes, save character count
- mvi e,'<' ;[MF]Write "<<" as in VMSKermit
- push d ;[MF]...
- call outcon ;[MF]...
- pop d ;[MF]...
- call outcon ;[MF]...
- pop psw ;[MF]Restore character count
- lxi h,data ; lets write the filename (?) to display
-rfil3f: push psw ;[MF]Save loop counter
- mov e,m ;[MF]Get character to write
- inx h ;[MF]and increment character pointer
- push h ;[MF]Save the pointer
- call outcon ;[MF]Write character to display
- pop h ;[MF]Restore pointer
- pop psw ;[MF]and loop counter
- dcr a ;[MF]Decrement the counter
- jnz rfil3f ;[MF]Display entire filename
- mvi e,'>' ;[MF]Put in ">>" as in VMSKermit
- push d ;[MF]...
- call outcon ;[MF]...
- pop d ;[MF]...
- call outcon ;[MF]...
- call prcrlf ;[MF]New line
-rfil3e: lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- call ackp
- mvi a,'D' ; expecting a D packet
- sta state
- lda czseen ;Check if we punted a file
- cpi 'Z' ;and didn't want any more
- rz ;If that was the request, keep telling other end
- xra a ;Otherwise, clear flag (^X is only for one file)
- sta czseen ;And store the flag back
- ret
-
-rfile4: cpi 'B' ;End of transmission.
- jnz rfile5
- call compp
- jnz nak0 ;No, NAK it and try again.
- xra a ;No data. (Packet number already in argblk).
- sta argblk+1
- mvi a,'Y' ;Acknowledge packet.
- call spack ;Send the packet.
- jmp abort
- mvi a,'C' ;Set the state to complete.
- sta state
- ret
-
-rfile5: cpi 'E' ;Is it an error packet.
- jnz abort
- call error
- jmp abort
-;
-; Receive data
-; called by: read
-
-rdata: lda numtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm rdata1
- lxi d,erms10
- call error3 ;Display error message.
-rdat16: lda remtxt ;[MF]Is a Remote command in progress?
- ora a ;[MF]...
- jnz abort ;[MF]Yes, don't worry about file disposition
- lda incflg ;[MF]Are we keeping incomplete files?
- ora a ;[MF]...
- jnz rdat17 ;[MF]Yes
- lxi d,fcb ;[MF]No, close the file, ignoring errors
- push d ;[MF]while protecting the pointer
- mvi c,closf ;[MF]...
- call bdos ;[MF]...
- pop d ;[MF]Now delete the file, ignoring errors
- mvi c,delf ;[MF]...
- call bdos ;[MF]...
- jmp abort ;Change the state to abort.
-rdat17: call clofil ;[MF]Try to close the file, writing
- ;[MF]outstanding buffers to disk
- jmp rdat37 ;[MF]We can't, the disk is full
- jmp abort ;[MF]Change the state to "abort"
-
-rdata1: inr a ;Increment it.
- sta numtry ;Save the updated number of tries.
- call rpack ;Get a packet.
- jmp nak ; Trashed packet: nak, retry.
- cpi 'D' ;Is it a data packet?
- jnz rdata2 ; No, try next type.
- call compp ;check for correct packet number (zero flag = ok)
- jz rdat14 ;its correct
- lda oldtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm rdat12 ;If not proceed.
- lxi d,erms10
- call error3 ;Display err msg.
- jmp rdat16 ;[MF]Change the state to abort.
-
-rdat12: call tryagn
- ret
-
-rdat14: call countp
- lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- lda argblk+1 ;Get the length of the data.
- call ptchr
- jmp rdat3b ;[MF] Unable to write out chars;abort.
- xra a
- sta numtry ;Reset the number of tries.
- sta argblk+1 ;No data. (Packet number still in argblk.)
- mov c,a ;Assume no data
- lda czseen ;Check if control-X typed
- ora a ; . . .
- jz rdat15 ;Zero if not typed
- mov c,a ;Get the type of character typed
- mvi a,1 ;One data character
- sta argblk+1 ;Save the count
- mov a,c ;Get the possible data character
- sta data ;Store in data area
-rdat15: mvi a,'Y' ;Acknowledge packet.
- call spack ;Send the packet.
- jmp rdat16 ;[MF]
- ret
-
-rdata2: cpi 'F' ;Start of file?
- jnz rdata3 ; No, try next type.
- lda oldtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm rdat21 ;If not proceed.
- lxi d,ermes5
- call error3 ;Display err msg.
- jmp rdat16 ;[MF]Change the state to abort.
-
-rdat21: call tryagn
- ret
-
-rdata3: cpi 'Z' ;Is it a EOF packet?
- jnz rdata4 ;Try and see if its an error.
- call compp
- jnz nak0 ;No, NAK it and try again.
- call countp
- lda argblk+1 ;Get the data length
- cpi 1 ;Have one item?
- jnz rdat33 ;If not, ignore data
- lda data ;Yes, get the character
- cpi 'D' ;Is it a 'D' for discard?
- jz rdat36 ;If so, punt file
-rdat33: lda remtxt ;[MF]Writing text to disk?
- ora a ;[MF]...
- jnz rdat38 ;[MF]No, don't close file
- call clofil ;Finish off the file.
- jmp rdat37 ; Give up if the disk is full.
-rdat38: xra a ;Since we kept the file,
- sta czseen ;don't say it was discarded.
- lda numtry ;Get the number of tries. [MF]
- sta oldtry ;Save it. [MF]
- call ackp ;[MF]
- jmp rdat39 ;[MF]and get ready to get more files
-rdat36: lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- call ackp
- lda remtxt ;[MF]Is a Remote command in progress?
- ora a ;[MF]...
- jnz rdat39 ;[MF]Yes, don't worry about file disposition
- lda dscflg ;[MF]Is the file being punted because
- ora a ;[MF]of a collision?
- jnz rdat39 ;[MF]Yes, don't delete the existing file
- lda incflg ;[MF]No, are we keeping incomplete files?
- ora a ;[MF]...
- jnz rdat3a ;[MF]Yes
- lxi d,fcb ;[MF]No, close the file,
- mvi c,closf ;[MF]ignoring errors
- push d ;[MF]...
- call bdos ;[MF]...
- pop d ;[MF]Now delete the file,
- mvi c,delf ;[MF]ignoring errors
- call bdos ;[MF]...
- jmp rdat39 ;[MF]and continue
-rdat3a: call clofil ;[MF]Try to close the file, writing
- ;[MF]outstanding buffers to disk
- jmp rdat37 ;[MF]Can't, disk is full
-rdat39: mvi a,'F'
- sta state
- ret
-
-rdat37: call ptchr9 ; Send "?Disk full" on the error line [MF]
- ; and to the remote Kermit [MF]
-rdat3b: lda remtxt ;[MF]Doing a Remote command?
- ora a ;[MF]...
- jnz abort ;[MF]Yes, just abort
- lxi d,fcb ;[MF]Close the file, ignoring errors
- push d ;[MF]Protect fcb pointer
- mvi c,closf ;[MF]...
- call bdos ;[MF]...
- pop d ;[MF]Restore pointer
- lda incflg ;[MF]Are we keeping incomplete files?
- ora a ;[MF]...
- jnz abort ;[MF]Yes, just abort transfer
- mvi c,delf ;[MF]No, delete the file, ignoring errors
- call bdos ;[MF]...
- jmp abort ;[MF] abort transfer
-
-rdata4: cpi 'E' ;Is it an error packet.
- jnz rdat16 ;[MF]
- call error
- jmp rdat16 ;[MF]
-;
-; SEND command
-; here from: kermit
-
-send: mvi a,cmifi ;Parse an input file spec.
- lxi d,fcb ;Give the address for the FCB.
- call comnd
- jmp kermit ; Give up on bad parse.
-; section to get remote filename [gnn]
- lxi d,remnam ;[gnn] where to put filename
- mvi a,cmtxt ;[gnn]
- call comnd ;[gnn] get the text to end of the line
- jmp kermt3 ;[gnn] failure in reading buffer
- sta remlen ;[gnn] save length (may be zero)
-;
- xra a
- sta mfflg1 ; clear flags...
- sta mfflg2
- sta mfflg3 ;[gnn]
- sta fcbcnt ;[gnn] clear fcbcount
- lxi h,fcb0 ;[gnn] and fcb pointer
- shld xfcbptr
-;
- call mfname ;handle (multi) files
- jnc send14 ;got a valid file-name
- lxi d,erms15
- call prtstr ;Display error msg. ([hh] where it's visible)
- jmp kermit
-
-send14: call init ;Clear the line and initialize the buffers.
- xra a
- sta pktnum ;Set the packet number to zero.
- sta numtry ;Set the number of tries to zero.
- sta wrn8 ;[jd] we haven't sent the 8-bit-lost warning
- lxi h,0
- shld numpkt ;Set the number of packets to zero.
- shld numrtr ;Set the number of retries to zero.
- lda quietd ; a quiet display?
- ana a
- jnz send15 ; yup, dont write
- call scrnrt ;Position cursor
- lxi h,0
- call nout ;Write the number of retries.
-send15: mvi a,'1' ;Reset to use single character checksum
- sta curchk ;For startup
- mvi a,'S'
- sta state ;Set the state to receive initiate.
- ;...
-;
-;SEND state table switcher
-
-send2: lda quietd ; a quiet display?
- ana a
- jnz send21 ; yes, so dont write
- call scrnp ;Position cursor
- lhld numpkt
- call nout ;Write the packet number.
-send21: lda state ;Get the state.
- cpi 'D' ;Are we in the data send state?
- jnz send3
- call sdata
- jmp send2
-
-send3: cpi 'F' ;Are we in the file send state?
- jnz send4
- call sfile ;Call send file.
- jmp send2
-
-send4: cpi 'Z' ;Are we in the EOF state?
- jnz send5
- call seof
- jmp send2
-
-send5: cpi 'S' ;Are we in the send initiate state?
- jnz send6
- call sinit
- lda state ;[jd] get state back
- cpi 'F' ;[jd] into file send state yet?
- jnz send2 ;[jd] no
- lxi d,inms23 ;[jd] yes, print sending...
- call finmes ;[jd]
- jmp send2
-
-send6: cpi 'B' ;Are we in the eot state?
- jnz send7
- call seot
- jmp send2
-
-send7: cpi 'C' ;Are we in the send complete state?
- jnz send8 ;No...
- lxi d,infms3 ;Yes, write "Complete" message.
- lda czseen ;Or was it interrupted?
- ora a ; . . .
- jz send7a ;No.
- lxi d,inms13 ;Yes, then say "Interrupted" instead.
-send7a: call finmes
- jmp kermit
-
-send8: cpi 'A' ;Are we in the send "abort" state?
- jnz send9
- lxi d,infms4 ;Print message.
- call finmes
- jmp kermit
-
-send9: lxi d,infms4 ;Anything else is equivalent to "abort".
- call finmes
- jmp kermit
-;
-; Send routines
-
-; Send initiate
-; called by: send
-
-sinit: lda numtry ;Get the number of tries.
- cpi imxtry ;Have we reached the maximum number of tries?
- jm sinit2
- lxi d,erms14
- call error3 ;Display ermsg
- jmp abort ;Change the state to abort.
-
-sinit2: inr a ;Increment it.
- sta numtry ;Save the updated number of tries.
- mvi a,'1' ;Reset to use single character checksum
- sta curchk ;For startup
- lda chktyp ;Get our desired block check type
- sta inichk ;Store so we tell other end
- lxi h,data ;Get a pointer to our data block.
- call rpar ;Set up the parameter information.
- sta argblk+1 ;Save the number of arguments.
- lda numpkt ;Get the packet number.
- sta argblk
- lda state ; load state (I or S)
-
- call spack ;Send the packet.
- jmp abort ; Failed, abort.
- call rpack ;Get a packet.
- jmp r ; Trashed packet don't change state, retry.
- cpi 'Y' ;ACK?
- jnz sinit3 ;If not try next.
- call compp ;compare packets. If ok, zero flag set
- rnz ;If not try again.
- call countp ;increment packet number modulo 64
- lda argblk+1 ;Get the number of pieces of data.
- lxi h,data ;Pointer to the data.
- call spar ;Read in the data. (decode what they want)
- lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- xra a
- sta numtry ;Reset the number of tries.
- lda state ; se if S or I state
- cpi 'I' ; I state, so set X as next state
- jnz sinita
-sinitb: mvi a,'X'
- sta state
- ret
-
-sinita: lda inichk ;Get the agreed upon block check type
- sta curchk ;Store as type to use for packets now
- mvi a,'F' ;Set the state to file send. (Assumed)
- sta state
- call getfil ;Open the file.
- ret ; assume success; mfname thinks the file exists.
-
-sinit3: cpi 'N' ;NAK?
- jnz sinit4 ;If not see if its an error.
- call updrtr ;Update the number of retries.
- lda pktnum ;Get the present packet number.
- inr a ;Increment
- ani 3FH ; modulo 64
- mov b,a
- lda argblk ;Get the packet's number.
- cmp b ;Is the packet's number one more than now?
- rnz ;If not assume its for this packet, go again.
- xra a
- sta numtry ;Reset number of tries.
- mvi a,'F' ;Set the state to file send.
- sta state
- ret
-
-sinit4: cpi 'E' ;Is it an error packet.
- jnz abort
- lda state ;[MF]Get state
- cpi 'I' ;[MF]If an "I" packet was sent,
- jz sinitb ;[MF]Ignore the error, pretend success
- call error ;[MF]else display the error info
- jmp abort ;[MF]and abort
-;
-; Send file header
-; called by: send
-;[5a] Question [majoc]: Why could not the filename
-; parsing have been done by comnd, like all the rest?
-
-sfile: lda numtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm sfile1
- lxi d,erms14
- call error3
- jmp abort ;Change the state to abort.
-
-sfile1: inr a ;Increment it.
- sta numtry ;Save the updated number of tries.
- xra a ;Clear A
- sta czseen ;No control-Z or X seen
- lxi h,data ;Get a pointer to our data block.
- shld datptr ;Save it.
-; use remote name if given, else use local name [gnn]
- lda remlen ;[gnn] anything given?
- ora a ;[gnn]
- jnz sfile4 ;[gnn] use remote name
-
- lxi h,fcb+1 ;Pointer to the file name in the FCB.
- shld fcbptr ;Save position in FCB.
- mvi b,0 ;No chars yet.
- mvi c,0
-sfil11: mov a,b
- cpi 8H ;Is this the ninth char?
- jnz sfil12 ;If not proceed.
- mvi a,'.' ;Get a dot.
- lhld datptr
- mov m,a ;Put the char in the data packet.
- inx h
- shld datptr ;Save position in data packet.
- inr c
-sfil12: inr b ;Increment the count.
- mov a,b
- cpi 0CH ;Twelve?
- jp sfil13
- lhld fcbptr
- mov a,m
- ani 7fH ;Turn off CP/M 2 or 3's high bits.
- inx h
- shld fcbptr ;Save position in FCB.
- cpi '!' ;Is it a good character?
- jm sfil11 ;If not get the next.
- lhld datptr
- mov m,a ;Put the char in the data packet.
- inx h
- shld datptr ;Save position in data packet.
- inr c
- jmp sfil11 ;Get another.
-
-sfil13: mov a,c ;Number of char in file name.
- sta argblk+1
- lhld datptr
- mvi a,'$'
- mov m,a ;Put in a dollar sign for printing.
- lda quietd ; a quiet display
- ana a
- jnz sfi13a ; yes, dont write
- call scrfln ;Position cursor
-sfi13a: lxi d,data ;Print the file name though, in either case
- call prtstr
- lda pktnum ;Get the packet number.
- sta argblk
- mvi a,'F' ;File header packet.
- call spack ;Send the packet.
- jmp abort ; Failed, abort.
- call rpack ;Get a packet.
- jmp r ; Trashed packet don't change state, retry.
- cpi 'Y' ;ACK?
- jnz sfile2 ;If not try next.
- call compp
- rnz ;If not hold out for the right one.
-sfil14: call countp
- lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- xra a
- sta numtry ;Reset the number of tries.
- sta bytes ;[10] clear the "bytes transferred" counter
- sta bytes+1 ;[10]
- sta bytes+2 ;[10]
- sta bytes+3 ;[10]
- call gtchr ;Fill the first data packet
- jmp sfil16 ;Error go see if its EOF.
-; ;Got the chars, proceed.
- sta size ;Save the size of the data gotten.
- mvi a,'D' ;Set the state to data send.
- sta state
- ret
-
-sfil16: cpi 0FFH ;Is it EOF?
- jnz abort ;If not give up.
- mvi a,'Z' ;Set the state to EOF.
- sta state
- ret
-
-sfile2: cpi 'N' ;NAK?
- jnz sfile3 ;Try if error packet.
- call updrtr ;Update the number of retries.
- lda pktnum ;Get the present packet number.
- inr a ;Increment
- ani 3FH ; modulo 64
- mov b,a
- lda argblk ;Get the packet's number.
- cmp b ;Is the packet's number one more than now?
- rnz ;If not go try again.
- jmp sfil14 ;Just as good as a ACK;go to the ACK code.
-
-sfile3: cpi 'E' ;Is it an error packet.
- jnz abort
- call error
- jmp abort
-
-; copy remote name into packet to send [gnn]
-sfile4: xchg ;[gnn] keep pointer to packet
- lxi h,remnam ;[gnn] set pointer to name
- mov c,a ;[gnn] keep count of length
- mov b,a ;[gnn] and set as loop counter
-sfil41: mov a,m ;[gnn] get a character
- stax d ;[gnn] copy it to packet
- inx h ;[gnn]
- inx d ;[gnn] move pointers
- dcr b ;[gnn]
- mov a,b ;[gnn]
- ora a ;[gnn] done them all?
- jnz sfil41 ;[gnn] repeat until done
- xchg ;[gnn] get final position
- shld datptr ;[gnn] and save it
- jmp sfil13 ;[gnn] now go and send packet
-
-;
-; Send data
-; called by: send
-
-sdata: lda numtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm sdata1
- lxi d,erms14
- call error3
- jmp abort ;Change the state to abort.
-
-sdata1: inr a ;Increment it.
- sta numtry ;Save the updated number of tries.
- lxi h, data ;Get a pointer to our data block.
- shld datptr ;Save it.
- lxi h,filbuf ;Pointer to chars to be sent.
- shld cbfptr ;Save position in char buffer.
- mvi b,1 ;First char.
-sdat11: lhld cbfptr
- mov a,m
- inx h
- shld cbfptr ;Save position in char buffer.
- mov c,a ;[jd] preserve character temporarily
- lda quot8 ;[jd] doing eighth-bit quoting?
- ora a ;[jd]
- mov a,c ;[jd] restore char
- jnz sdat4 ;[jd] using eighth-bit quoting, no warning
- lda parity ;[jd] get parity
- cpi parnon ;[jd] none?
- mov a,c ;[jd] restore character
- jz sdat4 ;[jd] no parity, leave char alone
- lda wrn8 ;[jd] look at warning flag
- ora a ;[jd] have we already given the warning?
- jnz sdat5 ;[jd] yes, skip this
- mov a,c ;[jd] restore character...
- ani 80h ;[jd] examine parity
- jz sdat5 ;[jd] no parity, no warning.
- call parwrn ;[jd] ...print warning - parity lost
- mvi a,0ffh ;[jd] remember that we sent the message
- sta wrn8 ;[jd]
-sdat5: mov a,c ;[jd] restore character again
- ani 7fh ;[jd] strip parity so not checksummed
-sdat4: lhld datptr
- mov m,a ;Put the char in the data packet.
- inx h
- shld datptr ;Save position in data packet.
- inr b ;Increment the count.
- lda size ;Get the number of chars in char buffer.
- cmp b ;Have we transfered that many?
- jp sdat11 ;If not get another.
- lda size ;Number of char in char buffer.
- sta argblk+1
- lda pktnum ;Get the packet number.
- sta argblk
- mvi a,'D' ;Data packet.
- call spack ;Send the packet.
- jmp abort ; Failed, abort.
- call rpack ;Get a packet.
- jmp r ; Trashed packet don't change state, retry.
- cpi 'Y' ;ACK?
- jnz sdata2 ;If not try next.
- call compp
- rnz ;If not hold out for the right one.
- lda argblk ;Get the packet number back
- call countp
- lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- xra a
- sta numtry ;Reset the number of tries.
- lda argblk+1 ;Get the data length
- cpi 1 ;Check if only 1 character?
- jnz sdat15 ;If not, just continue
- lda data ;Got one character, get it from data
- cpi 'Z' ;Want to abort entire stream?
- jnz sdat14 ;If not, check for just this file
- sta czseen ;Yes, remember it
- jmp sdat16 ;[MF] and set EOF state
-sdat14: cpi 'X' ;Desire abort of current file?
- jnz sdat15 ;If not, just continue
- sta czseen ;Yes, remember that
- jmp sdat16 ;[MF] and set EOF
-sdat15: lda czseen ;Also get control-Z flag
- ora a ;Check if either given
- jz sdat12 ;If neither given, continue
-sdat16: mvi a,'Z' ;Change state to EOF
- sta state ; . . .
- ret ;And return
-
-sdat12: call gtchr
- jmp sdat13 ;Error go see if its EOF.
- sta size ;Save the size of the data gotten.
- ret
-
-sdat13: cpi 0FFH ;Is it EOF?
- jnz abort ;If not give up.
- mvi a,'Z' ;Set the state to EOF.
- sta state
- ret
-
-sdata2: cpi 'N' ;NAK?
- jnz sdata3 ;See if is an error packet.
- call updrtr ;Update the number of retries.
- lda pktnum ;Get the present packet number.
- inr a ;Increment
- ani 3FH ; modulo 64
- mov b,a
- lda argblk ;Get the packet's number.
- cmp b ;Is the packet's number one more than now?
- rnz ;If not go try again.
- jmp sdat12 ;Just as good as a ACK;go to the ACK code.
-
-sdata3: cpi 'E' ;Is it an error packet.
- jnz abort
- call error
- jmp abort
-;
-; Send EOF
-; called by: send
-
-seof: lda numtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm seof1
- lxi d,erms14
- call error3
- jmp abort ;Change the state to abort.
-
-seof1: inr a ;Increment it.
- sta numtry ;Save the updated number of tries.
- lda pktnum ;Get the packet number.
- sta argblk
- xra a
- sta argblk+1 ;No data.
- lda czseen ;Check if C-Z or C-X typed
- ora a ; . . .
- jz seof14 ;If not aborted, just keep going
- mvi a,'D' ;Tell other end to discard packet
- sta data ;Store in data portion
- mvi a,1 ;One character
- sta argblk+1 ;Store the length
-seof14: mvi a,'Z' ;EOF packet.
- call spack ;Send the packet.
- jmp abort ; Failed, abort.
- call rpack ;Get a packet.
- jmp r ; Trashed packet don't change state, retry.
- cpi 'Y' ;ACK?
- jnz seof2 ;If not try next.
- call compp
- rnz ;If not hold out for the right one.
-seof12: call countp
- lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- xra a
- sta numtry ;Reset the number of tries.
- mvi c,closf ;Close the file.
- lxi d,fcb
- call bdos
-;* Check if successful
- lda czseen ;Desire abort of entire stream?
- cpi 'Z' ;Desire abort of entire stream?
- jz seof13 ;If so, just give up now
- call mfname ;Get the next file.
- jc seof13 ; No more.
- call getfil ;and open it (assume success)
- xra a ;Clear A
- sta czseen ;Since we have not aborted this file
- mvi a,'F' ;Set the state to file send.
- sta state
- ret
-
-seof13: mvi a,'B' ;Set the state to EOT.
- sta state
- ret
-
-seof2: cpi 'N' ;NAK?
- jnz seof3 ;Try and see if its an error packet.
- call updrtr ;Update the number of retries.
- lda pktnum ;Get the present packet number.
- inr a ;Increment
- ani 3FH ; modulo 64
- mov b,a
- lda argblk ;Get the packet's number.
- cmp b ;Is the packet's number one more than now?
- rnz ;If not go try again.
- jmp seof12 ;Just as good as a ACK;go to the ACK code.
-
-seof3: cpi 'E' ;Is it an error packet.
- jnz abort
- call error
- jmp abort
-;
-; Send EOT
-; called by: send
-
-seot: lda numtry ;Get the number of tries.
- cpi maxtry ;Have we reached the maximum number of tries?
- jm seot1
- lxi d,erms14
- call error3
- jmp abort ;Change the state to abort.
-
-seot1: inr a ;Increment it.
- sta numtry ;Save the updated number of tries.
- lda pktnum ;Get the packet number.
- sta argblk
- xra a
- sta argblk+1 ;No data.
- mvi a,'B' ;EOF packet.
- call spack ;Send the packet.
- jmp abort ; Failed, abort.
- call rpack ;Get a packet.
- jmp r ; Trashed packet don't change state, retry.
- cpi 'Y' ;ACK?
- jnz seot2 ;If not try next.
- call compp
- rnz ;If not hold out for the right one.
-seot12: call countp
- lda numtry ;Get the number of tries.
- sta oldtry ;Save it.
- xra a
- sta numtry ;Reset the number of tries.
- mvi a,'C' ;Set the state to file send.
- sta state
- ret
-
-seot2: cpi 'N' ;NAK?
- jnz seot3 ;Is it error.
- call updrtr ;Update the number of retries.
- lda pktnum ;Get the present packet number.
- inr a ;Increment
- ani 3FH ; modulo 64
- mov b,a
- lda argblk ;Get the packet's number.
- cmp b ;Is the packet's number one more than now?
- rnz ;If not go try again.
- jmp seot12 ;Just as good as a ACK;go to the ACK code.
-
-seot3: cpi 'E' ;Is it an error packet.
- jnz abort
- call error
- jmp abort
-;
-; This routine sets up the data for init packet (either the
-; Send_init or ACK packet).
-; called by: rinit, rfile, sinit
-;
-; Called by rinit, rfile and sinit. See what WE want from the other fella
-;
-; [11] by OBS - Stripped out all the new capas code etc and reverted
-; to Good Ol' Basic Kermit again!
-; Those keen should study the followin gode with care, and remove
-; or add semicolons as indicated.
-;
-; See also SPAR which decodes what comes in. It also decodes bits in
-; the "capability" fields. (Two CAPAS files allowed from remote
-; machines, but we will only send one at max.) Note that not all
-; if any of the capability bits will be used.
-;
-; Definitions - init packet (data section only.. rest of header assumed OK)
-; Byte 0 Maximum length I want to send
-; 1 The Timeout I want you to use
-; 2 Number of PAD characters I want tot use (May be null)
-; 3 The PAD character I want to use (May be Null)
-; 4 The End-of-Line character I will use (Carriage Return)
-; 5 The control character Quote Character I will use (#)
-; 6 The parity bit Quote Character I will use (&)
-; 7 The Checktype I will use
-; 8 The repeat prefix I will use (Null, as we cannot to repeats)
-; 9 Capability Byte 0 (See SPAR for defs)
-; 10 Capability byte 1 ( --- " --- but we will not send it.)
-; 11 The number of packets I will send per window (not used)
-; 12 MAXL1 - Long packet size, ms count
-; 13 MAXL2 - Long packet size, ls count
-;
-;
-; Enter with HL pointing to the "data" part of the packet.
-
-;
-; older part of rpar follows...
-;
-;
-rpar: lda rpsiz ;Get the receive packet size.
- adi space ;Add a space to make it printable.
- mov m,a ;Put it in the packet.
- inx h ;Point to the next char.
- lda rtime ;Get the receive packet time out.
- adi space ;Add a space.
- mov m,a ;Put it in the packet.
- inx h
- lda rpad ;Get the number of padding chars.
- adi space
- mov m,a
- inx h
- lda rpadch ;Get the padding char.
- adi 100O ;Uncontrol it.
- ani 7FH
- mov m,a
- inx h
- lda reol ;Get the EOL char.
- adi space
- mov m,a
- inx h
- lda rquote ;Get the quote char.
- mov m,a
- inx h
- mvi m,'Y' ;[jd] we know how to do 8-bit quoting
- lda parity ;[jd]
- cpi parnon ;[jd] parity none?
- jz rpar1 ;[jd] yes, keep going
- lda qbchr ;[jd] no, better request 8-bit quoting
- mov m,a
-
-rpar1:
- inx h ;Advance to next
- lda chktyp ;Get desired block check type
- mov m,a ;Store it
- inx h ;Advance pointer
-
-; Comment out the next two lines for capas etc. WILL require debugging
- mvi a,8 ; this id the older end for this routine. May be useful.
- ret
-
-; [11] Rest not needed for now, commented out
-; [10] (to ret)
-; New additions to rpar follows...
-
-; lda rcap1 ; get the first capability byte
-; ani 3eh ; mask out bit 0, ie only one CAPAS byte
-; adi space ; tochar it
-; mov m,a
-; inx h
-; mvi m,space ; No windows, ie space to packet
-; inx h
-; push h ; we need the HL regs for maths.
-; lhld rdpkt ; get receive packet length
-; lxi d,95 ; we want hl div 95 and hl mod 95
-; call divide ; return with divsion in hl, remainder in de
-; mov a,l ; two sets of bytes
-; pop h
-; adi space ; tochar(maxl1)
-; mov m,a
-; inx h
-; mov a,l
-; adi space ; tochar(maxl2)
-; mov m,a
-;
-; done all, set databytes = 12 and return
-; mvi a,12 ; 12 bits of data
-; ret
-
-;[11] End of commented out code for rpar
-
-
-;
-; This routine reads in all the send_init packet information.
-; called by: rinit, sinit
-
-;[11] As for rpar, restore the "old" kermit code for non-capas Kermit.
-;[10] (to ret at end)
-;
-; SPAR - routine to decode parameters received from the remote end
-;
-; Called by rinit,sinit
-;
-; Entry: a: Number of databytes in packet
-; hl: Pointer to "data" part of packet
-;
-;spar: sta temp4 ; save for a while
-; ; first clear some variables
-; lda dspsiz ; get default "send" packet length
-; sta spktl
-; lda dstime ; get default time-out
-; sta stimeo
-; xra a ; set no pad characters by default
-; sta spad
-; lda dspadc ; get the default padding character
-; sta spadc
-; mvi a,cr ; default end of line character (CR)
-; sta seol
-; mvi a,dsquot ; default quote character
-; sta squote
-; mvi a,dsbqut ; default binary quote character
-; sta qbchr
-; mvi a,dschkt ; set checktype = 1 for inits
-; sta inichk
-; mvi a,space ; no repeat prefixing ( otherwise ~)
-; sta srept
-;
-; Now follows the "capabilities" bits... 5 bits per capas byte.
-;
-; Note: Before extracting any data bits, apply unchar() to get the
-; six ls bits. If bit 0 = 1 the a subsequent capaa byte follows
-;
-; Byte0: Bit 0: Set to 1 if there are subsequent CAPAS bytes
-; 1: (Cap. 5) Set to 1 for long packets. Second byte
-; AFTER the last capas byte has packet length DIV 95
-; and Thire byte has length MOD 95
-; 2: (Cap. 4) Sliding Windows. If used, first byte AFTER
-; last capas byte has TOCHAR(no. of packets in window)
-; 3: (Cap. 3) Ability to accept "A" (attribute packets)
-; 4: (Cap. 2) Reserved
-; 5: (Cap. 1) Reserved
-; Byte 2 onward: not used in this implementation. Any capas bytes sent
-; will be stored, however.
-;
-; lda temp4 ; get the number of bytes to test
-; mov c,a ; to a count register
-; mov a,m ; get first byte
-; call decc ; unchar it, and decrement c
-; sta spsiz ; save a send packet size
-; jz sparx ; if no more, exit
-;
-; mov a,m ; get timout
-; call decc
-; sta stime ; save timeout
-; jz sparx
-;
-; mov a,m ; get pad characters
-; call decc
-; sta spadc ; save it
-; jz sparx
-;
-; mov a,m ; get pad character count
-; call decc
-; sta spad
-; jz sparx
-;
-; mov a,m ; get send EOL
-; call decc
-; sta seol
-; jz sparx
-;
-; mov a,m ; get control quote character
-; call decc
-; sta squote
-; jz sparx
-;
-; mov a,m ; get binary (parity) quote char
-; mov b,a ; this time we actually WANT accumulator
-; cpi space ; are we doing 8th bit quoteing
-; jz spar1 ; dont know, assume not
-; cpi 'N' ; definately not?
-; jz spar1
-; cpi 'Y' ; definately - use &
-; jz spar2
-; sta squote ; else save the new character
-;spar2: lda parity ; see if we are using the parity bit
-; cpi parnon ; no parity => no quoting
-; jz spar3 ; yup, so use the default quote character &
-;
-;spar1: xra a ; save not quoting
-; sta squote
-;spar3: call decc ; update counters etc
-; jz sparx
-;
-; mov a,m ; get repeat prefixing
-; call decc
-; push psw ; save flags
-; cpi space-32 ; we want it?
-; jz spar4
-; sta srept
-;spar4: pop psw ; restore flags
-; jz sparx
-;
-; lxi d,scapas ; point to start of capability byte(s)
-; push psw ; must do this...
-;spar5: pop psw ; cos we restore the spack
-; mov a,m
-; call decc ; get scap1 (or n)
-; sta scap1
-; push psw
-; ani 01 ; another byte following?
-; jnz spar5
-; pop psw ; see if any other data bytes (Windows etc)
-; jz sparx
-;
-; mov a,m ; get window size
-; call decc
-; sta swindo
-; jz sparx
-;
-; mov a,m ; get long packets ms bits
-; call decc ;
-; mov d,a ; unchared ms bits-ish
-; mov a,m
-; call decc ; ls bits-ish
-; push h ; and we are doing maths
-; push b ; and an intermediate result in c
-; push psw ; we want flags and the ls bits...
-; mvi b,0
-; mov c,d ; get ms bits-ish to bc
-; push b ; get number to hl
-; pop h
-; now multipy by 95
-; dad h ;*2
-; dad h ;*4
-; dad h ;*8
-; dad h ;*16
-; push h ; *16 to ...
-; pop d ; ... de
-; dad h ;*32
-; dad d ; *(32+16) = *48
-; dad h ; *96
-; mov a,l ; *(96-1)
-; sub c
-; mov l,a
-; mov a,0
-; sbb h
-; mov h,a
-; pop psw ; restore ls bitsish
-; mov e,a
-; mvi d,0
-; dad d ; *95 + ls bits. Phew.
-; shld sdpkt ; save long packet length
-; pop b
-; pop h ; restore regs
-;
-;sparx: ret ; if here, (assume) no more data to read in
-;[10] routines required follow
-;decc: mov a,m ; get data byte
-; sui space ; unchar it
-; inx h ; increment input pointer
-; dcr c ; decrement data counter
-; ret ; return
-;[10] end or spar replacement
-
-;[11] Restore older spar....
-; Older spar follows...
-spar: sta temp4 ;Save the number of arguments.
-; Initialize some variables to their required default values, so we use
-; the right values even if the remote Kermit doesn't send the full packet:
-; ; we don't do anything with timeout values yet.
-; ; no default pad count/pad character?
- mvi a,cr ; EOL character = carriage-return
- sta seol
- mvi a,'#' ; quote character = '#'
- sta squote
- mvi a,'&' ; eighth-bit quote character = '&'
- sta qbchr
- mvi a,'1' ; block-check = 1-character-checksum
- sta inichk
-;
- mov a,m ;Get the max packet size.
- sbi space ;Subtract a space.
- sta spsiz ;Save it.
- lda temp4
- cpi 3 ;Fewer than three pieces?
- rm ;If so we are done.
- inx h
- inx h ;Increment past the time out info.
- mov a,m ;Get the number of padding chars.
- sbi space
- sta spad
- lda temp4
- cpi 4 ;Fewer than four pieces?
- rm ;If so we are done.
- inx h
- mov a,m ;Get the padding char.
- adi 100O ;Re-controlify it.
- ani 7FH
- sta spadch
- lda temp4
- cpi 5 ;Fewer than five pieces?
- rm ;If so we are done.
- inx h
- mov a,m ;Get the EOL char.
- sbi space
- sta seol
- lda temp4
- cpi 6 ;Fewer than six pieces?
- rm ;If so we are done.
- inx h
- mov a,m ;Get the quote char.
- sta squote
- lda temp4 ;Get the amount of data supplied
- cpi 7 ;Have an 8-bit quote?
- rm ;If not there, all done
- inx h ;Yes, get the character
- mvi a,0 ;[jd]
- sta quot8 ;[jd] assume not quoting
- mov a,m ;Get the supplied character
- cpi 'N' ;[jd] No?
- jz spar1 ;[jd] then don't try to do it
- cpi space ;[jd] maybe they don't know about it...
- jz spar1 ;[jd] then don't try to do it.
- cpi 'Y' ;[jd] Yes?
- jnz spar2 ;[jd] if not 'Y', assume it's a quote char.
- lda parity ;[jd] using parity?
- cpi parnon ;[jd] no, don't need quoting...
- jz spar1 ;[jd]
- mvi a,0ffh ;[jd] else turn on...
- sta quot8 ;[jd] ...quote flag
- jmp spar1
-
-;[11] Note: If capas etc required, beware of the next two lables, as these
-; are used elswhere.
-
-spar2: sta qbchr ;[jd] use their quote char (should validate)
- mvi a,0ffh
- sta quot8 ;[jd] turn quote flag and fall thru...
-
-spar1: lda temp4 ;Determine if block check type given
- cpi 8 ;Is the field there?
- rm ;If not, all done
- inx h ;Point to the character
- mov a,m ;Get the value
- mov b,a ;Copy value
- lda chktyp ;Get our type
- cmp b ;Is it our desired type?
- rnz ; If not, use default (1-character-checksum)
- sta inichk ; Match, store as type to use after init
- ret ; and return
-;[10] end of replacement
-;[11] end of replacement of replacement (ie back to original code)
-;
-
-; Copy characters from packet to disk (or screen)
-; called by: rdata
-
-ptchr: sta temp1 ;Save the size.
- lda remtxt ;[MF]Get remote command flag
- ora a ;[MF]Remote command in progress?
- jnz ptchr0 ;[MF]Yes, don't check for file collisions
- lda flwflg ;[MF]Get File Warning (Set Collision) flag
- cpi 3 ;[MF]SET COLLISION DISCARD?
- jnz ptchr0 ;[MF]No
- lda dscflg ;[MF]Yes, get "discard" flag
- ora a ;[MF]Discarding file?
- jz ptchr0 ;[MF]No
- mvi a,'X' ;[MF]Yes, simulate a user rejection
- sta czseen ;[MF]...
- jmp rskp ;[MF]and pretend success
-ptchr0: ;[MF]
- lxi h,data ;Beginning of received packet data.
- shld outpnt ;Remember where we are.
- lda rquote
- mov b,a ;Keep the quote char in b.
- mvi c,0 ;[jd] assume no 8-bit quote char
- lda quot8 ;[jd] doing 8-bit quoting?
- ora a
- jz ptchr1 ;[jd] no, keep going
- lda qbchr ;[jd] else get 8-bit quote char
- mov c,a ;[jd] keep this in c
-ptchr1: lxi h,temp1
- dcr m ;Decrement # of chars in packet.
- jm rskp ;Return successfully if done.
- lda remtxt ; to screen only?
- ana a
- jnz ptchr2 ; dont do any disk stuff
- lxi h,chrcnt ;Number of chars remaining in dma.
- dcr m ;Decrement.
- jp ptchr2 ;Continue if space left.
- call outbuf ;Output it if full.
- jmp ptchr9 ; Error return if disk is full.
-ptchr2: lhld outpnt ;Get position in output buffer.
- mov a,m ;Grab a char.
- inx h
- shld outpnt ;and bump pointer.
- mvi e,0 ;[jd] assume nothing to OR in.
- cmp c ;[jd] is it the binary quote char?
- jnz ptch2a ;[jd] no, keep going
- mvi e,80h ;[jd] include parity bit
- lda temp1
- dcr a
- sta temp1 ;[jd] decrement character count
- mov a,m ;[jd] get next character
- inx h
- shld outpnt
-ptch2a: cmp b ;Is it the quote char?
- jnz ptchr3 ;[jd] changed to ptchr3 so includes parity
- mov a,m ;Get the quoted character
- inx h
- shld outpnt ;and bump pointer.
- lxi h,temp1
- dcr m ;Decrement # of chars in packet.
- mov d,a ;Save the char.
- ani 80H ;Turn off all but the parity bit.
- ora e ;[jd] let parity come from either (???)
- mov e,a ;Save the parity bit.
- mov a,d ;Get the char.
- ani 7FH ;Turn off the parity bit.
- cmp b ;Is it the quote char?
- jz ptchr3 ;If so just go write it out.
- cmp c ;[jd] maybe it's the 8-bit prefix character?
- jz ptchr3 ;[jd] then don't controllify.
- mov a,d ;Get the char.
- adi 40H ;Make the character a control char again.
- ani 7FH ;Modulo 128.
-ptchr3: ora e ;Or in the parity bit.
- sta temp3 ; save for a while
- lda remtxt ; to screen or disk?
- ana a
- lda temp3
- jz ptch31 ; to disk
- push h
- push d
- push b
- mov e,a ; to display
- mvi c,dconio
- call bdos
- pop b
- pop d
- pop h
- jmp ptchr1 ; continue
-
-ptch31: lhld bufpnt ;Destination buffer.
- mov m,a ;Store it.
- inx h
- shld bufpnt ;Update the pointer
- jmp ptchr1 ;and loop to next char.
-
-ptchr9: lxi d,erms11 ; "?Disk full"
- push d ;[MF] Save pointer
- call error3 ; put it on the error line
- pop d ;[MF] Restore pointer
- lxi h,data ;[MF] Where to put the message for "e" packet
- lda argblk ;[MF] Get packet-number
- call countp ;[MF]Increment it
- sta argblk ;[MF] as packet to send
- xra a ;[MF] Zero length of packet data
- sta temp1 ;[MF] ...
-ptch9a: ldax d ;[MF] Get a character to copy
- cpi cr ;[MF] No more to copy?
- jz ptch9b ;[MF] Yes, we can send the packet
- mov m,a ;[MF] No, copy the character
- inx d ;[MF] and increment source/dest pointers
- inx h ;[MF] ...
- lda temp1 ;[MF] Get character count
- inr a ;[MF] and increment it
- sta temp1 ;[MF] ...
- jmp ptch9a ;[MF] Copy entire error message
-ptch9b: mvi m,0 ;[MF]Put in a zero
- lda temp1 ;[MF] Get number of characters in the message
- sta argblk+1 ;[MF] and store as number of packet data chars
- mvi a,'E' ;[MF] Make it an error packet
- call spack ;[MF] Send the error packet
- nop ;[MF] Don't really care if
- nop ;[MF] the send fails since we're
- nop ;[MF] bombing off anyway
- ret ; take error return.
-;
-; Fill a data packet from file
-; called by: sfile, sdata
-
-gtchr: lda squote ;Get the quote char.
- mov c,a ;Keep quote char in c.
- lda curchk ;Get current block check type
- sui '1' ;Get the extra overhead
- mov b,a ;Get a copy
- lda spsiz ;Get the maximum packet size.
- sui 5 ;Subtract the overhead.
- sub b ;Determine max packet length
- sta temp1 ;This is the number of chars we are to get.
- lxi h,filbuf ;Where to put the data.
- shld cbfptr ;Remember where we are.
- mvi b,0 ;No chars.
-gtchr1: lda temp1
- dcr a ;Decrement the number of chars left.
- jp gtchr2 ;Go on if there is more than one left.
- mov a,b ;Return the count in A.
- jmp rskp
-
-gtchr2: sta temp1
- lda chrcnt ;Space left in the DMA.
- dcr a
-;* Can improve order here.
- jm gtchr3
- sta chrcnt
- jmp gtchr4
-
-gtchr3: call inbuf ;Get another buffer full.
- jmp gtch30 ; If no more return what we got.
- jmp gtchr4 ;If we got some, proceed.
-
-gtch30: mov a,b ;Return the count in A.
- ora a ;Get any chars?
- jnz rskp ;If so return them.
- jmp gtceof ;If not, say we found the end of the file.
-
-gtchr4: lhld bufpnt ;Position in DMA.
- mov a,m ;Get a char from the file.
- inx h
- shld bufpnt
- mov d,a ;Save the char.
- ani 80H ;Turn off all but parity.
- mov e,a ;Save the parity bit.
- jz gtch4a ;[jd] no parity, skip this check...
- lda quot8 ;[jd] doing eighth-bit quoting?
- ora a
- jz gtch4a ;[jd] no, just proceed normally
- lda temp1 ;[jd] get space remaining
- cpi 2 ;[jd] 3 chrs left (one cnted already)?
- jm gtchr9 ;[jd] no, skip this
- dcr a ;[jd] decrement space remaining
- sta temp1 ;[jd] put back.
- lhld cbfptr ;[jd] Position in character buffer.
- lda qbchr ;[jd] get quote character
- mov m,a ;]jd] Put the quote char in the buffer.
- inx h ;[jd] increment destination buffer pointer
- shld cbfptr ;[jd] store the pointer back
- inr b ;[jd] Increment the char count.
- mvi e,0 ;[jd] no parity bit to OR in.
-;[jd] fall thru...
-
-gtch4a: mov a,d ;Restore the char.
- ani 7FH ;Turn off the parity.
- mov d,a ;[jd] save here for later...
- cpi space ;Compare to a space.
- jm gtchr5 ;If less then its a control char, handle it.
- cpi del ;Is the char a delete?
- jz gtchr5 ;Go quote it.
- lda quot8 ; Are we doing 8th-bit quoting?
- ora a
- jz gtch4c ; if not, skip this test and restore character.
- lda qbchr ; get 8th-bit quote character
- cmp d ; same as current character?
- jz gtch4b ; yes, have to quote it...
-gtch4c: mov a,d ; no. get character back again.
- cmp c ;Is it the quote char?
- jnz gtchr8 ;If not proceed.
-gtch4b: lxi h,temp1 ;[jd] point to char count
- dcr m ;[jd] decrement (know room for at least one)
- lhld cbfptr ;Position in character buffer.
- mov m,c ;Put the (quote) char in the buffer.
- inx h
- shld cbfptr
- inr b ;Increment the char count.
- mov a,d ;[jd] restore character again
- jmp gtchr8
-
-gtchr5:
- ;[gnn] ignore parity for checking
-; ora e ;Turn on the parity bit.
-
- cpi ('Z'-100O) ;Is it a ^Z?
- jnz gtchr7 ;If not just proceed.
- lda cpmflg ;Was the file created by CPM...
- cpi 1 ;in ASCII-mode ?
- jz gtch52 ;Control-Z stops text
- cpi 2 ;in BINARY mode?
- jz gtchr6 ;Yes, pass the ^Z
-;At this point file-mode is DEFAULT.
-;If the rest of the record is filled with ^Zs, we're at EOF, otherwise
-;its a regular character.
- lhld bufpnt ;since CHRCNT is ZERO at EOF-time
- lda chrcnt ;(set by INBUF5 B.G.E)
- mov d,a ;Get the number of chars left in the DMA.
-gtch51: dcr d
- mov a,d
- jp gtch53 ;Any chars left?
-gtch52: xra a ;If not, get a zero.
- sta chrcnt ;Say no more chars in buffer.
- mov a,b ;Return the count in A.
- jmp rskp
-
-;Scan rest of buffer for non ^Z -- If we find a non ^Z, fall into gtchr6.
-;If we get to the end of the buffer before finding a non ^Z, fall into gtch52.
-gtch53: mov a,m ;Get the next char.
- inx h ;Move the pointer.
- cpi ('Z'-100O) ;Is it a ^Z?
- jz gtch51 ;If so see if the rest are.
-
-gtchr6: mvi a,('Z'-100O) ;Restore the ^Z.
-gtchr7: sta temp2 ;Save the char.
- lxi h,temp1 ;Point to the char total remaining.
- dcr m ;Decrement it.
- lhld cbfptr ;Position in character buffer.
- mov m,c ;Put the quote in the buffer.
- inx h
- shld cbfptr
- inr b ;Increment the char count.
- lda temp2 ;Get the control char back.
- adi 40H ;Make the non-control.
- ani 7fH ;Modulo 200 octal.
-gtchr8: lhld cbfptr ;Position in character buffer.
- ora e ;Or in the parity bit.
- mov m,a ;Put the char in the buffer.
- inx h
- shld cbfptr
- inr b ;Increment the char count.
- jmp gtchr1 ;Go around again.
-
-gtchr9: ;[jd] not enough room left in buffer...
- lhld bufpnt
- dcx h
- shld bufpnt ;[jd] back up over last character
- lxi h,chrcnt ;[jd] point to character count
- inr m ;[jd] increment it
- mov a,b ;[jd] count of chars transferred
- jmp rskp ;[jd] return it
-
-gtceof: mvi a,0FFH ;Get a minus one.
- ret
-;
-
-; Little code to allow some expansion of code without changing
-; every futher address, only up to the end of this file.
-; TO BE REMOVED FRO RELEASE!
-
-; org ($+100h) AND 0FF00H
-
-IF lasm
- LINK CPSPK2 ;[obs] Link to part two of the packet file
-ENDIF ;lasm
+; CPSPK1.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the (system-independent) routines that implement
+; the KERMIT protocol, and the commands that use them:
+; RECEIVE, SEND, FINISH, and LOGOUT.
+;
+; revision history:
+;
+;edit 23, 16-Jan-1991 by MF. The bug of (22) was not fixed (although
+; the error described needed to be corrected). Really fixed the bug this:
+; time. changed "lda 'E'" after "ptch9b" to "mvi a,'E'" -- Zilog
+; mnemonic thinking must've addled my brain!
+;edit 22, 14-Jan-1991 by MF. Fix bug in the code which sends an "E" packet
+; to the remote Kermit on encountering "disk full" so that
+; uncontrollified <CR><LF> is not copied to the packet data area (and
+; hence sent to the remote Kermit). This should fix a bug reported
+; by Russell Lang of Monash University in Australia wherein a PC
+; running Kermit in Server mode complained of invalid characters when
+; receiving the "disk full" error packet from CP/M Kermit.
+;edit 21 of 3-Jan-1991 by MF. Reverse part of edit 20 which flushes comm
+; input at EOF send: the problem of multiple copies of packets being
+; sent when a stream of files being sent is partially interrupted with
+; ^X has been fixed by modifying "inchr" in CPSPK2.ASM.
+;edit 20, 2-Jan-1991 by MF. Tightened up code just after "sdata1" and around
+; "sdat14". Added code to flush comm input after user has typed ^X
+; or ^Z to interrupt file sends so that duplicate packets are not
+; sent after the interrupt character (especially ^X) has been typed.
+;edit 19, 14-Dec-1990 by MF. Place "<<>>" around "F" and "X" packets coming
+; as replies to REMOTE commands a la VMS Bliss Kermit.
+; Also type each character of "X" or "F" packet explicitly in case
+; dollar-signs are part of the filename (as in VMS Bliss Kermit
+; when a REMOTE TYPE is given and SET FILE NAMING FULL is in effect).
+; Expanded code is at label rfil3f.
+;edit 18, 27-Nov-1990 by MF. Fix bug introduced with edit 17 which resulted
+; in "E" packet being sent twice when receiving file(s) and disk-full
+; occurred. Sorry about that, folks!
+;edit 17, 27-Nov-1990 by MF. When receiving files, make the decision as to
+; whether to delete a partially-received file on a "disk full"
+; condition subject to the setting of the SET INCOMPLETE-FILES
+; switch in conformity with the behavior of MSDOS Kermit.
+; An "E" packet is still sent to the remote Kermit. Also try to close
+; any incomplete file whether deleting it or not (labels rdat16 and
+; rdat3a). If keeping incomplete files, try to write outstanding
+; buffers to disk, giving an error if the disk is full.
+;edit 16, 23-Nov-1990 by MF. When receiving, cause the file being written
+; to disk to **always** be deleted and an "E" packet to be sent when a
+; "disk full" condition is encountered (per suggestion of
+; RJL@MONU1.CC.MONASH.EDU.AU).
+;edit 15, 15-Nov-1990 by MF. Changed code for the Receive Complete state
+; to always go into RECEIVE if AUTORECEIVE is on. This will happen
+; most of the time anyway as most mainframe Kermits issue a prompt
+; after a single SEND command (wild-carded or not), thus guaranteeing
+; that the modem status check of Kermit-80 ver. 4.09 would **always**
+; have characters ready for input (the mainframe Kermit's prompt),
+; defeating the status check and the Console input check (originally
+; intended to drop the user out of the loop if he/she typed a key with
+; no comm input present). Eliminate "any key" message there also.
+; the user can drop out by hitting ^C.
+; Of course, none of the foregoing applies if the Receive Complete
+; state occurs as the result of a "Get" command where Autoreceive
+; is meaningless and we just drop back to Kermit command-level.
+;edit 14, 1-Oct-1990 by MF. Added code to send an "I" packet before an
+; "R" packet in GET command.
+; Modified routine "sinit" to ignore "E" packets when sending an
+; "i" packet (per KPROTO.DOC).
+;edit 13, 14-Sep-1990 by MF. Added code to implement SET FILE COLLISION
+; and SET INCOMPLETE commands.
+;edit 12, 9-Sep-1990 by MF. Added code to prevent packet counts
+; from being displayed during Remote commands. Fixed
+; AUTORECEIVE code, file colision Rename algorithm and eliminated
+; multiple display of initial messages during GET/RECEIVE.
+; edit 11, 28 July, 1987 by OBSchou. Commented out capas etc support
+; (Long packets etc) as this is not worth the effort coding... but
+; I have left what WAS done for any enthusiast. Also set in a few
+; to NOT write to screen if SET TERMINAL QUIET set. Hopefully speeds
+; up transfers on systems taking forever to update screens.
+;
+; edit 10, 8 April, 1987 by OBSchou. Tarted up all sorts of bits n bobs
+; to cope with all the new aditions for Kermit-80 V 4.09
+; Look for the [10] for most cahnges. spar and rpar largely replaced
+;
+; edit 9, March 30th by OBSchou. Set bits for automatically receiving
+; another file if a remote sender sends files in seperate sessions.
+; The code simply checks the serial line, and if there is some
+; activity, assume its another SEND INIT packet. As there is no
+; simple way to go to receive with the control-a, just ignore the
+; packet. Causes one retry on the sender, but so what. Really
+; should make it a server gizzmo.
+;
+; edit 8: January 28, 1987 by OBSchou
+; Two major issues: firstly split CPSPKT.ASM into CPSPK(1 2).ASM
+; making it far easier to handle this file.
+; Second, some mode to the GET routines to correctly print the file
+; name instead of the fireworks. Trouble was with GET <file> <file>
+; and RECEIVE <file>. However, new bugs discovered...
+;
+; edit 7: August 11, 1986 Godfrey N. Nix [gnn] Nottingham University
+; To ignore echoed packets (ie send 'S' receive 'S' before 'A');
+; To allow character other than SOH for packet header (see also
+; updates to CP4MIT and CP4UTL for other code needed);
+; To permit SEND and RECEIVE to specify a host filename which
+; is of a different structure to that of CP/M.
+;
+; edit 6a: [OBSchou] 7 March, 1985.
+; Edited file with additions from MJ Carter. He writes:
+; 25th September 1985, M J Carter [majoc], Nottingham University
+; Code in gofil() amended, for exactly the same reasons to the
+; alteration to cmifil() in cpscmd.asm. If there is any deep
+; reason why gofil() has to be used instead of a call to comnd(cmofil),
+; I can't see it. The bug (on a British Micro Mimi 803) caused
+; gofil() to overwrite existing files in GET and RECEIVE, even
+; with file warning SET ON.
+;
+;edir 6: November 22, 1984
+; Change SEND's 'Unable to find file' error exit from calling
+; error3 to calling prtstr instead. I don't know about you, but
+; I greatly dislike having messages dumped into pre-existing
+; junk on the screen where I have to spend lots of time hunting
+; for them. [Hal Hostetler]
+;
+; edit 5: September 9, 1984
+; Call flsmdm in init to flush old input when starting transfers.
+; Select console before returning from inpkt.
+; Replace inline code with calls to makfil/clofil to set up for
+; multisector buffering on output.
+; Remove superfluous call to clrlin in error3.
+;
+; edit 4: August 21, 1984 (CJC)
+; Fix comment in inpkt: packet is terminated by NUL on return, not CR.
+; If debugging, display the outgoing packet before putting the EOL
+; character on, so the dumped packet doesn't get overwritten.
+;
+; edit 3: July 27, 1984
+; add link directive for LASM. CP4PKT is linked by CP4MIT, and links
+; to CP4TT. Add Toad Hall TACtrap to permit operations through a TAC.
+;
+; edit 2: June 8, 1984
+; formatting and documentation; remove some unused labels; move setpar
+; to cp4mit.m80; add module version string; make all arithmetic on
+; 'pktnum' modulo 64; apply defaults correctly for missing parameters
+; in send-init packet (and corresponding ack).
+;
+; edit 1: May, 1984
+; extracted from CPMBASE.M80 version 3.9; modifications are described
+; in the accompanying .UPD file.
+;
+pk1ver: db 'CPSPK1.ASM (23) 16-Jan-1991$' ; name, edit number, date
+
+; GET command [gnn]
+; here from: kermit
+
+read: mvi a,0ffh ;[obs 8] we are doing a get
+ sta getrxflg ;[obs 8] so set flag
+ lxi d,remdat ;Where to put the text (if any.)
+ mvi a,cmtxt
+ call comnd ;Get either some text or a confirm.
+ jmp kermt3 ; Didn't get anything.
+ ora a ;Get any chars?
+ jz kermt3 ;[gnn] GET must have a filename
+ sta rdl ;Store the number of chars.
+ xchg ;Get pointer into HL.
+ mvi m,'$' ;Put in a dollar sign for printing.
+ call init ;Clear the line and initialize the buffers.
+ lda quietd ; quiet display?
+ ana a
+ jz read01 ;[MF]No, go ahead and position cursor
+ call prcrlf ;[MF]Yes, keep from overwriting the prompt
+ jmp read00 ;[MF]and write filename
+read01: call scrfln ;Position cursor [MF]
+read00: lxi d,remdat ;Print the file name, in either case
+ call prtstr
+ jmp read0a ;[gnn] go get local name if any
+
+
+; enter here for RECEIVE command [gnn]
+read0: mvi a,0 ;[gnn]
+ sta rdl ;[gnn][MF] flag entry as receive, not get
+ sta getrxflg ;[obs 8] doing a receive, so reset flag
+ call init ;clear line, initialise buffers
+read0a: lxi d,remnam ;[gnn] save local name here
+ mvi a,cmtxt ;[gnn]
+ call comnd ;[gnn] read second filename if present
+ jmp kermt3 ;[gnn] error exit
+ sta remlen ;[gnn] save length of name, may be zero
+ sta getrxflg ;[obs 8] May also be receive <fnam> so
+ ;[obs 8]pretend get for printing filename
+ lda rdl ;[gnn] look at first name
+ ora a ;[gnn] receive or get?
+ jz read1 ;[gnn] receive
+
+ mvi a,'I' ;[MF]Set state to send "I" packet
+ sta state ;[MF]...
+
+; jmp read12 ;[obs] [gnn] does not want this
+
+read1: ;call init ;Clear the line and initialize the buffers.
+read12: xra a
+ sta czseen ;Clear the ^X/^Z flag initially.
+ lxi h,0
+ shld numpkt ;Set the number of packets to zero.
+ shld numrtr ;Set the number of retries to zero.
+ sta pktnum ;Set the packet number to zero.
+ sta numtry ;Set the number of tries to zero.
+ lda quietd ; quiet display?
+ ana a
+ jnz read13 ; yes, so dont write...
+ call scrnrt ;Position cursor
+ lxi h,0
+ call nout ;Write the number of retries.
+read13: lda rdl ;[MF]Get or receive?
+ ora a ;[MF]...
+ jnz read2 ;[MF]Get, don't reset state
+ mvi a,'R'
+ sta state ;Set the state to receive initiate.
+ ;...
+;
+;RECEIVE state table switcher.
+
+read2: lda quietd ; noisy display?
+ ana a
+ jnz read21 ; no, a quiet one
+ lda remtxt ;[MF] In Remote command?
+ ora a
+ jnz read21 ;[MF] Yes, don't write to screen
+ call scrnp ;Position cursor
+ lhld numpkt
+ call nout ;Write the current packet number.
+read21: lda state ;Get the state.
+ cpi 'D' ;Are we in the DATA receive state?
+ jnz read22
+ call rdata
+ jmp read2
+
+read22: cpi 'X' ; F packet but not an F packet?
+ jnz read3 ; nope, so try next one
+ call rfile ; 'get' the filename (but dont open it)
+ jmp read2
+
+read3: cpi 'F' ;Are we in the FILE receive state?
+ jnz read4
+ call rfile ;Call receive file.
+ jmp read2
+
+read4: cpi 'R' ;Are we in the Receive-Initiate state?
+ jnz read5
+ call rinit
+ lda state ;[jd] get new state
+ cpi 'F' ;[jd] went into receive state?
+ jnz read2 ;[jd] no
+ lxi d,inms24 ;[jd] yes, get receiving... message
+ call finmes ;[jd] go print it
+ jmp read2
+
+read5: cpi 'C' ;Are we in the Receive-Complete state?
+ jnz read6
+ lxi d,infms3 ;Put in "Complete" message.
+ lda czseen ;Or was it interrupted?
+ ora a ; . . .
+ jz read5a ;No.
+ xra a ;Yes, clear flag.
+ sta czseen ; ...
+ lxi d,inms13 ;Issue "interrupted" message.
+read5a: lda remtxt ;[MF] Doing a Remote command?
+ ora a
+ cz finmes ;Print completion message in right place if not
+;
+ lda rdl ;[MF]Receive or Get?
+ ora a ;[MF]...
+ jnz kermit ;[MF]Get, Autoreceive means nothing.
+ lda autorc ; see if we want autoreceives
+ ana a
+ jz kermit ;[MF]No autoreceives, so drop out
+ lxi d,autmes ;[MF]Yes, tell the user what we're doing
+ call prtstr ;[MF]...
+ jmp read1 ;[MF]Try another Receive (we get one
+ ;[MF]retry from the sender as the ^A is lost)
+
+read6: cpi 'Y' ;[MF]Simple ack (from remote command)?
+ jz kermit ;[MF]Yes
+
+ cpi 'I' ;[MF]Exchanging parameters via info packet?
+ jnz read7 ;[MF]No
+ call sinit ;[MF]Yes, send the packet
+ lda state ;[MF]Now see what happened
+ cpi 'X' ;[MF]Did we exchange parameters successfully?
+ jz read6a ;[MF]Yes, go send the filespec
+ cpi 'A' ;[MF]No, are we in abort state?
+ jnz read2 ;[MF]No, try again
+ jmp kermit ;[MF]Yes, it's a real disaster, we must stop
+read6a: lda rdl ;[MF]Get length of filespec
+ sta argblk+1 ;[MF]as length of packet
+ mov c,a ;[MF]We must copy the filespec
+ mvi b,0 ;[MF]...
+ lxi h,remdat ;[MF]from the temporary buffer
+ lxi d,data ;[MF]to the packet data area
+ call mover ;[MF]Do it.
+; for GET we must send the name of the file we want [gnn]
+
+ mvi a,'1' ;Start with single character checksum
+ sta curchk ;Save the type
+ xra a ;Start a packet zero.
+ sta argblk
+ mvi a,'R' ;Receive init packet.
+ call spack ;Send the packet.
+ jmp kermt3 ; Die!
+ xra a
+ sta czseen ;Clear the ^X/^Z flag initially.
+ lxi h,0
+ shld numpkt ;Set the number of packets to zero.
+ sta pktnum ;Set the packet number to zero.
+ sta numtry ;Set the number of tries to zero.
+ mvi a,'R' ;[MF]Set state to Receive-Initiate
+ sta state ;[MF]...
+ jmp read21 ;[MF]and go around again
+ ;[MF]without retyping packet-number
+
+read7: cpi 'A' ;Are we in the Receive-"Abort" state?
+ jnz read8
+read8: lxi d,infms4 ;Anything else is equivalent to "abort".
+ call finmes
+ jmp kermit
+;
+; Receive routines
+
+; Receive init
+; called by: read
+
+rinit: lda numtry ;Get the number of tries.
+ cpi imxtry ;Have we reached the maximum number of tries?
+ jm rinit2
+ lxi d,ermes4
+ call error3 ;Move cursor and print an error message.
+ jmp abort ;Change the state to abort.
+
+rinit2: inr a ;Increment it.
+ sta numtry ;Save the updated number of tries.
+ mvi a,'1' ;Reset block check type to single character
+ sta curchk ;Store as current type for initialization
+ call rpack ;Get a packet.
+ jmp nak ; Trashed packet: nak, retry.
+ cpi 'S' ;Is it a send initiate packet?
+ jnz rinit3 ;If not see if its an error.
+rini2a: lda numtry ;Get the number of tries.
+ sta oldtry ;Save it.
+ xra a
+ sta numtry ;Reset the number of tries.
+ lda argblk ;Returned packet number. (Synchronize them.)
+ call countp
+ lda argblk+1 ;Get the number of arguments received.
+ lxi h,data ;Get a pointer to the data.
+ call spar ;Get the data into the proper variables.
+ lxi h,data ;Get a pointer to our data block.
+ call rpar ;Set up the receive parameters.
+ sta argblk+1 ;Store the returned number of arguments.
+ mvi a,'Y' ;Acknowledge packet.
+ call spack ;Send the packet.
+ jmp abort ; Failed, abort.
+ lda inichk ;Now switch to agreed upon check-type
+ sta curchk ;For all future packets
+ mvi a,'F' ;Set the state to file send.
+ sta state
+ ret
+
+rinit3: cpi 'E' ;Is it an error packet.
+ jnz nak0 ;If not NAK whatever it is.
+ call error
+ jmp abort
+;
+; Receive file
+; called by: read
+
+rfile: lda numtry ;Get the number of tries.
+ cpi maxtry ;Have we reached the maximum number of tries?
+ jm rfile1
+ lxi d,ermes5
+ call error3 ;Move cursor and print an error message.
+ jmp abort ;Change the state to abort.
+
+rfile1: inr a ;Increment it.
+ sta numtry ;Save the updated number of tries.
+ call rpack ;Get a packet.
+ jmp nak ; Trashed packet: nak, retry.
+ cpi 'S' ;Is it a send initiate packet?
+ jnz rfile2 ; No, try next type.
+ lda oldtry ;Get the number of tries.
+ cpi imxtry ;Have we reached the maximum number of tries?
+ jm rfil12 ;If not proceed.
+ lxi d,ermes4
+ call error3 ;Move cursor and print an error message.
+ jmp abort ;Change the state to abort.
+
+rfil12: inr a ;Increment it.
+ sta oldtry ;Save the updated number of tries.
+ lda pktnum ;Get the present packet number.
+ dcr a ;Decrement
+ ani 3FH ; modulo 64
+ mov b,a
+ lda argblk ;Get the packet's number
+ cmp b ;Is the packet's number one less than now?
+ jnz nak0 ;No, NAK and try again.
+ call updrtr ;Update the retry count.
+ xra a
+ sta numtry ;Reset the number of tries.
+ lxi h,data ;Get a pointer to our data block.
+ call rpar ;Set up the parameter information.
+ sta argblk+1 ;Save the number of arguments.
+ mvi a,'Y' ;Acknowledge packet.
+ call spack ;Send the packet.
+ jmp abort ; Failed, abort.
+ ret
+
+rfile2: cpi 'Z' ;Is it an EOF packet?
+ jnz rfile3 ; No, try next type.
+ lda oldtry ;Get the number of tries.
+ cpi maxtry ;Have we reached the maximum number of tries?
+ jm rfil21 ;If not proceed.
+ lxi d,ermes6
+ call error3 ;Move cursor and print an error message.
+ jmp abort ;Change the state to abort.
+
+rfil21: call tryagn
+ ret
+
+rfile3: cpi 'F' ;Start of file?
+ jnz rfil3b
+ mov c,a ;[MF]Save packet type
+ lda remtxt ;[MF]Doing a remote server command?
+ ora a ;[MF]...
+ mov a,c ;[MF]Restore packet type
+ jnz rfil3d ;[MF]If yes, same as x packet
+ call compp
+ jnz nak0 ;No, NAK it and try again.
+ call countp
+ mov c,a ;[MF]
+ lda remtxt ;[MF]Doing a remote command?
+ ora a ;[MF]...
+ mov a,c ;[MF]
+ jnz rfil3a ;[MF]Yes, don't open a file
+ call gofil ;Get a file to write to, and init output buffer.
+ jmp abort
+rfil3a: lda numtry ;Get the number of tries.
+ sta oldtry ;Save it.
+ call ackp
+ mvi a,'D' ;Set the state to data receive.
+ sta state
+ lda czseen ;Check if we punted a file
+ cpi 'Z' ;and didn't want any more
+ rz ;If that was the request, keep telling other end
+ xra a ;Otherwise, clear flag (^X is only for one file)
+ sta czseen ;And store the flag back
+ ret
+
+rfil3b: cpi 'X' ;Start of 'file?' , but not a file?
+ jnz rfile4
+rfil3d: call compp
+ jnz nak0 ;No, NAK it and try again.
+ call countp
+
+ call selcon ;[MF]Select Console
+ lda argblk+1 ; get length
+ ora a ;[MF]Anything to write?
+ jz rfil3e ;[MF]No
+ push psw ;[MF]Yes, save character count
+ mvi e,'<' ;[MF]Write "<<" as in VMSKermit
+ push d ;[MF]...
+ call outcon ;[MF]...
+ pop d ;[MF]...
+ call outcon ;[MF]...
+ pop psw ;[MF]Restore character count
+ lxi h,data ; lets write the filename (?) to display
+rfil3f: push psw ;[MF]Save loop counter
+ mov e,m ;[MF]Get character to write
+ inx h ;[MF]and increment character pointer
+ push h ;[MF]Save the pointer
+ call outcon ;[MF]Write character to display
+ pop h ;[MF]Restore pointer
+ pop psw ;[MF]and loop counter
+ dcr a ;[MF]Decrement the counter
+ jnz rfil3f ;[MF]Display entire filename
+ mvi e,'>' ;[MF]Put in ">>" as in VMSKermit
+ push d ;[MF]...
+ call outcon ;[MF]...
+ pop d ;[MF]...
+ call outcon ;[MF]...
+ call prcrlf ;[MF]New line
+rfil3e: lda numtry ;Get the number of tries.
+ sta oldtry ;Save it.
+ call ackp
+ mvi a,'D' ; expecting a D packet
+ sta state
+ lda czseen ;Check if we punted a file
+ cpi 'Z' ;and didn't want any more
+ rz ;If that was the request, keep telling other end
+ xra a ;Otherwise, clear flag (^X is only for one file)
+ sta czseen ;And store the flag back
+ ret
+
+rfile4: cpi 'B' ;End of transmission.
+ jnz rfile5
+ call compp
+ jnz nak0 ;No, NAK it and try again.
+ xra a ;No data. (Packet number already in argblk).
+ sta argblk+1
+ mvi a,'Y' ;Acknowledge packet.
+ call spack ;Send the packet.
+ jmp abort
+ mvi a,'C' ;Set the state to complete.
+ sta state
+ ret
+
+rfile5: cpi 'E' ;Is it an error packet.
+ jnz abort
+ call error
+ jmp abort
+;
+; Receive data
+; called by: read
+
+rdata: lda numtry ;Get the number of tries.
+ cpi maxtry ;Have we reached the maximum number of tries?
+ jm rdata1
+ lxi d,erms10
+ call error3 ;Display error message.
+rdat16: lda remtxt ;[MF]Is a Remote command in progress?
+ ora a ;[MF]...
+ jnz abort ;[MF]Yes, don't worry about file disposition
+ lda incflg ;[MF]Are we keeping incomplete files?
+ ora a ;[MF]...
+ jnz rdat17 ;[MF]Yes
+ lxi d,fcb ;[MF]No, close the file, ignoring errors
+ push d ;[MF]while protecting the pointer
+ mvi c,closf ;[MF]...
+ call bdos ;[MF]...
+ pop d ;[MF]Now delete the file, ignoring errors
+ mvi c,delf ;[MF]...
+ call bdos ;[MF]...
+ jmp abort ;Change the state to abort.
+rdat17: call clofil ;[MF]Try to close the file, writing
+ ;[MF]outstanding buffers to disk
+ jmp rdat37 ;[MF]We can't, the disk is full
+ jmp abort ;[MF]Change the state to "abort"
+
+rdata1: inr a ;Increment it.
+ sta numtry ;Save the updated number of tries.
+ call rpack ;Get a packet.
+ jmp nak ; Trashed packet: nak, retry.
+ cpi 'D' ;Is it a data packet?
+ jnz rdata2 ; No, try next type.
+ call compp ;check for correct packet number (zero flag = ok)
+ jz rdat14 ;its correct
+ lda oldtry ;Get the number of tries.
+ cpi maxtry ;Have we reached the maximum number of tries?
+ jm rdat12 ;If not proceed.
+ lxi d,erms10
+ call error3 ;Display err msg.
+ jmp rdat16 ;[MF]Change the state to abort.
+
+rdat12: call tryagn
+ ret
+
+rdat14: call countp
+ lda numtry ;Get the number of tries.
+ sta oldtry ;Save it.
+ lda argblk+1 ;Get the length of the data.
+ call ptchr
+ jmp rdat3b ;[MF] Unable to write out chars;abort.
+ xra a
+ sta numtry ;Reset the number of tries.
+ sta argblk+1 ;No data. (Packet number still in argblk.)
+ mov c,a ;Assume no data
+ lda czseen ;Check if control-X typed
+ ora a ; . . .
+ jz rdat15 ;Zero if not typed
+ mov c,a ;Get the type of character typed
+ mvi a,1 ;One data character
+ sta argblk+1 ;Save the count
+ mov a,c ;Get the possible data character
+ sta data ;Store in data area
+rdat15: mvi a,'Y' ;Acknowledge packet.
+ call spack ;Send the packet.
+ jmp rdat16 ;[MF]
+ ret
+
+rdata2: cpi 'F' ;Start of file?
+ jnz rdata3 ; No, try next type.
+ lda oldtry ;Get the number of tries.
+ cpi maxtry ;Have we reached the maximum number of tries?
+ jm rdat21 ;If not proceed.
+ lxi d,ermes5
+ call error3 ;Display err msg.
+ jmp rdat16 ;[MF]Change the state to abort.
+
+rdat21: call tryagn
+ ret
+
+rdata3: cpi 'Z' ;Is it a EOF packet?
+ jnz rdata4 ;Try and see if its an error.
+ call compp
+ jnz nak0 ;No, NAK it and try again.
+ call countp
+ lda argblk+1 ;Get the data length
+ cpi 1 ;Have one item?
+ jnz rdat33 ;If not, ignore data
+ lda data ;Yes, get the character
+ cpi 'D' ;Is it a 'D' for discard?
+ jz rdat36 ;If so, punt file
+rdat33: lda remtxt ;[MF]Writing text to disk?
+ ora a ;[MF]...
+ jnz rdat38 ;[MF]No, don't close file
+ call clofil ;Finish off the file.
+ jmp rdat37 ; Give up if the disk is full.
+rdat38: xra a ;Since we kept the file,
+ sta czseen ;don't say it was discarded.
+ lda numtry ;Get the number of tries. [MF]
+ sta oldtry ;Save it. [MF]
+ call ackp ;[MF]
+ jmp rdat39 ;[MF]and get ready to get more files
+rdat36: lda numtry ;Get the number of tries.
+ sta oldtry ;Save it.
+ call ackp
+ lda remtxt ;[MF]Is a Remote command in progress?
+ ora a ;[MF]...
+ jnz rdat39 ;[MF]Yes, don't worry about file disposition
+ lda dscflg ;[MF]Is the file being punted because
+ ora a ;[MF]of a collision?
+ jnz rdat39 ;[MF]Yes, don't delete the existing file
+ lda incflg ;[MF]No, are we keeping incomplete files?
+ ora a ;[MF]...
+ jnz rdat3a ;[MF]Yes
+ lxi d,fcb ;[MF]No, close the file,
+ mvi c,closf ;[MF]ignoring errors
+ push d ;[MF]...
+ call bdos ;[MF]...
+ pop d ;[MF]Now delete the file,
+ mvi c,delf ;[MF]ignoring errors
+ call bdos ;[MF]...
+ jmp rdat39 ;[MF]and continue
+rdat3a: call clofil ;[MF]Try to close the file, writing
+ ;[MF]outstanding buffers to disk
+ jmp rdat37 ;[MF]Can't, disk is full
+rdat39: mvi a,'F'
+ sta state
+ ret
+
+rdat37: call ptchr9 ; Send "?Disk full" on the error line [MF]
+ ; and to the remote Kermit [MF]
+rdat3b: lda remtxt ;[MF]Doing a Remote command?
+ ora a ;[MF]...
+ jnz abort ;[MF]Yes, just abort
+ lxi d,fcb ;[MF]Close the file, ignoring errors
+ push d ;[MF]Protect fcb pointer
+ mvi c,closf ;[MF]...
+ call bdos ;[MF]...
+ pop d ;[MF]Restore pointer
+ lda incflg ;[MF]Are we keeping incomplete files?
+ ora a ;[MF]...
+ jnz abort ;[MF]Yes, just abort transfer
+ mvi c,delf ;[MF]No, delete the file, ignoring errors
+ call bdos ;[MF]...
+ jmp abort ;[MF] abort transfer
+
+rdata4: cpi 'E' ;Is it an error packet.
+ jnz rdat16 ;[MF]
+ call error
+ jmp rdat16 ;[MF]
+;
+; SEND command
+; here from: kermit
+
+send: mvi a,cmifi ;Parse an input file spec.
+ lxi d,fcb ;Give the address for the FCB.
+ call comnd
+ jmp kermit ; Give up on bad parse.
+; section to get remote filename [gnn]
+ lxi d,remnam ;[gnn] where to put filename
+ mvi a,cmtxt ;[gnn]
+ call comnd ;[gnn] get the text to end of the line
+ jmp kermt3 ;[gnn] failure in reading buffer
+ sta remlen ;[gnn] save length (may be zero)
+;
+ xra a
+ sta mfflg1 ; clear flags...
+ sta mfflg2
+ sta mfflg3 ;[gnn]
+ sta fcbcnt ;[gnn] clear fcbcount
+ lxi h,fcb0 ;[gnn] and fcb pointer
+ shld xfcbptr
+;
+ call mfname ;handle (multi) files
+ jnc send14 ;got a valid file-name
+ lxi d,erms15
+ call prtstr ;Display error msg. ([hh] where it's visible)
+ jmp kermit
+
+send14: call init ;Clear the line and initialize the buffers.
+ xra a
+ sta pktnum ;Set the packet number to zero.
+ sta numtry ;Set the number of tries to zero.
+ sta wrn8 ;[jd] we haven't sent the 8-bit-lost warning
+ lxi h,0
+ shld numpkt ;Set the number of packets to zero.
+ shld numrtr ;Set the number of retries to zero.
+ lda quietd ; a quiet display?
+ ana a
+ jnz send15 ; yup, dont write
+ call scrnrt ;Position cursor
+ lxi h,0
+ call nout ;Write the number of retries.
+send15: mvi a,'1' ;Reset to use single character checksum
+ sta curchk ;For startup
+ mvi a,'S'
+ sta state ;Set the state to receive initiate.
+ ;...
+;
+;SEND state table switcher
+
+send2: lda quietd ; a quiet display?
+ ana a
+ jnz send21 ; yes, so dont write
+ call scrnp ;Position cursor
+ lhld numpkt
+ call nout ;Write the packet number.
+send21: lda state ;Get the state.
+ cpi 'D' ;Are we in the data send state?
+ jnz send3
+ call sdata
+ jmp send2
+
+send3: cpi 'F' ;Are we in the file send state?
+ jnz send4
+ call sfile ;Call send file.
+ jmp send2
+
+send4: cpi 'Z' ;Are we in the EOF state?
+ jnz send5
+ call seof
+ jmp send2
+
+send5: cpi 'S' ;Are we in the send initiate state?
+ jnz send6
+ call sinit
+ lda state ;[jd] get state back
+ cpi 'F' ;[jd] into file send state yet?
+ jnz send2 ;[jd] no
+ lxi d,inms23 ;[jd] yes, print sending...
+ call finmes ;[jd]
+ jmp send2
+
+send6: cpi 'B' ;Are we in the eot state?
+ jnz send7
+ call seot
+ jmp send2
+
+send7: cpi 'C' ;Are we in the send complete state?
+ jnz send8 ;No...
+ lxi d,infms3 ;Yes, write "Complete" message.
+ lda czseen ;Or was it interrupted?
+ ora a ; . . .
+ jz send7a ;No.
+ lxi d,inms13 ;Yes, then say "Interrupted" instead.
+send7a: call finmes
+ jmp kermit
+
+send8: cpi 'A' ;Are we in the send "abort" state?
+ jnz send9
+ lxi d,infms4 ;Print message.
+ call finmes
+ jmp kermit
+
+send9: lxi d,infms4 ;Anything else is equivalent to "abort".
+ call finmes
+ jmp kermit
+;
+; Send routines
+
+; Send initiate
+; called by: send
+
+sinit: lda numtry ;Get the number of tries.
+ cpi imxtry ;Have we reached the maximum number of tries?
+ jm sinit2
+ lxi d,erms14
+ call error3 ;Display ermsg
+ jmp abort ;Change the state to abort.
+
+sinit2: inr a ;Increment it.
+ sta numtry ;Save the updated number of tries.
+ mvi a,'1' ;Reset to use single character checksum
+ sta curchk ;For startup
+ lda chktyp ;Get our desired block check type
+ sta inichk ;Store so we tell other end
+ lxi h,data ;Get a pointer to our data block.
+ call rpar ;Set up the parameter information.
+ sta argblk+1 ;Save the number of arguments.
+ lda numpkt ;Get the packet number.
+ sta argblk
+ lda state ; load state (I or S)
+
+ call spack ;Send the packet.
+ jmp abort ; Failed, abort.
+ call rpack ;Get a packet.
+ jmp r ; Trashed packet don't change state, retry.
+ cpi 'Y' ;ACK?
+ jnz sinit3 ;If not try next.
+ call compp ;compare packets. If ok, zero flag set
+ rnz ;If not try again.
+ call countp ;increment packet number modulo 64
+ lda argblk+1 ;Get the number of pieces of data.
+ lxi h,data ;Pointer to the data.
+ call spar ;Read in the data. (decode what they want)
+ lda numtry ;Get the number of tries.
+ sta oldtry ;Save it.
+ xra a
+ sta numtry ;Reset the number of tries.
+ lda state ; se if S or I state
+ cpi 'I' ; I state, so set X as next state
+ jnz sinita
+sinitb: mvi a,'X'
+ sta state
+ ret
+
+sinita: lda inichk ;Get the agreed upon block check type
+ sta curchk ;Store as type to use for packets now
+ mvi a,'F' ;Set the state to file send. (Assumed)
+ sta state
+ call getfil ;Open the file.
+ ret ; assume success; mfname thinks the file exists.
+
+sinit3: cpi 'N' ;NAK?
+ jnz sinit4 ;If not see if its an error.
+ call updrtr ;Update the number of retries.
+ lda pktnum ;Get the present packet number.
+ inr a ;Increment
+ ani 3FH ; modulo 64
+ mov b,a
+ lda argblk ;Get the packet's number.
+ cmp b ;Is the packet's number one more than now?
+ rnz ;If not assume its for this packet, go again.
+ xra a
+ sta numtry ;Reset number of tries.
+ mvi a,'F' ;Set the state to file send.
+ sta state
+ ret
+
+sinit4: cpi 'E' ;Is it an error packet.
+ jnz abort
+ lda state ;[MF]Get state
+ cpi 'I' ;[MF]If an "I" packet was sent,
+ jz sinitb ;[MF]Ignore the error, pretend success
+ call error ;[MF]else display the error info
+ jmp abort ;[MF]and abort
+;
+; Send file header
+; called by: send
+;[5a] Question [majoc]: Why could not the filename
+; parsing have been done by comnd, like all the rest?
+
+sfile: lda numtry ;Get the number of tries.
+ cpi maxtry ;Have we reached the maximum number of tries?
+ jm sfile1
+ lxi d,erms14
+ call error3
+ jmp abort ;Change the state to abort.
+
+sfile1: inr a ;Increment it.
+ sta numtry ;Save the updated number of tries.
+ xra a ;Clear A
+ sta czseen ;No control-Z or X seen
+ lxi h,data ;Get a pointer to our data block.
+ shld datptr ;Save it.
+; use remote name if given, else use local name [gnn]
+ lda remlen ;[gnn] anything given?
+ ora a ;[gnn]
+ jnz sfile4 ;[gnn] use remote name
+
+ lxi h,fcb+1 ;Pointer to the file name in the FCB.
+ shld fcbptr ;Save position in FCB.
+ mvi b,0 ;No chars yet.
+ mvi c,0
+sfil11: mov a,b
+ cpi 8H ;Is this the ninth char?
+ jnz sfil12 ;If not proceed.
+ mvi a,'.' ;Get a dot.
+ lhld datptr
+ mov m,a ;Put the char in the data packet.
+ inx h
+ shld datptr ;Save position in data packet.
+ inr c
+sfil12: inr b ;Increment the count.
+ mov a,b
+ cpi 0CH ;Twelve?
+ jp sfil13
+ lhld fcbptr
+ mov a,m
+ ani 7fH ;Turn off CP/M 2 or 3's high bits.
+ inx h
+ shld fcbptr ;Save position in FCB.
+ cpi '!' ;Is it a good character?
+ jm sfil11 ;If not get the next.
+ lhld datptr
+ mov m,a ;Put the char in the data packet.
+ inx h
+ shld datptr ;Save position in data packet.
+ inr c
+ jmp sfil11 ;Get another.
+
+sfil13: mov a,c ;Number of char in file name.
+ sta argblk+1
+ lhld datptr
+ mvi a,'$'
+ mov m,a ;Put in a dollar sign for printing.
+ lda quietd ; a quiet display
+ ana a
+ jnz sfi13a ; yes, dont write
+ call scrfln ;Position cursor
+sfi13a: lxi d,data ;Print the file name though, in either case
+ call prtstr
+ lda pktnum ;Get the packet number.
+ sta argblk
+ mvi a,'F' ;File header packet.
+ call spack ;Send the packet.
+ jmp abort ; Failed, abort.
+ call rpack ;Get a packet.
+ jmp r ; Trashed packet don't change state, retry.
+ cpi 'Y' ;ACK?
+ jnz sfile2 ;If not try next.
+ call compp
+ rnz ;If not hold out for the right one.
+sfil14: call countp
+ lda numtry ;Get the number of tries.
+ sta oldtry ;Save it.
+ xra a
+ sta numtry ;Reset the number of tries.
+ sta bytes ;[10] clear the "bytes transferred" counter
+ sta bytes+1 ;[10]
+ sta bytes+2 ;[10]
+ sta bytes+3 ;[10]
+ call gtchr ;Fill the first data packet
+ jmp sfil16 ;Error go see if its EOF.
+; ;Got the chars, proceed.
+ sta size ;Save the size of the data gotten.
+ mvi a,'D' ;Set the state to data send.
+ sta state
+ ret
+
+sfil16: cpi 0FFH ;Is it EOF?
+ jnz abort ;If not give up.
+ mvi a,'Z' ;Set the state to EOF.
+ sta state
+ ret
+
+sfile2: cpi 'N' ;NAK?
+ jnz sfile3 ;Try if error packet.
+ call updrtr ;Update the number of retries.
+ lda pktnum ;Get the present packet number.
+ inr a ;Increment
+ ani 3FH ; modulo 64
+ mov b,a
+ lda argblk ;Get the packet's number.
+ cmp b ;Is the packet's number one more than now?
+ rnz ;If not go try again.
+ jmp sfil14 ;Just as good as a ACK;go to the ACK code.
+
+sfile3: cpi 'E' ;Is it an error packet.
+ jnz abort
+ call error
+ jmp abort
+
+; copy remote name into packet to send [gnn]
+sfile4: xchg ;[gnn] keep pointer to packet
+ lxi h,remnam ;[gnn] set pointer to name
+ mov c,a ;[gnn] keep count of length
+ mov b,a ;[gnn] and set as loop counter
+sfil41: mov a,m ;[gnn] get a character
+ stax d ;[gnn] copy it to packet
+ inx h ;[gnn]
+ inx d ;[gnn] move pointers
+ dcr b ;[gnn]
+ mov a,b ;[gnn]
+ ora a ;[gnn] done them all?
+ jnz sfil41 ;[gnn] repeat until done
+ xchg ;[gnn] get final position
+ shld datptr ;[gnn] and save it
+ jmp sfil13 ;[gnn] now go and send packet
+
+;
+; Send data
+; called by: send
+
+sdata: lda numtry ;Get the number of tries.
+ cpi maxtry ;Have we reached the maximum number of tries?
+ jm sdata1
+ lxi d,erms14
+ call error3
+ jmp abort ;Change the state to abort.
+
+sdata1: inr a ;Increment it.
+ sta numtry ;Save the updated number of tries.
+ lxi h, data ;Get a pointer to our data block.
+ shld datptr ;Save it.
+ lxi h,filbuf ;Pointer to chars to be sent.
+ shld cbfptr ;Save position in char buffer.
+ mvi b,1 ;First char.
+sdat11: lhld cbfptr
+ mov a,m
+ inx h
+ shld cbfptr ;Save position in char buffer.
+ mov c,a ;[jd] preserve character temporarily
+ lda quot8 ;[jd] doing eighth-bit quoting?
+ ora a ;[jd]
+ mov a,c ;[jd] restore char
+ jnz sdat4 ;[jd] using eighth-bit quoting, no warning
+ lda parity ;[jd] get parity
+ cpi parnon ;[jd] none?
+ mov a,c ;[jd] restore character
+ jz sdat4 ;[jd] no parity, leave char alone
+ lda wrn8 ;[jd] look at warning flag
+ ora a ;[jd] have we already given the warning?
+ jnz sdat5 ;[jd] yes, skip this
+ mov a,c ;[jd] restore character...
+ ani 80h ;[jd] examine parity
+ jz sdat5 ;[jd] no parity, no warning.
+ call parwrn ;[jd] ...print warning - parity lost
+ mvi a,0ffh ;[jd] remember that we sent the message
+ sta wrn8 ;[jd]
+sdat5: mov a,c ;[jd] restore character again
+ ani 7fh ;[jd] strip parity so not checksummed
+sdat4: lhld datptr
+ mov m,a ;Put the char in the data packet.
+ inx h
+ shld datptr ;Save position in data packet.
+ inr b ;Increment the count.
+ lda size ;Get the number of chars in char buffer.
+ cmp b ;Have we transfered that many?
+ jp sdat11 ;If not get another.
+ lda size ;Number of char in char buffer.
+ sta argblk+1
+ lda pktnum ;Get the packet number.
+ sta argblk
+ mvi a,'D' ;Data packet.
+ call spack ;Send the packet.
+ jmp abort ; Failed, abort.
+ call rpack ;Get a packet.
+ jmp r ; Trashed packet don't change state, retry.
+ cpi 'Y' ;ACK?
+ jnz sdata2 ;If not try next.
+ call compp
+ rnz ;If not hold out for the right one.
+ lda argblk ;Get the packet number back
+ call countp
+ lda numtry ;Get the number of tries.
+ sta oldtry ;Save it.
+ xra a
+ sta numtry ;Reset the number of tries.
+ lda argblk+1 ;Get the data length
+ cpi 1 ;Check if only 1 character?
+ jnz sdat15 ;If not, just continue
+ lda data ;Got one character, get it from data
+ cpi 'Z' ;Want to abort entire stream?
+ jnz sdat14 ;If not, check for just this file
+ sta czseen ;Yes, remember it
+ jmp sdat16 ;[MF] and set EOF state
+sdat14: cpi 'X' ;Desire abort of current file?
+ jnz sdat15 ;If not, just continue
+ sta czseen ;Yes, remember that
+ jmp sdat16 ;[MF] and set EOF
+sdat15: lda czseen ;Also get control-Z flag
+ ora a ;Check if either given
+ jz sdat12 ;If neither given, continue
+sdat16: mvi a,'Z' ;Change state to EOF
+ sta state ; . . .
+ ret ;And return
+
+sdat12: call gtchr
+ jmp sdat13 ;Error go see if its EOF.
+ sta size ;Save the size of the data gotten.
+ ret
+
+sdat13: cpi 0FFH ;Is it EOF?
+ jnz abort ;If not give up.
+ mvi a,'Z' ;Set the state to EOF.
+ sta state
+ ret
+
+sdata2: cpi 'N' ;NAK?
+ jnz sdata3 ;See if is an error packet.
+ call updrtr ;Update the number of retries.
+ lda pktnum ;Get the present packet number.
+ inr a ;Increment
+ ani 3FH ; modulo 64
+ mov b,a
+ lda argblk ;Get the packet's number.
+ cmp b ;Is the packet's number one more than now?
+ rnz ;If not go try again.
+ jmp sdat12 ;Just as good as a ACK;go to the ACK code.
+
+sdata3: cpi 'E' ;Is it an error packet.
+ jnz abort
+ call error
+ jmp abort
+;
+; Send EOF
+; called by: send
+
+seof: lda numtry ;Get the number of tries.
+ cpi maxtry ;Have we reached the maximum number of tries?
+ jm seof1
+ lxi d,erms14
+ call error3
+ jmp abort ;Change the state to abort.
+
+seof1: inr a ;Increment it.
+ sta numtry ;Save the updated number of tries.
+ lda pktnum ;Get the packet number.
+ sta argblk
+ xra a
+ sta argblk+1 ;No data.
+ lda czseen ;Check if C-Z or C-X typed
+ ora a ; . . .
+ jz seof14 ;If not aborted, just keep going
+ mvi a,'D' ;Tell other end to discard packet
+ sta data ;Store in data portion
+ mvi a,1 ;One character
+ sta argblk+1 ;Store the length
+seof14: mvi a,'Z' ;EOF packet.
+ call spack ;Send the packet.
+ jmp abort ; Failed, abort.
+ call rpack ;Get a packet.
+ jmp r ; Trashed packet don't change state, retry.
+ cpi 'Y' ;ACK?
+ jnz seof2 ;If not try next.
+ call compp
+ rnz ;If not hold out for the right one.
+seof12: call countp
+ lda numtry ;Get the number of tries.
+ sta oldtry ;Save it.
+ xra a
+ sta numtry ;Reset the number of tries.
+ mvi c,closf ;Close the file.
+ lxi d,fcb
+ call bdos
+;* Check if successful
+ lda czseen ;Desire abort of entire stream?
+ cpi 'Z' ;Desire abort of entire stream?
+ jz seof13 ;If so, just give up now
+ call mfname ;Get the next file.
+ jc seof13 ; No more.
+ call getfil ;and open it (assume success)
+ xra a ;Clear A
+ sta czseen ;Since we have not aborted this file
+ mvi a,'F' ;Set the state to file send.
+ sta state
+ ret
+
+seof13: mvi a,'B' ;Set the state to EOT.
+ sta state
+ ret
+
+seof2: cpi 'N' ;NAK?
+ jnz seof3 ;Try and see if its an error packet.
+ call updrtr ;Update the number of retries.
+ lda pktnum ;Get the present packet number.
+ inr a ;Increment
+ ani 3FH ; modulo 64
+ mov b,a
+ lda argblk ;Get the packet's number.
+ cmp b ;Is the packet's number one more than now?
+ rnz ;If not go try again.
+ jmp seof12 ;Just as good as a ACK;go to the ACK code.
+
+seof3: cpi 'E' ;Is it an error packet.
+ jnz abort
+ call error
+ jmp abort
+;
+; Send EOT
+; called by: send
+
+seot: lda numtry ;Get the number of tries.
+ cpi maxtry ;Have we reached the maximum number of tries?
+ jm seot1
+ lxi d,erms14
+ call error3
+ jmp abort ;Change the state to abort.
+
+seot1: inr a ;Increment it.
+ sta numtry ;Save the updated number of tries.
+ lda pktnum ;Get the packet number.
+ sta argblk
+ xra a
+ sta argblk+1 ;No data.
+ mvi a,'B' ;EOF packet.
+ call spack ;Send the packet.
+ jmp abort ; Failed, abort.
+ call rpack ;Get a packet.
+ jmp r ; Trashed packet don't change state, retry.
+ cpi 'Y' ;ACK?
+ jnz seot2 ;If not try next.
+ call compp
+ rnz ;If not hold out for the right one.
+seot12: call countp
+ lda numtry ;Get the number of tries.
+ sta oldtry ;Save it.
+ xra a
+ sta numtry ;Reset the number of tries.
+ mvi a,'C' ;Set the state to file send.
+ sta state
+ ret
+
+seot2: cpi 'N' ;NAK?
+ jnz seot3 ;Is it error.
+ call updrtr ;Update the number of retries.
+ lda pktnum ;Get the present packet number.
+ inr a ;Increment
+ ani 3FH ; modulo 64
+ mov b,a
+ lda argblk ;Get the packet's number.
+ cmp b ;Is the packet's number one more than now?
+ rnz ;If not go try again.
+ jmp seot12 ;Just as good as a ACK;go to the ACK code.
+
+seot3: cpi 'E' ;Is it an error packet.
+ jnz abort
+ call error
+ jmp abort
+;
+; This routine sets up the data for init packet (either the
+; Send_init or ACK packet).
+; called by: rinit, rfile, sinit
+;
+; Called by rinit, rfile and sinit. See what WE want from the other fella
+;
+; [11] by OBS - Stripped out all the new capas code etc and reverted
+; to Good Ol' Basic Kermit again!
+; Those keen should study the followin gode with care, and remove
+; or add semicolons as indicated.
+;
+; See also SPAR which decodes what comes in. It also decodes bits in
+; the "capability" fields. (Two CAPAS files allowed from remote
+; machines, but we will only send one at max.) Note that not all
+; if any of the capability bits will be used.
+;
+; Definitions - init packet (data section only.. rest of header assumed OK)
+; Byte 0 Maximum length I want to send
+; 1 The Timeout I want you to use
+; 2 Number of PAD characters I want tot use (May be null)
+; 3 The PAD character I want to use (May be Null)
+; 4 The End-of-Line character I will use (Carriage Return)
+; 5 The control character Quote Character I will use (#)
+; 6 The parity bit Quote Character I will use (&)
+; 7 The Checktype I will use
+; 8 The repeat prefix I will use (Null, as we cannot to repeats)
+; 9 Capability Byte 0 (See SPAR for defs)
+; 10 Capability byte 1 ( --- " --- but we will not send it.)
+; 11 The number of packets I will send per window (not used)
+; 12 MAXL1 - Long packet size, ms count
+; 13 MAXL2 - Long packet size, ls count
+;
+;
+; Enter with HL pointing to the "data" part of the packet.
+
+;
+; older part of rpar follows...
+;
+;
+rpar: lda rpsiz ;Get the receive packet size.
+ adi space ;Add a space to make it printable.
+ mov m,a ;Put it in the packet.
+ inx h ;Point to the next char.
+ lda rtime ;Get the receive packet time out.
+ adi space ;Add a space.
+ mov m,a ;Put it in the packet.
+ inx h
+ lda rpad ;Get the number of padding chars.
+ adi space
+ mov m,a
+ inx h
+ lda rpadch ;Get the padding char.
+ adi 100O ;Uncontrol it.
+ ani 7FH
+ mov m,a
+ inx h
+ lda reol ;Get the EOL char.
+ adi space
+ mov m,a
+ inx h
+ lda rquote ;Get the quote char.
+ mov m,a
+ inx h
+ mvi m,'Y' ;[jd] we know how to do 8-bit quoting
+ lda parity ;[jd]
+ cpi parnon ;[jd] parity none?
+ jz rpar1 ;[jd] yes, keep going
+ lda qbchr ;[jd] no, better request 8-bit quoting
+ mov m,a
+
+rpar1:
+ inx h ;Advance to next
+ lda chktyp ;Get desired block check type
+ mov m,a ;Store it
+ inx h ;Advance pointer
+
+; Comment out the next two lines for capas etc. WILL require debugging
+ mvi a,8 ; this id the older end for this routine. May be useful.
+ ret
+
+; [11] Rest not needed for now, commented out
+; [10] (to ret)
+; New additions to rpar follows...
+
+; lda rcap1 ; get the first capability byte
+; ani 3eh ; mask out bit 0, ie only one CAPAS byte
+; adi space ; tochar it
+; mov m,a
+; inx h
+; mvi m,space ; No windows, ie space to packet
+; inx h
+; push h ; we need the HL regs for maths.
+; lhld rdpkt ; get receive packet length
+; lxi d,95 ; we want hl div 95 and hl mod 95
+; call divide ; return with divsion in hl, remainder in de
+; mov a,l ; two sets of bytes
+; pop h
+; adi space ; tochar(maxl1)
+; mov m,a
+; inx h
+; mov a,l
+; adi space ; tochar(maxl2)
+; mov m,a
+;
+; done all, set databytes = 12 and return
+; mvi a,12 ; 12 bits of data
+; ret
+
+;[11] End of commented out code for rpar
+
+
+;
+; This routine reads in all the send_init packet information.
+; called by: rinit, sinit
+
+;[11] As for rpar, restore the "old" kermit code for non-capas Kermit.
+;[10] (to ret at end)
+;
+; SPAR - routine to decode parameters received from the remote end
+;
+; Called by rinit,sinit
+;
+; Entry: a: Number of databytes in packet
+; hl: Pointer to "data" part of packet
+;
+;spar: sta temp4 ; save for a while
+; ; first clear some variables
+; lda dspsiz ; get default "send" packet length
+; sta spktl
+; lda dstime ; get default time-out
+; sta stimeo
+; xra a ; set no pad characters by default
+; sta spad
+; lda dspadc ; get the default padding character
+; sta spadc
+; mvi a,cr ; default end of line character (CR)
+; sta seol
+; mvi a,dsquot ; default quote character
+; sta squote
+; mvi a,dsbqut ; default binary quote character
+; sta qbchr
+; mvi a,dschkt ; set checktype = 1 for inits
+; sta inichk
+; mvi a,space ; no repeat prefixing ( otherwise ~)
+; sta srept
+;
+; Now follows the "capabilities" bits... 5 bits per capas byte.
+;
+; Note: Before extracting any data bits, apply unchar() to get the
+; six ls bits. If bit 0 = 1 the a subsequent capaa byte follows
+;
+; Byte0: Bit 0: Set to 1 if there are subsequent CAPAS bytes
+; 1: (Cap. 5) Set to 1 for long packets. Second byte
+; AFTER the last capas byte has packet length DIV 95
+; and Thire byte has length MOD 95
+; 2: (Cap. 4) Sliding Windows. If used, first byte AFTER
+; last capas byte has TOCHAR(no. of packets in window)
+; 3: (Cap. 3) Ability to accept "A" (attribute packets)
+; 4: (Cap. 2) Reserved
+; 5: (Cap. 1) Reserved
+; Byte 2 onward: not used in this implementation. Any capas bytes sent
+; will be stored, however.
+;
+; lda temp4 ; get the number of bytes to test
+; mov c,a ; to a count register
+; mov a,m ; get first byte
+; call decc ; unchar it, and decrement c
+; sta spsiz ; save a send packet size
+; jz sparx ; if no more, exit
+;
+; mov a,m ; get timout
+; call decc
+; sta stime ; save timeout
+; jz sparx
+;
+; mov a,m ; get pad characters
+; call decc
+; sta spadc ; save it
+; jz sparx
+;
+; mov a,m ; get pad character count
+; call decc
+; sta spad
+; jz sparx
+;
+; mov a,m ; get send EOL
+; call decc
+; sta seol
+; jz sparx
+;
+; mov a,m ; get control quote character
+; call decc
+; sta squote
+; jz sparx
+;
+; mov a,m ; get binary (parity) quote char
+; mov b,a ; this time we actually WANT accumulator
+; cpi space ; are we doing 8th bit quoteing
+; jz spar1 ; dont know, assume not
+; cpi 'N' ; definately not?
+; jz spar1
+; cpi 'Y' ; definately - use &
+; jz spar2
+; sta squote ; else save the new character
+;spar2: lda parity ; see if we are using the parity bit
+; cpi parnon ; no parity => no quoting
+; jz spar3 ; yup, so use the default quote character &
+;
+;spar1: xra a ; save not quoting
+; sta squote
+;spar3: call decc ; update counters etc
+; jz sparx
+;
+; mov a,m ; get repeat prefixing
+; call decc
+; push psw ; save flags
+; cpi space-32 ; we want it?
+; jz spar4
+; sta srept
+;spar4: pop psw ; restore flags
+; jz sparx
+;
+; lxi d,scapas ; point to start of capability byte(s)
+; push psw ; must do this...
+;spar5: pop psw ; cos we restore the spack
+; mov a,m
+; call decc ; get scap1 (or n)
+; sta scap1
+; push psw
+; ani 01 ; another byte following?
+; jnz spar5
+; pop psw ; see if any other data bytes (Windows etc)
+; jz sparx
+;
+; mov a,m ; get window size
+; call decc
+; sta swindo
+; jz sparx
+;
+; mov a,m ; get long packets ms bits
+; call decc ;
+; mov d,a ; unchared ms bits-ish
+; mov a,m
+; call decc ; ls bits-ish
+; push h ; and we are doing maths
+; push b ; and an intermediate result in c
+; push psw ; we want flags and the ls bits...
+; mvi b,0
+; mov c,d ; get ms bits-ish to bc
+; push b ; get number to hl
+; pop h
+; now multipy by 95
+; dad h ;*2
+; dad h ;*4
+; dad h ;*8
+; dad h ;*16
+; push h ; *16 to ...
+; pop d ; ... de
+; dad h ;*32
+; dad d ; *(32+16) = *48
+; dad h ; *96
+; mov a,l ; *(96-1)
+; sub c
+; mov l,a
+; mov a,0
+; sbb h
+; mov h,a
+; pop psw ; restore ls bitsish
+; mov e,a
+; mvi d,0
+; dad d ; *95 + ls bits. Phew.
+; shld sdpkt ; save long packet length
+; pop b
+; pop h ; restore regs
+;
+;sparx: ret ; if here, (assume) no more data to read in
+;[10] routines required follow
+;decc: mov a,m ; get data byte
+; sui space ; unchar it
+; inx h ; increment input pointer
+; dcr c ; decrement data counter
+; ret ; return
+;[10] end or spar replacement
+
+;[11] Restore older spar....
+; Older spar follows...
+spar: sta temp4 ;Save the number of arguments.
+; Initialize some variables to their required default values, so we use
+; the right values even if the remote Kermit doesn't send the full packet:
+; ; we don't do anything with timeout values yet.
+; ; no default pad count/pad character?
+ mvi a,cr ; EOL character = carriage-return
+ sta seol
+ mvi a,'#' ; quote character = '#'
+ sta squote
+ mvi a,'&' ; eighth-bit quote character = '&'
+ sta qbchr
+ mvi a,'1' ; block-check = 1-character-checksum
+ sta inichk
+;
+ mov a,m ;Get the max packet size.
+ sbi space ;Subtract a space.
+ sta spsiz ;Save it.
+ lda temp4
+ cpi 3 ;Fewer than three pieces?
+ rm ;If so we are done.
+ inx h
+ inx h ;Increment past the time out info.
+ mov a,m ;Get the number of padding chars.
+ sbi space
+ sta spad
+ lda temp4
+ cpi 4 ;Fewer than four pieces?
+ rm ;If so we are done.
+ inx h
+ mov a,m ;Get the padding char.
+ adi 100O ;Re-controlify it.
+ ani 7FH
+ sta spadch
+ lda temp4
+ cpi 5 ;Fewer than five pieces?
+ rm ;If so we are done.
+ inx h
+ mov a,m ;Get the EOL char.
+ sbi space
+ sta seol
+ lda temp4
+ cpi 6 ;Fewer than six pieces?
+ rm ;If so we are done.
+ inx h
+ mov a,m ;Get the quote char.
+ sta squote
+ lda temp4 ;Get the amount of data supplied
+ cpi 7 ;Have an 8-bit quote?
+ rm ;If not there, all done
+ inx h ;Yes, get the character
+ mvi a,0 ;[jd]
+ sta quot8 ;[jd] assume not quoting
+ mov a,m ;Get the supplied character
+ cpi 'N' ;[jd] No?
+ jz spar1 ;[jd] then don't try to do it
+ cpi space ;[jd] maybe they don't know about it...
+ jz spar1 ;[jd] then don't try to do it.
+ cpi 'Y' ;[jd] Yes?
+ jnz spar2 ;[jd] if not 'Y', assume it's a quote char.
+ lda parity ;[jd] using parity?
+ cpi parnon ;[jd] no, don't need quoting...
+ jz spar1 ;[jd]
+ mvi a,0ffh ;[jd] else turn on...
+ sta quot8 ;[jd] ...quote flag
+ jmp spar1
+
+;[11] Note: If capas etc required, beware of the next two lables, as these
+; are used elswhere.
+
+spar2: sta qbchr ;[jd] use their quote char (should validate)
+ mvi a,0ffh
+ sta quot8 ;[jd] turn quote flag and fall thru...
+
+spar1: lda temp4 ;Determine if block check type given
+ cpi 8 ;Is the field there?
+ rm ;If not, all done
+ inx h ;Point to the character
+ mov a,m ;Get the value
+ mov b,a ;Copy value
+ lda chktyp ;Get our type
+ cmp b ;Is it our desired type?
+ rnz ; If not, use default (1-character-checksum)
+ sta inichk ; Match, store as type to use after init
+ ret ; and return
+;[10] end of replacement
+;[11] end of replacement of replacement (ie back to original code)
+;
+
+; Copy characters from packet to disk (or screen)
+; called by: rdata
+
+ptchr: sta temp1 ;Save the size.
+ lda remtxt ;[MF]Get remote command flag
+ ora a ;[MF]Remote command in progress?
+ jnz ptchr0 ;[MF]Yes, don't check for file collisions
+ lda flwflg ;[MF]Get File Warning (Set Collision) flag
+ cpi 3 ;[MF]SET COLLISION DISCARD?
+ jnz ptchr0 ;[MF]No
+ lda dscflg ;[MF]Yes, get "discard" flag
+ ora a ;[MF]Discarding file?
+ jz ptchr0 ;[MF]No
+ mvi a,'X' ;[MF]Yes, simulate a user rejection
+ sta czseen ;[MF]...
+ jmp rskp ;[MF]and pretend success
+ptchr0: ;[MF]
+ lxi h,data ;Beginning of received packet data.
+ shld outpnt ;Remember where we are.
+ lda rquote
+ mov b,a ;Keep the quote char in b.
+ mvi c,0 ;[jd] assume no 8-bit quote char
+ lda quot8 ;[jd] doing 8-bit quoting?
+ ora a
+ jz ptchr1 ;[jd] no, keep going
+ lda qbchr ;[jd] else get 8-bit quote char
+ mov c,a ;[jd] keep this in c
+ptchr1: lxi h,temp1
+ dcr m ;Decrement # of chars in packet.
+ jm rskp ;Return successfully if done.
+ lda remtxt ; to screen only?
+ ana a
+ jnz ptchr2 ; dont do any disk stuff
+ lxi h,chrcnt ;Number of chars remaining in dma.
+ dcr m ;Decrement.
+ jp ptchr2 ;Continue if space left.
+ call outbuf ;Output it if full.
+ jmp ptchr9 ; Error return if disk is full.
+ptchr2: lhld outpnt ;Get position in output buffer.
+ mov a,m ;Grab a char.
+ inx h
+ shld outpnt ;and bump pointer.
+ mvi e,0 ;[jd] assume nothing to OR in.
+ cmp c ;[jd] is it the binary quote char?
+ jnz ptch2a ;[jd] no, keep going
+ mvi e,80h ;[jd] include parity bit
+ lda temp1
+ dcr a
+ sta temp1 ;[jd] decrement character count
+ mov a,m ;[jd] get next character
+ inx h
+ shld outpnt
+ptch2a: cmp b ;Is it the quote char?
+ jnz ptchr3 ;[jd] changed to ptchr3 so includes parity
+ mov a,m ;Get the quoted character
+ inx h
+ shld outpnt ;and bump pointer.
+ lxi h,temp1
+ dcr m ;Decrement # of chars in packet.
+ mov d,a ;Save the char.
+ ani 80H ;Turn off all but the parity bit.
+ ora e ;[jd] let parity come from either (???)
+ mov e,a ;Save the parity bit.
+ mov a,d ;Get the char.
+ ani 7FH ;Turn off the parity bit.
+ cmp b ;Is it the quote char?
+ jz ptchr3 ;If so just go write it out.
+ cmp c ;[jd] maybe it's the 8-bit prefix character?
+ jz ptchr3 ;[jd] then don't controllify.
+ mov a,d ;Get the char.
+ adi 40H ;Make the character a control char again.
+ ani 7FH ;Modulo 128.
+ptchr3: ora e ;Or in the parity bit.
+ sta temp3 ; save for a while
+ lda remtxt ; to screen or disk?
+ ana a
+ lda temp3
+ jz ptch31 ; to disk
+ push h
+ push d
+ push b
+ mov e,a ; to display
+ mvi c,dconio
+ call bdos
+ pop b
+ pop d
+ pop h
+ jmp ptchr1 ; continue
+
+ptch31: lhld bufpnt ;Destination buffer.
+ mov m,a ;Store it.
+ inx h
+ shld bufpnt ;Update the pointer
+ jmp ptchr1 ;and loop to next char.
+
+ptchr9: lxi d,erms11 ; "?Disk full"
+ push d ;[MF] Save pointer
+ call error3 ; put it on the error line
+ pop d ;[MF] Restore pointer
+ lxi h,data ;[MF] Where to put the message for "e" packet
+ lda argblk ;[MF] Get packet-number
+ call countp ;[MF]Increment it
+ sta argblk ;[MF] as packet to send
+ xra a ;[MF] Zero length of packet data
+ sta temp1 ;[MF] ...
+ptch9a: ldax d ;[MF] Get a character to copy
+ cpi cr ;[MF] No more to copy?
+ jz ptch9b ;[MF] Yes, we can send the packet
+ mov m,a ;[MF] No, copy the character
+ inx d ;[MF] and increment source/dest pointers
+ inx h ;[MF] ...
+ lda temp1 ;[MF] Get character count
+ inr a ;[MF] and increment it
+ sta temp1 ;[MF] ...
+ jmp ptch9a ;[MF] Copy entire error message
+ptch9b: mvi m,0 ;[MF]Put in a zero
+ lda temp1 ;[MF] Get number of characters in the message
+ sta argblk+1 ;[MF] and store as number of packet data chars
+ mvi a,'E' ;[MF] Make it an error packet
+ call spack ;[MF] Send the error packet
+ nop ;[MF] Don't really care if
+ nop ;[MF] the send fails since we're
+ nop ;[MF] bombing off anyway
+ ret ; take error return.
+;
+; Fill a data packet from file
+; called by: sfile, sdata
+
+gtchr: lda squote ;Get the quote char.
+ mov c,a ;Keep quote char in c.
+ lda curchk ;Get current block check type
+ sui '1' ;Get the extra overhead
+ mov b,a ;Get a copy
+ lda spsiz ;Get the maximum packet size.
+ sui 5 ;Subtract the overhead.
+ sub b ;Determine max packet length
+ sta temp1 ;This is the number of chars we are to get.
+ lxi h,filbuf ;Where to put the data.
+ shld cbfptr ;Remember where we are.
+ mvi b,0 ;No chars.
+gtchr1: lda temp1
+ dcr a ;Decrement the number of chars left.
+ jp gtchr2 ;Go on if there is more than one left.
+ mov a,b ;Return the count in A.
+ jmp rskp
+
+gtchr2: sta temp1
+ lda chrcnt ;Space left in the DMA.
+ dcr a
+;* Can improve order here.
+ jm gtchr3
+ sta chrcnt
+ jmp gtchr4
+
+gtchr3: call inbuf ;Get another buffer full.
+ jmp gtch30 ; If no more return what we got.
+ jmp gtchr4 ;If we got some, proceed.
+
+gtch30: mov a,b ;Return the count in A.
+ ora a ;Get any chars?
+ jnz rskp ;If so return them.
+ jmp gtceof ;If not, say we found the end of the file.
+
+gtchr4: lhld bufpnt ;Position in DMA.
+ mov a,m ;Get a char from the file.
+ inx h
+ shld bufpnt
+ mov d,a ;Save the char.
+ ani 80H ;Turn off all but parity.
+ mov e,a ;Save the parity bit.
+ jz gtch4a ;[jd] no parity, skip this check...
+ lda quot8 ;[jd] doing eighth-bit quoting?
+ ora a
+ jz gtch4a ;[jd] no, just proceed normally
+ lda temp1 ;[jd] get space remaining
+ cpi 2 ;[jd] 3 chrs left (one cnted already)?
+ jm gtchr9 ;[jd] no, skip this
+ dcr a ;[jd] decrement space remaining
+ sta temp1 ;[jd] put back.
+ lhld cbfptr ;[jd] Position in character buffer.
+ lda qbchr ;[jd] get quote character
+ mov m,a ;]jd] Put the quote char in the buffer.
+ inx h ;[jd] increment destination buffer pointer
+ shld cbfptr ;[jd] store the pointer back
+ inr b ;[jd] Increment the char count.
+ mvi e,0 ;[jd] no parity bit to OR in.
+;[jd] fall thru...
+
+gtch4a: mov a,d ;Restore the char.
+ ani 7FH ;Turn off the parity.
+ mov d,a ;[jd] save here for later...
+ cpi space ;Compare to a space.
+ jm gtchr5 ;If less then its a control char, handle it.
+ cpi del ;Is the char a delete?
+ jz gtchr5 ;Go quote it.
+ lda quot8 ; Are we doing 8th-bit quoting?
+ ora a
+ jz gtch4c ; if not, skip this test and restore character.
+ lda qbchr ; get 8th-bit quote character
+ cmp d ; same as current character?
+ jz gtch4b ; yes, have to quote it...
+gtch4c: mov a,d ; no. get character back again.
+ cmp c ;Is it the quote char?
+ jnz gtchr8 ;If not proceed.
+gtch4b: lxi h,temp1 ;[jd] point to char count
+ dcr m ;[jd] decrement (know room for at least one)
+ lhld cbfptr ;Position in character buffer.
+ mov m,c ;Put the (quote) char in the buffer.
+ inx h
+ shld cbfptr
+ inr b ;Increment the char count.
+ mov a,d ;[jd] restore character again
+ jmp gtchr8
+
+gtchr5:
+ ;[gnn] ignore parity for checking
+; ora e ;Turn on the parity bit.
+
+ cpi ('Z'-100O) ;Is it a ^Z?
+ jnz gtchr7 ;If not just proceed.
+ lda cpmflg ;Was the file created by CPM...
+ cpi 1 ;in ASCII-mode ?
+ jz gtch52 ;Control-Z stops text
+ cpi 2 ;in BINARY mode?
+ jz gtchr6 ;Yes, pass the ^Z
+;At this point file-mode is DEFAULT.
+;If the rest of the record is filled with ^Zs, we're at EOF, otherwise
+;its a regular character.
+ lhld bufpnt ;since CHRCNT is ZERO at EOF-time
+ lda chrcnt ;(set by INBUF5 B.G.E)
+ mov d,a ;Get the number of chars left in the DMA.
+gtch51: dcr d
+ mov a,d
+ jp gtch53 ;Any chars left?
+gtch52: xra a ;If not, get a zero.
+ sta chrcnt ;Say no more chars in buffer.
+ mov a,b ;Return the count in A.
+ jmp rskp
+
+;Scan rest of buffer for non ^Z -- If we find a non ^Z, fall into gtchr6.
+;If we get to the end of the buffer before finding a non ^Z, fall into gtch52.
+gtch53: mov a,m ;Get the next char.
+ inx h ;Move the pointer.
+ cpi ('Z'-100O) ;Is it a ^Z?
+ jz gtch51 ;If so see if the rest are.
+
+gtchr6: mvi a,('Z'-100O) ;Restore the ^Z.
+gtchr7: sta temp2 ;Save the char.
+ lxi h,temp1 ;Point to the char total remaining.
+ dcr m ;Decrement it.
+ lhld cbfptr ;Position in character buffer.
+ mov m,c ;Put the quote in the buffer.
+ inx h
+ shld cbfptr
+ inr b ;Increment the char count.
+ lda temp2 ;Get the control char back.
+ adi 40H ;Make the non-control.
+ ani 7fH ;Modulo 200 octal.
+gtchr8: lhld cbfptr ;Position in character buffer.
+ ora e ;Or in the parity bit.
+ mov m,a ;Put the char in the buffer.
+ inx h
+ shld cbfptr
+ inr b ;Increment the char count.
+ jmp gtchr1 ;Go around again.
+
+gtchr9: ;[jd] not enough room left in buffer...
+ lhld bufpnt
+ dcx h
+ shld bufpnt ;[jd] back up over last character
+ lxi h,chrcnt ;[jd] point to character count
+ inr m ;[jd] increment it
+ mov a,b ;[jd] count of chars transferred
+ jmp rskp ;[jd] return it
+
+gtceof: mvi a,0FFH ;Get a minus one.
+ ret
+;
+
+; Little code to allow some expansion of code without changing
+; every futher address, only up to the end of this file.
+; TO BE REMOVED FRO RELEASE!
+
+; org ($+100h) AND 0FF00H
+
+IF lasm
+ LINK CPSPK2 ;[obs] Link to part two of the packet file
+ENDIF ;lasm
diff --git a/cpspk2.asm b/cpspk2.asm
index b246967..724c6d2 100644
--- a/cpspk2.asm
+++ b/cpspk2.asm
@@ -1,1336 +1,1336 @@
-; CPSPK2.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the (system-independent) routines that implement
-; the KERMIT protocol, and the commands that use them:
-; RECEIVE, SEND, FINISH, and LOGOUT.
-;
-; revision history:
-;
-;edit 11, 21-Mar-1991 by MF. After "inchr7", close TAKE-file (if any) so
-; ^C will halt all processing (including commands from TAKE-files)
-; and put the user back at Kermit command-level.
-;edit 10, 3-Jan-1991 by MF. Modify routine "inchr" after label "inchr5" to
-; not take retry (nonskip) return if ^X/^Z seen on the Console. This
-; will prevent multiple copies of packets being sent if user aborts
-; some files in a stream being sent via ^X and is a better fix to this
-; problem than flushing comm input before sending the "Z" packet
-; requesting the remote Kermit to discard the current file being
-; received (as implemented in CPSPK1.ASM edit of 2-jan-1991).
-;edit 9, 14-Dec-1990 by MF. Modified "gofil" routine to allow for
-; specification of a drive in the local filespec for GET and
-; RECEIVE commands. Thus commands such as
-; GET HELLO.TXT B:GOODBYE.TXT
-; and
-; RECEIVE B:GOODBYE.TXT
-; now work as expected.
-;edit 8, 22-Oct-1990 by MF. Fixed bug in completion-message routine
-; "finmes" wherein the completion message was not printed if the
-; terminal was set to QUIET because the message pointer was clobbered
-; by prcrlf.
-;edit 7, 14-Sep-1990 by MF. Add hooks for SET COLLISION command.
-; Eliminate commented-out old file warning rename routine.
-; Clear communication input buffers (call flsmdm) before
-; BYE, FINISH and LOGOUT commands.
-;edit 6, 9-Sep-1990 by MF. Implemented fixes in CPKERM.BWR for
-; garbage printout during quiet transfers and for file existence/
-; rename algorithm.
-; Also implemented hooks for Remote commands.
-; edit 5, 18 June 1990 by Russell Lang [rjl@monu1.cc.monash.edu.au]
-; When trying to generate a unique file name on receive, zero
-; the attribute bits between file opening attempts. This is
-; to fix a bug which caused the unique file name to have the
-; attributes of the already existing file. If the attribute
-; was R/O, a bdos error occured later when an attempt was made
-; to write to the file.
-;
-; edit 4, 27 October, 1987 By OBSchou. Changed the rename routine to
-; be more like the MSDOS issue.
-;
-; edit 3, 28 July, by OBSchou. Added traps to NOT print to screen during
-; file transfers if quietd is non zero (ie we SET TERMINAL QUIET)
-; This hopefully speeds up transfers in systems spending an age
-; updating the screen.
-;
-; edit 2, 8 April, 1987 by OBSchou. Minor edit to put drive and user number
-; in the "filename" field on the transfer screen. This means that the
-; offset on the line foe the file name proper has moved along 4 space.
-; Also, it writes 15 spaces AFER the xxd: string to clear the field
-; of any prevous file. Needed for thos terminals that cannot
-; clear to end of line...
-;
-; edit 1, 28 January, 1987 by OBSchou.
-; Hived off about 1/2 of CPSPKT.ASM to form two (smaller => easier
-; to handle) files.
-;
-;
-
-pk2ver: db 'CPSPK2.ASM (11) 21-Mar-1991$' ; name, edit number, date
-
-
-;
-; Get the file name (including host to micro translation)
-; called by: rfile
-
-gofil: xra a
- sta fcb ;Set the drive to default to current.
- lxi h,data ;Get the address of the file name.
-; allow use of local name if one was given [gnn]
- lda remlen ;[gnn]
- ora a ;[gnn] anything there?
- jz gofil0 ;[gnn] no, use the one in the data packet
- lxi h,remnam ;[gnn] yes, use this instead
- lda remnam+1 ;[MF]Get 2nd char of local filename
- cpi ':' ;[MF]Was a drive specified?
- jnz gofil0 ;[MF]No, proceed as of old
- mov a,m ;[MF]Yes, get drive
- ani 5fh ;[MF]Force uppercase
- sui 'A'-1 ;[MF]Make valid drive for fcb
- sta fcb ;[MF]and store in fcb
- inx h ;[MF]Skip drive and delimiter
- inx h ;[MF]...
-gofil0: ;[gnn] continue to set up the file [gnn]
-;
- shld datptr ;Store the address.
- lxi h,fcb+1 ;Address of the FCB.
- shld fcbptr ;Save it.
- xra a
- sta temp1 ;Initialize the char count.
- sta temp2
- mvi b,' '
-gofil1: mov m,b ;Blank the FCB.
- inx h
- inr a
-; cpi 0CH ;Twelve?[5a]
- cpi 0BH ; Eleven? [5a]
- jm gofil1
- mvi m,0 ; [5a] Specify extent 0
-gofil2: lhld datptr ;Get the NAME field.
- mov a,m
- cpi 'a' ;Force upper case
- jm gofl2a ;
- ani 5FH ;
-gofl2a: inx h
- cpi '.' ;Seperator?
- jnz gofil3
- shld datptr ;[jd] update ptr (moved from above)
- lxi h,fcb+9H
- shld fcbptr
- lda temp1
- sta temp2
- mvi a,9H
- sta temp1
- jmp gofil6
-
-gofil3: ora a ;Trailing null?
- jz gofil7 ;Then we're done.
- shld datptr ;[jd] no, can update ptr now.
- lhld fcbptr
- mov m,a
- inx h
- shld fcbptr
- lda temp1 ;Get the char count.
- inr a
- sta temp1
- cpi 8H ;Are we finished with this field?
- jm gofil2
-gofil4: sta temp2
- lhld datptr
- mov a,m
- inx h
- shld datptr
- ora a
- jz gofil7
- cpi '.' ;Is this the terminator?
- jnz gofil4 ;Go until we find it.
-gofil6: lhld datptr ;Get the TYPE field.
- mov a,m
- cpi 'a' ;Force upper case
- jm gofl6a ;
- ani 5FH ;
-gofl6a: ora a ;Trailing null?
- jz gofil7 ;Then we're done.
-;[jd] move above two lines so we don't increment pointer if char is null
- inx h
- shld datptr
- lhld fcbptr
- mov m,a
- inx h
- shld fcbptr
- lda temp1 ;Get the char count.
- inr a
- sta temp1
- cpi 0CH ;Are we finished with this field?
- jm gofil6
-gofil7: lhld datptr
- mvi m,'$' ;Put in a dollar sign for printing.
- lda quietd ; quiet display?
- ana a
- jnz gofi70 ; yes, so skip it.
- call scrfln ;Position cursor
-gofi70: lxi d,data ;Print the file name
- lda getrxflg ;[obs 8] are we doing a get or receive?
- ana a ;[obs 8]
- jz gofi7a ;[obs 8] if zero, receive
- lxi d,remnam ;[obs 8]
-gofi7a: ;[obs 8]
-
- call prtstr
-gofi7b: xra a ;[MF]Zero "discard" flag
- sta dscflg ;[MF]...
- lda flwflg ;Is file warning on?
- ora a
- jz gofil9 ;If not, just proceed.
- mvi c,openf ;See if the file exists.
- lxi d,fcb
- call bdos
- cpi 0FFH ;Does it exist?
- jz gofil9 ;If not create it.
-;
- lda flwflg ;[MF]Get flag again
- cpi 3 ;[MF]SET COLLISION DISCARD?
- jnz gofi7h ;[MF]No
- mvi a,0ffh ;[MF]Yes, order rejection of the file
- sta dscflg ;[MF]...
- jmp rskp ;[MF]and pretend successful open
-gofi7h: push psw ;[MF]Save Collision status
- lxi d,infms5
- call error3
- pop psw ;[MF]Restore Collision status
- cpi 1 ;[MF]SET COLLISION RENAME?
- jz gofi7i ;[MF]Yes, same as SET WARNING ON
- ;[MF]If we come here, SET COLLISION BACKUP
- lxi h,fcb ;[MF]Copy original fcb to a safe place
- lxi d,colfcb ;[MF]...
- lxi b,33 ;[MF]...
- call mover ;[MF]...
- ;[MF]and fall into rename code
-gofi7i: ;[MF]
-;
-; Replacement file name renamer routine. Incomming
-; files are renamed in this manner:
-; original file name: filex.ext
-; first rename: filex001.ext
-; ... ...
-; ninth rename filex009.ext
-; 10th rename fail - would we really want 10
-; files of the same name??
-;
-;
-; 1)
-; Assume that we need to "rename" the file, so lets make sure
-; that there is a full. 8 character filename. (We make it if
-; it does not already exist)
-; 1a) If full file name, last character is to be replaced
-; by a zero. This gives us up to no#ine renames.
-; 2)open file
-; 2a)If exists, increment last character by one
-; 2b)if = '9' then abort
-; 2c)If does not exist, got 2)
-; 3)we have a valid 'renamed' file
-;
-;Part 1) - fill out filename part
-
- mvi c,8 ; max 8 characters to test for
- mvi a,'0' ; spaces to be replaced by a zero.
- lxi h,fcb+8 ; start at the end
-gofi7c: mov m,a ; put a zero in here
- dcr c ; come to the end?
- jz gofi7d ; should not have, but just in case...
- dcx h ; previous chararcter
- mov a,m ; get it
- cpi ' ' ; if this character a space as well, zero it
- mvi a,'0' ; set it to ascii zero just in case...
- jz gofi7c ;
-;
-; Part 2) open the file (if success, then it exists)
-
-gofi7d:
-;zero the attribute bits. [rjl@monu1.cc.monash.edu.au]
- lxi h,fcb+1 ;[rjl]
- mvi c,11 ;[rjl]
-gofi7z: mov a,m ;[rjl]
- ani 07fh ;[rjl]
- mov m,a ;[rjl]
- inx h ;[rjl]
- dcr c ;[rjl]
- jnz gofi7z ;[rjl]
- lxi d,fcb
- mvi c,openf
- call BDOS
- inr a ; if 0ffh returned, error (ie does not exist)
- jz gofi7e
- lda fcb+8 ; get last character
- inr a
- sta fcb+8
- cpi '9'+1 ; more than '9' => too far, lets give up.
- jnz gofi7d ; else try again
-;Giving up, so lets exit
- lxi d,erms16 ;
- call prtstr
- ret ; return to error routine
-
-gofi7e: lxi d,fnbuf ; make the file name into a character string
- lxi h,fcb+1 ; point to source file name, less drive name
- mvi c,8 ; 11 characters (8+3) + dot to copy across
-;
-gofi7f: mov a,m ; get character
- stax d
- inx h
- inx d
- dcr c
- jnz gofi7f ; loop until all done
-
- mvi a,'.' ; then the dot
- stax d
- inx d
-
- mvi c,3 ; then the file extention
-
-gofi7g: mov a,m
- stax d
- inx h
- inx d
- dcr c
- jnz gofi7g ; loop until extention copied across
-
- mvi a,'$' ; dollar terminate string
- stax d
- lxi d,fnbuf ;[MF]Point to string
- call prtstr ; write string to console
-
- lda flwflg ;[MF]Get warning (SET COLLISION) flag
- cpi 2 ;[MF]SET COLLISION BACKUP?
- jnz gofil9 ;[MF]No
- lxi h,fcb ;[MF]Yes, get new filename fcb
- lxi d,colfcb+16 ;[MF]Where to copy to for rename
- lxi b,16 ;[MF]Copy 16 bytes
- call mover ;[MF]...
- lxi d,colfcb ;[MF]Point to rename fcb
- mvi c,renam ;[MF]Rename function
- call bdos ;[MF]Try to rename original file
- cpi 0ffh ;[MF]Did we win?
- jnz gofl82 ;[MF]Yes
- lxi d,erms16 ;[MF]No, complain and bomb
- jmp error3 ;[MF]...
-gofl82: lxi h,colfcb ;[MF]Now recopy original filename into fcb
- lxi d,fcb ;[MF]to create new file with original name
- lxi b,16 ;[MF]...
- call mover ;[MF]...
-;
-;
-;Now lets make the file (create it)
-
-gofil9: call makfil ; Create the file.
- jmp gofl91 ; Disk was full.
- jmp rskp ; Success.
-
-gofl91: lxi d,erms11
- call error3
- ret
-;
-; This is the FINISH command. It tells the remote KERSRV to exit.
-; here from kermit
-
-finish: call cfmcmd
- call selmdm ;[MF]Select modem
- call flsmdm ;[MF]Flush buffers
- call selcon ;[MF]Select keyboard again
- xra a
- sta numtry ;Inititialize count.
- mvi a,'1' ;Reset block check type to single character
- sta curchk ; . . .
-
-finsh1: lda numtry ;How many times have we tried?
- cpi maxtry ;Too many times?
- jm finsh3 ;No, try it.
-finsh2: lxi d,erms18 ;Say we couldn't do it.
- call prtstr
- jmp kermit ;Go home.
-
-finsh3: inr a ;Increment the number of tries.
- sta numtry
- xra a
- sta argblk ;Make it packet number zero.
- mvi a,1
- sta argblk+1 ;One piece of data.
- lxi h,data
- mvi m,'F' ;Finish running Kermit.
- mvi a,'G' ;Generic command packet.
- call spack
- jmp finsh2 ; Tell the user and die.
- call rpack ;Get an acknowledgement.
- jmp finsh1 ; Go try again.
- cpi 'Y' ;ACK?
- jz kermit ;Yes, we are done.
- cpi 'E' ;Is it an error packet?
- jnz finsh1 ;Try sending the packet again.
- call error1 ;Print the error message.
- jmp kermit
-;
-; This is the LOGOUT command. It tells the remote KERSRV to logout.
-; here from: kermit
-
-logout: call cfmcmd
- call logo ;Send the logout packet.
- jmp kermit ;Go get another command
- jmp kermit ; whether we succeed or not.
-
-; do logout processing.
-; called by: bye, logout
-
-logo: call selmdm ;[MF]Select modem
- call flsmdm ;[MF]Flush buffers
- call selcon ;[MF]Select keyboard again
- xra a
- sta numtry ;Inititialize count.
- mvi a,'1' ;Reset block check type to single character
- sta curchk ; . . .
-
-logo1: lda numtry ;How many times have we tried?
- cpi maxtry ;Too many times?
- jm logo3 ;No, try it.
-logo2: lxi d,erms19 ;Say we couldn't do it.
- call prtstr
- ret ;Finished.
-
-logo3: inr a ;Increment the number of tries.
- sta numtry
- xra a
- sta argblk ;Make it packet number zero.
- mvi a,1
- sta argblk+1 ;One piece of data.
- lxi h,data
- mvi m,'L' ;Logout the remote host.
- mvi a,'G' ;Generic command packet.
- call spack
- jmp logo2 ; Tell the user and die.
- call rpack ;Get an acknowledgement
- jmp logo1 ; Go try again.
- cpi 'Y' ;ACK?
- jz rskp ;Yes, we are done.
- cpi 'E' ;Is it an error packet?
- jnz logo1 ;Try sending the packet again.
- call error1 ;Print the error message.
- ret ;All done.
-;
-; Packet routines
-
-; Send_Packet
-; This routine assembles a packet from the arguments given and sends it
-; to the host.
-;
-; Expects the following:
-; A - Type of packet (D,Y,N,S,R,E,F,Z,T)
-; ARGBLK - Packet sequence number
-; ARGBLK+1 - Number of data characters
-; Returns: nonskip if failure
-; skip if success
-; called by: read, rinit, rfile, rdata, sinit, sfile, sdata, seof, seot,
-; finish, logout, nak, ackp
-
-spack: sta argblk+2
- lxi h,packet ;Get address of the send packet.
- lda sndsop ;[gnn] send start-of-pkt char.
- mov m,a ;Put in the packet.
- inx h ;Point to next char.
- lda curchk ;Get current checksum type
- sui '1' ;Determine extra length of checksum
- mov b,a ;Copy length
- lda argblk+1 ;Get the number of data chars.
- adi ' '+3 ;Real packet character count made printable.
- add b ;Determine overall length
- mov m,a ;Put in the packet.
- inx h ;Point to next char.
- lxi b,0 ;Zero the checksum AC.
- mov c,a ;Start the checksum.
- lda argblk ;Get the packet number.
- adi ' ' ;Add a space so the number is printable.
- mov m,a ;Put in the packet.
- inx h ;Point to next char.
- add c
- mov c,a ;Add the packet number to the checksum.
- mvi a,0 ;Clear A (Cannot be XRA A, since we can't
- ; touch carry flag)
- adc b ;Get high order portion of checksum
- mov b,a ;Copy back to B
- lda argblk+2 ;Get the packet type.
- mov m,a ;Put in the packet.
- inx h ;Point to next char.
- add c
- mov c,a ;Add the packet number to the checksum.
- mvi a,0 ;Clear A
- adc b ;Get high order portion of checksum
- mov b,a ;Copy back to B
-spack2: lda argblk+1 ;Get the packet size.
- ora a ;Are there any chars of data?
- jz spack3 ; No, finish up.
- dcr a ;Decrement the char count.
- sta argblk+1 ;Put it back.
- mov a,m ;Get the next char.
- inx h ;Point to next char.
- add c
- mov c,a ;Add the packet number to the checksum.
- mvi a,0 ;Clear A
- adc b ;Get high order portion of checksum
- mov b,a ;Copy back to B
- jmp spack2 ;Go try again.
-
-spack3: lda curchk ;Get the current checksum type
- cpi '2' ;Two character?
- jz spack4 ;Yes, go handle it
- jnc spack5 ;No, go handle CRC if '3'
- mov a,c ;Get the character total.
- ani 0C0H ;Turn off all but the two high order bits.
- ;Shift them into the low order position.
- rlc ;Two left rotates same as 6 rights
- rlc ; . . .
- add c ;Add it to the old bits.
- ani 3FH ;Turn off the two high order bits. (MOD 64)
- adi ' ' ;Add a space so the number is printable.
- mov m,a ;Put in the packet.
- inx h ;Point to next char.
- jmp spack7 ;Go store eol character
-
-;Here for 3 character CRC-CCITT
-
-spack5: mvi m,0 ;Store a null for current end
- push h ;Save H
- lxi h,packet+1 ;Point to first checksumed character
- call crcclc ;Calculate the CRC
- pop h ;Restore the pointer
- mov c,e ;Get low order half for later
- mov b,d ;Copy the high order
- mov a,d ;Get the high order portion
- rlc ;Shift off low 4 bits
- rlc ; . . .
- rlc ; . . .
- rlc ; . . .
- ani 0FH ;Keep only low 4 bits
- adi ' ' ;Put into printing range
- mov m,a ;Store the character
- inx h ;Point to next position
-
-;Here for two character checksum
-
-spack4: mov a,b ;Get high order portion
- ani 0FH ;Only keep last four bits
- rlc ;Shift up two bits
- rlc ; . . .
- mov b,a ;Copy back into safe place
- mov a,c ;Get low order half
- rlc ;Shift high two bits
- rlc ;to low two bits
- ani 03H ;Keep only two low bits
- ora b ;Get high order portion in
- adi ' ' ;Convert to printing character range
- mov m,a ;Store the character
- inx h ;Point to next character
- mov a,c ;get low order portion
- ani 3FH ;Keep only six bits
- adi ' ' ;Convert to printing range
- mov m,a ;Store it
- inx h ;Bump the pointer
-
-spack7: lda dbgflg
- ora a ; is debugging enabled?
- jz spack8
- push h ; yes. save address of end of packet
- mvi m,0 ; null-terminate the packet for display
- lda quietd ; a quiet display?
- ana a
- jnz spac7a ; so dont say a thing
- call sppos ; position cursor
- lxi h,packet+1 ; print the packet
- call dmptxt
- lda prnflg ; is the printer on too?
- ana a
- jz spac7a
- lxi h,sstatm ; print state
- call printm ; dumptext but to printer
- lda state
- mov e,a
- call outprn
- lxi h,princr ; cr lf to printer
- call printm
- lxi h,spackm
- call printm
- lxi h,packet+1
- call printm
- lxi h,princr
- call printm
- lxi h,princr
- call printm
-
-spac7a: pop h ; restore address of end of packet
-spack8: lda seol ;Get the EOL the other host wants.
- mov m,a ;Put in the packet.
- inx h ;Point to next char.
- xra a ;Get a null.
- mov m,a ;Put in the packet.
-; Write out the packet.
-outpkt: call selmdm ; Set up for output to comm port if iobyt
- lda spad ;Get the number of padding chars.
- sta temp1
-outpk2: lda temp1 ;Get the count.
- dcr a
- ora a
- jm outpk6 ;If none left proceed.
- sta temp1
- lda spadch ;Get the padding char.
- call setpar ;Set parity appropriately
- mov e,a ;Put the char in right AC.
- call outmdm ;Output it.
- jmp outpk2
-
-outpk6: lxi h,packet ; Point to the packet.
-outlup: mov a,m ; Get the next character.
- ora a ; Is it a null?
- jz outlud ; If so return success.
- call setpar ; Set parity for the character
- mov e,a ; Put it in right AC
- call outmdm ; and output it.
-; TAC trap: If this character is the TAC intercept character, and the TAC
-; trap is enabled, we have to output it twice. If the TAC trap is enabled,
-; tacflg contains the intercept character. (The current character cannot
-; be NUL, so we don't have to worry about doubling nulls in the message)
- lda tacflg ; get current intercept character, or zero.
- cmp m ; compare against current data character.
- jnz outpk8 ; if different, do nothing.
- call setpar ; match. set appropriate parity,
- mov e,a ; put it in the right register,
- call outmdm ; and output it a second time.
-outpk8:
- inx h ; Increment the char pointer.
- jmp outlup
-
-outlud: call selcon ; select console
- jmp rskp ; and return success
-;
-; Receive_Packet
-; This routine waits for a packet to arrive from the host. It reads
-; characters until it finds a SOH. It then reads the packet into packet.
-;
-; Returns: nonskip if failure (checksum wrong or packet trashed)
-; skip if success, with
-; A - message type
-; ARGBLK - message number
-; ARGBLK+1 - length of data
-; called by: rinit, rfile, rdata,
-; sinit, sfile, sdata, seof, seot, finish, logout
-
-rpack: call inpkt ;Read up to the end-of-line character
- jmp r ; Return bad.
-rpack0: call getchr ;Get a character.
- jmp rpack ; Hit eol;null line;just start over.
- lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
- cmp m ;[gnn]
- jnz rpack0 ; No, go until it is.
-rpack1: call getchr ;Get a character.
- jmp r ; Hit end of line, return bad.
- lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
- cmp m ;[gnn]
- jz rpack1 ; Yes, then go start over.
- sta packet+1 ;Store in packet also
- mov c,a ;Start the checksum.
- lda curchk ;Get block check type
- sui '1' ;Determine extra length of block check
- mov b,a ;Get a copy
- mov a,c ;Get back length character
- sui ' '+3 ;Get the real data count.
- sub b ;Get total length
- sta argblk+1
- mvi b,0 ;Clear high order half of checksum
- call getchr ;Get a character.
- jmp r ; Hit end of line, return bad.
- lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
- cmp m ;[gnn]
- jz rpack1 ; Yes, then go start over.
- sta argblk
- sta packet+2 ;Save also in packet
- add c
- mov c,a ;Add the character to the checksum.
- mvi a,0 ;Clear A
- adc b ;Get high order portion of checksum
- mov b,a ;Copy back to B
- lda argblk
- sui ' ' ;Get the real packet number.
- sta argblk
- call getchr ;Get a character.
- jmp r ; Hit end of line, return bad.
- lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
- cmp m ;[gnn]
- jz rpack1 ; Yes, then go start over.
- sta temp1 ;Save the message type.
- sta packet+3 ;Save in packet
- add c
- mov c,a ;Add the character to the checksum.
- mvi a,0 ;Clear A
- adc b ;Get high order portion of checksum
- mov b,a ;Copy back to B
- lda argblk+1 ;Get the number of data characters.
- sta temp2
- lxi h,data ;Point to the data buffer.
- shld datptr
-rpack2: lda temp2
- sui 1 ;Any data characters?
- jm rpack3 ; If not go get the checksum.
- sta temp2
- call getchr ;Get a character.
- jmp r ; Hit end of line, return bad.
- lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
- cmp m ;[gnn]
- jz rpack1 ; Yes, then go start over.
- lhld datptr
- mov m,a ;Put the char into the packet.
- inx h ;Point to the next character.
- shld datptr
- add c
- mov c,a ;Add the character to the checksum.
- mvi a,0 ;Clear A
- adc b ;Get high order portion of checksum
- mov b,a ;Copy back to B
- jmp rpack2 ;Go get another.
-
-rpack3: call getchr ;Get a character.
- jmp r ; Hit end of line, return bad.
- lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
- cmp m ;[gnn]
- jz rpack1 ; Yes, then go start over.
- sui ' ' ;Turn the char back into a number.
- sta temp3
-;Determine type of checksum
-
- lda curchk ;Get the current checksum type
- cpi '2' ;1, 2 or 3 character?
- jz rpack4 ;If zero, 2 character
- jnc rpack5 ;Go handle 3 character
- mov a,c ;Get the character total.
- ani 0C0H ;Turn off all but the two high order bits.
- ;Shift them into the low order position.
- rlc ;Two left rotates same as six rights
- rlc ; . . .
- add c ;Add it to the old bits.
- ani 3FH ;Turn off the two high order bits. (MOD 64)
- mov b,a
- lda temp3 ;Get the real received checksum.
- cmp b ;Are they equal?
- jz rpack7 ;If so, proceed.
-rpack9: call updrtr ;If not, update the number of retries.
- ret ;Return error.
-
-;Here for three character CRC-CCITT
-
-rpack5: lhld datptr ;Get the address of the data
- mvi m,0 ;Store a zero in the buffer to terminate packet
- lxi h,packet+1 ;Point at start of checksummed region
- call crcclc ;Calculate the CRC
- mov c,e ;Save low order half for later
- mov b,d ;Also copy high order
- mov a,d ;Get high byte
- rlc ;Want high four bits
- rlc ; . . .
- rlc ;And shift two more
- rlc ; . . .
- ani 0FH ;Keep only 4 bits
- mov d,a ;Back into D
- lda temp3 ;Get first value back
- cmp d ;Correct?
- jnz rpack9 ;No, punt
- call getchr ;Get a character.
- jmp r ; Hit end of line, return bad.
- lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
- cmp m ;[gnn]
- jz rpack1 ; Yes, then go start over.
- sui ' ' ;Remove space offset
- sta temp3 ;Store for later check
- ;...
-
-;Here for a two character checksum and last two characters of CRC
-
-rpack4: mov a,b ;Get high order portion
- ani 0FH ;Only four bits
- rlc ;Shift up two bits
- rlc ; . . .
- mov b,a ;Save back in B
- mov a,c ;Get low order
- rlc ;move two high bits to low bits
- rlc ; . . .
- ani 03H ;Save only low two bits
- ora b ;Get other 4 bits
- mov b,a ;Save back in B
- lda temp3 ;Get this portion of checksum
- cmp b ;Check first half
- jnz rpack9 ;If bad, go give up
- call getchr ;Get a character.
- jmp r ; Hit end of line, return bad.
- lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
- cmp m ;[gnn]
- jz rpack1 ; Yes, then go start over.
- sui ' ' ;Remove space offset
- mov b,a ;Save in safe place
- mov a,c ;Get low 8 bits of checksum
- ani 3FH ;Keep only 6 bits
- cmp b ;Correct value
- jnz rpack9 ;Bad, give up
-rpack7: lhld datptr
- mvi m,0 ;Put a null at the end of the data.
- lda temp1 ;Get the type.
- jmp rskp
-;
-; inpkt - receive and buffer packet
-; returns: nonskip if error (timeout)
-; skip if success; packet starts at recpkt (which holds the SOH)
-; and is terminated by a null.
-; console is selected in either case.
-; called by: rpack
-
-inpkt: lxi h,recpkt ;Point to the beginning of the packet.
- shld pktptr
-inpkt1: call inchr ;Get first character
- jmp r ;Return failure
- lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
- cmp m ;[gnn]
- jnz inpkt1 ;if not, ignore leading junk
- jmp inpkt3 ;else go put it in packet
-
-inpkt2: call inchr ;Get a character.
- jmp r ; Return failure.
- lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
- cmp m ;[gnn]
- jnz inpkt3 ;if not continue
- lxi h,recpkt ;else throw away what we've got so far
- shld pktptr ;
-inpkt3: lhld pktptr ;
- mov m,a ;Put the char in the packet.
- inx h
- shld pktptr
- mov b,a
- lxi d,-recpkx ;Start over if packet buffer overflow
- dad d ;
- jc inpkt ;buffer overflow
- lda reol ;Get the EOL char.
- cmp b
- jnz inpkt2 ;If not loop for another.
-;[gnn] *** added by Godfrey Nix Nottingham University ***
-;[gnn] to allow Kermit server to echo our packets back
- lxi h,recpkt+3 ;[gnn] point to packet type
- lda packet+3 ;[gnn] get the one we sent
- cmp m ;[gnn] are they the same?
- jz inpkt ;[gnn] yes, get another packet
-;[gnn] *** end of patch *****
- ;...
- ;...
-
-;Begin IBM change/fdc
-;This moved from OUTPK7 -- it appears that waiting until we're
-;ready to send a packet before looking for turnaround character
-;is long enough for it to get lost. Better to look now.
-
- lda ibmflg ;Is this the IBM?
- ora a
- jz inpkt6 ;If not then proceed.
- lda state ;Check if this is the Send-Init packet.
- cpi 'S'
- jz inpkt6 ;If so don't wait for the XON.
-inpkt5: call inchr ;Wait for the turn around char.
- jmp inpkt6
- cpi xon ;Is it the IBM turn around character?
- jnz inpkt5 ;If not, go until it is.
-inpkt6: lhld pktptr ;Reload packet pointer
-;End IBM change/fdc.
- dcx h ;Back up to end of line character
- mvi m,0 ;Replace it with a null to stop rpack:
- call selcon ;We've got the packet. Return to console.
-
- lda dbgflg ; Is debugging enabled?
- ora a
- jz inpkt7
- inx h ; Point to next char.
- lda quietd ; a quiet display?
- ana a
- jnz inpkt7 ; so dont say a thing
- call rppos ; position cursor
- lxi h,recpkt+1 ; print the packet
- call dmptxt
-
- lda prnflg ; is the printer on too?
- ana a
- jz inpkt7
- lxi h,rstatm ; print state
- call printm ; dumptext but to printer
- lda state
- mov e,a
- call outprn
- lxi h,princr ; cr lf to printer
- call printm
- lxi h,rpackm
- call printm
- lxi h,recpkt+1
- call printm
- lxi h,princr
- call printm
- lxi h,princr
- call printm
-
-
-inpkt7: lxi h,recpkt
- shld pktptr ;Save the packet pointer.
- jmp rskp ;If so we are done.
-
-; getchr - get next character from buffered packet.
-; returns nonskip at end of packet.
-; called by: rpack
-
-getchr: lhld pktptr ;Get the packet pointer.
- mov a,m ;Get the char.
- inx h
- shld pktptr
- ora a ;Is it the null we put at the end of the packet?
- jnz rskp ;If not return retskp.
- ret ;If so return failure.
-;
-;
-; inchr - character input loop for file transfer
-; returns: nonskip if timeout or character typed on console
-; (console selected)
-; skip with character from modem in A (parity stripped
-; if necessary; modem selected)
-; preserves bc, de, hl in either case.
-; called by: inpkt
-
-inchr: push h ; save hl and bc
- push b
- lhld timout ;Get initial value for timeout
- shld timval ;[jd]
-inchr0: call selmdm ;select modem
- call inpmdm ;Try to get a character from the modem
- ora a
- jz inchr2 ;if zero, nothing there.
- mov b,a
- lda parity ;Is the parity none?
- cpi parnon
- mov a,b
- jz inchr1 ;If so just return.
- ani 7FH ;Turn off the parity bit.
-inchr1: pop b ;restore registers
- pop h
- jmp rskp ;take skip return, character in A
-
-inchr2: call selcon ;select console
- call inpcon ; Try to get a character from the console
- ora a
- jz inchr6 ;If not go do timer thing
- cpi cr ;Is it a carriage return?
- jz inchr4 ;If so return
- cpi ('Z'-100O) ;Control-Z?
- jz inchr5 ;Yes, go flag it
- cpi ('C'-100O) ;Control-C?
- jz inchr7 ;re-enter, he wants to get out
- cpi ('X'-100O) ;Control-X?
- jnz inchr6 ;No, ignore it. do timer thing.
-inchr5: adi 100O ;Convert to printing range
- sta czseen ;Flag we saw a control-Z
- jmp inchr6 ;[MF] and do timer thing
-inchr4: pop b ; restore registers
- pop h
- ret ;And return
-
-inchr6: lda timflg ;[jd] pick up timer flag
- ora a ;[jd] are we allowed to use timer?
- jz inchr0 ;[jd] no, don't time out
- lhld timval ; decrement fuzzy time-out
- dcx h ;
- shld timval ;((timout-1) * loop time)
- mov a,h ;(Retry if not time-out)
- ora l ;
- jnz inchr0 ;
- call updrtr ;Count as retry (?)
- pop b ;restore registers
- pop h
- ret ;and return to do retry
-
-inchr7: call clrtop ;[hh] clear screen and home cursor
- lda takflg ;[MF]Take-file in progress?
- ani 1 ;[MF]...
- cnz closet ;[MF]Yes, close it and reset TAKE-flag
- ;[MF]so all processing is halted
- jmp kermit ;[hh] then re-enter kermit
-
-;
-; CRCCLC - Routine to calculate a CRC-CCITT for a string.
-;
-; This routine will calculate a CRC using the CCITT polynomial for
-; a string.
-;
-; call with: HL/ Address of null-terminated string
-; 16-bit CRC value is returned in DE.
-; Registers BC and HL are preserved.
-;
-; called by: spack, rpack
-
-crcclc: push h ;Save HL
- push b ;And BC
- lxi d,0 ;Initial CRC value is 0
-
-crccl0: mov a,m ;Get a character
- ora a ;Check if zero
- jz crccl1 ;If so, all done
- push h ;Save the pointer
- xra e ;Add in with previous value
- mov e,a ;Get a copy
- ani 0FH ;Get last 4 bits of combined value
- mov c,a ;Get into C
- mvi b,0 ;And make high order zero
- lxi h,crctb2 ;Point at low order table
- dad b ;Point to correct entry
- dad b ; . . .
- push h ;Save the address
- mov a,e ;Get combined value back again
- rrc ;Shift over to make index
- rrc ; . . .
- rrc ; . . .
- ani 1EH ;Keep only 4 bits
- mov c,a ;Set up to offset table
- lxi h,crctab ;Point at high order table
- dad b ;Correct entry
- mov a,m ;Get low order portion of entry
- xra d ;XOR with previous high order half
- inx h ;Point to high order byte
- mov d,m ;Get into D
- pop h ;Get back pointer to other table entry
- xra m ;Include with new high order half
- mov e,a ;Copy new low order portion
- inx h ;Point to other portion
- mov a,m ;Get the other portion of the table entry
- xra d ;Include with other high order portion
- mov d,a ;Move back into D
-
- pop h ;And H
- inx h ;Point to next character
- jmp crccl0 ;Go get next character
-
-crccl1: pop b ;Restore B
- pop h ;And HL
-
- ret ;And return, DE=CRC-CCITT
-
-CRCTAB: DW 00000H
- DW 01081H
- DW 02102H
- DW 03183H
- DW 04204H
- DW 05285H
- DW 06306H
- DW 07387H
- DW 08408H
- DW 09489H
- DW 0A50AH
- DW 0B58BH
- DW 0C60CH
- DW 0D68DH
- DW 0E70EH
- DW 0F78FH
-
-CRCTB2: DW 00000H
- DW 01189H
- DW 02312H
- DW 0329BH
- DW 04624H
- DW 057ADH
- DW 06536H
- DW 074BFH
- DW 08C48H
- DW 09DC1H
- DW 0AF5AH
- DW 0BED3H
- DW 0CA6CH
- DW 0DBE5H
- DW 0E97EH
- DW 0F8F7H
-;
-; This is where we go if we get an error during a protocol communication.
-; error prints the error packet on line 6 or so, and aborts the
-; transfer.
-; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, seot
-; error1 print CRLF followed by the error packet.
-; called by: finish, logout
-; error2 just prints the error packet.
-; error3 positions cursor and prints error message specified in DE.
-; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof,
-; seot, parwrn, gofil, outbuf
-
-error: lda quietd ; a quiet display?
- ana a
- jnz error0 ; so dont say a thing
- lda remtxt ;[MF]Doing a remote command?
- ora a ;[MF]...
- jnz error0 ;[MF]Yes, don't position cursor
- call screrr ;Position the cursor.
-error0: mvi a,'A' ;Set the state to abort.
- sta state
- jmp error2
-
-error1: lxi d,crlf ;Print a CRLF.
- lda quietd ; a quiet display?
- ana a
- jnz error2 ; so dont say a thing
- call prtstr
-error2: lda argblk+1 ;Get the length of the data.
- mov c,a
- mvi b,0 ;Put it into BC
- lxi h,data ;Get the address of the data.
- dad b ;Get to the end of the string.
- mvi m,'$' ;Put a dollar sign at the end.
- lxi d,data ;Print error message
- lda remtxt ;[MF]Doing a remote command?
- ora a ;[MF]...
- jnz errr2a ;[MF]Yes, print message, quiet or not!
- lda quietd ; a quiet display?
- ana a
- rnz ; so dont say a thing
-errr2a: call prtstr
- ret
-
-error3: lda quietd ; a quiet display?
- ana a
- rnz ; so dont say a thing
- lda remtxt ;[MF]Doing a remote command?
- ora a ;[MF]...
- jnz err3a ;[MF]Yes, don't position cursor
- push d ;Save the pointer to the message.
- call screrr ;Position the cursor.
- pop d ;Get the pointer back.
-err3a: call prtstr ;Print error message
- ret
-;
-; Set up for file transfer.
-; called by read, send.
-
-init: lxi d,version ; point at Kermit's version string
- lda quietd ; a quiet display?
- ana a
- jnz init1 ; so dont say a thing
- call sysscr ; fix up screen
-init1: call selmdm ; select modem
- call flsmdm ; purge any pending data
- call selcon ; select console again.
- ret
-
-; Set state to ABORT
-; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, seot,
-; nak, ackp
-
-abort: mvi a,'A' ;Otherwise abort.
- sta state
- ret
-
-; nak - send NAK packet
-; here from: rinit, rfile, rdata
-; nak0 - update retry count and send NAK packet
-; here from: rinit, rfile, rdata, tryagn
-
-nak0: call updrtr ;Update number of retries.
-nak: lda pktnum ;Get the packet number we're waiting for.
- sta argblk
- xra a ;No data.
- sta argblk+1
- mvi a,'N' ;NAK that packet.
- call spack
- jmp abort ; Give up.
- ret ;Go around again.
-
-; increment and display retry count
-; called by: rfile, sinit, sfile, sdata, seof, seot,
-; nak, rpack, inchr, tryagn
-
-updrtr: lhld numrtr
- inx h ;Increment the number of retries
- shld numrtr
- lda remtxt ;[MF]Doing a remote server command?
- ora a ;[MF]...
- rnz ;[MF]Yes, keep mum
- lda quietd ; a quiet display?
- ana a
- rnz ; so dont say a thing
- call scrnrt ;Position cursor
- lhld numrtr ;[MF]
-call nout ;Write the number of retries.
- ret
-
-; [jd] this routine prints parity warnings. All registers are
-; saved except for a.
-; called by: sdata
-
-parwrn: push b
- push d
- push h
- lxi d,inms25
- call error3
- pop h
- pop d
- pop b
- ret
-;[jd] end of addition
-
-; print message in status field. address of message is in DE.
-; called by: read, send
-
-finmes: lda quietd ; a quiet display?
- ana a
- jz finme0 ; so do usual stuff
- push d ;[MF]Save pointer to completion message
- call prcrlf ; best do a new line
- pop d ;[MF]Restore completion message pointer
- call prtstr ; and send message
- mvi e,space ; send a space or two
- mvi c,dconio
- push b
- push d
- call bdos
- pop d
- pop b
- call bdos
- ret ; and exit back
-;
-;else for screaming screens...
-
-finme0: push d ;Save message.
- call scrst ;Position cursor
- pop d ;Print the termination message
- call prtstr
- ret ; may not want this **************
-
- mvi c,4 ;[2] copy across user no and drive
- lxi h,kerm1 ;[2] as we have the text already
-finme1: mov e,m
- push h ;[2] conout probably destroys these
- push b
- call conout
- pop b
- pop h
- inx h ;[2] next character
- dcr c ;[2] ah, but have we done?
- jnz finme1 ;[2] nope
- lxi d,spac15 ;[2] send 15 spaces (clears previous filename)
- call prtstr ;[2]
- call scrend ;Position cursor for prompt
- ret
-
-; Compare expected packet number against received packet number.
-; return with flags set (Z = packet number valid)
-; called by: rfile, rdata, sinit, sfile, sdata, seof, seot
-
-compp: lda pktnum ;Get the packet Nr.
- mov b,a
- lda argblk
- cmp b
- ret
-
-; Increment the packet number, modulo 64.
-; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, seot
-
-countp: inr a ;Increment packet Nr.
- ani 3FH ;Turn off the two high order bits
- sta pktnum ;Save modulo 64 of number
- lhld numpkt
- inx h ;Increment Nr. of packets
- shld numpkt
- ret
-
-; Send an ACK-packet
-; called by: rfile, rdata, tryagn
-
-ackp: xra a
- sta numtry ;Reset number of retries
- sta argblk+1 ;No data. (The packet number is in argblk)
- mvi a,'Y' ;Acknowledge packet
- call spack ;Send packet
- jmp abort
- ret
-
-; ?
-; called with A/ current retry count
-; called by: rfile, rdata
-
-tryagn: inr a ;Increment it.
- sta oldtry ;Save the updated number of tries.
- lda pktnum ;Get the present packet number.
- dcr a ;Decrement
- ani 3FH ; modulo 64
- mov b,a
- lda argblk ;Get the packet's number
- cmp b ;Is the packet's number one less than now?
- jnz nak0 ;No, NAK it and try again.
- call updrtr ;Update the number of retries.
- call ackp
- ret
-
-; Output a null-terminated string to the console. We assume that the
-; console has been selected. Called with HL = address of string.
-; called by: spack, inpkt
-
-dmptxt: mov a,m ; get character from string
- ora a
- rz ; done if null
- push h ; save string address
- mov e,a ; move character to E for outcon
- call outcon ; output character to console
- pop h ; restore string address
- inx h ; point past printed character
- jmp dmptxt ; go output rest of string
-
-
-; Output a null-terminated string to the PRINTER We assume that the
-; console has been selected. Called with HL = address of string.
-; called by: spack, inpkt
-
-printm: mov a,m ; get character from string
- ora a
- rz ; done if null
- push h ; save string address
- mov e,a ; move character to E for outcon
- call outprn ; output character to printer
- pop h ; restore string address
- inx h ; point past printed character
- jmp printm ; go output rest of string
-
-
-;
-; test if character in A is the start of header character. We get
-; the start of packet character from sohchr, which can be SET
-tstsoh: push b ; save these registers for a bit
- mov c,a ; we have to test if this is the character
- lda sohchr
- cmp c ; if zero, then it is
- mov a,c ; restore accumulator but not flags
- pop b
- ret ; return with flags set
-;
-
-
-; Little code to allow some expansion of code without changing
-; every futher address, only up to the end of this file.
-; TO BE REMOVED FRO RELEASE!
-
-; org ($+100h) AND 0FF00H
-
-
-IF lasm
- LINK CPSREM
-ENDIF;lasm
+; CPSPK2.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the (system-independent) routines that implement
+; the KERMIT protocol, and the commands that use them:
+; RECEIVE, SEND, FINISH, and LOGOUT.
+;
+; revision history:
+;
+;edit 11, 21-Mar-1991 by MF. After "inchr7", close TAKE-file (if any) so
+; ^C will halt all processing (including commands from TAKE-files)
+; and put the user back at Kermit command-level.
+;edit 10, 3-Jan-1991 by MF. Modify routine "inchr" after label "inchr5" to
+; not take retry (nonskip) return if ^X/^Z seen on the Console. This
+; will prevent multiple copies of packets being sent if user aborts
+; some files in a stream being sent via ^X and is a better fix to this
+; problem than flushing comm input before sending the "Z" packet
+; requesting the remote Kermit to discard the current file being
+; received (as implemented in CPSPK1.ASM edit of 2-jan-1991).
+;edit 9, 14-Dec-1990 by MF. Modified "gofil" routine to allow for
+; specification of a drive in the local filespec for GET and
+; RECEIVE commands. Thus commands such as
+; GET HELLO.TXT B:GOODBYE.TXT
+; and
+; RECEIVE B:GOODBYE.TXT
+; now work as expected.
+;edit 8, 22-Oct-1990 by MF. Fixed bug in completion-message routine
+; "finmes" wherein the completion message was not printed if the
+; terminal was set to QUIET because the message pointer was clobbered
+; by prcrlf.
+;edit 7, 14-Sep-1990 by MF. Add hooks for SET COLLISION command.
+; Eliminate commented-out old file warning rename routine.
+; Clear communication input buffers (call flsmdm) before
+; BYE, FINISH and LOGOUT commands.
+;edit 6, 9-Sep-1990 by MF. Implemented fixes in CPKERM.BWR for
+; garbage printout during quiet transfers and for file existence/
+; rename algorithm.
+; Also implemented hooks for Remote commands.
+; edit 5, 18 June 1990 by Russell Lang [rjl@monu1.cc.monash.edu.au]
+; When trying to generate a unique file name on receive, zero
+; the attribute bits between file opening attempts. This is
+; to fix a bug which caused the unique file name to have the
+; attributes of the already existing file. If the attribute
+; was R/O, a bdos error occured later when an attempt was made
+; to write to the file.
+;
+; edit 4, 27 October, 1987 By OBSchou. Changed the rename routine to
+; be more like the MSDOS issue.
+;
+; edit 3, 28 July, by OBSchou. Added traps to NOT print to screen during
+; file transfers if quietd is non zero (ie we SET TERMINAL QUIET)
+; This hopefully speeds up transfers in systems spending an age
+; updating the screen.
+;
+; edit 2, 8 April, 1987 by OBSchou. Minor edit to put drive and user number
+; in the "filename" field on the transfer screen. This means that the
+; offset on the line foe the file name proper has moved along 4 space.
+; Also, it writes 15 spaces AFER the xxd: string to clear the field
+; of any prevous file. Needed for thos terminals that cannot
+; clear to end of line...
+;
+; edit 1, 28 January, 1987 by OBSchou.
+; Hived off about 1/2 of CPSPKT.ASM to form two (smaller => easier
+; to handle) files.
+;
+;
+
+pk2ver: db 'CPSPK2.ASM (11) 21-Mar-1991$' ; name, edit number, date
+
+
+;
+; Get the file name (including host to micro translation)
+; called by: rfile
+
+gofil: xra a
+ sta fcb ;Set the drive to default to current.
+ lxi h,data ;Get the address of the file name.
+; allow use of local name if one was given [gnn]
+ lda remlen ;[gnn]
+ ora a ;[gnn] anything there?
+ jz gofil0 ;[gnn] no, use the one in the data packet
+ lxi h,remnam ;[gnn] yes, use this instead
+ lda remnam+1 ;[MF]Get 2nd char of local filename
+ cpi ':' ;[MF]Was a drive specified?
+ jnz gofil0 ;[MF]No, proceed as of old
+ mov a,m ;[MF]Yes, get drive
+ ani 5fh ;[MF]Force uppercase
+ sui 'A'-1 ;[MF]Make valid drive for fcb
+ sta fcb ;[MF]and store in fcb
+ inx h ;[MF]Skip drive and delimiter
+ inx h ;[MF]...
+gofil0: ;[gnn] continue to set up the file [gnn]
+;
+ shld datptr ;Store the address.
+ lxi h,fcb+1 ;Address of the FCB.
+ shld fcbptr ;Save it.
+ xra a
+ sta temp1 ;Initialize the char count.
+ sta temp2
+ mvi b,' '
+gofil1: mov m,b ;Blank the FCB.
+ inx h
+ inr a
+; cpi 0CH ;Twelve?[5a]
+ cpi 0BH ; Eleven? [5a]
+ jm gofil1
+ mvi m,0 ; [5a] Specify extent 0
+gofil2: lhld datptr ;Get the NAME field.
+ mov a,m
+ cpi 'a' ;Force upper case
+ jm gofl2a ;
+ ani 5FH ;
+gofl2a: inx h
+ cpi '.' ;Seperator?
+ jnz gofil3
+ shld datptr ;[jd] update ptr (moved from above)
+ lxi h,fcb+9H
+ shld fcbptr
+ lda temp1
+ sta temp2
+ mvi a,9H
+ sta temp1
+ jmp gofil6
+
+gofil3: ora a ;Trailing null?
+ jz gofil7 ;Then we're done.
+ shld datptr ;[jd] no, can update ptr now.
+ lhld fcbptr
+ mov m,a
+ inx h
+ shld fcbptr
+ lda temp1 ;Get the char count.
+ inr a
+ sta temp1
+ cpi 8H ;Are we finished with this field?
+ jm gofil2
+gofil4: sta temp2
+ lhld datptr
+ mov a,m
+ inx h
+ shld datptr
+ ora a
+ jz gofil7
+ cpi '.' ;Is this the terminator?
+ jnz gofil4 ;Go until we find it.
+gofil6: lhld datptr ;Get the TYPE field.
+ mov a,m
+ cpi 'a' ;Force upper case
+ jm gofl6a ;
+ ani 5FH ;
+gofl6a: ora a ;Trailing null?
+ jz gofil7 ;Then we're done.
+;[jd] move above two lines so we don't increment pointer if char is null
+ inx h
+ shld datptr
+ lhld fcbptr
+ mov m,a
+ inx h
+ shld fcbptr
+ lda temp1 ;Get the char count.
+ inr a
+ sta temp1
+ cpi 0CH ;Are we finished with this field?
+ jm gofil6
+gofil7: lhld datptr
+ mvi m,'$' ;Put in a dollar sign for printing.
+ lda quietd ; quiet display?
+ ana a
+ jnz gofi70 ; yes, so skip it.
+ call scrfln ;Position cursor
+gofi70: lxi d,data ;Print the file name
+ lda getrxflg ;[obs 8] are we doing a get or receive?
+ ana a ;[obs 8]
+ jz gofi7a ;[obs 8] if zero, receive
+ lxi d,remnam ;[obs 8]
+gofi7a: ;[obs 8]
+
+ call prtstr
+gofi7b: xra a ;[MF]Zero "discard" flag
+ sta dscflg ;[MF]...
+ lda flwflg ;Is file warning on?
+ ora a
+ jz gofil9 ;If not, just proceed.
+ mvi c,openf ;See if the file exists.
+ lxi d,fcb
+ call bdos
+ cpi 0FFH ;Does it exist?
+ jz gofil9 ;If not create it.
+;
+ lda flwflg ;[MF]Get flag again
+ cpi 3 ;[MF]SET COLLISION DISCARD?
+ jnz gofi7h ;[MF]No
+ mvi a,0ffh ;[MF]Yes, order rejection of the file
+ sta dscflg ;[MF]...
+ jmp rskp ;[MF]and pretend successful open
+gofi7h: push psw ;[MF]Save Collision status
+ lxi d,infms5
+ call error3
+ pop psw ;[MF]Restore Collision status
+ cpi 1 ;[MF]SET COLLISION RENAME?
+ jz gofi7i ;[MF]Yes, same as SET WARNING ON
+ ;[MF]If we come here, SET COLLISION BACKUP
+ lxi h,fcb ;[MF]Copy original fcb to a safe place
+ lxi d,colfcb ;[MF]...
+ lxi b,33 ;[MF]...
+ call mover ;[MF]...
+ ;[MF]and fall into rename code
+gofi7i: ;[MF]
+;
+; Replacement file name renamer routine. Incomming
+; files are renamed in this manner:
+; original file name: filex.ext
+; first rename: filex001.ext
+; ... ...
+; ninth rename filex009.ext
+; 10th rename fail - would we really want 10
+; files of the same name??
+;
+;
+; 1)
+; Assume that we need to "rename" the file, so lets make sure
+; that there is a full. 8 character filename. (We make it if
+; it does not already exist)
+; 1a) If full file name, last character is to be replaced
+; by a zero. This gives us up to no#ine renames.
+; 2)open file
+; 2a)If exists, increment last character by one
+; 2b)if = '9' then abort
+; 2c)If does not exist, got 2)
+; 3)we have a valid 'renamed' file
+;
+;Part 1) - fill out filename part
+
+ mvi c,8 ; max 8 characters to test for
+ mvi a,'0' ; spaces to be replaced by a zero.
+ lxi h,fcb+8 ; start at the end
+gofi7c: mov m,a ; put a zero in here
+ dcr c ; come to the end?
+ jz gofi7d ; should not have, but just in case...
+ dcx h ; previous chararcter
+ mov a,m ; get it
+ cpi ' ' ; if this character a space as well, zero it
+ mvi a,'0' ; set it to ascii zero just in case...
+ jz gofi7c ;
+;
+; Part 2) open the file (if success, then it exists)
+
+gofi7d:
+;zero the attribute bits. [rjl@monu1.cc.monash.edu.au]
+ lxi h,fcb+1 ;[rjl]
+ mvi c,11 ;[rjl]
+gofi7z: mov a,m ;[rjl]
+ ani 07fh ;[rjl]
+ mov m,a ;[rjl]
+ inx h ;[rjl]
+ dcr c ;[rjl]
+ jnz gofi7z ;[rjl]
+ lxi d,fcb
+ mvi c,openf
+ call BDOS
+ inr a ; if 0ffh returned, error (ie does not exist)
+ jz gofi7e
+ lda fcb+8 ; get last character
+ inr a
+ sta fcb+8
+ cpi '9'+1 ; more than '9' => too far, lets give up.
+ jnz gofi7d ; else try again
+;Giving up, so lets exit
+ lxi d,erms16 ;
+ call prtstr
+ ret ; return to error routine
+
+gofi7e: lxi d,fnbuf ; make the file name into a character string
+ lxi h,fcb+1 ; point to source file name, less drive name
+ mvi c,8 ; 11 characters (8+3) + dot to copy across
+;
+gofi7f: mov a,m ; get character
+ stax d
+ inx h
+ inx d
+ dcr c
+ jnz gofi7f ; loop until all done
+
+ mvi a,'.' ; then the dot
+ stax d
+ inx d
+
+ mvi c,3 ; then the file extention
+
+gofi7g: mov a,m
+ stax d
+ inx h
+ inx d
+ dcr c
+ jnz gofi7g ; loop until extention copied across
+
+ mvi a,'$' ; dollar terminate string
+ stax d
+ lxi d,fnbuf ;[MF]Point to string
+ call prtstr ; write string to console
+
+ lda flwflg ;[MF]Get warning (SET COLLISION) flag
+ cpi 2 ;[MF]SET COLLISION BACKUP?
+ jnz gofil9 ;[MF]No
+ lxi h,fcb ;[MF]Yes, get new filename fcb
+ lxi d,colfcb+16 ;[MF]Where to copy to for rename
+ lxi b,16 ;[MF]Copy 16 bytes
+ call mover ;[MF]...
+ lxi d,colfcb ;[MF]Point to rename fcb
+ mvi c,renam ;[MF]Rename function
+ call bdos ;[MF]Try to rename original file
+ cpi 0ffh ;[MF]Did we win?
+ jnz gofl82 ;[MF]Yes
+ lxi d,erms16 ;[MF]No, complain and bomb
+ jmp error3 ;[MF]...
+gofl82: lxi h,colfcb ;[MF]Now recopy original filename into fcb
+ lxi d,fcb ;[MF]to create new file with original name
+ lxi b,16 ;[MF]...
+ call mover ;[MF]...
+;
+;
+;Now lets make the file (create it)
+
+gofil9: call makfil ; Create the file.
+ jmp gofl91 ; Disk was full.
+ jmp rskp ; Success.
+
+gofl91: lxi d,erms11
+ call error3
+ ret
+;
+; This is the FINISH command. It tells the remote KERSRV to exit.
+; here from kermit
+
+finish: call cfmcmd
+ call selmdm ;[MF]Select modem
+ call flsmdm ;[MF]Flush buffers
+ call selcon ;[MF]Select keyboard again
+ xra a
+ sta numtry ;Inititialize count.
+ mvi a,'1' ;Reset block check type to single character
+ sta curchk ; . . .
+
+finsh1: lda numtry ;How many times have we tried?
+ cpi maxtry ;Too many times?
+ jm finsh3 ;No, try it.
+finsh2: lxi d,erms18 ;Say we couldn't do it.
+ call prtstr
+ jmp kermit ;Go home.
+
+finsh3: inr a ;Increment the number of tries.
+ sta numtry
+ xra a
+ sta argblk ;Make it packet number zero.
+ mvi a,1
+ sta argblk+1 ;One piece of data.
+ lxi h,data
+ mvi m,'F' ;Finish running Kermit.
+ mvi a,'G' ;Generic command packet.
+ call spack
+ jmp finsh2 ; Tell the user and die.
+ call rpack ;Get an acknowledgement.
+ jmp finsh1 ; Go try again.
+ cpi 'Y' ;ACK?
+ jz kermit ;Yes, we are done.
+ cpi 'E' ;Is it an error packet?
+ jnz finsh1 ;Try sending the packet again.
+ call error1 ;Print the error message.
+ jmp kermit
+;
+; This is the LOGOUT command. It tells the remote KERSRV to logout.
+; here from: kermit
+
+logout: call cfmcmd
+ call logo ;Send the logout packet.
+ jmp kermit ;Go get another command
+ jmp kermit ; whether we succeed or not.
+
+; do logout processing.
+; called by: bye, logout
+
+logo: call selmdm ;[MF]Select modem
+ call flsmdm ;[MF]Flush buffers
+ call selcon ;[MF]Select keyboard again
+ xra a
+ sta numtry ;Inititialize count.
+ mvi a,'1' ;Reset block check type to single character
+ sta curchk ; . . .
+
+logo1: lda numtry ;How many times have we tried?
+ cpi maxtry ;Too many times?
+ jm logo3 ;No, try it.
+logo2: lxi d,erms19 ;Say we couldn't do it.
+ call prtstr
+ ret ;Finished.
+
+logo3: inr a ;Increment the number of tries.
+ sta numtry
+ xra a
+ sta argblk ;Make it packet number zero.
+ mvi a,1
+ sta argblk+1 ;One piece of data.
+ lxi h,data
+ mvi m,'L' ;Logout the remote host.
+ mvi a,'G' ;Generic command packet.
+ call spack
+ jmp logo2 ; Tell the user and die.
+ call rpack ;Get an acknowledgement
+ jmp logo1 ; Go try again.
+ cpi 'Y' ;ACK?
+ jz rskp ;Yes, we are done.
+ cpi 'E' ;Is it an error packet?
+ jnz logo1 ;Try sending the packet again.
+ call error1 ;Print the error message.
+ ret ;All done.
+;
+; Packet routines
+
+; Send_Packet
+; This routine assembles a packet from the arguments given and sends it
+; to the host.
+;
+; Expects the following:
+; A - Type of packet (D,Y,N,S,R,E,F,Z,T)
+; ARGBLK - Packet sequence number
+; ARGBLK+1 - Number of data characters
+; Returns: nonskip if failure
+; skip if success
+; called by: read, rinit, rfile, rdata, sinit, sfile, sdata, seof, seot,
+; finish, logout, nak, ackp
+
+spack: sta argblk+2
+ lxi h,packet ;Get address of the send packet.
+ lda sndsop ;[gnn] send start-of-pkt char.
+ mov m,a ;Put in the packet.
+ inx h ;Point to next char.
+ lda curchk ;Get current checksum type
+ sui '1' ;Determine extra length of checksum
+ mov b,a ;Copy length
+ lda argblk+1 ;Get the number of data chars.
+ adi ' '+3 ;Real packet character count made printable.
+ add b ;Determine overall length
+ mov m,a ;Put in the packet.
+ inx h ;Point to next char.
+ lxi b,0 ;Zero the checksum AC.
+ mov c,a ;Start the checksum.
+ lda argblk ;Get the packet number.
+ adi ' ' ;Add a space so the number is printable.
+ mov m,a ;Put in the packet.
+ inx h ;Point to next char.
+ add c
+ mov c,a ;Add the packet number to the checksum.
+ mvi a,0 ;Clear A (Cannot be XRA A, since we can't
+ ; touch carry flag)
+ adc b ;Get high order portion of checksum
+ mov b,a ;Copy back to B
+ lda argblk+2 ;Get the packet type.
+ mov m,a ;Put in the packet.
+ inx h ;Point to next char.
+ add c
+ mov c,a ;Add the packet number to the checksum.
+ mvi a,0 ;Clear A
+ adc b ;Get high order portion of checksum
+ mov b,a ;Copy back to B
+spack2: lda argblk+1 ;Get the packet size.
+ ora a ;Are there any chars of data?
+ jz spack3 ; No, finish up.
+ dcr a ;Decrement the char count.
+ sta argblk+1 ;Put it back.
+ mov a,m ;Get the next char.
+ inx h ;Point to next char.
+ add c
+ mov c,a ;Add the packet number to the checksum.
+ mvi a,0 ;Clear A
+ adc b ;Get high order portion of checksum
+ mov b,a ;Copy back to B
+ jmp spack2 ;Go try again.
+
+spack3: lda curchk ;Get the current checksum type
+ cpi '2' ;Two character?
+ jz spack4 ;Yes, go handle it
+ jnc spack5 ;No, go handle CRC if '3'
+ mov a,c ;Get the character total.
+ ani 0C0H ;Turn off all but the two high order bits.
+ ;Shift them into the low order position.
+ rlc ;Two left rotates same as 6 rights
+ rlc ; . . .
+ add c ;Add it to the old bits.
+ ani 3FH ;Turn off the two high order bits. (MOD 64)
+ adi ' ' ;Add a space so the number is printable.
+ mov m,a ;Put in the packet.
+ inx h ;Point to next char.
+ jmp spack7 ;Go store eol character
+
+;Here for 3 character CRC-CCITT
+
+spack5: mvi m,0 ;Store a null for current end
+ push h ;Save H
+ lxi h,packet+1 ;Point to first checksumed character
+ call crcclc ;Calculate the CRC
+ pop h ;Restore the pointer
+ mov c,e ;Get low order half for later
+ mov b,d ;Copy the high order
+ mov a,d ;Get the high order portion
+ rlc ;Shift off low 4 bits
+ rlc ; . . .
+ rlc ; . . .
+ rlc ; . . .
+ ani 0FH ;Keep only low 4 bits
+ adi ' ' ;Put into printing range
+ mov m,a ;Store the character
+ inx h ;Point to next position
+
+;Here for two character checksum
+
+spack4: mov a,b ;Get high order portion
+ ani 0FH ;Only keep last four bits
+ rlc ;Shift up two bits
+ rlc ; . . .
+ mov b,a ;Copy back into safe place
+ mov a,c ;Get low order half
+ rlc ;Shift high two bits
+ rlc ;to low two bits
+ ani 03H ;Keep only two low bits
+ ora b ;Get high order portion in
+ adi ' ' ;Convert to printing character range
+ mov m,a ;Store the character
+ inx h ;Point to next character
+ mov a,c ;get low order portion
+ ani 3FH ;Keep only six bits
+ adi ' ' ;Convert to printing range
+ mov m,a ;Store it
+ inx h ;Bump the pointer
+
+spack7: lda dbgflg
+ ora a ; is debugging enabled?
+ jz spack8
+ push h ; yes. save address of end of packet
+ mvi m,0 ; null-terminate the packet for display
+ lda quietd ; a quiet display?
+ ana a
+ jnz spac7a ; so dont say a thing
+ call sppos ; position cursor
+ lxi h,packet+1 ; print the packet
+ call dmptxt
+ lda prnflg ; is the printer on too?
+ ana a
+ jz spac7a
+ lxi h,sstatm ; print state
+ call printm ; dumptext but to printer
+ lda state
+ mov e,a
+ call outprn
+ lxi h,princr ; cr lf to printer
+ call printm
+ lxi h,spackm
+ call printm
+ lxi h,packet+1
+ call printm
+ lxi h,princr
+ call printm
+ lxi h,princr
+ call printm
+
+spac7a: pop h ; restore address of end of packet
+spack8: lda seol ;Get the EOL the other host wants.
+ mov m,a ;Put in the packet.
+ inx h ;Point to next char.
+ xra a ;Get a null.
+ mov m,a ;Put in the packet.
+; Write out the packet.
+outpkt: call selmdm ; Set up for output to comm port if iobyt
+ lda spad ;Get the number of padding chars.
+ sta temp1
+outpk2: lda temp1 ;Get the count.
+ dcr a
+ ora a
+ jm outpk6 ;If none left proceed.
+ sta temp1
+ lda spadch ;Get the padding char.
+ call setpar ;Set parity appropriately
+ mov e,a ;Put the char in right AC.
+ call outmdm ;Output it.
+ jmp outpk2
+
+outpk6: lxi h,packet ; Point to the packet.
+outlup: mov a,m ; Get the next character.
+ ora a ; Is it a null?
+ jz outlud ; If so return success.
+ call setpar ; Set parity for the character
+ mov e,a ; Put it in right AC
+ call outmdm ; and output it.
+; TAC trap: If this character is the TAC intercept character, and the TAC
+; trap is enabled, we have to output it twice. If the TAC trap is enabled,
+; tacflg contains the intercept character. (The current character cannot
+; be NUL, so we don't have to worry about doubling nulls in the message)
+ lda tacflg ; get current intercept character, or zero.
+ cmp m ; compare against current data character.
+ jnz outpk8 ; if different, do nothing.
+ call setpar ; match. set appropriate parity,
+ mov e,a ; put it in the right register,
+ call outmdm ; and output it a second time.
+outpk8:
+ inx h ; Increment the char pointer.
+ jmp outlup
+
+outlud: call selcon ; select console
+ jmp rskp ; and return success
+;
+; Receive_Packet
+; This routine waits for a packet to arrive from the host. It reads
+; characters until it finds a SOH. It then reads the packet into packet.
+;
+; Returns: nonskip if failure (checksum wrong or packet trashed)
+; skip if success, with
+; A - message type
+; ARGBLK - message number
+; ARGBLK+1 - length of data
+; called by: rinit, rfile, rdata,
+; sinit, sfile, sdata, seof, seot, finish, logout
+
+rpack: call inpkt ;Read up to the end-of-line character
+ jmp r ; Return bad.
+rpack0: call getchr ;Get a character.
+ jmp rpack ; Hit eol;null line;just start over.
+ lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
+ cmp m ;[gnn]
+ jnz rpack0 ; No, go until it is.
+rpack1: call getchr ;Get a character.
+ jmp r ; Hit end of line, return bad.
+ lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
+ cmp m ;[gnn]
+ jz rpack1 ; Yes, then go start over.
+ sta packet+1 ;Store in packet also
+ mov c,a ;Start the checksum.
+ lda curchk ;Get block check type
+ sui '1' ;Determine extra length of block check
+ mov b,a ;Get a copy
+ mov a,c ;Get back length character
+ sui ' '+3 ;Get the real data count.
+ sub b ;Get total length
+ sta argblk+1
+ mvi b,0 ;Clear high order half of checksum
+ call getchr ;Get a character.
+ jmp r ; Hit end of line, return bad.
+ lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
+ cmp m ;[gnn]
+ jz rpack1 ; Yes, then go start over.
+ sta argblk
+ sta packet+2 ;Save also in packet
+ add c
+ mov c,a ;Add the character to the checksum.
+ mvi a,0 ;Clear A
+ adc b ;Get high order portion of checksum
+ mov b,a ;Copy back to B
+ lda argblk
+ sui ' ' ;Get the real packet number.
+ sta argblk
+ call getchr ;Get a character.
+ jmp r ; Hit end of line, return bad.
+ lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
+ cmp m ;[gnn]
+ jz rpack1 ; Yes, then go start over.
+ sta temp1 ;Save the message type.
+ sta packet+3 ;Save in packet
+ add c
+ mov c,a ;Add the character to the checksum.
+ mvi a,0 ;Clear A
+ adc b ;Get high order portion of checksum
+ mov b,a ;Copy back to B
+ lda argblk+1 ;Get the number of data characters.
+ sta temp2
+ lxi h,data ;Point to the data buffer.
+ shld datptr
+rpack2: lda temp2
+ sui 1 ;Any data characters?
+ jm rpack3 ; If not go get the checksum.
+ sta temp2
+ call getchr ;Get a character.
+ jmp r ; Hit end of line, return bad.
+ lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
+ cmp m ;[gnn]
+ jz rpack1 ; Yes, then go start over.
+ lhld datptr
+ mov m,a ;Put the char into the packet.
+ inx h ;Point to the next character.
+ shld datptr
+ add c
+ mov c,a ;Add the character to the checksum.
+ mvi a,0 ;Clear A
+ adc b ;Get high order portion of checksum
+ mov b,a ;Copy back to B
+ jmp rpack2 ;Go get another.
+
+rpack3: call getchr ;Get a character.
+ jmp r ; Hit end of line, return bad.
+ lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
+ cmp m ;[gnn]
+ jz rpack1 ; Yes, then go start over.
+ sui ' ' ;Turn the char back into a number.
+ sta temp3
+;Determine type of checksum
+
+ lda curchk ;Get the current checksum type
+ cpi '2' ;1, 2 or 3 character?
+ jz rpack4 ;If zero, 2 character
+ jnc rpack5 ;Go handle 3 character
+ mov a,c ;Get the character total.
+ ani 0C0H ;Turn off all but the two high order bits.
+ ;Shift them into the low order position.
+ rlc ;Two left rotates same as six rights
+ rlc ; . . .
+ add c ;Add it to the old bits.
+ ani 3FH ;Turn off the two high order bits. (MOD 64)
+ mov b,a
+ lda temp3 ;Get the real received checksum.
+ cmp b ;Are they equal?
+ jz rpack7 ;If so, proceed.
+rpack9: call updrtr ;If not, update the number of retries.
+ ret ;Return error.
+
+;Here for three character CRC-CCITT
+
+rpack5: lhld datptr ;Get the address of the data
+ mvi m,0 ;Store a zero in the buffer to terminate packet
+ lxi h,packet+1 ;Point at start of checksummed region
+ call crcclc ;Calculate the CRC
+ mov c,e ;Save low order half for later
+ mov b,d ;Also copy high order
+ mov a,d ;Get high byte
+ rlc ;Want high four bits
+ rlc ; . . .
+ rlc ;And shift two more
+ rlc ; . . .
+ ani 0FH ;Keep only 4 bits
+ mov d,a ;Back into D
+ lda temp3 ;Get first value back
+ cmp d ;Correct?
+ jnz rpack9 ;No, punt
+ call getchr ;Get a character.
+ jmp r ; Hit end of line, return bad.
+ lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
+ cmp m ;[gnn]
+ jz rpack1 ; Yes, then go start over.
+ sui ' ' ;Remove space offset
+ sta temp3 ;Store for later check
+ ;...
+
+;Here for a two character checksum and last two characters of CRC
+
+rpack4: mov a,b ;Get high order portion
+ ani 0FH ;Only four bits
+ rlc ;Shift up two bits
+ rlc ; . . .
+ mov b,a ;Save back in B
+ mov a,c ;Get low order
+ rlc ;move two high bits to low bits
+ rlc ; . . .
+ ani 03H ;Save only low two bits
+ ora b ;Get other 4 bits
+ mov b,a ;Save back in B
+ lda temp3 ;Get this portion of checksum
+ cmp b ;Check first half
+ jnz rpack9 ;If bad, go give up
+ call getchr ;Get a character.
+ jmp r ; Hit end of line, return bad.
+ lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
+ cmp m ;[gnn]
+ jz rpack1 ; Yes, then go start over.
+ sui ' ' ;Remove space offset
+ mov b,a ;Save in safe place
+ mov a,c ;Get low 8 bits of checksum
+ ani 3FH ;Keep only 6 bits
+ cmp b ;Correct value
+ jnz rpack9 ;Bad, give up
+rpack7: lhld datptr
+ mvi m,0 ;Put a null at the end of the data.
+ lda temp1 ;Get the type.
+ jmp rskp
+;
+; inpkt - receive and buffer packet
+; returns: nonskip if error (timeout)
+; skip if success; packet starts at recpkt (which holds the SOH)
+; and is terminated by a null.
+; console is selected in either case.
+; called by: rpack
+
+inpkt: lxi h,recpkt ;Point to the beginning of the packet.
+ shld pktptr
+inpkt1: call inchr ;Get first character
+ jmp r ;Return failure
+ lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
+ cmp m ;[gnn]
+ jnz inpkt1 ;if not, ignore leading junk
+ jmp inpkt3 ;else go put it in packet
+
+inpkt2: call inchr ;Get a character.
+ jmp r ; Return failure.
+ lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char.
+ cmp m ;[gnn]
+ jnz inpkt3 ;if not continue
+ lxi h,recpkt ;else throw away what we've got so far
+ shld pktptr ;
+inpkt3: lhld pktptr ;
+ mov m,a ;Put the char in the packet.
+ inx h
+ shld pktptr
+ mov b,a
+ lxi d,-recpkx ;Start over if packet buffer overflow
+ dad d ;
+ jc inpkt ;buffer overflow
+ lda reol ;Get the EOL char.
+ cmp b
+ jnz inpkt2 ;If not loop for another.
+;[gnn] *** added by Godfrey Nix Nottingham University ***
+;[gnn] to allow Kermit server to echo our packets back
+ lxi h,recpkt+3 ;[gnn] point to packet type
+ lda packet+3 ;[gnn] get the one we sent
+ cmp m ;[gnn] are they the same?
+ jz inpkt ;[gnn] yes, get another packet
+;[gnn] *** end of patch *****
+ ;...
+ ;...
+
+;Begin IBM change/fdc
+;This moved from OUTPK7 -- it appears that waiting until we're
+;ready to send a packet before looking for turnaround character
+;is long enough for it to get lost. Better to look now.
+
+ lda ibmflg ;Is this the IBM?
+ ora a
+ jz inpkt6 ;If not then proceed.
+ lda state ;Check if this is the Send-Init packet.
+ cpi 'S'
+ jz inpkt6 ;If so don't wait for the XON.
+inpkt5: call inchr ;Wait for the turn around char.
+ jmp inpkt6
+ cpi xon ;Is it the IBM turn around character?
+ jnz inpkt5 ;If not, go until it is.
+inpkt6: lhld pktptr ;Reload packet pointer
+;End IBM change/fdc.
+ dcx h ;Back up to end of line character
+ mvi m,0 ;Replace it with a null to stop rpack:
+ call selcon ;We've got the packet. Return to console.
+
+ lda dbgflg ; Is debugging enabled?
+ ora a
+ jz inpkt7
+ inx h ; Point to next char.
+ lda quietd ; a quiet display?
+ ana a
+ jnz inpkt7 ; so dont say a thing
+ call rppos ; position cursor
+ lxi h,recpkt+1 ; print the packet
+ call dmptxt
+
+ lda prnflg ; is the printer on too?
+ ana a
+ jz inpkt7
+ lxi h,rstatm ; print state
+ call printm ; dumptext but to printer
+ lda state
+ mov e,a
+ call outprn
+ lxi h,princr ; cr lf to printer
+ call printm
+ lxi h,rpackm
+ call printm
+ lxi h,recpkt+1
+ call printm
+ lxi h,princr
+ call printm
+ lxi h,princr
+ call printm
+
+
+inpkt7: lxi h,recpkt
+ shld pktptr ;Save the packet pointer.
+ jmp rskp ;If so we are done.
+
+; getchr - get next character from buffered packet.
+; returns nonskip at end of packet.
+; called by: rpack
+
+getchr: lhld pktptr ;Get the packet pointer.
+ mov a,m ;Get the char.
+ inx h
+ shld pktptr
+ ora a ;Is it the null we put at the end of the packet?
+ jnz rskp ;If not return retskp.
+ ret ;If so return failure.
+;
+;
+; inchr - character input loop for file transfer
+; returns: nonskip if timeout or character typed on console
+; (console selected)
+; skip with character from modem in A (parity stripped
+; if necessary; modem selected)
+; preserves bc, de, hl in either case.
+; called by: inpkt
+
+inchr: push h ; save hl and bc
+ push b
+ lhld timout ;Get initial value for timeout
+ shld timval ;[jd]
+inchr0: call selmdm ;select modem
+ call inpmdm ;Try to get a character from the modem
+ ora a
+ jz inchr2 ;if zero, nothing there.
+ mov b,a
+ lda parity ;Is the parity none?
+ cpi parnon
+ mov a,b
+ jz inchr1 ;If so just return.
+ ani 7FH ;Turn off the parity bit.
+inchr1: pop b ;restore registers
+ pop h
+ jmp rskp ;take skip return, character in A
+
+inchr2: call selcon ;select console
+ call inpcon ; Try to get a character from the console
+ ora a
+ jz inchr6 ;If not go do timer thing
+ cpi cr ;Is it a carriage return?
+ jz inchr4 ;If so return
+ cpi ('Z'-100O) ;Control-Z?
+ jz inchr5 ;Yes, go flag it
+ cpi ('C'-100O) ;Control-C?
+ jz inchr7 ;re-enter, he wants to get out
+ cpi ('X'-100O) ;Control-X?
+ jnz inchr6 ;No, ignore it. do timer thing.
+inchr5: adi 100O ;Convert to printing range
+ sta czseen ;Flag we saw a control-Z
+ jmp inchr6 ;[MF] and do timer thing
+inchr4: pop b ; restore registers
+ pop h
+ ret ;And return
+
+inchr6: lda timflg ;[jd] pick up timer flag
+ ora a ;[jd] are we allowed to use timer?
+ jz inchr0 ;[jd] no, don't time out
+ lhld timval ; decrement fuzzy time-out
+ dcx h ;
+ shld timval ;((timout-1) * loop time)
+ mov a,h ;(Retry if not time-out)
+ ora l ;
+ jnz inchr0 ;
+ call updrtr ;Count as retry (?)
+ pop b ;restore registers
+ pop h
+ ret ;and return to do retry
+
+inchr7: call clrtop ;[hh] clear screen and home cursor
+ lda takflg ;[MF]Take-file in progress?
+ ani 1 ;[MF]...
+ cnz closet ;[MF]Yes, close it and reset TAKE-flag
+ ;[MF]so all processing is halted
+ jmp kermit ;[hh] then re-enter kermit
+
+;
+; CRCCLC - Routine to calculate a CRC-CCITT for a string.
+;
+; This routine will calculate a CRC using the CCITT polynomial for
+; a string.
+;
+; call with: HL/ Address of null-terminated string
+; 16-bit CRC value is returned in DE.
+; Registers BC and HL are preserved.
+;
+; called by: spack, rpack
+
+crcclc: push h ;Save HL
+ push b ;And BC
+ lxi d,0 ;Initial CRC value is 0
+
+crccl0: mov a,m ;Get a character
+ ora a ;Check if zero
+ jz crccl1 ;If so, all done
+ push h ;Save the pointer
+ xra e ;Add in with previous value
+ mov e,a ;Get a copy
+ ani 0FH ;Get last 4 bits of combined value
+ mov c,a ;Get into C
+ mvi b,0 ;And make high order zero
+ lxi h,crctb2 ;Point at low order table
+ dad b ;Point to correct entry
+ dad b ; . . .
+ push h ;Save the address
+ mov a,e ;Get combined value back again
+ rrc ;Shift over to make index
+ rrc ; . . .
+ rrc ; . . .
+ ani 1EH ;Keep only 4 bits
+ mov c,a ;Set up to offset table
+ lxi h,crctab ;Point at high order table
+ dad b ;Correct entry
+ mov a,m ;Get low order portion of entry
+ xra d ;XOR with previous high order half
+ inx h ;Point to high order byte
+ mov d,m ;Get into D
+ pop h ;Get back pointer to other table entry
+ xra m ;Include with new high order half
+ mov e,a ;Copy new low order portion
+ inx h ;Point to other portion
+ mov a,m ;Get the other portion of the table entry
+ xra d ;Include with other high order portion
+ mov d,a ;Move back into D
+
+ pop h ;And H
+ inx h ;Point to next character
+ jmp crccl0 ;Go get next character
+
+crccl1: pop b ;Restore B
+ pop h ;And HL
+
+ ret ;And return, DE=CRC-CCITT
+
+CRCTAB: DW 00000H
+ DW 01081H
+ DW 02102H
+ DW 03183H
+ DW 04204H
+ DW 05285H
+ DW 06306H
+ DW 07387H
+ DW 08408H
+ DW 09489H
+ DW 0A50AH
+ DW 0B58BH
+ DW 0C60CH
+ DW 0D68DH
+ DW 0E70EH
+ DW 0F78FH
+
+CRCTB2: DW 00000H
+ DW 01189H
+ DW 02312H
+ DW 0329BH
+ DW 04624H
+ DW 057ADH
+ DW 06536H
+ DW 074BFH
+ DW 08C48H
+ DW 09DC1H
+ DW 0AF5AH
+ DW 0BED3H
+ DW 0CA6CH
+ DW 0DBE5H
+ DW 0E97EH
+ DW 0F8F7H
+;
+; This is where we go if we get an error during a protocol communication.
+; error prints the error packet on line 6 or so, and aborts the
+; transfer.
+; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, seot
+; error1 print CRLF followed by the error packet.
+; called by: finish, logout
+; error2 just prints the error packet.
+; error3 positions cursor and prints error message specified in DE.
+; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof,
+; seot, parwrn, gofil, outbuf
+
+error: lda quietd ; a quiet display?
+ ana a
+ jnz error0 ; so dont say a thing
+ lda remtxt ;[MF]Doing a remote command?
+ ora a ;[MF]...
+ jnz error0 ;[MF]Yes, don't position cursor
+ call screrr ;Position the cursor.
+error0: mvi a,'A' ;Set the state to abort.
+ sta state
+ jmp error2
+
+error1: lxi d,crlf ;Print a CRLF.
+ lda quietd ; a quiet display?
+ ana a
+ jnz error2 ; so dont say a thing
+ call prtstr
+error2: lda argblk+1 ;Get the length of the data.
+ mov c,a
+ mvi b,0 ;Put it into BC
+ lxi h,data ;Get the address of the data.
+ dad b ;Get to the end of the string.
+ mvi m,'$' ;Put a dollar sign at the end.
+ lxi d,data ;Print error message
+ lda remtxt ;[MF]Doing a remote command?
+ ora a ;[MF]...
+ jnz errr2a ;[MF]Yes, print message, quiet or not!
+ lda quietd ; a quiet display?
+ ana a
+ rnz ; so dont say a thing
+errr2a: call prtstr
+ ret
+
+error3: lda quietd ; a quiet display?
+ ana a
+ rnz ; so dont say a thing
+ lda remtxt ;[MF]Doing a remote command?
+ ora a ;[MF]...
+ jnz err3a ;[MF]Yes, don't position cursor
+ push d ;Save the pointer to the message.
+ call screrr ;Position the cursor.
+ pop d ;Get the pointer back.
+err3a: call prtstr ;Print error message
+ ret
+;
+; Set up for file transfer.
+; called by read, send.
+
+init: lxi d,version ; point at Kermit's version string
+ lda quietd ; a quiet display?
+ ana a
+ jnz init1 ; so dont say a thing
+ call sysscr ; fix up screen
+init1: call selmdm ; select modem
+ call flsmdm ; purge any pending data
+ call selcon ; select console again.
+ ret
+
+; Set state to ABORT
+; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, seot,
+; nak, ackp
+
+abort: mvi a,'A' ;Otherwise abort.
+ sta state
+ ret
+
+; nak - send NAK packet
+; here from: rinit, rfile, rdata
+; nak0 - update retry count and send NAK packet
+; here from: rinit, rfile, rdata, tryagn
+
+nak0: call updrtr ;Update number of retries.
+nak: lda pktnum ;Get the packet number we're waiting for.
+ sta argblk
+ xra a ;No data.
+ sta argblk+1
+ mvi a,'N' ;NAK that packet.
+ call spack
+ jmp abort ; Give up.
+ ret ;Go around again.
+
+; increment and display retry count
+; called by: rfile, sinit, sfile, sdata, seof, seot,
+; nak, rpack, inchr, tryagn
+
+updrtr: lhld numrtr
+ inx h ;Increment the number of retries
+ shld numrtr
+ lda remtxt ;[MF]Doing a remote server command?
+ ora a ;[MF]...
+ rnz ;[MF]Yes, keep mum
+ lda quietd ; a quiet display?
+ ana a
+ rnz ; so dont say a thing
+ call scrnrt ;Position cursor
+ lhld numrtr ;[MF]
+call nout ;Write the number of retries.
+ ret
+
+; [jd] this routine prints parity warnings. All registers are
+; saved except for a.
+; called by: sdata
+
+parwrn: push b
+ push d
+ push h
+ lxi d,inms25
+ call error3
+ pop h
+ pop d
+ pop b
+ ret
+;[jd] end of addition
+
+; print message in status field. address of message is in DE.
+; called by: read, send
+
+finmes: lda quietd ; a quiet display?
+ ana a
+ jz finme0 ; so do usual stuff
+ push d ;[MF]Save pointer to completion message
+ call prcrlf ; best do a new line
+ pop d ;[MF]Restore completion message pointer
+ call prtstr ; and send message
+ mvi e,space ; send a space or two
+ mvi c,dconio
+ push b
+ push d
+ call bdos
+ pop d
+ pop b
+ call bdos
+ ret ; and exit back
+;
+;else for screaming screens...
+
+finme0: push d ;Save message.
+ call scrst ;Position cursor
+ pop d ;Print the termination message
+ call prtstr
+ ret ; may not want this **************
+
+ mvi c,4 ;[2] copy across user no and drive
+ lxi h,kerm1 ;[2] as we have the text already
+finme1: mov e,m
+ push h ;[2] conout probably destroys these
+ push b
+ call conout
+ pop b
+ pop h
+ inx h ;[2] next character
+ dcr c ;[2] ah, but have we done?
+ jnz finme1 ;[2] nope
+ lxi d,spac15 ;[2] send 15 spaces (clears previous filename)
+ call prtstr ;[2]
+ call scrend ;Position cursor for prompt
+ ret
+
+; Compare expected packet number against received packet number.
+; return with flags set (Z = packet number valid)
+; called by: rfile, rdata, sinit, sfile, sdata, seof, seot
+
+compp: lda pktnum ;Get the packet Nr.
+ mov b,a
+ lda argblk
+ cmp b
+ ret
+
+; Increment the packet number, modulo 64.
+; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, seot
+
+countp: inr a ;Increment packet Nr.
+ ani 3FH ;Turn off the two high order bits
+ sta pktnum ;Save modulo 64 of number
+ lhld numpkt
+ inx h ;Increment Nr. of packets
+ shld numpkt
+ ret
+
+; Send an ACK-packet
+; called by: rfile, rdata, tryagn
+
+ackp: xra a
+ sta numtry ;Reset number of retries
+ sta argblk+1 ;No data. (The packet number is in argblk)
+ mvi a,'Y' ;Acknowledge packet
+ call spack ;Send packet
+ jmp abort
+ ret
+
+; ?
+; called with A/ current retry count
+; called by: rfile, rdata
+
+tryagn: inr a ;Increment it.
+ sta oldtry ;Save the updated number of tries.
+ lda pktnum ;Get the present packet number.
+ dcr a ;Decrement
+ ani 3FH ; modulo 64
+ mov b,a
+ lda argblk ;Get the packet's number
+ cmp b ;Is the packet's number one less than now?
+ jnz nak0 ;No, NAK it and try again.
+ call updrtr ;Update the number of retries.
+ call ackp
+ ret
+
+; Output a null-terminated string to the console. We assume that the
+; console has been selected. Called with HL = address of string.
+; called by: spack, inpkt
+
+dmptxt: mov a,m ; get character from string
+ ora a
+ rz ; done if null
+ push h ; save string address
+ mov e,a ; move character to E for outcon
+ call outcon ; output character to console
+ pop h ; restore string address
+ inx h ; point past printed character
+ jmp dmptxt ; go output rest of string
+
+
+; Output a null-terminated string to the PRINTER We assume that the
+; console has been selected. Called with HL = address of string.
+; called by: spack, inpkt
+
+printm: mov a,m ; get character from string
+ ora a
+ rz ; done if null
+ push h ; save string address
+ mov e,a ; move character to E for outcon
+ call outprn ; output character to printer
+ pop h ; restore string address
+ inx h ; point past printed character
+ jmp printm ; go output rest of string
+
+
+;
+; test if character in A is the start of header character. We get
+; the start of packet character from sohchr, which can be SET
+tstsoh: push b ; save these registers for a bit
+ mov c,a ; we have to test if this is the character
+ lda sohchr
+ cmp c ; if zero, then it is
+ mov a,c ; restore accumulator but not flags
+ pop b
+ ret ; return with flags set
+;
+
+
+; Little code to allow some expansion of code without changing
+; every futher address, only up to the end of this file.
+; TO BE REMOVED FRO RELEASE!
+
+; org ($+100h) AND 0FF00H
+
+
+IF lasm
+ LINK CPSREM
+ENDIF;lasm
diff --git a/cpsrem.asm b/cpsrem.asm
index 2f480b9..677f307 100644
--- a/cpsrem.asm
+++ b/cpsrem.asm
@@ -1,1149 +1,1149 @@
-; CPSREM.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the (system-independent) routines that implement
-; the REMOTE commands of the KERMIT protocol.
-;
-; revision history:
-;
-;edit 13, 21-Mar-1991 by MF. Renamed REMOTE SET FILE COLLISION REPLACE to
-; REMOTE SET FILE COLLISION OVERWRITE and modified the corresponding
-; help text slightly.
-;edit 12, 13-Feb-1991 by MF. Simplified code at "remcl0" to get REMOTE
-; command arguments by calling "cmgtch" in order to get command-line
-; characters directly. This means that command-line characters are
-; passed literally (except for prefixingand space-compression) to the
-; remote Kermit and that one need not send "?" or <esc> as "\"-prefixed
-; octal numbers in order to avoid immediate action by CP/M Kermit.
-;edit 11, 30-Jan-1991 by MF. Corrected code to always require entry of at least
-; one argument in the REMOTE COPY, REMOTE DELETE (REMOTE ERASE),
-; REMOTE MESSAGE, REMOTE RENAME and REMOTE TYPE commands. This is
-; done by branching to KERMT3 (the "not confirmed" code) if the
-; first argument isn't given. This should correct a bug which occurred
-; in numerous places in which the character immediately following
-; that specifying the flavor of a Generic command was not defined if
-; the first of multiple (at least two) arguments was left blank but
-; subsequent arguments were not. This should correct a problem
-; encountered by Russell Lang of Monash University In Australia when
-; he did a REMOTE MESSAGE command with a blank first argument (the
-; user id) and a nonblank second argument (the message text) from
-; CP/M Kermit to Ms-Kermit in Server mode.
-;edit 10, 14-Dec-1990 by MF. Put "<<>>" around "x" or "F" packet replies
-; to REMOTE commands as in VMS Bliss Kermit and eliminate unnecessary
-; instruction before label remc2d.
-;edit 9, 1-Nov-1990 by MF. Changed REMOTE CWD to REMOTE CD in the quest for
-; uniformity of nomenclature (per request of FDC).
-;edit 8, 29-Oct-1990 by MF. Corrected Remote command code to properly
-; prefix control characters (repeat prefix (~) isn't done in CP/M
-; yet).
-;edit 7, 17-Oct-1990 by MF. Changed verb "REMOTE SEND-MESSAGE" to
-; "REMOTE MESSAGE" to conform with the nomenclature suggested in
-; Chapter 10 of the 6th edition of the Kermit Protocol Manual.
-;edit 6, 10-Oct-1990 by MF. Corrected Remote command code to
-; properly prefix the control-character prefix character and the
-; eighth-bit quotation prefix character. Remote Set commands
-; now function correctly.
-; Also change the REMOTE SET FILE COLLISION ASK value to 5 per
-; Kermit Digest V12 #6 (though I still have no idea how the local
-; Kermit is supposed to answer).
-;edit 5, 5-Oct-1990 by MF. Coded many Remote Set commands.
-; The commands I have omitted deal with Attribute packets which
-; don't make much sense on a CP/M system.
-; Note also that for those Remote Set commands which take a
-; numeric argument, no range-checking is done here.
-; Also note that, for now, REMOTE SET FILE-COLLISION ASK is
-; equivalent to REMOTE SET FILE-COLLISION DISCARD because
-; (a) that's what the Kermit Digest indicated and (b) no mechanism
-; has been proposed for the Remote Kermit to query the Local Kermit.
-;edit 4, 29-Sep-1990 by MF. Corrected code to ignore error packets in
-; response to sending an "I" packet, per KPROTO.DOC
-;edit 3, 9-Sep-1990 by MF. Extensively revised this file to implement
-; Remote commands except for the following:
-; REMOTE JOURNAL, REMOTE MAIL, REMOTE PRINT, REMOTE PROGRAM,
-; REMOTE SET, REMOTE VARIABLE.
-;edit 2 ... MF Dunno where edit 2 went (shown in Version string).
-; edit 1: September 8th, 1987. Created this file from bits of the two packet files.
-; The commands supported by this system are all the REMOTE commands,
-; to allow users to acces remote host systems via Kermit. Added REMOTE
-; command table and REMOTE DIR command.
-;
-;
-remver: db 'CPSREM.ASM (13) 21-Mar-1991$' ; name, edit number, date
-
-;
-; REMOTE command - quite similar to the SET command
-remote: call selmdm ;Select modem
- call flsmdm ;Flush buffers
- call selcon ;Back to keyboard
- lxi d,remtab ; remote commands table
- lxi h,remhlp ; remote help table
- call keycmd ; get result
- xchg
- pchl ; and do it
-
-
-
-
-; REMOTE command table. Works the same way as every other table etc.
-;
-remtab: db 19 ; nineteen commands so far
- db 2,'CD$'
- dw remcd ; remote cd command
- db 4,'COPY$'
- dw remcpy ; remote copy command
- db 6,'DELETE$'
- dw remdel ; remote delete command
- db 9,'DIRECTORY$'
- dw remdir ; remote directory command
- db 10,'DISK-USAGE$'
- dw remdsk ; remote disk-usage command
- db 5,'ERASE$'
- dw remdel ; remote erase command (same as delete)
- db 6,'FINISH$'
- dw finish ; same as finish
- db 4,'HELP$'
- dw remhep ; remote help command
- db 4,'HOST$'
- dw remhos ; remote host command
- db 6,'KERMIT$'
- dw remker ; remote Kermit command
- db 5,'LOGIN$'
- dw remlgi ; remote login
- db 6,'LOGOUT$'
- dw logout ; same as logout
- db 7,'MESSAGE$'
- dw remmsg ; remote message command
- db 6,'RENAME$'
- dw remren ; remote rename
- db 3,'SET$'
- dw remset ; remote set command
- db 5,'SPACE$'
- dw remdsk ; remote space command (same as disk-usage)
- db 6,'STATUS$'
- dw remsta ; remote status (of server) command
- db 4,'TYPE$'
- dw remtyp ; remote type command
- db 3,'WHO$'
- dw remwho ; remote who command
-
-remhlp: db cr,lf,'CD - change default directory for remote server'
- db ' operations'
- db cr,lf,'COPY - copy files on a remote system'
- db cr,lf,'DELETE - delete files on a remote system'
- db cr,lf,'DIRECTORY - list a directory on a remote system'
- db cr,lf,'DISK-USAGE - show disk usage on a remote system'
- db cr,lf,'FINISH - stop a remote server'
- db cr,lf,'HELP - get help from a remote server'
- db cr,lf,'HOST - execute a command on a remote system'
- db cr,lf,'KERMIT - tell a remote server to execute a Kermit '
- db 'command'
- db cr,lf,'LOGIN - send user-identification to a remote server'
- db cr,lf,'LOGOUT - stop and logout a remote server'
- db cr,lf,'MESSAGE - send a message to a remote system user'
- db cr,lf,'RENAME - rename files on a remote system'
- db cr,lf,'SET - set remote server parameters'
- db cr,lf,'SPACE - show disk-usage on a remote system'
- db cr,lf,'STATUS - Get status of a remote server'
- db cr,lf,'TYPE - type files on a remote system'
- db cr,lf,'WHO - show current users on a remote system'
- db '$'
-
-
-;Description of remote commands
-
-;
-; Packets start with an I packet in place of S/R packet. An X
-; packet is the same as an F (filename) packet except the 'file'
-; is not applicable. Copy X packet data field to display. Set
-; options so that no data is written to disk during D packets.
-; (REMTXT <> 0)
-;
-;Packets:
-; we we comments
-; send receive
-; I
-; ACK
-; Command packet
-; Ack or
-; Init
-; ACK
-; X Dummy header.
-; ACK
-; D listing from remote end
-; ACK We got it
-; ....
-; ACK last packet received ok
-; Z
-; ACK
-; B
-; ACK end of transaction.
-;
-;**Note** If the Remote system gives a simple ack to the command packet,
-;that is, a "short reply" is given, the data, if any, in the packet
-;is displayed and the transaction ends. The outline shown above is for a
-;"long reply".
-;
-; Remote commands
-;
-; Remote Copy - Copy file(s) on remote system
-;
-remcpy: lxi h,newfms ;Second argument prompt
- shld rprmpt ;...
- mvi a,'K' ;Generic type
-remcp0: sta remdat ;into packet
- mvi a,2 ;Packet has at least two characters
- sta rdl ;...
- mvi a,'G' ;Generic command
- sta rcom ;...
- lxi d,remdat+2 ;Point to data buffer
- call remcli ;Get filespec (if any) from command line
- ora a ;Anything typed?
- jz kermt3 ;No, we must have an argument
- mov b,a ;Save length
- adi space ;Yes, make encoded field length
- sta remdat+1 ;and store in packet data area
- lda rdl ;Get packet length so far
- add b ;Count answer length
- sta rdl ;and remember new packet size
- lhld rprmpt ;Point to "new file" prompt
- xchg ;...
- shld rptr ;Save data pointer
- call prompt ;Prompt the user
- lhld rptr ;Get data pointer again
- inx h ;Skip encoded field-length
- xchg ;...
- call remcli ;get user's answer
- lhld rptr ;Restore pointer
- mov c,a ;Save answer length
- adi space ;Convert to encoded field length
- mov m,a ;Put length in packet
- lda rdl ;Get accumulated data length
- add c ;plus data length
- adi 1 ;plus field length character
- sta rdl ;and remember it
- jmp remcom ;and branch to common code
-;
-; Remote Cd - Change Directory
-;
-remcd: lxi h,pswdms ;Second argument prompt
- shld rprmpt ;...
- mvi a,'C' ;Generic cd
-remcd0: sta remdat ;into packet
- mvi a,1 ;Packet is at least one character long
- sta rdl ;...
- mvi a,'G' ;Generic command
- sta rcom ;...
- lxi d,remdat+2 ;Point to data buffer
- call remcli ;Get filespec (if any) from command line
- mov b,a ;Save answer length (may be zero)
- adi space ;Make encoded field length
- sta remdat+1 ;and store in packet data area
- lda rdl ;Get length so far
- add b ;Count answer length
- adi 1 ;and field length character
- sta rdl ;and remember current packet-size
- lda remdat ;Get generic packet flavor
- cpi 'C' ;Remote CD?
- jnz remcd1 ;No
- mov a,b ;Get length of possible directory spec
- ora a ;Did the user give a directory spec?
- jz remcom ;No, we can process the command immediately
- mvi a,0ffH ;Yes, password follows, make it not echo
- sta cmqflg ;...
-remcd1: lhld rprmpt ;Point to "password" prompt
- xchg ;...
- shld rptr ;Save data pointer
- mvi a,0ffH ;Allow blank password
- sta cmbflg ;...
- call prompt ;Prompt the user
- lhld rptr ;Restore data pointer
- xchg ;...
- inx d ;and increment it
- call remcli ;Get user's answer
- ora a ;Password given?
- jz remcom ;No, proceed with command
- mov c,a ;Yes, save answer length
- adi space ;Convert to encoded field length
- lhld rptr ;Get data pointer
- mov m,a ;Put length in packet
- lda rdl ;Get accumulated data length
- adi 1 ;Count encoded field length
- add c ;plus data length
- sta rdl ;and remember packet-size
- jmp remcom ;Branch to common code
-;
-; Remote Delete (Erase) command
-;
-remdel: mvi a,'E' ;Delete (Erase) command
-remdl0: sta remdat ;...
- mvi a,1 ;At least one character in packet
- sta rdl ;...
- mvi a,'G' ;Generic command
- sta rcom ;...
- lxi d,remdat+2 ;Point to data field
- call remcli ;Get filespec
- mov b,a ;Save length
- lda remdat ;Get packet type
- cpi 'E' ;If Generic Delete
- jz remdl1 ;We must have an argument
- cpi 'T' ;Ditto for Generic Type
- jz remdl1 ;...
- mov a,b ;Else get back character count
- ora a ;Answer typed?
- jz remcom ;No, process packet as is
-remdl1: mov a,b ;Get character count again
- ora a ;Anything typed?
- jz kermt3 ;No, we must have an argument (Delete/Type)
- adi space ;Yes, encode field length
- sta remdat+1 ;and put in packet
- lda rdl ;Get packet length so far
- add b ;Count length of filespec
- adi 1 ;Count field length character
- sta rdl ;and store packet length
- jmp remcom ;and do our stuff
-;
-; Remote Directory command
-;
-remdir: mvi a,'D' ;generic directory command
- jmp remdl0 ;Do common code
-;
-; Remote Disk-usage (Space) command
-;
-remdsk: mvi a,'U' ;Disk-usage generic command
- jmp remdl0 ;Do common code
-;
-; Remote Help command
-;
-remhep: mvi a,'H' ;generic help command
- jmp remdl0 ;Do common code
-;
-; Remote Host command
-;
-remhos: mvi a,'C' ;Remote Host command
-remho0: sta rcom ;...
- xra a ;Zero packet length
- sta rdl ;...
- lxi d,remdat ;Point to packet data buffer
- call remcli ;Get host command
- ora a ;Anything typed?
- jz kermt3 ;No, don't let the user get away with this
- sta rdl ;Yes, store packet length
- jmp remcom ;and do the command
-;
-; Remote Kermit command
-;
-remker: mvi a,'K' ;Remote Kermit command
- jmp remho0 ;Do common code
-;
-; Remote Login command
-;
-remlgi: mvi a,'G' ;Generic command
- sta rcom ;...
- mvi a,'I' ;Generic type
- sta remdat ;into packet
- mvi a,1 ;At least one character in packet
- sta rdl ;...
- lxi d,remdat+2 ;Point to data buffer
- call remcli ;Get userid (if any) from command line
- ora a ;Userid typed?
- jz remcom ;No, nothing more to do
- mov b,a ;Yes, save length
- adi space ;Make encoded field length
- sta remdat+1 ;and store in packet data area
- lda rdl ;Get packet length
- add b ;Count id length
- adi 1 ;and field length character
- sta rdl ;and remember accumulated length
- xchg ;Save data pointer
- shld rptr ;...
- mvi a,0ffH ;Allow blank answers
- sta cmbflg ;...
- sta cmqflg ;Passwords don't echo
- lxi d,pswdms ;Point to "password" prompt
- call prompt ;Prompt the user
- lhld rptr ;Get data pointer
- xchg ;Put in DE
- inx d ;Skip encoded field-length
- call remcli ;Get password, if any
- ora a ;Anything typed?
- jz remcom ;No, do command immediately
- mov c,a ;Yes, save answer length
- adi space ;Convert to encoded field length
- lhld rptr ;Get pointer
- mov m,a ;Put length in packet
- lda rdl ;Get accumulated data length
- adi 1 ;Count encoded field length
- add c ;Count "password" field length
- sta rdl ;and remember new packet length
- xchg ;Save data pointer
- shld rptr ;...
- xra a ;Allow echoing again for "account" field
- sta cmqflg ;...
- lxi d,acctms ;Point to "account" prompt
- call prompt ;Prompt the user
- lhld rptr ;Get data pointer
- xchg ;into DE
- inx d ;Skip encoded field length
- call remcli ;Get "account" field, if any
- ora a ;Anything typed?
- jz remcom ;No, do the command now
- mov c,a ;Yes, save length of answer
- adi space ;Convert to encoded field length
- lhld rptr ;Get data pointer
- mov m,a ;Put length in packet
- lda rdl ;Get accumulated data length
- adi 1 ;Count encoded field length
- add c ;plus "account" length
- sta rdl ;and remember it
- jmp remcom ;Branch to common code
-;
-; Remote Rename command
-;
-remren: lxi h,newfms ;Second argument prompt
- shld rprmpt ;...
- mvi a,'R' ;generic rename
- jmp remcp0 ;Do common code
-;
-; Remote Message command
-;
-remmsg: lxi h,msgms ;Second argument prompt
- shld rprmpt ;...
- mvi a,'M' ;generic message
- jmp remcp0 ;Do common code
-;
-;Remote Set command
-;
-remset: mvi a,6 ;Packet data area has at least six chars
- sta rdl ;...
- mvi a,'S' ;Remote Set command
- sta remdat ;...
- mvi a,'G' ;It's a generic command
- sta rcom ;...
- mvi a,'#' ;Encoded field-length for SET type
- sta remdat+1 ;which is three chars long
- lxi d,rmstab ;Point to Set command table
- lxi h,rmshlp ;and the help table
- call keycmd ;Find out which command is to be executed
- xchg ;Put dispatch address in HL
- pchl ;Go do the command
-;
-; Common code for Remote Set commands that take an argument
-;
-remscm: lxi d,remdat+6 ;We get an argument from the user
- mvi a,cmtxt ;...
- call comnd ;...
- jmp kermt3 ;Couldn't get one.
- ora a ;Did the user give one?
- jz kermt3 ;a blank answer isn't acceptable
- mov c,a ;Save length of answer
- adi space ;Convert to encoded field-length
- sta remdat+5 ;and put in packet data area
- lda rdl ;Get current data length
- add c ;Count length of answer
- sta rdl ;and store new data length
- call cfmcmd ;Get a "confirm"
- jmp remcom ;Do common Remote command code
-;
-; Common code for Remote Set commands requiring another table lookup
-;
-remsc1: call chkkey ;Get user's selection
- sta remdat+6 ;and put into the packet data area
- mvi a,'!' ;Encoded field length for 1 char
- sta remdat+5 ;Put in packet
- lda rdl ;Get accumulated packet data length
- adi 1 ;Count length of answer (1 char)
- sta rdl ;and store as new packet data length
- jmp remcom ;Go do common Remote command processing
-;
-; Remote Status (of server) command
-;
-remsta: call cfmcmd ;Get return
- mvi a,'Q' ;Command type (Server Status)
- sta remdat ;...
- mvi a,'G' ;Generic Kermit command
- sta rcom ;...
- mvi a,1 ;1 character in packet
- sta rdl ;...
- jmp remcom ;Do common code
-;
-; Remote Type command
-;
-remtyp: mvi a,'T' ;generic type command
- jmp remdl0 ;Do common code
-;
-; Remote Who command
-;
-remwho: lxi h,optms ;Second argument prompt
- shld rprmpt ;...
- mvi a,'W' ;generic who
- jmp remcd0 ;Do common code
-
-; Common code for Remote commands
-;
-remcom:
- mvi a,0ffH ; Make sure returned info is sent
- sta remtxt ;to the user's screen rather than to a file
- lda rcom ;Get packet-type
- cpi 'G' ;Is it a generic command?
- jnz remc0e ;No, go clear the screen
- lda remdat ;Yes, get generic command type
- cpi 'S' ;Is it a Remote Set command?
- jz remc0f ;Yes, don't clear the screen
-remc0e: call clrtop ; clear the screen
-remc0f: xra a
- sta numtry ; reset retries
- sta czseen
- sta pktnum
- lxi h,0
- shld numpkt
- shld numrtr ; clear some variables
-
- mvi a,'1' ; reset block check type
- sta curchk
-remcm0: mvi a,'I' ; init state
- sta state
- call sinit ; do sendinit with I packet (??)
- lda state ; now see if we are in the 'X' state
- cpi 'X'
- jz remco0 ;Yup, all is in order
- cpi 'A' ;No, in abort state?
- jnz remcm0 ;No, try I-packet again
- jmp kermit ;Yes, like Danny Boy, we must die.
- ;If we get this far, either the "I" packet
- ;was understood or the Server couldn't
- ;handle it and we ignored the error.
- ;In either case, we can proceed.
-
-
-
-remco0: xra a
- sta numtry ; reset retries
- sta czseen
- sta pktnum
- lxi h,0
- shld numpkt
- shld numrtr ; clear some variables
- mvi a,'1' ;Make sure we use
- sta curchk ;1-character checksum
- lda rdl ;Get packet-length (number of bytes to copy)
- ora a ;Anything to copy?
- jz remcm1 ;No
- sta temp1 ;Yes, save loop counter
- lda spsiz ;Get max packet size
- sui 5 ;less overhead
- sta temp2 ;gives max chars we can send
- lxi d,remdat ;Copy from private buffer
- lxi h,data ;to packet data area
- lda qbchr ;Get eightgh-bit quoting prefix char
- mov b,a ;Save it
- lda squote ;Get control-char quoting char
- mov c,a ;and save it
-remc0a: lda temp2 ;Get characters to go in packet
- dcr a ;and decrement it
- sta temp2 ;...
- jm remc0x ;We can't copy any more
- ldax d ;Get a packet data character
- cpi space ;Is it a control char?
- jm remc0b ;Yes, quote it
- cmp c ;Is it the control-char prefix?
- jz remc0b ;Yes, quote it
- lda quot8 ;No, is eighth-bit quoting in effect?
- ora a ;...
- jz remc0c ;No, just copy the character
- ldax d ;Get character again
- cmp b ;Is it the eighth-bit quote char?
- jnz remc0d ;No, just copy it
-remc0b: mov m,c ;Yes, quote the character
- inx h ;Increment the dest. pointer
- lda temp2 ;Get chars to go
- dcr a ;Decrement
- sta temp2 ;...
- jm remc0x ;Can't copy any more
- lda rdl ;Count quote prefix
- inr a ;...
- sta rdl ;...
-remc0c: ldax d ;Get character again
- cpi space ;If not a control char,
- jp remc0d ;just copy the character, else
- adi 40H ;Convert to printing character
- ani 7fH ;modulo 128
-remc0d: mov m,a ;Copy the character
- inx h ;Increment the pointers
- inx d ;...
-remc0x: lda temp1 ;Get loop counter
- dcr a ;and decrement it
- sta temp1 ;...
- jnz remc0a ;Copy entire packet data area
-;
-remcm1: xra a
- sta argblk ; set packet no zero
- lda rdl ;Number of bytes in packet
- sta argblk+1 ;into argument block
- lda rcom ;Remote command
- call spack ;Send the packet
- jmp kermt3 ;Nogo, die!
- jmp remco2 ;Try to get an answer
-
-remco1: call nak0 ;Nak packet
-;
-
-remco2: lda numtry ;Get number of retries
- inr a ; update retries
- cpi maxtry ;To many retries?
- jm remc2a ;No
- lxi d,erms28 ;Yes, complain
- call prtstr ;...
- jmp kermit ;and abort
-
-remc2a: sta numtry
- call rpack ;Get a packet
- jmp remco1 ;Couldn't get one.
- cpi 'E' ;Error packet?
- jnz remc2b ;No
- lda rcom ;What kind of packet did we send?
- cpi 'G' ;If it wasn't generic,
- jnz remc2f ;there is no need to start a new message line
- lda remdat ;Packet was generic
- cpi 'S' ;Was it a Remote Set?
- cz prcrlf ;Yes, start a new line since the screen
- ;isn't blank and we would clobber the command-
- ;line otherwise
-remc2f: call error0 ;Yes, inform the user
- jmp kermit ;and abort to main command loop
-remc2b: cpi 'S' ;Send-init?
- jnz remc2c ;No
- call rini2a ;Initialize parameters
- lda state ;Get state
- cpi 'A' ;If abort,
- jz kermit ;Go back to main command loop
- mvi a,'X' ;Set state to text-display
- sta state ;...
- jmp read2 ;Get more packets
-remc2c: cpi 'N' ;Nacked packet?
- jz remco2 ;Yes, try again
- sta state ;Save packet type
- call selcon ;Select Console
- lxi h,data ;Point to data
- lda argblk+1 ;Anything in packet data?
- ora a ;...
- jz remco6 ;No
- push h ;Yes, save pointer
- push psw ;and character count
- mvi e,'<' ;Type "<<" as in VMSKermit
- push d ;...
- call outcon ;...
- pop d ;...
- call outcon ;...
- pop psw ;Restore character counter
- pop h ;and data pointer
-remc2d: ora a ;...
- jz remc2e ;No more characters
- dcr a ;Decrement loop counter
-mov e,m ;Get character
- inx h ;Increment pointer
- push psw ;Save loop counter
- push h ;Save data pointer
- call outcon ;Type on Console
- pop h ;Restore pointer
- pop psw ;Restore loop counter
- jmp remc2d ;Type all packet data
-remc2e: mvi e,'>' ;Type ">>" as in VMSKermit
- push d ;...
- call outcon ;...
- pop d ;...
- call outcon ;...
- call prcrlf ;End the line
-remco6: lda state ;Get packet type again
- cpi 'Y' ;If simple ack,
- jz kermit ;Done, else
- call ackp ;Acknoledge the packet
- call countp ;Count the packet
- mvi a,'D' ;Set to data-receive
- sta state ;...
- jmp read2 ; do the same as read a file, but echo
- ; to the screen.. Dont close non-open files.
-;
-;
-;REMCLI - Get command-line for Remote commands
-;
-remcli: xra a ;Zero accumulated length
- sta rcl ;...
- mov b,a ;[12]...
-;
-;[MF][12]Eliminate following code which calls "comnd" in favor of code which
-;[MF][12]calls "cmgtch" directly so that characters are sent without
-;[MF][12]alteration or inadvertent action ("?" or <esc>). The only thing
-;[MF][12]lost is the ability to produce any ASCII character via
-;[MF][12]octal numbers prefixed with "\" but this isn't used much in remote
-;[MF][12]commands anyway.
-;
-;remcl0: mvi a,cmtxt ;We get arbitrary text
-; call comnd ;from the command-line
-; jmp kermt3 ;We couldn't get any.
-; ora a ;Anything given?
-; jz remcl1 ;No, done
-; push b ;Save BC
-; mov c,a ;Save length
-; lda rcl ;Get accumulated length
-; add c ;plus current word length
-; adi 1 ;plus a space
-; sta rcl ;and save accumulated length
-; mvi a,space ;Put in a space separator
-; stax d ;...
-; inx d ;Increment pointer
-; pop b ;Restore BC
-; jmp remcl0 ;Get text to end-of-line
-;remcl1: lda rcl ;Get accumulated length
-; ora a ;Anything typed?
-; rz ;No
-; dcr a ;Yes, don't count final space
-; push psw ;Save count
-; dcx d ;Point to final space
-; xra a ;Zap it
-; stax d ;...
-; pop psw ;Restore count
-;
-;[MF][12]Simplified code follows
-;
-remcl0: call cmgtch ;[12]Get a character from the user
- ani 7fh ;[12]Turn off minus bit
- cpi cr ;[12]If end-of-line,
- jz remclx ;[12]We're done
- cpi lf ;[12]...
- jz remclx ;[12]...
- stax d ;[12]else store the character
- inr b ;[12]and count it
- inx d ;[12]Increment character buffer pointer
- cpi esc ;[12]is character an <esc>?
- jz remcl2 ;[12]Yes
- cpi ff ;[12]an <ff>?
- jz remcl1 ;[12]Yes, diddle command buffer pointer
- cpi '?' ;[12]a "?"?
- jnz remcl0 ;[12]No, just get more characters
-remcl1: push h ;[12]Protect HL
- lhld cmdptr ;[12]get "cmgtch"'s character pointer
- inx h ;[12]and reverse the action at "cmgtc4"
- ;[12]since we don't need a "confirm" and
- ;[12]infinite loops are beaucoup bad news
- shld cmdptr ;[12]...
- pop h ;[12]Restore HL
-remcl2: push psw ;[12]Save the character
- xra a ;[12]Zero the action flag so we get input
- sta cmaflg ;[12]to end-of-line without special action
- pop psw ;[12]Restore the character
- jmp remcl0 ;[12]Get more characters
-remclx: mov a,b ;[12]Get accumulated text length
- sta rcl ;[12]and remember it
-;
- ret ;Return
-;
-;Remote set values
-;
-; REMOTE SET FILE TYPE 300 0 = TEXT, 1 = BINARY
-; REMOTE SET FILE NAMES 301 0 = CONVERTED, 1 = LITERAL
-; REMOTE SET FILE COLLISION 302 0 = RENAME, 1 = OVERWRITE,
-; 2 = BACKUP, 3 = APPEND,
-; 4 = DISCARD, 5 = ASK
-; REMOTE SET FILE REPLACE 303 0 = PRESERVE, 1 = DEFAULT
-; REMOTE SET FILE INCOMPLETE 310 0 = DISCARD, 1 = KEEP
-; REMOTE SET INCOMPLETE (same as above)
-; REMOTE SET BLOCK-CHECK 400 number (1, 2, or 3)
-; REMOTE SET RECEIVE PACKET-LENGTH 401 number (10-9024)
-; REMOTE SET RECEIVE TIMEOUT 402 number (any, 0 = no timeout)
-; REMOTE SET RETRY 403 number (any, 0 = no limit)
-; REMOTE SET SERVER TIMEOUT 404 number (any, 0 = no timeout)
-;REMOTE SET FILE BLOCKSIZE 311 number
-;REMOTE SET FILE RECORD-LENGTH 312 number
-;REMOTE SET FILE RECORD-FORMAT 313 F (fixed), V (variable), etc...
-;This is just for the record, to assign these numbers to these commands
-;for somebody who needed them. Details to be filled in later.
-;
-;Remote Set command table
-;
-rmstab: db 7 ;seven entries
- db 16,'BLOCK-CHECK-TYPE$'
- dw remsbc ;Remote Set Block Check
- db 4,'FILE$'
- dw remsfl ;Remote Set File
- db 10,'INCOMPLETE$'
- dw remsfi ;Remote Set (file) Incomplete
- db 7,'RECEIVE$'
- dw remsrc ;Remote Set Receive
- db 7,'REPLACE$'
- dw remsfr ;Remote Set (file) Replace
- db 5,'RETRY$'
- dw remsry ;Remote Set Retry
- db 14,'SERVER-TIMEOUT$'
- dw remsst ;Remote Set Server Timeout
-;
-rmshlp: db cr,lf,'BLOCK-CHECK-TYPE for a remote server'
- db cr,lf,'FILE parameters for a remote server'
- db cr,lf,'INCOMPLETE file disposition for a remote server'
- db cr,lf,'RECEIVE parameters for a remote server'
- db cr,lf,'REPLACE file attribute handling for a remote server'
- db cr,lf,'RETRY maximum for a remote server'
- db cr,lf,'SERVER-TIMEOUT interval for a remote server'
- db '$'
-;
-;Remote Set File tables
-;
-rsftab: db 8 ;eight entries
- db 10,'BLOCK-SIZE$'
- dw remsbs ;Remote Set File Block-size command
- db 9,'COLLISION$'
- dw remsfc ;Remote Set File Collision command
- db 10,'INCOMPLETE$'
- dw remsfi ;Remote Set File Incomplete command
- db 5,'NAMES$'
- dw remsfn ;Remote Set File Names command
- db 13,'RECORD-FORMAT$'
- dw remsrf ;Remote Set File Record-format
- db 13,'RECORD-LENGTH$'
- dw remsrl ;Remote Set File Record-length
- db 7,'REPLACE$'
- dw remsfr ;Remote Set File Replace command
- db 4,'TYPE$'
- dw remsft ;Remote Set File Type command
-;
-rsfhlp: db cr,lf,'BLOCK-SIZE of files for a remote server'
- db cr,lf,'COLLISION action on filename conflicts for a remote'
- db ' server'
- db cr,lf,'INCOMPLETE file disposition for a remote server'
- db cr,lf,'NAMES translation of files for a remote server'
- db cr,lf,'RECORD-FORMAT of files for a remote server'
- db cr,lf,'RECORD-LENGTH for a remote server'
- db cr,lf,'REPLACE file attribute handling for a remote server'
- db cr,lf,'TYPE of files for a remote server'
- db '$'
-;
-;Remote Set File Record-format tables
-;
-rcftab: db 2 ;two entries
- db 5,'FIXED$'
- db 'F','F' ;Remote Set File Record-format Fixed command
- db 8,'VARIABLE$'
- db 'V','V' ;Remote Set File Record-format Variable cmd
-;
-rcfhlp: db cr,lf,'FIXED VARIABLE'
- db '$'
-;
-;Remote Set Receive tables
-;
-rrctab: db 2 ;two entries
- db 13,'PACKET-LENGTH$'
- dw remrpl ;Remote Set Receive Packet-length command
- db 7,'TIMEOUT$'
- dw remsrt ;Remote Set Receive Timeout command
-;
-rrchlp: db cr,lf,'PACKET-length TIMEOUT'
- db '$'
-;
-;Remote Set File-collision table
-;
-rfctab: db 6 ;six entries
- db 6,'APPEND$'
- db '3','3' ;Set collision append
- db 3,'ASK$'
- db '5','5' ;Set collision ask
- db 6,'BACKUP$'
- db '2','2' ;Set collision backup
- db 7,'DISCARD$'
- db '4','4' ;Set collision discard
- db 9,'OVERWRITE$'
- db '1','1' ;Set collision overwrite
- db 6,'RENAME$'
- db '0','0' ;Set collision rename
-;
-rfchlp: db cr,lf,'ASK about existing files on a remote system'
- db cr,lf,'APPEND to existing files on a remote system'
- db cr,lf,'BACKUP (rename) existing files on a remote system'
- db cr,lf,'DISCARD new versions of existing files on a'
- db ' remote system'
- db cr,lf,'OVERWRITE existing files on a remote system'
- db cr,lf,'RENAME new versions of existing files on a'
- db ' remote system'
- db '$'
-;
-;Remote Set File-Incomplete tables
-;
-rfitab: db 2 ;2 entries
- db 7,'DISCARD$'
- db '0','0' ;Remote Set File Incomplete Discard
- db 4,'KEEP$'
- db '1','1' ;Remote Set File Incomplete Keep
-;
-rfihlp: db cr,lf,'DISCARD KEEP'
- db '$'
-;
-;Remote Set File-Names tables
-;
-rfntab: db 2 ;two entries
- db 9,'CONVERTED$'
- db '0','0' ;Remote Set File Names Converted
- db 7,'LITERAL$'
- db '1','1' ;Remote Set File Names Literal
-;
-rfnhlp: db cr,lf,'CONVERTED LITERAL'
- db '$'
-;
-;Remote Set File Replace tables
-;
-rfrtab: db 2 ;two entries
- db 8,'PRESERVE$'
- db '0','0' ;Remote Set File Replace Preserve
- db 7,'DEFAULT$'
- db '1','1' ;Remote Set File Replace Default
-;
-rfrhlp: db cr,lf,'PRESERVE DEFAULT'
- db '$'
-;
-;Remote Set File Type tables
-;
-rfttab: db 2 ;two entries
- db 6,'BINARY$'
- db '1','1' ;Remote Set File Type Binary
- db 4,'TEXT$'
- db '0','0' ;Remote Set File Type Text
-;
-rfthlp: db cr,lf,'BINARY TEXT'
- db '$'
-;
-; Remote Set Block-check
-;
-remsbc:
-IF lasm
- lxi h,'40' ;1st 2 chars of "400"
-ENDIF ;lasm
-IF NOT lasm
- lxi h,'04'
-ENDIF ;NOT lasm
- shld remdat+2 ;Store in correct order
- mvi a,'0' ;Put last char of type in buffer
- sta remdat+4 ;...
- lxi d,blktab ;Point to block-check table
- lxi h,blkhlp ;and help table
- jmp remsc1 ;Do common code
-;
-;Remote Set File command
-;
-remsfl: lxi d,rsftab ;Point to Remote Set File tables
- lxi h,rsfhlp ;...
-remsf0: call keycmd ;Get user's selection
- xchg ;Put dispatch address in HL
- pchl ;and obey the user's most fervent desires
-;
-;Remote Set Receive command
-;
-remsrc: lxi d,rrctab ;Point to the appropriate tables
- lxi h,rrchlp ;...
- jmp remsf0 ;and do command
-;
-;Remote Set Block-size command
-;
-remsbs:
-IF lasm
- lxi h,'31' ;1st 2 chars of Set code
-ENDIF ;lasm
-IF NOT lasm
- lxi h,'13'
-ENDIF ;NOT lasm
- shld remdat+2 ;Store chars in correct order
- mvi a,'1' ;Put last char in buffer
- sta remdat+4 ;...
- jmp remscm ;and do common Remote Set code
-;
-;Remote Set File-collision command
-;
-remsfc:
-IF lasm
- lxi h,'30' ;Put set type code in buffer
-ENDIF ;lasm
-IF NOT lasm
- lxi h,'03'
-ENDIF ;NOT lasm
- shld remdat+2 ;...
- mvi a,'2' ;...
- sta remdat+4 ;...
- lxi d,rfctab ;Point to tables
- lxi h,rfchlp ;...
- jmp remsc1 ;and do common code
-;
-;Remote Set File Incomplete command
-;
-remsfi:
-IF lasm
- lxi h,'31' ;Establish command keyword code
-ENDIF ;lasm
-IF NOT lasm
- lxi h,'13'
-ENDIF ;NOT lasm
- shld remdat+2 ;...
- mvi a,'0' ;...
- sta remdat+4 ;...
- lxi d,rfitab ;Point to tables
- lxi h,rfihlp ;...
- jmp remsc1 ;and do common code
-;
-;Remote Set File-Names command
-;
-remsfn:
-IF lasm
- lxi h,'30' ;Set command code
-ENDIF ;lasm
-IF NOT lasm
- lxi h,'03'
-ENDIF ;NOT lasm
- shld remdat+2 ;...
- mvi a,'1' ;...
- sta remdat+4 ;...
- lxi d,rfntab ;Point to the appropriate tables
- lxi h,rfnhlp ;...
- jmp remsc1 ;and do common code
-;
-;Remote Set File Record Format command
-;
-remsrf:
-IF lasm
- lxi h,'31' ;Set command code
-ENDIF ;lasm
-IF NOT lasm
- lxi h,'13'
-ENDIF ;NOT lasm
- shld remdat+2 ;...
- mvi a,'3' ;...
- sta remdat+4 ;...
- lxi d,rcftab ;Point to proper tables
- lxi h,rcfhlp ;...
- jmp remsc1 ;and do common code
-;
-;Remote Set File Record Length command
-;
-remsrl:
-IF lasm
- lxi h,'31' ;Set command code
-ENDIF ;lasm
-IF NOT lasm
- lxi h,'13'
-ENDIF ;NOT lasm
- shld remdat+2 ;...
- mvi a,'2' ;...
- sta remdat+4 ;...
- jmp remscm ;and do common code
-;
-;Remote Set File Replace command
-;
-remsfr:
-IF lasm
- lxi h,'30' ;Set command code
-ENDIF ;lasm
-IF NOT lasm
- lxi h,'03'
-ENDIF ;NOT lasm
- shld remdat+2 ;...
- mvi a,'3' ;...
- sta remdat+4 ;...
- lxi d,rfrtab ;Point to tables
- lxi h,rfrhlp ;...
- jmp remsc1 ;and do common code
-;
-;Remote Set File Type command
-;
-remsft:
-IF lasm
- lxi h,'30' ;Set command code
-ENDIF ;lasm
-IF NOT lasm
- lxi h,'03'
-ENDIF ;NOT lasm
- shld remdat+2 ;...
- mvi a,'0' ;...
- sta remdat+4 ;...
- lxi d,rfttab ;Point to tables
- lxi h,rfthlp ;...
- jmp remsc1 ;and go to common code
-;
-;Remote Set Receive Packet-length command
-;
-remrpl:
-IF lasm
- lxi h,'40' ;Set command code
-ENDIF ;lasm
-IF NOT lasm
- lxi h,'04'
-ENDIF ;NOT lasm
- shld remdat+2 ;...
- mvi a,'1' ;...
- sta remdat+4 ;...
- jmp remscm ;and do common code
-;
-;Remote Set Receive Timeout command
-;
-remsrt:
-IF lasm
- lxi h,'40' ;Set code
-ENDIF ;lasm
-IF NOT lasm
- lxi h,'04'
-ENDIF ;NOT lasm
- shld remdat+2 ;...
- mvi a,'2' ;...
- sta remdat+4 ;...
- jmp remscm ;and do common code
-;
-;Remote Set Retry command
-;
-remsry:
-IF lasm
- lxi h,'40' ;Set code
-ENDIF ;lasm
-IF NOT lasm
- lxi h,'04'
-ENDIF ;NOT lasm
- shld remdat+2 ;...
- mvi a,'3' ;...
- sta remdat+4 ;...
- jmp remscm ;Go to common code
-;
-;Remote Set Server Timeout command
-;
-remsst:
-IF lasm
- lxi h,'40' ;Set code
-ENDIF ;lasm
-IF NOT lasm
- lxi h,'04'
-ENDIF ;NOT lasm
- shld remdat+2 ;...
- mvi a,'4' ;...
- sta remdat+4 ;...
- jmp remscm ;Do common code
-
-
-
-
-
-; Little code to allow some expansion of code without changing
-; every futher address, only up to the end of this file.
-; TO BE REMOVED FOR RELEASE
-
-; ORG ($+100H) AND 0FF00H
-
-
-IF lasm
- LINK CPSSER
-ENDIF ;lasm
+; CPSREM.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the (system-independent) routines that implement
+; the REMOTE commands of the KERMIT protocol.
+;
+; revision history:
+;
+;edit 13, 21-Mar-1991 by MF. Renamed REMOTE SET FILE COLLISION REPLACE to
+; REMOTE SET FILE COLLISION OVERWRITE and modified the corresponding
+; help text slightly.
+;edit 12, 13-Feb-1991 by MF. Simplified code at "remcl0" to get REMOTE
+; command arguments by calling "cmgtch" in order to get command-line
+; characters directly. This means that command-line characters are
+; passed literally (except for prefixingand space-compression) to the
+; remote Kermit and that one need not send "?" or <esc> as "\"-prefixed
+; octal numbers in order to avoid immediate action by CP/M Kermit.
+;edit 11, 30-Jan-1991 by MF. Corrected code to always require entry of at least
+; one argument in the REMOTE COPY, REMOTE DELETE (REMOTE ERASE),
+; REMOTE MESSAGE, REMOTE RENAME and REMOTE TYPE commands. This is
+; done by branching to KERMT3 (the "not confirmed" code) if the
+; first argument isn't given. This should correct a bug which occurred
+; in numerous places in which the character immediately following
+; that specifying the flavor of a Generic command was not defined if
+; the first of multiple (at least two) arguments was left blank but
+; subsequent arguments were not. This should correct a problem
+; encountered by Russell Lang of Monash University In Australia when
+; he did a REMOTE MESSAGE command with a blank first argument (the
+; user id) and a nonblank second argument (the message text) from
+; CP/M Kermit to Ms-Kermit in Server mode.
+;edit 10, 14-Dec-1990 by MF. Put "<<>>" around "x" or "F" packet replies
+; to REMOTE commands as in VMS Bliss Kermit and eliminate unnecessary
+; instruction before label remc2d.
+;edit 9, 1-Nov-1990 by MF. Changed REMOTE CWD to REMOTE CD in the quest for
+; uniformity of nomenclature (per request of FDC).
+;edit 8, 29-Oct-1990 by MF. Corrected Remote command code to properly
+; prefix control characters (repeat prefix (~) isn't done in CP/M
+; yet).
+;edit 7, 17-Oct-1990 by MF. Changed verb "REMOTE SEND-MESSAGE" to
+; "REMOTE MESSAGE" to conform with the nomenclature suggested in
+; Chapter 10 of the 6th edition of the Kermit Protocol Manual.
+;edit 6, 10-Oct-1990 by MF. Corrected Remote command code to
+; properly prefix the control-character prefix character and the
+; eighth-bit quotation prefix character. Remote Set commands
+; now function correctly.
+; Also change the REMOTE SET FILE COLLISION ASK value to 5 per
+; Kermit Digest V12 #6 (though I still have no idea how the local
+; Kermit is supposed to answer).
+;edit 5, 5-Oct-1990 by MF. Coded many Remote Set commands.
+; The commands I have omitted deal with Attribute packets which
+; don't make much sense on a CP/M system.
+; Note also that for those Remote Set commands which take a
+; numeric argument, no range-checking is done here.
+; Also note that, for now, REMOTE SET FILE-COLLISION ASK is
+; equivalent to REMOTE SET FILE-COLLISION DISCARD because
+; (a) that's what the Kermit Digest indicated and (b) no mechanism
+; has been proposed for the Remote Kermit to query the Local Kermit.
+;edit 4, 29-Sep-1990 by MF. Corrected code to ignore error packets in
+; response to sending an "I" packet, per KPROTO.DOC
+;edit 3, 9-Sep-1990 by MF. Extensively revised this file to implement
+; Remote commands except for the following:
+; REMOTE JOURNAL, REMOTE MAIL, REMOTE PRINT, REMOTE PROGRAM,
+; REMOTE SET, REMOTE VARIABLE.
+;edit 2 ... MF Dunno where edit 2 went (shown in Version string).
+; edit 1: September 8th, 1987. Created this file from bits of the two packet files.
+; The commands supported by this system are all the REMOTE commands,
+; to allow users to acces remote host systems via Kermit. Added REMOTE
+; command table and REMOTE DIR command.
+;
+;
+remver: db 'CPSREM.ASM (13) 21-Mar-1991$' ; name, edit number, date
+
+;
+; REMOTE command - quite similar to the SET command
+remote: call selmdm ;Select modem
+ call flsmdm ;Flush buffers
+ call selcon ;Back to keyboard
+ lxi d,remtab ; remote commands table
+ lxi h,remhlp ; remote help table
+ call keycmd ; get result
+ xchg
+ pchl ; and do it
+
+
+
+
+; REMOTE command table. Works the same way as every other table etc.
+;
+remtab: db 19 ; nineteen commands so far
+ db 2,'CD$'
+ dw remcd ; remote cd command
+ db 4,'COPY$'
+ dw remcpy ; remote copy command
+ db 6,'DELETE$'
+ dw remdel ; remote delete command
+ db 9,'DIRECTORY$'
+ dw remdir ; remote directory command
+ db 10,'DISK-USAGE$'
+ dw remdsk ; remote disk-usage command
+ db 5,'ERASE$'
+ dw remdel ; remote erase command (same as delete)
+ db 6,'FINISH$'
+ dw finish ; same as finish
+ db 4,'HELP$'
+ dw remhep ; remote help command
+ db 4,'HOST$'
+ dw remhos ; remote host command
+ db 6,'KERMIT$'
+ dw remker ; remote Kermit command
+ db 5,'LOGIN$'
+ dw remlgi ; remote login
+ db 6,'LOGOUT$'
+ dw logout ; same as logout
+ db 7,'MESSAGE$'
+ dw remmsg ; remote message command
+ db 6,'RENAME$'
+ dw remren ; remote rename
+ db 3,'SET$'
+ dw remset ; remote set command
+ db 5,'SPACE$'
+ dw remdsk ; remote space command (same as disk-usage)
+ db 6,'STATUS$'
+ dw remsta ; remote status (of server) command
+ db 4,'TYPE$'
+ dw remtyp ; remote type command
+ db 3,'WHO$'
+ dw remwho ; remote who command
+
+remhlp: db cr,lf,'CD - change default directory for remote server'
+ db ' operations'
+ db cr,lf,'COPY - copy files on a remote system'
+ db cr,lf,'DELETE - delete files on a remote system'
+ db cr,lf,'DIRECTORY - list a directory on a remote system'
+ db cr,lf,'DISK-USAGE - show disk usage on a remote system'
+ db cr,lf,'FINISH - stop a remote server'
+ db cr,lf,'HELP - get help from a remote server'
+ db cr,lf,'HOST - execute a command on a remote system'
+ db cr,lf,'KERMIT - tell a remote server to execute a Kermit '
+ db 'command'
+ db cr,lf,'LOGIN - send user-identification to a remote server'
+ db cr,lf,'LOGOUT - stop and logout a remote server'
+ db cr,lf,'MESSAGE - send a message to a remote system user'
+ db cr,lf,'RENAME - rename files on a remote system'
+ db cr,lf,'SET - set remote server parameters'
+ db cr,lf,'SPACE - show disk-usage on a remote system'
+ db cr,lf,'STATUS - Get status of a remote server'
+ db cr,lf,'TYPE - type files on a remote system'
+ db cr,lf,'WHO - show current users on a remote system'
+ db '$'
+
+
+;Description of remote commands
+
+;
+; Packets start with an I packet in place of S/R packet. An X
+; packet is the same as an F (filename) packet except the 'file'
+; is not applicable. Copy X packet data field to display. Set
+; options so that no data is written to disk during D packets.
+; (REMTXT <> 0)
+;
+;Packets:
+; we we comments
+; send receive
+; I
+; ACK
+; Command packet
+; Ack or
+; Init
+; ACK
+; X Dummy header.
+; ACK
+; D listing from remote end
+; ACK We got it
+; ....
+; ACK last packet received ok
+; Z
+; ACK
+; B
+; ACK end of transaction.
+;
+;**Note** If the Remote system gives a simple ack to the command packet,
+;that is, a "short reply" is given, the data, if any, in the packet
+;is displayed and the transaction ends. The outline shown above is for a
+;"long reply".
+;
+; Remote commands
+;
+; Remote Copy - Copy file(s) on remote system
+;
+remcpy: lxi h,newfms ;Second argument prompt
+ shld rprmpt ;...
+ mvi a,'K' ;Generic type
+remcp0: sta remdat ;into packet
+ mvi a,2 ;Packet has at least two characters
+ sta rdl ;...
+ mvi a,'G' ;Generic command
+ sta rcom ;...
+ lxi d,remdat+2 ;Point to data buffer
+ call remcli ;Get filespec (if any) from command line
+ ora a ;Anything typed?
+ jz kermt3 ;No, we must have an argument
+ mov b,a ;Save length
+ adi space ;Yes, make encoded field length
+ sta remdat+1 ;and store in packet data area
+ lda rdl ;Get packet length so far
+ add b ;Count answer length
+ sta rdl ;and remember new packet size
+ lhld rprmpt ;Point to "new file" prompt
+ xchg ;...
+ shld rptr ;Save data pointer
+ call prompt ;Prompt the user
+ lhld rptr ;Get data pointer again
+ inx h ;Skip encoded field-length
+ xchg ;...
+ call remcli ;get user's answer
+ lhld rptr ;Restore pointer
+ mov c,a ;Save answer length
+ adi space ;Convert to encoded field length
+ mov m,a ;Put length in packet
+ lda rdl ;Get accumulated data length
+ add c ;plus data length
+ adi 1 ;plus field length character
+ sta rdl ;and remember it
+ jmp remcom ;and branch to common code
+;
+; Remote Cd - Change Directory
+;
+remcd: lxi h,pswdms ;Second argument prompt
+ shld rprmpt ;...
+ mvi a,'C' ;Generic cd
+remcd0: sta remdat ;into packet
+ mvi a,1 ;Packet is at least one character long
+ sta rdl ;...
+ mvi a,'G' ;Generic command
+ sta rcom ;...
+ lxi d,remdat+2 ;Point to data buffer
+ call remcli ;Get filespec (if any) from command line
+ mov b,a ;Save answer length (may be zero)
+ adi space ;Make encoded field length
+ sta remdat+1 ;and store in packet data area
+ lda rdl ;Get length so far
+ add b ;Count answer length
+ adi 1 ;and field length character
+ sta rdl ;and remember current packet-size
+ lda remdat ;Get generic packet flavor
+ cpi 'C' ;Remote CD?
+ jnz remcd1 ;No
+ mov a,b ;Get length of possible directory spec
+ ora a ;Did the user give a directory spec?
+ jz remcom ;No, we can process the command immediately
+ mvi a,0ffH ;Yes, password follows, make it not echo
+ sta cmqflg ;...
+remcd1: lhld rprmpt ;Point to "password" prompt
+ xchg ;...
+ shld rptr ;Save data pointer
+ mvi a,0ffH ;Allow blank password
+ sta cmbflg ;...
+ call prompt ;Prompt the user
+ lhld rptr ;Restore data pointer
+ xchg ;...
+ inx d ;and increment it
+ call remcli ;Get user's answer
+ ora a ;Password given?
+ jz remcom ;No, proceed with command
+ mov c,a ;Yes, save answer length
+ adi space ;Convert to encoded field length
+ lhld rptr ;Get data pointer
+ mov m,a ;Put length in packet
+ lda rdl ;Get accumulated data length
+ adi 1 ;Count encoded field length
+ add c ;plus data length
+ sta rdl ;and remember packet-size
+ jmp remcom ;Branch to common code
+;
+; Remote Delete (Erase) command
+;
+remdel: mvi a,'E' ;Delete (Erase) command
+remdl0: sta remdat ;...
+ mvi a,1 ;At least one character in packet
+ sta rdl ;...
+ mvi a,'G' ;Generic command
+ sta rcom ;...
+ lxi d,remdat+2 ;Point to data field
+ call remcli ;Get filespec
+ mov b,a ;Save length
+ lda remdat ;Get packet type
+ cpi 'E' ;If Generic Delete
+ jz remdl1 ;We must have an argument
+ cpi 'T' ;Ditto for Generic Type
+ jz remdl1 ;...
+ mov a,b ;Else get back character count
+ ora a ;Answer typed?
+ jz remcom ;No, process packet as is
+remdl1: mov a,b ;Get character count again
+ ora a ;Anything typed?
+ jz kermt3 ;No, we must have an argument (Delete/Type)
+ adi space ;Yes, encode field length
+ sta remdat+1 ;and put in packet
+ lda rdl ;Get packet length so far
+ add b ;Count length of filespec
+ adi 1 ;Count field length character
+ sta rdl ;and store packet length
+ jmp remcom ;and do our stuff
+;
+; Remote Directory command
+;
+remdir: mvi a,'D' ;generic directory command
+ jmp remdl0 ;Do common code
+;
+; Remote Disk-usage (Space) command
+;
+remdsk: mvi a,'U' ;Disk-usage generic command
+ jmp remdl0 ;Do common code
+;
+; Remote Help command
+;
+remhep: mvi a,'H' ;generic help command
+ jmp remdl0 ;Do common code
+;
+; Remote Host command
+;
+remhos: mvi a,'C' ;Remote Host command
+remho0: sta rcom ;...
+ xra a ;Zero packet length
+ sta rdl ;...
+ lxi d,remdat ;Point to packet data buffer
+ call remcli ;Get host command
+ ora a ;Anything typed?
+ jz kermt3 ;No, don't let the user get away with this
+ sta rdl ;Yes, store packet length
+ jmp remcom ;and do the command
+;
+; Remote Kermit command
+;
+remker: mvi a,'K' ;Remote Kermit command
+ jmp remho0 ;Do common code
+;
+; Remote Login command
+;
+remlgi: mvi a,'G' ;Generic command
+ sta rcom ;...
+ mvi a,'I' ;Generic type
+ sta remdat ;into packet
+ mvi a,1 ;At least one character in packet
+ sta rdl ;...
+ lxi d,remdat+2 ;Point to data buffer
+ call remcli ;Get userid (if any) from command line
+ ora a ;Userid typed?
+ jz remcom ;No, nothing more to do
+ mov b,a ;Yes, save length
+ adi space ;Make encoded field length
+ sta remdat+1 ;and store in packet data area
+ lda rdl ;Get packet length
+ add b ;Count id length
+ adi 1 ;and field length character
+ sta rdl ;and remember accumulated length
+ xchg ;Save data pointer
+ shld rptr ;...
+ mvi a,0ffH ;Allow blank answers
+ sta cmbflg ;...
+ sta cmqflg ;Passwords don't echo
+ lxi d,pswdms ;Point to "password" prompt
+ call prompt ;Prompt the user
+ lhld rptr ;Get data pointer
+ xchg ;Put in DE
+ inx d ;Skip encoded field-length
+ call remcli ;Get password, if any
+ ora a ;Anything typed?
+ jz remcom ;No, do command immediately
+ mov c,a ;Yes, save answer length
+ adi space ;Convert to encoded field length
+ lhld rptr ;Get pointer
+ mov m,a ;Put length in packet
+ lda rdl ;Get accumulated data length
+ adi 1 ;Count encoded field length
+ add c ;Count "password" field length
+ sta rdl ;and remember new packet length
+ xchg ;Save data pointer
+ shld rptr ;...
+ xra a ;Allow echoing again for "account" field
+ sta cmqflg ;...
+ lxi d,acctms ;Point to "account" prompt
+ call prompt ;Prompt the user
+ lhld rptr ;Get data pointer
+ xchg ;into DE
+ inx d ;Skip encoded field length
+ call remcli ;Get "account" field, if any
+ ora a ;Anything typed?
+ jz remcom ;No, do the command now
+ mov c,a ;Yes, save length of answer
+ adi space ;Convert to encoded field length
+ lhld rptr ;Get data pointer
+ mov m,a ;Put length in packet
+ lda rdl ;Get accumulated data length
+ adi 1 ;Count encoded field length
+ add c ;plus "account" length
+ sta rdl ;and remember it
+ jmp remcom ;Branch to common code
+;
+; Remote Rename command
+;
+remren: lxi h,newfms ;Second argument prompt
+ shld rprmpt ;...
+ mvi a,'R' ;generic rename
+ jmp remcp0 ;Do common code
+;
+; Remote Message command
+;
+remmsg: lxi h,msgms ;Second argument prompt
+ shld rprmpt ;...
+ mvi a,'M' ;generic message
+ jmp remcp0 ;Do common code
+;
+;Remote Set command
+;
+remset: mvi a,6 ;Packet data area has at least six chars
+ sta rdl ;...
+ mvi a,'S' ;Remote Set command
+ sta remdat ;...
+ mvi a,'G' ;It's a generic command
+ sta rcom ;...
+ mvi a,'#' ;Encoded field-length for SET type
+ sta remdat+1 ;which is three chars long
+ lxi d,rmstab ;Point to Set command table
+ lxi h,rmshlp ;and the help table
+ call keycmd ;Find out which command is to be executed
+ xchg ;Put dispatch address in HL
+ pchl ;Go do the command
+;
+; Common code for Remote Set commands that take an argument
+;
+remscm: lxi d,remdat+6 ;We get an argument from the user
+ mvi a,cmtxt ;...
+ call comnd ;...
+ jmp kermt3 ;Couldn't get one.
+ ora a ;Did the user give one?
+ jz kermt3 ;a blank answer isn't acceptable
+ mov c,a ;Save length of answer
+ adi space ;Convert to encoded field-length
+ sta remdat+5 ;and put in packet data area
+ lda rdl ;Get current data length
+ add c ;Count length of answer
+ sta rdl ;and store new data length
+ call cfmcmd ;Get a "confirm"
+ jmp remcom ;Do common Remote command code
+;
+; Common code for Remote Set commands requiring another table lookup
+;
+remsc1: call chkkey ;Get user's selection
+ sta remdat+6 ;and put into the packet data area
+ mvi a,'!' ;Encoded field length for 1 char
+ sta remdat+5 ;Put in packet
+ lda rdl ;Get accumulated packet data length
+ adi 1 ;Count length of answer (1 char)
+ sta rdl ;and store as new packet data length
+ jmp remcom ;Go do common Remote command processing
+;
+; Remote Status (of server) command
+;
+remsta: call cfmcmd ;Get return
+ mvi a,'Q' ;Command type (Server Status)
+ sta remdat ;...
+ mvi a,'G' ;Generic Kermit command
+ sta rcom ;...
+ mvi a,1 ;1 character in packet
+ sta rdl ;...
+ jmp remcom ;Do common code
+;
+; Remote Type command
+;
+remtyp: mvi a,'T' ;generic type command
+ jmp remdl0 ;Do common code
+;
+; Remote Who command
+;
+remwho: lxi h,optms ;Second argument prompt
+ shld rprmpt ;...
+ mvi a,'W' ;generic who
+ jmp remcd0 ;Do common code
+
+; Common code for Remote commands
+;
+remcom:
+ mvi a,0ffH ; Make sure returned info is sent
+ sta remtxt ;to the user's screen rather than to a file
+ lda rcom ;Get packet-type
+ cpi 'G' ;Is it a generic command?
+ jnz remc0e ;No, go clear the screen
+ lda remdat ;Yes, get generic command type
+ cpi 'S' ;Is it a Remote Set command?
+ jz remc0f ;Yes, don't clear the screen
+remc0e: call clrtop ; clear the screen
+remc0f: xra a
+ sta numtry ; reset retries
+ sta czseen
+ sta pktnum
+ lxi h,0
+ shld numpkt
+ shld numrtr ; clear some variables
+
+ mvi a,'1' ; reset block check type
+ sta curchk
+remcm0: mvi a,'I' ; init state
+ sta state
+ call sinit ; do sendinit with I packet (??)
+ lda state ; now see if we are in the 'X' state
+ cpi 'X'
+ jz remco0 ;Yup, all is in order
+ cpi 'A' ;No, in abort state?
+ jnz remcm0 ;No, try I-packet again
+ jmp kermit ;Yes, like Danny Boy, we must die.
+ ;If we get this far, either the "I" packet
+ ;was understood or the Server couldn't
+ ;handle it and we ignored the error.
+ ;In either case, we can proceed.
+
+
+
+remco0: xra a
+ sta numtry ; reset retries
+ sta czseen
+ sta pktnum
+ lxi h,0
+ shld numpkt
+ shld numrtr ; clear some variables
+ mvi a,'1' ;Make sure we use
+ sta curchk ;1-character checksum
+ lda rdl ;Get packet-length (number of bytes to copy)
+ ora a ;Anything to copy?
+ jz remcm1 ;No
+ sta temp1 ;Yes, save loop counter
+ lda spsiz ;Get max packet size
+ sui 5 ;less overhead
+ sta temp2 ;gives max chars we can send
+ lxi d,remdat ;Copy from private buffer
+ lxi h,data ;to packet data area
+ lda qbchr ;Get eightgh-bit quoting prefix char
+ mov b,a ;Save it
+ lda squote ;Get control-char quoting char
+ mov c,a ;and save it
+remc0a: lda temp2 ;Get characters to go in packet
+ dcr a ;and decrement it
+ sta temp2 ;...
+ jm remc0x ;We can't copy any more
+ ldax d ;Get a packet data character
+ cpi space ;Is it a control char?
+ jm remc0b ;Yes, quote it
+ cmp c ;Is it the control-char prefix?
+ jz remc0b ;Yes, quote it
+ lda quot8 ;No, is eighth-bit quoting in effect?
+ ora a ;...
+ jz remc0c ;No, just copy the character
+ ldax d ;Get character again
+ cmp b ;Is it the eighth-bit quote char?
+ jnz remc0d ;No, just copy it
+remc0b: mov m,c ;Yes, quote the character
+ inx h ;Increment the dest. pointer
+ lda temp2 ;Get chars to go
+ dcr a ;Decrement
+ sta temp2 ;...
+ jm remc0x ;Can't copy any more
+ lda rdl ;Count quote prefix
+ inr a ;...
+ sta rdl ;...
+remc0c: ldax d ;Get character again
+ cpi space ;If not a control char,
+ jp remc0d ;just copy the character, else
+ adi 40H ;Convert to printing character
+ ani 7fH ;modulo 128
+remc0d: mov m,a ;Copy the character
+ inx h ;Increment the pointers
+ inx d ;...
+remc0x: lda temp1 ;Get loop counter
+ dcr a ;and decrement it
+ sta temp1 ;...
+ jnz remc0a ;Copy entire packet data area
+;
+remcm1: xra a
+ sta argblk ; set packet no zero
+ lda rdl ;Number of bytes in packet
+ sta argblk+1 ;into argument block
+ lda rcom ;Remote command
+ call spack ;Send the packet
+ jmp kermt3 ;Nogo, die!
+ jmp remco2 ;Try to get an answer
+
+remco1: call nak0 ;Nak packet
+;
+
+remco2: lda numtry ;Get number of retries
+ inr a ; update retries
+ cpi maxtry ;To many retries?
+ jm remc2a ;No
+ lxi d,erms28 ;Yes, complain
+ call prtstr ;...
+ jmp kermit ;and abort
+
+remc2a: sta numtry
+ call rpack ;Get a packet
+ jmp remco1 ;Couldn't get one.
+ cpi 'E' ;Error packet?
+ jnz remc2b ;No
+ lda rcom ;What kind of packet did we send?
+ cpi 'G' ;If it wasn't generic,
+ jnz remc2f ;there is no need to start a new message line
+ lda remdat ;Packet was generic
+ cpi 'S' ;Was it a Remote Set?
+ cz prcrlf ;Yes, start a new line since the screen
+ ;isn't blank and we would clobber the command-
+ ;line otherwise
+remc2f: call error0 ;Yes, inform the user
+ jmp kermit ;and abort to main command loop
+remc2b: cpi 'S' ;Send-init?
+ jnz remc2c ;No
+ call rini2a ;Initialize parameters
+ lda state ;Get state
+ cpi 'A' ;If abort,
+ jz kermit ;Go back to main command loop
+ mvi a,'X' ;Set state to text-display
+ sta state ;...
+ jmp read2 ;Get more packets
+remc2c: cpi 'N' ;Nacked packet?
+ jz remco2 ;Yes, try again
+ sta state ;Save packet type
+ call selcon ;Select Console
+ lxi h,data ;Point to data
+ lda argblk+1 ;Anything in packet data?
+ ora a ;...
+ jz remco6 ;No
+ push h ;Yes, save pointer
+ push psw ;and character count
+ mvi e,'<' ;Type "<<" as in VMSKermit
+ push d ;...
+ call outcon ;...
+ pop d ;...
+ call outcon ;...
+ pop psw ;Restore character counter
+ pop h ;and data pointer
+remc2d: ora a ;...
+ jz remc2e ;No more characters
+ dcr a ;Decrement loop counter
+mov e,m ;Get character
+ inx h ;Increment pointer
+ push psw ;Save loop counter
+ push h ;Save data pointer
+ call outcon ;Type on Console
+ pop h ;Restore pointer
+ pop psw ;Restore loop counter
+ jmp remc2d ;Type all packet data
+remc2e: mvi e,'>' ;Type ">>" as in VMSKermit
+ push d ;...
+ call outcon ;...
+ pop d ;...
+ call outcon ;...
+ call prcrlf ;End the line
+remco6: lda state ;Get packet type again
+ cpi 'Y' ;If simple ack,
+ jz kermit ;Done, else
+ call ackp ;Acknoledge the packet
+ call countp ;Count the packet
+ mvi a,'D' ;Set to data-receive
+ sta state ;...
+ jmp read2 ; do the same as read a file, but echo
+ ; to the screen.. Dont close non-open files.
+;
+;
+;REMCLI - Get command-line for Remote commands
+;
+remcli: xra a ;Zero accumulated length
+ sta rcl ;...
+ mov b,a ;[12]...
+;
+;[MF][12]Eliminate following code which calls "comnd" in favor of code which
+;[MF][12]calls "cmgtch" directly so that characters are sent without
+;[MF][12]alteration or inadvertent action ("?" or <esc>). The only thing
+;[MF][12]lost is the ability to produce any ASCII character via
+;[MF][12]octal numbers prefixed with "\" but this isn't used much in remote
+;[MF][12]commands anyway.
+;
+;remcl0: mvi a,cmtxt ;We get arbitrary text
+; call comnd ;from the command-line
+; jmp kermt3 ;We couldn't get any.
+; ora a ;Anything given?
+; jz remcl1 ;No, done
+; push b ;Save BC
+; mov c,a ;Save length
+; lda rcl ;Get accumulated length
+; add c ;plus current word length
+; adi 1 ;plus a space
+; sta rcl ;and save accumulated length
+; mvi a,space ;Put in a space separator
+; stax d ;...
+; inx d ;Increment pointer
+; pop b ;Restore BC
+; jmp remcl0 ;Get text to end-of-line
+;remcl1: lda rcl ;Get accumulated length
+; ora a ;Anything typed?
+; rz ;No
+; dcr a ;Yes, don't count final space
+; push psw ;Save count
+; dcx d ;Point to final space
+; xra a ;Zap it
+; stax d ;...
+; pop psw ;Restore count
+;
+;[MF][12]Simplified code follows
+;
+remcl0: call cmgtch ;[12]Get a character from the user
+ ani 7fh ;[12]Turn off minus bit
+ cpi cr ;[12]If end-of-line,
+ jz remclx ;[12]We're done
+ cpi lf ;[12]...
+ jz remclx ;[12]...
+ stax d ;[12]else store the character
+ inr b ;[12]and count it
+ inx d ;[12]Increment character buffer pointer
+ cpi esc ;[12]is character an <esc>?
+ jz remcl2 ;[12]Yes
+ cpi ff ;[12]an <ff>?
+ jz remcl1 ;[12]Yes, diddle command buffer pointer
+ cpi '?' ;[12]a "?"?
+ jnz remcl0 ;[12]No, just get more characters
+remcl1: push h ;[12]Protect HL
+ lhld cmdptr ;[12]get "cmgtch"'s character pointer
+ inx h ;[12]and reverse the action at "cmgtc4"
+ ;[12]since we don't need a "confirm" and
+ ;[12]infinite loops are beaucoup bad news
+ shld cmdptr ;[12]...
+ pop h ;[12]Restore HL
+remcl2: push psw ;[12]Save the character
+ xra a ;[12]Zero the action flag so we get input
+ sta cmaflg ;[12]to end-of-line without special action
+ pop psw ;[12]Restore the character
+ jmp remcl0 ;[12]Get more characters
+remclx: mov a,b ;[12]Get accumulated text length
+ sta rcl ;[12]and remember it
+;
+ ret ;Return
+;
+;Remote set values
+;
+; REMOTE SET FILE TYPE 300 0 = TEXT, 1 = BINARY
+; REMOTE SET FILE NAMES 301 0 = CONVERTED, 1 = LITERAL
+; REMOTE SET FILE COLLISION 302 0 = RENAME, 1 = OVERWRITE,
+; 2 = BACKUP, 3 = APPEND,
+; 4 = DISCARD, 5 = ASK
+; REMOTE SET FILE REPLACE 303 0 = PRESERVE, 1 = DEFAULT
+; REMOTE SET FILE INCOMPLETE 310 0 = DISCARD, 1 = KEEP
+; REMOTE SET INCOMPLETE (same as above)
+; REMOTE SET BLOCK-CHECK 400 number (1, 2, or 3)
+; REMOTE SET RECEIVE PACKET-LENGTH 401 number (10-9024)
+; REMOTE SET RECEIVE TIMEOUT 402 number (any, 0 = no timeout)
+; REMOTE SET RETRY 403 number (any, 0 = no limit)
+; REMOTE SET SERVER TIMEOUT 404 number (any, 0 = no timeout)
+;REMOTE SET FILE BLOCKSIZE 311 number
+;REMOTE SET FILE RECORD-LENGTH 312 number
+;REMOTE SET FILE RECORD-FORMAT 313 F (fixed), V (variable), etc...
+;This is just for the record, to assign these numbers to these commands
+;for somebody who needed them. Details to be filled in later.
+;
+;Remote Set command table
+;
+rmstab: db 7 ;seven entries
+ db 16,'BLOCK-CHECK-TYPE$'
+ dw remsbc ;Remote Set Block Check
+ db 4,'FILE$'
+ dw remsfl ;Remote Set File
+ db 10,'INCOMPLETE$'
+ dw remsfi ;Remote Set (file) Incomplete
+ db 7,'RECEIVE$'
+ dw remsrc ;Remote Set Receive
+ db 7,'REPLACE$'
+ dw remsfr ;Remote Set (file) Replace
+ db 5,'RETRY$'
+ dw remsry ;Remote Set Retry
+ db 14,'SERVER-TIMEOUT$'
+ dw remsst ;Remote Set Server Timeout
+;
+rmshlp: db cr,lf,'BLOCK-CHECK-TYPE for a remote server'
+ db cr,lf,'FILE parameters for a remote server'
+ db cr,lf,'INCOMPLETE file disposition for a remote server'
+ db cr,lf,'RECEIVE parameters for a remote server'
+ db cr,lf,'REPLACE file attribute handling for a remote server'
+ db cr,lf,'RETRY maximum for a remote server'
+ db cr,lf,'SERVER-TIMEOUT interval for a remote server'
+ db '$'
+;
+;Remote Set File tables
+;
+rsftab: db 8 ;eight entries
+ db 10,'BLOCK-SIZE$'
+ dw remsbs ;Remote Set File Block-size command
+ db 9,'COLLISION$'
+ dw remsfc ;Remote Set File Collision command
+ db 10,'INCOMPLETE$'
+ dw remsfi ;Remote Set File Incomplete command
+ db 5,'NAMES$'
+ dw remsfn ;Remote Set File Names command
+ db 13,'RECORD-FORMAT$'
+ dw remsrf ;Remote Set File Record-format
+ db 13,'RECORD-LENGTH$'
+ dw remsrl ;Remote Set File Record-length
+ db 7,'REPLACE$'
+ dw remsfr ;Remote Set File Replace command
+ db 4,'TYPE$'
+ dw remsft ;Remote Set File Type command
+;
+rsfhlp: db cr,lf,'BLOCK-SIZE of files for a remote server'
+ db cr,lf,'COLLISION action on filename conflicts for a remote'
+ db ' server'
+ db cr,lf,'INCOMPLETE file disposition for a remote server'
+ db cr,lf,'NAMES translation of files for a remote server'
+ db cr,lf,'RECORD-FORMAT of files for a remote server'
+ db cr,lf,'RECORD-LENGTH for a remote server'
+ db cr,lf,'REPLACE file attribute handling for a remote server'
+ db cr,lf,'TYPE of files for a remote server'
+ db '$'
+;
+;Remote Set File Record-format tables
+;
+rcftab: db 2 ;two entries
+ db 5,'FIXED$'
+ db 'F','F' ;Remote Set File Record-format Fixed command
+ db 8,'VARIABLE$'
+ db 'V','V' ;Remote Set File Record-format Variable cmd
+;
+rcfhlp: db cr,lf,'FIXED VARIABLE'
+ db '$'
+;
+;Remote Set Receive tables
+;
+rrctab: db 2 ;two entries
+ db 13,'PACKET-LENGTH$'
+ dw remrpl ;Remote Set Receive Packet-length command
+ db 7,'TIMEOUT$'
+ dw remsrt ;Remote Set Receive Timeout command
+;
+rrchlp: db cr,lf,'PACKET-length TIMEOUT'
+ db '$'
+;
+;Remote Set File-collision table
+;
+rfctab: db 6 ;six entries
+ db 6,'APPEND$'
+ db '3','3' ;Set collision append
+ db 3,'ASK$'
+ db '5','5' ;Set collision ask
+ db 6,'BACKUP$'
+ db '2','2' ;Set collision backup
+ db 7,'DISCARD$'
+ db '4','4' ;Set collision discard
+ db 9,'OVERWRITE$'
+ db '1','1' ;Set collision overwrite
+ db 6,'RENAME$'
+ db '0','0' ;Set collision rename
+;
+rfchlp: db cr,lf,'ASK about existing files on a remote system'
+ db cr,lf,'APPEND to existing files on a remote system'
+ db cr,lf,'BACKUP (rename) existing files on a remote system'
+ db cr,lf,'DISCARD new versions of existing files on a'
+ db ' remote system'
+ db cr,lf,'OVERWRITE existing files on a remote system'
+ db cr,lf,'RENAME new versions of existing files on a'
+ db ' remote system'
+ db '$'
+;
+;Remote Set File-Incomplete tables
+;
+rfitab: db 2 ;2 entries
+ db 7,'DISCARD$'
+ db '0','0' ;Remote Set File Incomplete Discard
+ db 4,'KEEP$'
+ db '1','1' ;Remote Set File Incomplete Keep
+;
+rfihlp: db cr,lf,'DISCARD KEEP'
+ db '$'
+;
+;Remote Set File-Names tables
+;
+rfntab: db 2 ;two entries
+ db 9,'CONVERTED$'
+ db '0','0' ;Remote Set File Names Converted
+ db 7,'LITERAL$'
+ db '1','1' ;Remote Set File Names Literal
+;
+rfnhlp: db cr,lf,'CONVERTED LITERAL'
+ db '$'
+;
+;Remote Set File Replace tables
+;
+rfrtab: db 2 ;two entries
+ db 8,'PRESERVE$'
+ db '0','0' ;Remote Set File Replace Preserve
+ db 7,'DEFAULT$'
+ db '1','1' ;Remote Set File Replace Default
+;
+rfrhlp: db cr,lf,'PRESERVE DEFAULT'
+ db '$'
+;
+;Remote Set File Type tables
+;
+rfttab: db 2 ;two entries
+ db 6,'BINARY$'
+ db '1','1' ;Remote Set File Type Binary
+ db 4,'TEXT$'
+ db '0','0' ;Remote Set File Type Text
+;
+rfthlp: db cr,lf,'BINARY TEXT'
+ db '$'
+;
+; Remote Set Block-check
+;
+remsbc:
+IF lasm
+ lxi h,'40' ;1st 2 chars of "400"
+ENDIF ;lasm
+IF NOT lasm
+ lxi h,'04'
+ENDIF ;NOT lasm
+ shld remdat+2 ;Store in correct order
+ mvi a,'0' ;Put last char of type in buffer
+ sta remdat+4 ;...
+ lxi d,blktab ;Point to block-check table
+ lxi h,blkhlp ;and help table
+ jmp remsc1 ;Do common code
+;
+;Remote Set File command
+;
+remsfl: lxi d,rsftab ;Point to Remote Set File tables
+ lxi h,rsfhlp ;...
+remsf0: call keycmd ;Get user's selection
+ xchg ;Put dispatch address in HL
+ pchl ;and obey the user's most fervent desires
+;
+;Remote Set Receive command
+;
+remsrc: lxi d,rrctab ;Point to the appropriate tables
+ lxi h,rrchlp ;...
+ jmp remsf0 ;and do command
+;
+;Remote Set Block-size command
+;
+remsbs:
+IF lasm
+ lxi h,'31' ;1st 2 chars of Set code
+ENDIF ;lasm
+IF NOT lasm
+ lxi h,'13'
+ENDIF ;NOT lasm
+ shld remdat+2 ;Store chars in correct order
+ mvi a,'1' ;Put last char in buffer
+ sta remdat+4 ;...
+ jmp remscm ;and do common Remote Set code
+;
+;Remote Set File-collision command
+;
+remsfc:
+IF lasm
+ lxi h,'30' ;Put set type code in buffer
+ENDIF ;lasm
+IF NOT lasm
+ lxi h,'03'
+ENDIF ;NOT lasm
+ shld remdat+2 ;...
+ mvi a,'2' ;...
+ sta remdat+4 ;...
+ lxi d,rfctab ;Point to tables
+ lxi h,rfchlp ;...
+ jmp remsc1 ;and do common code
+;
+;Remote Set File Incomplete command
+;
+remsfi:
+IF lasm
+ lxi h,'31' ;Establish command keyword code
+ENDIF ;lasm
+IF NOT lasm
+ lxi h,'13'
+ENDIF ;NOT lasm
+ shld remdat+2 ;...
+ mvi a,'0' ;...
+ sta remdat+4 ;...
+ lxi d,rfitab ;Point to tables
+ lxi h,rfihlp ;...
+ jmp remsc1 ;and do common code
+;
+;Remote Set File-Names command
+;
+remsfn:
+IF lasm
+ lxi h,'30' ;Set command code
+ENDIF ;lasm
+IF NOT lasm
+ lxi h,'03'
+ENDIF ;NOT lasm
+ shld remdat+2 ;...
+ mvi a,'1' ;...
+ sta remdat+4 ;...
+ lxi d,rfntab ;Point to the appropriate tables
+ lxi h,rfnhlp ;...
+ jmp remsc1 ;and do common code
+;
+;Remote Set File Record Format command
+;
+remsrf:
+IF lasm
+ lxi h,'31' ;Set command code
+ENDIF ;lasm
+IF NOT lasm
+ lxi h,'13'
+ENDIF ;NOT lasm
+ shld remdat+2 ;...
+ mvi a,'3' ;...
+ sta remdat+4 ;...
+ lxi d,rcftab ;Point to proper tables
+ lxi h,rcfhlp ;...
+ jmp remsc1 ;and do common code
+;
+;Remote Set File Record Length command
+;
+remsrl:
+IF lasm
+ lxi h,'31' ;Set command code
+ENDIF ;lasm
+IF NOT lasm
+ lxi h,'13'
+ENDIF ;NOT lasm
+ shld remdat+2 ;...
+ mvi a,'2' ;...
+ sta remdat+4 ;...
+ jmp remscm ;and do common code
+;
+;Remote Set File Replace command
+;
+remsfr:
+IF lasm
+ lxi h,'30' ;Set command code
+ENDIF ;lasm
+IF NOT lasm
+ lxi h,'03'
+ENDIF ;NOT lasm
+ shld remdat+2 ;...
+ mvi a,'3' ;...
+ sta remdat+4 ;...
+ lxi d,rfrtab ;Point to tables
+ lxi h,rfrhlp ;...
+ jmp remsc1 ;and do common code
+;
+;Remote Set File Type command
+;
+remsft:
+IF lasm
+ lxi h,'30' ;Set command code
+ENDIF ;lasm
+IF NOT lasm
+ lxi h,'03'
+ENDIF ;NOT lasm
+ shld remdat+2 ;...
+ mvi a,'0' ;...
+ sta remdat+4 ;...
+ lxi d,rfttab ;Point to tables
+ lxi h,rfthlp ;...
+ jmp remsc1 ;and go to common code
+;
+;Remote Set Receive Packet-length command
+;
+remrpl:
+IF lasm
+ lxi h,'40' ;Set command code
+ENDIF ;lasm
+IF NOT lasm
+ lxi h,'04'
+ENDIF ;NOT lasm
+ shld remdat+2 ;...
+ mvi a,'1' ;...
+ sta remdat+4 ;...
+ jmp remscm ;and do common code
+;
+;Remote Set Receive Timeout command
+;
+remsrt:
+IF lasm
+ lxi h,'40' ;Set code
+ENDIF ;lasm
+IF NOT lasm
+ lxi h,'04'
+ENDIF ;NOT lasm
+ shld remdat+2 ;...
+ mvi a,'2' ;...
+ sta remdat+4 ;...
+ jmp remscm ;and do common code
+;
+;Remote Set Retry command
+;
+remsry:
+IF lasm
+ lxi h,'40' ;Set code
+ENDIF ;lasm
+IF NOT lasm
+ lxi h,'04'
+ENDIF ;NOT lasm
+ shld remdat+2 ;...
+ mvi a,'3' ;...
+ sta remdat+4 ;...
+ jmp remscm ;Go to common code
+;
+;Remote Set Server Timeout command
+;
+remsst:
+IF lasm
+ lxi h,'40' ;Set code
+ENDIF ;lasm
+IF NOT lasm
+ lxi h,'04'
+ENDIF ;NOT lasm
+ shld remdat+2 ;...
+ mvi a,'4' ;...
+ sta remdat+4 ;...
+ jmp remscm ;Do common code
+
+
+
+
+
+; Little code to allow some expansion of code without changing
+; every futher address, only up to the end of this file.
+; TO BE REMOVED FOR RELEASE
+
+; ORG ($+100H) AND 0FF00H
+
+
+IF lasm
+ LINK CPSSER
+ENDIF ;lasm
diff --git a/cpsser.asm b/cpsser.asm
index d49ebe0..707f1c3 100644
--- a/cpsser.asm
+++ b/cpsser.asm
@@ -1,44 +1,44 @@
-; CPSSER.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the (system-independent) routines that implement
-; the SERVER part of the KERMIT protocol.
-;
-; revision history:
-;
-;
-; edit 1: September, 1987. Created CPSSER.ASM from bits from the two CPSPK?
-; files.
-; The code herein is to allow remote systems to communicate to
-; this Kermit running in SERVER mode. Note that not every server
-; command will be supported, mind...
-;
-server: db 'CPSSER.ASM (1) 8-SEP-87$' ; name, edit number, date
-
-
-
-; Little code to allow some expansion of code without changing
-; every futher address, only up to the end of this file.
-; TO BE REMOVED FOR RELEASE!
-
-; org ($+100h) AND 0FF00H
-
-
-IF lasm
- LINK CPSTT
-ENDIF;lasm
+; CPSSER.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the (system-independent) routines that implement
+; the SERVER part of the KERMIT protocol.
+;
+; revision history:
+;
+;
+; edit 1: September, 1987. Created CPSSER.ASM from bits from the two CPSPK?
+; files.
+; The code herein is to allow remote systems to communicate to
+; this Kermit running in SERVER mode. Note that not every server
+; command will be supported, mind...
+;
+server: db 'CPSSER.ASM (1) 8-SEP-87$' ; name, edit number, date
+
+
+
+; Little code to allow some expansion of code without changing
+; every futher address, only up to the end of this file.
+; TO BE REMOVED FOR RELEASE!
+
+; org ($+100h) AND 0FF00H
+
+
+IF lasm
+ LINK CPSTT
+ENDIF;lasm
diff --git a/cpstt.asm b/cpstt.asm
index 41a30af..1e96171 100644
--- a/cpstt.asm
+++ b/cpstt.asm
@@ -1,862 +1,862 @@
-; CPSTT.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the code for the TRANSMIT and CONNECT commands,
-; which communicate with a host which is not running KERMIT.
-;
-; revision history:
-;
-;edit 12, 31-Jan-1991 by MF. Delete call to "inbuf" after "xmit1" in
-; the TRANSMIT command. "getfil" initializes various counters so that
-; when "in1chr" is first called, "inbuf" will be called immediately
-; and will read sectors of the file to be transmitted from disk.
-; This, along with a fix to "in1chr" in CPSUTL.ASM, fixes a bug
-; discovered by Lance Tagliapietra of the University of Wisconsin at
-; Platteville wherein the TRANSMIT command was failing to transmit some
-; characters in files over one sector in length. See CPSUTL.ASM,
-; edit 29.
-; edit 11, 10 September, a987, by OBSchou. Modified TRANSMIT command
-; to TRANSMIT <file> <string>
-;
-; edit 10, 27 August, 1987 by OBSchou. Fixed bugs in Transmit, but I may
-; be introducing problems for IBM/CMS or half duplex systems. What
-; does this combination do??
-;
-; edit 9 30 March, 1987 by OBSchou to replace the TRANSMIT routine.
-; Syntax is now TRANSMIT file after a previous
-; INPUT <wait time> <string to wait for>
-;
-; edit 8 19 June, 1986 by OBSchou. Modified the interupt testing routine
-; to see if the command was a 'D' (Drop the line), in which case also
-; do a 'C', ie disconnect. This is really a little too much of a
-; system dependent thing.
-; For now, Ill leave it here, and possibly move it later.
-;
-; edit 7 30 May 1986 OBSchou. Moved xon/xoff control (ie XON/OFF sent to host)
-; out to CPSUTL so that ther printer routine can use it too.
-;
-; edit 6 30 April, 1986 by OBSchou.
-; Fixed transmit bug, so as soon as the protocol character is
-; received from the host is received then another line is sent.
-; added in a comchr (ds 1) to save the character read from the comm
-; line in prtchr, and is restored in a on return.
-;
-; edit 5 7 March, 1986 by OBSchou Loughborough University.
-; Need to save the E register before calling outmdm (in CPSSYS.ASM)
-; if doing Half duplex. Push/pop DE should sort this problem
-;
-; edit 4: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
-;
-;pcc002 28-Dec-84 modules:cp4tt,cp4utl
-; Add connect mode <esc>P command to toggle printer on
-; and off. Conflicts with "official" recommended commands
-; in protocol manual, but I don't think CP/M will ever get
-; a PUSH command.
-;
-;pcc003-pcc005 2-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl
-; These edits must all be installed together and change the way
-; logging is handled. The log file spec is moved to a separate
-; fcb, and not opened until an actual CONNECT command is given.
-; This takes care of a NASTY bug that if you used any other file
-; command between the LOG and CONNECT, the log file would get
-; written over the last file used. This also allows logging to
-; be "permanently" enabled until an CLOSE (new command) for all
-; CONNECT sessions, like most other kermits do. If a log file
-; already exists, it will be appended to. Also add two new
-; CONNECT mode commands <esc>Q to suspend logging and <esc>R to
-; resume. <esc>R means something else during TRANSMIT, but
-; logging is never on then, so there shouldn't be any conflict.
-; I also changed the write code, so that it can handle one more
-; character after the XOFF is send to stop the host. This allows
-; a little "slop" for systems that don't stop immediately (such
-; as TOPS10), but it didn't help much.
-;
-;pcc008 2-Jan-85 vjc modules:cp4def,cp4tt,cp4utl
-; Keyboard input during CONNECT mode can get locked out if
-; there is enough input from the modem port to keep prtchr
-; busy. This can happen for example, if the printer is running
-; at the same speed as the modem line, leaving you helpless to
-; turn it off or abort the host. Add a fairness count, so that
-; at least every prfair characters we look at console input.
-;
-;pcc012 4-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl
-; Use the big buffer for the log file. Move the log file back
-; into the common fcb and only save the drive, name, and
-; extension between connects. Add new routines to cp4utl to
-; create or append to an existing file, and to conditionally
-; advance buffers only if in memory. Remove edit pcc003 that
-; allows one more character after the xoff, since it didn't
-; really work very well and does not fit in well with the way
-; the buffer advancing routines are set up. If someone still
-; thinks this would be useful, it could be put back in with a
-; little more work.
-;
-; While testing this edit, I also noticed another bug that
-; the command parsing routines do not limit or check the
-; length of command lines or file specs, trashing what ever
-; comes after them. Currently because of where the fcb and
-; command buffer are located, this does not usually cause a
-; problem, but could if an extremely long line was typed in,
-; or in the future multiple fcbs defined elsewhere in memory
-; were used. Maybe this should be put on the bug list
-; somewhere.
-;
-; edit 3: July 27, 1984
-; Allow assembly with LASM: to CP4TT is linked by CP4PKT, and links
-; to CP4CPM; remove exclamation points so as not to confuse LASM.
-; Add Toad Hall TACtrap to TRANSMIT command (TAC intercept character
-; is only doubled if it's data; when typed by the user, they're not
-; automatically doubled)
-;
-; edit 2: June 7, 1984
-; formatting and documentation; add module version number; make sure
-; console is selected when leaving intchr.
-;
-; edit 1: May, 1984
-; extracted from CPMBASE.M80 version 3.9; modifications are described
-; in the accompanying .UPD file.
-
-ttver: db 'CPSTT.ASM (12) 31-Jan-1991$'
-
-; This is the TRANSMIT command. It attempts to send a file, even
-; though there is no KERMIT on the other side.
-; here from: kermit
-;
-; [OBS] I have replaced the routine, so that TRANSMIT <filename> <wait string>
-; will send a line at a time to the host in a manner similar to MSKERMIT
-;
-;
-xmit: mvi a,cmofi ;Parse an input file spec (non-wild).
- lxi d,fcb ;Give the address for the FCB.
- call comnd
- jmp kermit ;Give up on bad parse.
-;
- lxi d,stbuff ; where to put the string
- mvi a,cmtxt ; get text
- call comnd
- jmp kermit ; not quite correct...
- sta strcnt ; string count returned in a
- ana a ; if its zero, make it 1 character (CR)
- jnz xmit0
- mvi a,1
- sta strcnt
- mvi a,cr
- sta stbuff
-;
-xmit0: call cfmcmd
- call getfil ;Open file.
- cpi 0FFH ;Succeed?
- jnz xmit1
- lxi d,erms15
- call prtstr ;Display error msg.
- jmp kermit
-
-;
-; New TRANSMIT routine - transmit a file, line by line, to a remote host
-; waiting each time for one or more characters to be returned
-; as a remote host prompt. It could be as simple as a CR or LF
-; character. Repeat until the complete file has been sent, then
-; close the transmitted file, and drop into the connect state so the
-; user can tidy up at the host end.
-;get the file to send, open it up, and read first sector from disk
-
-xmit1: lxi d,inms19 ; say we are send a file to the host
- call prtstr
-
- xra a
- sta repcnt ; clear the host prompt chars. counter
- sta starc ; clear star count
-;[MF][12]Delete the following call to "inbuf" as the call to "getfil"
-;[MF][12]above will have initialized counters and flags so that when
-;[MF][12]"in1chr" is called, "inbuf" will be called immediately and will
-;[MF][12]immediately read from disk. Counters and flags will then be
-;[MF][12]properly set up to read all characters of the file to be
-;[MF][12]transmitted.
-; call inbuf ; read one sector from disk
-; jmp xmtex ; exit if error
-
-
-xmt10: xra a ; clear retransmit flag and count etc
- sta rexbfl ; retransmit flag (1=> retransmit)
- sta rexcnt ; character counter
-
-xmt1: call xmt1ch ; send a character
- ani 7fh ; strip any parity
- cpi cr ; have we reached the end of the line
- jnz xmt1 ; nope, loop around again
-
-; Now wait for a string back from the host. Compare with STRING buffer
-;
- xra a ; clear the character count
- sta rexcnt
-;
- call selcon ; sent a line, send a star to console
- mvi e,'*'
- call outcon
- lda starc ; update star count
- inr a
- sta starc
- cpi 60 ; sent 60 stars?
- jnz xmt1a ; nope...
- xra a
- sta starc
- call prcrlf
-xmt1a:
-
-xmt3: lda eoflag ; have we hit end of file?
- ana a
- jnz xmtex ; yup, so quit.
- xra a
- sta repcnt ; clear the host prompt chars.counter
-xmt2: call rd1chl ; read a character from the line
- ani 7fh ; set flags
- jnz xmt4 ; Not zero => we have a character from host
- call ckchr ; see if *WE* have a character from console
- push psw ; restore to modem
- call selmdm
- pop psw
- ani 7fh ; stip parity (should not be there)
- jnz xmt2a ; if a null, try again
- lda strcnt ; if the string length is zero, dont wait.
- ana a
- jz xmt1 ; so loop back again
- jmp xmt4 ; else test for xon/off and incomming string
-
-xmt2a: cpi cntlc ; do we want to abort?
- jz xmtex ; in which case drop through to connect mode
- cpi cntlz ; if control z exit back to command loop
- jnz xmt2b ; else try for other characters
- lxi d,fcb ; close file before exiting to command loop
- mvi c,closf
- call bdos
- jmp kermit
-
-xmt2b: cpi cr ; a cr => resend last line
- jnz xmt2 ; nope, then ignore it
- mvi a,1
- sta rexbfl ; else we want to resend the line.
- jmp xmt1
-
-xmt4: jmp xmt6 ; skit xoff test for now...*****************
-
- cpi xoff ; xoff from host?
- jnz xmt6
-xmt5: call rd1chl ; else see if XOFF comming
- ani 7fh
- jnz xmt6 ; assume an xoff
- call ckchr ; anything at console?
- push psw
- call selmdm
- pop psw
- ani 7fh
- cpi cntlc ; control-c == abort & play terminal
- jz xmtex
- ana a ; anything else?
- jz xmt5 ;loop again
-
-xmt6: mov e,a ; save it for a while
- lda repcnt ; see if this character matches with one in buffer
- lxi h,stbuff ; point to string buffer
- add l ; make hl = hl + a
- mov l,a
- mvi a,0
- adc h
- mov h,a ; not using xra, as that clears the Carry flag
- mov a,e ; get the character back again
- cmp m ; is it = to what we expect?
- jnz xmt3 ; no, clear counter and try again
- lda repcnt ; yes, then update the pointer, and ...
- inr a ; ... see if we have received all ...
- sta repcnt ; ... we should have received
- mov e,a ; save length into E again
- lda strcnt ; get the length to compare
- sub e ; if (e) > string length, we have it
- jz xmt10 ; so send next line (clear counters etc)
- jmp xmt2 ; else wait for a little longer
-
-
-;
-; Routine below sends a character to the line. It sends up to a CR, and then
-; it waits for a reply. This routine is called from xmt1, so if at
-; end of file, return. Then XMT1 will drop through
-; to connect.
-xmt1ch: ; send a character from the xmtbuf to the line
- call selmdm ; just in case it uses it
- lda eoflag ; have we hit end of file
- ana a ; set flags
- jnz xmt1c1 ; no, so dont...
- mvi a,cr ; load up a carriage return
-xmt1c1: call get1xc ; get the character to send
- cpi lf ; dont send line feeds
-; jz xmt1c1
- cpi cntlz ; if control z, then we are at end of the file
- jz xmtex ; so close the file and drop into telcon
- cpi 20h ; control character?
- jp xmt11 ; no, so ok
- cpi cr ; cr, and tabs ok to send
- jz xmt11
- cpi tab
- jz xmt11
- jmp xmt1c1 ; else try for another character
-
-xmt11: call setpar ; else set parity etc
- push psw ; we want to keep this for a while
- mov e,a ; we need character in e
- call outmdm
- pop psw ; restore the character we sent
- mov e,a ; now, if a TAC is set on..
- lda tacflg
- ana a
- mov a,e ; (return must have sent character in a)
- jz xmt1c2 ; test for xon/off
- lda tacchr ;... get the tac character
- cmp e ; do we send it again?
- jnz xmt1c2 ; test for xon/off
- push psw ; save character for return. Already set E...
- call outmdm
- pop psw
-
-xmt1c2: ret
-
-get1xc: ; get a character from the sector or re-transmit buffer read
-; into a. Read a new sector if we run out.
-;
-; First, see if we do a retransmit
- lda rexbfl
- ana a ; if zero, a genuine line
- jz get1x1
-; have to retransmit a line
- lxi h,rexbuf
- lda rexcnt ; add counter to buffer base
- mvi d,0
- mov e,a
- dad d
- inr a ; update pointer
- sta rexcnt
- mov a,m ; get next character to send
- ret ; and exit
-
-get1x1: call in1chr ; get a character from the file.
- mov c,a ; save it to the retransmit buffer
- lda rexcnt
- mov e,a
- mvi d,0
- lxi h,rexbuf
- dad d ; point to next position
- inr a
- sta rexcnt ; update the character pointer
- mov a,c ; restore character to a
- mov m,c ; get character to c
- ret
-
-
-
-; read a character from the line.
-rd1chl:
- call selmdm ; select the modem
- call inpmdm ; get input from the modem
- ani 7fh ; strip parity
- ; may UPPERCASE-ify if case sensitivity off
- ret ; return to caller
-
-; End of transmit routine. Close input file name, and say we are dropping
-; throught to telnet. Note that if eof not found, it is assumed that
-; this is the ABORT exit.
-
-xmtex:
- lxi d,fcb ; close the transmitted file
- mvi c,closf
- call bdos
- call selcon ; make sure we are talking to the console
-
- lda eoflag ; end of file or abort exit?
- lxi d,inms22 ; assume eof...
- ana a
- jz xmtex1
- lxi d,inms29 ; we were wrong, its an abort.
-xmtex1: jmp telnt1 ; and drop through to connect mode
- ; telnet does the printing
-
-
-
-;
-; telnet - the CONNECT command.
-; here from: kermit
-; telnt1 - entry to connect mode from TRANSMIT command
-; here from: xend
-
-telnet: call cfmcmd
- lxi d,infms7 ;Output start of message
-; enter here from TRANSMIT command.
-telnt1: call prtstr
- call escpr ;Print the escape char.
- lxi d,infms8 ;Output some more of the message
- call prtstr
- call escpr ;Print the escape char again.
- lxi d,inms8a ;Print the remainder of the message
- call prtstr
- call syscon ;do system-dependent stuff
- lda logflg ;[pcc005] Want a log?
- ora a ;[pcc005]
- cnz logopn ;[pcc005] Open if so
-
-chrlup: call prtchr ;See if char at port (send to console).
- call conchr ;See if char at console (send to port).
- jmp kermit ;requested to end session - go to command loop.
- jmp chrlup ;Go do it again.
-;
-;
-; prtchr - copy characters from comm line to console
-; returns: nonskip, console selected.
-; called by: xnext, rexmit, telnet
-;
-
-prtchr: call selmdm ; select modem port
- call inpmdm ; try to get a character from it
- push psw ; restore to console
- call selcon ; select console
- pop psw ; restore the (possible character) read
- ora a ; test character
- jnz prtch0 ; if non-zero, process it.
- sta prtcnt ;[pcc008] zero out prt fairness count
- ret ; return.
-
-prtch0: ani 7FH ; drop parity bit.
- sta comchr ;[6] save it in case we need it again
- lda vtflg ;[9] get the vt52 emulation flag
- cpi vtdefe ;[9] are we doing external emulation?
- lda comchr ;[9] collect character again
- jz extern ;[9] jup, go do it.
-
- ana a ; set flags. it may be a null
- jz prtchr ; ignore null (filler)
- cpi del ; ignore delete, too
- jz prtchr
- cpi xon ;Is it an XON?
- jz prtxon ;yes
- cpi xoff ;Is it an XOFF?
- jz prtxof ;yes
- mov e,a ;Set the char aside.
- lda vtflg ;Get the VT52 emulation flag.
- cpi vtdefv ;Is the flag set for VT52 (ie 1)
- ;0 = none
- ;1 = VT52
- ;2 = external
- ;3 = dumb (traps non printing chars)
- ;0ffh not possible by local code (Will change)
- jnz prtch1 ;If not, don't do this stuff.
- lda escflg ;Get the escape flag.
- ora a ;Are we working on an escape sequence?
- jz prtch2 ;If not, continue.
- call vt52 ;If so, work on it some more
- jmp prtchr ;try for more characters.
-
-prtch2: mov a,e ;normal text.
- cpi esc ;Is the char an escape?
- jnz prtch1 ;If not skip on.
- mvi a,1
- sta escflg ;Set the escape flag: escape seen.
- jmp prtchr ;Get another char...
-
-prtch1: cpi vtdefe ; are we doing external emulation?
- jnz prtch3 ; assume we continue on
- lxi h,extern+1 ; get address of external emulator
- mov a,h ; se if address = 0 (not implemented)
- ora l
- jz prtch3 ; not external, assume we just carry on
- pchl ; go do external emulation. RET back to caller
-
-prtch3: cpi vtdefd ; are we trapping all non printing characters?
- jnz prtch4 ; nope, something else
- lda comchr ; Dumb terminal. Lets test the character
- cpi cr ; cr then ok
- jz prtch4 ; its ok
- cpi lf ; lf then ok
- jz prtch4
- cpi tab
- jz prtch4 ; assume tabs are expanded
- cpi space ; if less than 20H ignore it
- rm ; return if a control character
-
-prtch4: call sysflt ; ok to print this character (in E)?
- ora a
- jz prtchr ; no, skip it.
- lda logflg ;Get the log flag.
- cpi 81H ;[pcc003] Are we logging
- cz logit ;[pcc003] Do so if needed
- call selcon ; select console
- lda prnflg ;Get Print parallel flag
- ora a
- cnz outlpt ; output to printer if flag set
- call outcon ; output to console.
- lxi h,prtcnt ;[pcc008] point to prt fairness count
- inr m ;[pcc008] bump
- mov a,m ;[pcc008] get it in a
- cpi prfair+1 ;[pcc008] time to be fair?
- jm prtchr ;[pcc008] no, go around again.
- mvi m,0 ;[pcc008] reset count
- lda comchr ;[6] restore that character read from comm line
- ret ;[pcc008] and return
-
-; I don't think we want to print xon/xoff - this should be
-; flow control only across the link between us and the host.
-; (besides, IBM host xon's don't make sense to most micros)
-; remember xon/xoff state in xofflg (zero = xon, non-zero = xoff)
-prtxon: xra a ;Yes, reset XOFF flag
-prtxof: sta xofflg
- jmp prtchr ; look for another character
-; ;[pcc005] Log file routines
-
-;[pcc005]
-; logopn - open the log file
-; Open the log file and append to it if it already exists
-; or create one if not.
-
-logopn:
- mvi a,ctrlz ;[9] ignore control-z in log files
- cmp e ;[9] well, was it?
- rz ;[9] yes, to ignore it.
- lxi h,lognam ;[pcc012] copy name
- lxi d,fcb ;[pcc012] to fcb
- lxi b,12 ;[pcc012] 12 bytes
- call mover ;[pcc012] copy it
- call appfil ;[pcc012] open file for appending
- jmp logerr ;[pcc012] error
- lxi h,logflg ;[pcc005] point to log flag
- mvi a,80H ;[pcc005] file open flag
- ora m ;[pcc005] or in contents of logflg
- mov m,a ;[pcc005] and store back
- lxi d,inms28 ;[pcc005] assume logging is on
- cpi 81H ;[pcc005] check
- jz prtstr ;[pcc005] print msg if true
- lxi d,inms27 ;[pcc005] no, must be suspended
- jmp prtstr ;[pcc005] print and return
-
-;
-; logit - output character in E to log file.
-; we assume the host recognizes xon/xoff. (we probably shouldn't)
-; modem port is selected.
-; preserves de
-; called by: prtchr
-
-logit: lxi h,chrcnt ;[pcc012] point to buffer count
- dcr m ;[pcc012] and decrement
- jp logit1 ;[pcc012] continue if ok
- push d ;[pcc012] save de
- call outadv ;[pcc012] advance buffer if in memory
- call logwrt ;[pcc012] sigh, time to write to disk
- pop d ;[pcc012] restore de
- lda logflg ;[pcc012] get logging flag
- ora a ;[pcc012] Did we quit because of an error
- rz ;[pcc012] return now if so
-logit1: lhld bufpnt ;[pcc012] get buffer pointer
- mov m,e ;Store the char.
- inx h
- shld bufpnt
- ret ;[pcc012] and return
-
-;[pcc012]
-; logwrt - write to log file with XON/XOFF since it may take a while.
-
-logwrt: call sndxoff ;[7] send and xoff to host
- call outbuf ;[pcc012] output the buffer and advance
- call logerr ;[pcc005] quit if error
- call sndxon ;[send an xon to host
- ret ;[pcc012]
-
-;[pcc005]
-; logcls - Close the log file and reset the flag
-
-logcls: lxi d,infms6 ;[pcc005] Tell user we are closing file.
- call prtstr ;[pcc005]
- call clofil ;[pcc012] and do it
- jmp logerr ;[pcc005] jump if error
- lxi h,logflg ;[pcc005] point to flag
- mov a,m ;[pcc005] get it
- ani 7FH ;[pcc005] clear the open bit
- mov m,a ;[pcc005] and store back
- ret ;[pcc005]
-
-;[pcc005]
-; logerr - here on a variety of logging errors
-; just close the file and disable logging
-; called from logopn,logptr,logcls
-
-logerr: lxi d,erms22 ;[pcc005] Error message
- call prtstr ;[pcc005] print it
- mvi c,closf ;[pcc005] Close the file.
- lxi d,fcb ;[pcc012]
- call bdos ;[pcc005]
- xra a ;[pcc005] clear logflg
- sta logflg ;[pcc005] so don't try again
- ret ;[pcc005]
-;
-;
-; VT52 emulation.
-; called by: prtchr
-; A/ contents of escflg (guaranteed non-zero)
-; E/ current character
-; modem is selected.
-;
-vt52: cpi 1 ; first character after escape?
- jnz vt52y ; no, must be doing cursor positioning.
-;
-; E contains the character that followed the escape.
-; valid characters are:
-; A - cursor up
-; B - cursor down
-; C - cursor right
-; D - cursor left
-; F - enter graphics mode (hard to do on a non-vt52)
-; G - exit graphics mode
-; H - home
-; I - reverse linefeed
-; J - erase to end of screen
-; K - erase to end of line
-; Y - cursor positioning leadin
-; Z - identify terminal as VT52
-; [ - enter hold-screen mode (not supported)
-; \ - exit hold-screen mode (not supported)
-; > - enter alternate-keypad mode? (not supported)
-; = - exit alternate-keypad mode? (not supported)
-;
-; Invalid sequences are handled as the VT52 does - the escape and
-; the following character are swallowed, never to be seen again.
-; For <esc>E, the translation table may contain just '$' (no action),
-; or may be used as clear-and-home, as in the Heath/Zenith H19.
-;
- mov a,e ; get the second character of the sequence.
- cpi 'Y' ; if cursor lead-in handle it.
- jnz vt52a ; if not, go on.
- mvi a,2 ; state = 2: row follows.
- sta escflg ; update the flag.
- ret ; back for another character
-
-vt52a: cpi 'Z' ; VT52 ID query?
- jz vt52id ; yes. claim to be one.
- cpi 'A' ;Less than an 'A'?
- jm vtig ;Yes - ignore.
- cpi 'K'+1 ;Greater than 'K'?
- jp vtig ;Yes - ignore.
- sui 'A' ;Else make into index.
- rlc ;Multiply by four.
- rlc ;(Shift left twice.)
- lhld pttab ;Load base addr of table.
- mov e,a ;Move a into de pair.
- mvi d,00H ;Zero out high byte.
- dad d ;Double add index+offset.
- xchg ;Exchange de with hl.
- call selcon ; select console
- call prtstr ;and syscall.
-vtig: ;Ignore escape sequence.
- xra a ;Reset the ol' escape flag.
- sta escflg
- ret ;Return home.
-
-; here for <esc>Z. Tell the host we're a VT52. (Sure we are...)
-vt52id: mvi a,esc ; response is escape...
- call setpar ; (need correct parity)
- mov e,a
- call outmdm ; (console already selected)
- mvi a,'/' ; ... slash ...
- call setpar ; (with parity)
- mov e,a
- call outmdm
- mvi a,'K' ; ... K.
- call setpar
- mov e,a
- call outmdm
- jmp vtig ; clear escape-sequence flag and return.
-
-; here when escflg isn't 0 or 1 - processing cursor positioning sequence.
-vt52y: cpi 2 ; looking for row? (y-coordinate)
- jnz vt52x ; no, must be column.
- mov a,e ; yes. get coordinate
- sui (' '-1) ; convert from ascii (1 = top line)
- sta vtyval ; store for later
- mvi a,3 ; advance to next state (x coord)
- sta escflg ; store it
- ret ; try for another character
-
-; here when escflag isn't 0, 1, or 2 - it must be 3. (right?)
-; E holds the last character of the cursor positioning sequence.
-vt52x: xra a ; end of escape sequence, reset state.
- sta escflg
- mov a,e ; get column (' ' is left margin)
- sui (' '-1) ; make left margin be one
- mov c,a ; stash column in c
- lda vtyval ; get row number
- mov b,a ; in b
- call selcon ; select console
- call csrpos ; call system-dependent cursor positioner
- ret ; all through.
-;
-;
-; conchr - copy character from console to comm line, processing
-; (kermit's) escape sequences.
-; Enter and exit with console selected.
-; nonskip return: transparent mode terminated.
-; skip return: still in transparent mode.
-; called by: rexmit, telnet
-
-conchr: call inpcon ;Try to get a character from the console
- ani 07FH ;Keep only 7 bits
- jz rskp ;Null means nothing there.
- mov e,a ;Move the char for comparison.
- sta lstchr ;Save it
- lda escchr ;Get the escape char.
- cmp e ;Is it an escape char?
- jz intchr ;If so go process it.
- call selmdm ; select the modem
- mov a,e ;Get the char.
- call setpar ;Set parity (if any).
- mov e,a ;Restore it.
- push d ; need to save e in case we are half dplx [5]
- call outmdm ;Output the char to the port.
- pop d ; Just in case we are half dplx [5]
- call selcon ; reselect console
- lda ecoflg ;Get the echo flag.
- ora a ;Is it turned on?
- jz rskp ;If not we're done here.
- mov a,e ;Get the char.
- ani 7FH ;Turn off the parity bit.
- mov e,a
- call outcon ; echo the character.
- jmp rskp ; use skip return
-;
-; transparent escape character has been typed. dispatch on second
-; character. (console is still selected)
-; here from: conchr
-
-intchr: call inpcon ; get another character from the console
- ora a ; zero means no character available yet.
- jz intchr ; If so, loop until we get a char.
- mov b,a ;Save the actual char.
- cpi ctrlc ;is it Control-C?
- jz contc ;yes
- ani 137O ;Convert to upper case.
- cpi 'C' ;Is it close?
- jnz intch0 ;If not proceed.
-contc: lxi d,infms9 ;Say we are back.
- call prtstr
- call syscls ; call system-dependent close routine
- lda logflg ;Get the log flag.
- ora a ;[pcc005] Check if open
- cm logcls ;[pcc005] Close if needed
- ret
-
-;Here if not a 'C' or '^C'
-
-intch0: cpi 'S' ;Is it status?
- jnz inch01 ;If not, proceed.
- call stat01 ;Print out the status stuff.
- call prcrlf ;[pcc011] add a crlf
- jmp rskp ;return from conchr
-
-inch01:
-inch03: mov a,b ;Get the char.
- cpi '?' ;Is it a help request?
- jnz intch1 ;If not, go to the next check.
-inch3a: lda logflg ;[pcc003] Logging flag
- ora a ;[pcc003] see if active
- jp inch04 ;[pcc005] jump if no file open
- lxi d,loghlp ;[pcc003] yes, tell about R AND Q
- call prtstr ;[pcc003]
-inch04: lxi d,inthlp ;If so, get the address of the help message.
- call prtstr
- call sysinh ; print system-dependent help message
- lxi d,inhlp1 ; Tell about doubling the escape character
- call prtstr
- call escpr ;Print escape character
- lxi d,inhlp2 ;Print the rest
- call prtstr
- jmp intchr ;Get another char.
-
-intch1: mov a,b ;Get the character.
- cpi '0' ;Is it '0', to send a null?
- jnz intch3 ;No.
- xra a ;Yes, send an ASCII zero.
- call setpar ; with the correct parity
- mov e,a
- call selmdm ; (to the modem...)
- call outmdm
- call selcon ; return with console selected
- jmp rskp
-
-intch3: lda escchr ;Get the escape char.
- cmp b ;Is it the escape char?
- jnz intch4 ;[pcc002] jump if not
- mov a,b ;Get the char.
- call setpar
- mov e,a ;Restore it.
- call selmdm
- call outmdm ;Output it.
- call selcon ;We promised console would be selected...
- jmp rskp ;Return, we are done here.
-intch4: mov a,b ;[pcc002] get it again
- ani 137o ;[pcc002] in upper case
- cpi 'P' ;[pcc002] toggle printer?
- jnz intch5 ;[pcc003] nope
- lda prnflg ;[pcc002] get printer flag
- xri 01h ;[pcc002] complement it
- sta prnflg ;[pcc002] and put back
- jmp rskp ;[pcc002]
-intch5: lda logflg ;[pcc003] get log flag
- ora a ;[pcc003] See if open
- jp intch7 ;[pcc003] no, skip R and Q
- mov a,b ;[pcc003] get back chr
- ani 137o ;[pcc003] make upper case
- cpi 'R' ;[pcc003] Is it R
- jnz intch6 ;[pcc003] Jump if not
- mvi a,81H ;[pcc003] set flag for logging
- sta logflg ;[pcc003] put it back
- lxi d,inms28 ;[pcc003] message
- call prtstr ;[pcc003]
- jmp rskp ;[pcc003] done
-intch6: cpi 'Q' ;[pcc003] Quit logging?
- jnz intch7 ;[pcc003] no
- mvi a,82H ;[pcc003] flag for open, but suspended
- sta logflg ;[pcc003] store away
- lxi d,inms27 ;[pcc003] keep them informed
- call prtstr ;[pcc003]
- jmp rskp ;[pcc003]
-intch7: ;[pcc003]
-
-intchz: mov a,b ; not recognized. get saved copy back.
- push psw ;[8] save as we will want to test for 'D'
- call sysint ; interpret system-dependent sequences
- jmp intchy ; done. [10] Now see if D. If so, do a C.
- pop psw ;[10] tidy stack
- mvi e,'G'-100O ;Otherwise send a beep.
- call outcon ; to the console.
- jmp rskp
-
-intchy: pop psw ;[10] adjust stack
- ani 5fh ;[10] strip parity, make it upper case
- cpi 'D' ;[10] was it a D?
- jz contc ;[10] yup, so to the equivalent of an escape-C
- jmp rskp
-;
-; Little code to allow some expansion of code without changing
-; every futher address, only up to the end of this file.
-; TO BE REMOVED FOR RELEASE!
-
-; org ($+100h) AND 0FF00H
-IF lasm
- LINK CPSCPM
-ENDIF;lasm
+; CPSTT.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the code for the TRANSMIT and CONNECT commands,
+; which communicate with a host which is not running KERMIT.
+;
+; revision history:
+;
+;edit 12, 31-Jan-1991 by MF. Delete call to "inbuf" after "xmit1" in
+; the TRANSMIT command. "getfil" initializes various counters so that
+; when "in1chr" is first called, "inbuf" will be called immediately
+; and will read sectors of the file to be transmitted from disk.
+; This, along with a fix to "in1chr" in CPSUTL.ASM, fixes a bug
+; discovered by Lance Tagliapietra of the University of Wisconsin at
+; Platteville wherein the TRANSMIT command was failing to transmit some
+; characters in files over one sector in length. See CPSUTL.ASM,
+; edit 29.
+; edit 11, 10 September, a987, by OBSchou. Modified TRANSMIT command
+; to TRANSMIT <file> <string>
+;
+; edit 10, 27 August, 1987 by OBSchou. Fixed bugs in Transmit, but I may
+; be introducing problems for IBM/CMS or half duplex systems. What
+; does this combination do??
+;
+; edit 9 30 March, 1987 by OBSchou to replace the TRANSMIT routine.
+; Syntax is now TRANSMIT file after a previous
+; INPUT <wait time> <string to wait for>
+;
+; edit 8 19 June, 1986 by OBSchou. Modified the interupt testing routine
+; to see if the command was a 'D' (Drop the line), in which case also
+; do a 'C', ie disconnect. This is really a little too much of a
+; system dependent thing.
+; For now, Ill leave it here, and possibly move it later.
+;
+; edit 7 30 May 1986 OBSchou. Moved xon/xoff control (ie XON/OFF sent to host)
+; out to CPSUTL so that ther printer routine can use it too.
+;
+; edit 6 30 April, 1986 by OBSchou.
+; Fixed transmit bug, so as soon as the protocol character is
+; received from the host is received then another line is sent.
+; added in a comchr (ds 1) to save the character read from the comm
+; line in prtchr, and is restored in a on return.
+;
+; edit 5 7 March, 1986 by OBSchou Loughborough University.
+; Need to save the E register before calling outmdm (in CPSSYS.ASM)
+; if doing Half duplex. Push/pop DE should sort this problem
+;
+; edit 4: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
+;
+;pcc002 28-Dec-84 modules:cp4tt,cp4utl
+; Add connect mode <esc>P command to toggle printer on
+; and off. Conflicts with "official" recommended commands
+; in protocol manual, but I don't think CP/M will ever get
+; a PUSH command.
+;
+;pcc003-pcc005 2-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl
+; These edits must all be installed together and change the way
+; logging is handled. The log file spec is moved to a separate
+; fcb, and not opened until an actual CONNECT command is given.
+; This takes care of a NASTY bug that if you used any other file
+; command between the LOG and CONNECT, the log file would get
+; written over the last file used. This also allows logging to
+; be "permanently" enabled until an CLOSE (new command) for all
+; CONNECT sessions, like most other kermits do. If a log file
+; already exists, it will be appended to. Also add two new
+; CONNECT mode commands <esc>Q to suspend logging and <esc>R to
+; resume. <esc>R means something else during TRANSMIT, but
+; logging is never on then, so there shouldn't be any conflict.
+; I also changed the write code, so that it can handle one more
+; character after the XOFF is send to stop the host. This allows
+; a little "slop" for systems that don't stop immediately (such
+; as TOPS10), but it didn't help much.
+;
+;pcc008 2-Jan-85 vjc modules:cp4def,cp4tt,cp4utl
+; Keyboard input during CONNECT mode can get locked out if
+; there is enough input from the modem port to keep prtchr
+; busy. This can happen for example, if the printer is running
+; at the same speed as the modem line, leaving you helpless to
+; turn it off or abort the host. Add a fairness count, so that
+; at least every prfair characters we look at console input.
+;
+;pcc012 4-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl
+; Use the big buffer for the log file. Move the log file back
+; into the common fcb and only save the drive, name, and
+; extension between connects. Add new routines to cp4utl to
+; create or append to an existing file, and to conditionally
+; advance buffers only if in memory. Remove edit pcc003 that
+; allows one more character after the xoff, since it didn't
+; really work very well and does not fit in well with the way
+; the buffer advancing routines are set up. If someone still
+; thinks this would be useful, it could be put back in with a
+; little more work.
+;
+; While testing this edit, I also noticed another bug that
+; the command parsing routines do not limit or check the
+; length of command lines or file specs, trashing what ever
+; comes after them. Currently because of where the fcb and
+; command buffer are located, this does not usually cause a
+; problem, but could if an extremely long line was typed in,
+; or in the future multiple fcbs defined elsewhere in memory
+; were used. Maybe this should be put on the bug list
+; somewhere.
+;
+; edit 3: July 27, 1984
+; Allow assembly with LASM: to CP4TT is linked by CP4PKT, and links
+; to CP4CPM; remove exclamation points so as not to confuse LASM.
+; Add Toad Hall TACtrap to TRANSMIT command (TAC intercept character
+; is only doubled if it's data; when typed by the user, they're not
+; automatically doubled)
+;
+; edit 2: June 7, 1984
+; formatting and documentation; add module version number; make sure
+; console is selected when leaving intchr.
+;
+; edit 1: May, 1984
+; extracted from CPMBASE.M80 version 3.9; modifications are described
+; in the accompanying .UPD file.
+
+ttver: db 'CPSTT.ASM (12) 31-Jan-1991$'
+
+; This is the TRANSMIT command. It attempts to send a file, even
+; though there is no KERMIT on the other side.
+; here from: kermit
+;
+; [OBS] I have replaced the routine, so that TRANSMIT <filename> <wait string>
+; will send a line at a time to the host in a manner similar to MSKERMIT
+;
+;
+xmit: mvi a,cmofi ;Parse an input file spec (non-wild).
+ lxi d,fcb ;Give the address for the FCB.
+ call comnd
+ jmp kermit ;Give up on bad parse.
+;
+ lxi d,stbuff ; where to put the string
+ mvi a,cmtxt ; get text
+ call comnd
+ jmp kermit ; not quite correct...
+ sta strcnt ; string count returned in a
+ ana a ; if its zero, make it 1 character (CR)
+ jnz xmit0
+ mvi a,1
+ sta strcnt
+ mvi a,cr
+ sta stbuff
+;
+xmit0: call cfmcmd
+ call getfil ;Open file.
+ cpi 0FFH ;Succeed?
+ jnz xmit1
+ lxi d,erms15
+ call prtstr ;Display error msg.
+ jmp kermit
+
+;
+; New TRANSMIT routine - transmit a file, line by line, to a remote host
+; waiting each time for one or more characters to be returned
+; as a remote host prompt. It could be as simple as a CR or LF
+; character. Repeat until the complete file has been sent, then
+; close the transmitted file, and drop into the connect state so the
+; user can tidy up at the host end.
+;get the file to send, open it up, and read first sector from disk
+
+xmit1: lxi d,inms19 ; say we are send a file to the host
+ call prtstr
+
+ xra a
+ sta repcnt ; clear the host prompt chars. counter
+ sta starc ; clear star count
+;[MF][12]Delete the following call to "inbuf" as the call to "getfil"
+;[MF][12]above will have initialized counters and flags so that when
+;[MF][12]"in1chr" is called, "inbuf" will be called immediately and will
+;[MF][12]immediately read from disk. Counters and flags will then be
+;[MF][12]properly set up to read all characters of the file to be
+;[MF][12]transmitted.
+; call inbuf ; read one sector from disk
+; jmp xmtex ; exit if error
+
+
+xmt10: xra a ; clear retransmit flag and count etc
+ sta rexbfl ; retransmit flag (1=> retransmit)
+ sta rexcnt ; character counter
+
+xmt1: call xmt1ch ; send a character
+ ani 7fh ; strip any parity
+ cpi cr ; have we reached the end of the line
+ jnz xmt1 ; nope, loop around again
+
+; Now wait for a string back from the host. Compare with STRING buffer
+;
+ xra a ; clear the character count
+ sta rexcnt
+;
+ call selcon ; sent a line, send a star to console
+ mvi e,'*'
+ call outcon
+ lda starc ; update star count
+ inr a
+ sta starc
+ cpi 60 ; sent 60 stars?
+ jnz xmt1a ; nope...
+ xra a
+ sta starc
+ call prcrlf
+xmt1a:
+
+xmt3: lda eoflag ; have we hit end of file?
+ ana a
+ jnz xmtex ; yup, so quit.
+ xra a
+ sta repcnt ; clear the host prompt chars.counter
+xmt2: call rd1chl ; read a character from the line
+ ani 7fh ; set flags
+ jnz xmt4 ; Not zero => we have a character from host
+ call ckchr ; see if *WE* have a character from console
+ push psw ; restore to modem
+ call selmdm
+ pop psw
+ ani 7fh ; stip parity (should not be there)
+ jnz xmt2a ; if a null, try again
+ lda strcnt ; if the string length is zero, dont wait.
+ ana a
+ jz xmt1 ; so loop back again
+ jmp xmt4 ; else test for xon/off and incomming string
+
+xmt2a: cpi cntlc ; do we want to abort?
+ jz xmtex ; in which case drop through to connect mode
+ cpi cntlz ; if control z exit back to command loop
+ jnz xmt2b ; else try for other characters
+ lxi d,fcb ; close file before exiting to command loop
+ mvi c,closf
+ call bdos
+ jmp kermit
+
+xmt2b: cpi cr ; a cr => resend last line
+ jnz xmt2 ; nope, then ignore it
+ mvi a,1
+ sta rexbfl ; else we want to resend the line.
+ jmp xmt1
+
+xmt4: jmp xmt6 ; skit xoff test for now...*****************
+
+ cpi xoff ; xoff from host?
+ jnz xmt6
+xmt5: call rd1chl ; else see if XOFF comming
+ ani 7fh
+ jnz xmt6 ; assume an xoff
+ call ckchr ; anything at console?
+ push psw
+ call selmdm
+ pop psw
+ ani 7fh
+ cpi cntlc ; control-c == abort & play terminal
+ jz xmtex
+ ana a ; anything else?
+ jz xmt5 ;loop again
+
+xmt6: mov e,a ; save it for a while
+ lda repcnt ; see if this character matches with one in buffer
+ lxi h,stbuff ; point to string buffer
+ add l ; make hl = hl + a
+ mov l,a
+ mvi a,0
+ adc h
+ mov h,a ; not using xra, as that clears the Carry flag
+ mov a,e ; get the character back again
+ cmp m ; is it = to what we expect?
+ jnz xmt3 ; no, clear counter and try again
+ lda repcnt ; yes, then update the pointer, and ...
+ inr a ; ... see if we have received all ...
+ sta repcnt ; ... we should have received
+ mov e,a ; save length into E again
+ lda strcnt ; get the length to compare
+ sub e ; if (e) > string length, we have it
+ jz xmt10 ; so send next line (clear counters etc)
+ jmp xmt2 ; else wait for a little longer
+
+
+;
+; Routine below sends a character to the line. It sends up to a CR, and then
+; it waits for a reply. This routine is called from xmt1, so if at
+; end of file, return. Then XMT1 will drop through
+; to connect.
+xmt1ch: ; send a character from the xmtbuf to the line
+ call selmdm ; just in case it uses it
+ lda eoflag ; have we hit end of file
+ ana a ; set flags
+ jnz xmt1c1 ; no, so dont...
+ mvi a,cr ; load up a carriage return
+xmt1c1: call get1xc ; get the character to send
+ cpi lf ; dont send line feeds
+; jz xmt1c1
+ cpi cntlz ; if control z, then we are at end of the file
+ jz xmtex ; so close the file and drop into telcon
+ cpi 20h ; control character?
+ jp xmt11 ; no, so ok
+ cpi cr ; cr, and tabs ok to send
+ jz xmt11
+ cpi tab
+ jz xmt11
+ jmp xmt1c1 ; else try for another character
+
+xmt11: call setpar ; else set parity etc
+ push psw ; we want to keep this for a while
+ mov e,a ; we need character in e
+ call outmdm
+ pop psw ; restore the character we sent
+ mov e,a ; now, if a TAC is set on..
+ lda tacflg
+ ana a
+ mov a,e ; (return must have sent character in a)
+ jz xmt1c2 ; test for xon/off
+ lda tacchr ;... get the tac character
+ cmp e ; do we send it again?
+ jnz xmt1c2 ; test for xon/off
+ push psw ; save character for return. Already set E...
+ call outmdm
+ pop psw
+
+xmt1c2: ret
+
+get1xc: ; get a character from the sector or re-transmit buffer read
+; into a. Read a new sector if we run out.
+;
+; First, see if we do a retransmit
+ lda rexbfl
+ ana a ; if zero, a genuine line
+ jz get1x1
+; have to retransmit a line
+ lxi h,rexbuf
+ lda rexcnt ; add counter to buffer base
+ mvi d,0
+ mov e,a
+ dad d
+ inr a ; update pointer
+ sta rexcnt
+ mov a,m ; get next character to send
+ ret ; and exit
+
+get1x1: call in1chr ; get a character from the file.
+ mov c,a ; save it to the retransmit buffer
+ lda rexcnt
+ mov e,a
+ mvi d,0
+ lxi h,rexbuf
+ dad d ; point to next position
+ inr a
+ sta rexcnt ; update the character pointer
+ mov a,c ; restore character to a
+ mov m,c ; get character to c
+ ret
+
+
+
+; read a character from the line.
+rd1chl:
+ call selmdm ; select the modem
+ call inpmdm ; get input from the modem
+ ani 7fh ; strip parity
+ ; may UPPERCASE-ify if case sensitivity off
+ ret ; return to caller
+
+; End of transmit routine. Close input file name, and say we are dropping
+; throught to telnet. Note that if eof not found, it is assumed that
+; this is the ABORT exit.
+
+xmtex:
+ lxi d,fcb ; close the transmitted file
+ mvi c,closf
+ call bdos
+ call selcon ; make sure we are talking to the console
+
+ lda eoflag ; end of file or abort exit?
+ lxi d,inms22 ; assume eof...
+ ana a
+ jz xmtex1
+ lxi d,inms29 ; we were wrong, its an abort.
+xmtex1: jmp telnt1 ; and drop through to connect mode
+ ; telnet does the printing
+
+
+
+;
+; telnet - the CONNECT command.
+; here from: kermit
+; telnt1 - entry to connect mode from TRANSMIT command
+; here from: xend
+
+telnet: call cfmcmd
+ lxi d,infms7 ;Output start of message
+; enter here from TRANSMIT command.
+telnt1: call prtstr
+ call escpr ;Print the escape char.
+ lxi d,infms8 ;Output some more of the message
+ call prtstr
+ call escpr ;Print the escape char again.
+ lxi d,inms8a ;Print the remainder of the message
+ call prtstr
+ call syscon ;do system-dependent stuff
+ lda logflg ;[pcc005] Want a log?
+ ora a ;[pcc005]
+ cnz logopn ;[pcc005] Open if so
+
+chrlup: call prtchr ;See if char at port (send to console).
+ call conchr ;See if char at console (send to port).
+ jmp kermit ;requested to end session - go to command loop.
+ jmp chrlup ;Go do it again.
+;
+;
+; prtchr - copy characters from comm line to console
+; returns: nonskip, console selected.
+; called by: xnext, rexmit, telnet
+;
+
+prtchr: call selmdm ; select modem port
+ call inpmdm ; try to get a character from it
+ push psw ; restore to console
+ call selcon ; select console
+ pop psw ; restore the (possible character) read
+ ora a ; test character
+ jnz prtch0 ; if non-zero, process it.
+ sta prtcnt ;[pcc008] zero out prt fairness count
+ ret ; return.
+
+prtch0: ani 7FH ; drop parity bit.
+ sta comchr ;[6] save it in case we need it again
+ lda vtflg ;[9] get the vt52 emulation flag
+ cpi vtdefe ;[9] are we doing external emulation?
+ lda comchr ;[9] collect character again
+ jz extern ;[9] jup, go do it.
+
+ ana a ; set flags. it may be a null
+ jz prtchr ; ignore null (filler)
+ cpi del ; ignore delete, too
+ jz prtchr
+ cpi xon ;Is it an XON?
+ jz prtxon ;yes
+ cpi xoff ;Is it an XOFF?
+ jz prtxof ;yes
+ mov e,a ;Set the char aside.
+ lda vtflg ;Get the VT52 emulation flag.
+ cpi vtdefv ;Is the flag set for VT52 (ie 1)
+ ;0 = none
+ ;1 = VT52
+ ;2 = external
+ ;3 = dumb (traps non printing chars)
+ ;0ffh not possible by local code (Will change)
+ jnz prtch1 ;If not, don't do this stuff.
+ lda escflg ;Get the escape flag.
+ ora a ;Are we working on an escape sequence?
+ jz prtch2 ;If not, continue.
+ call vt52 ;If so, work on it some more
+ jmp prtchr ;try for more characters.
+
+prtch2: mov a,e ;normal text.
+ cpi esc ;Is the char an escape?
+ jnz prtch1 ;If not skip on.
+ mvi a,1
+ sta escflg ;Set the escape flag: escape seen.
+ jmp prtchr ;Get another char...
+
+prtch1: cpi vtdefe ; are we doing external emulation?
+ jnz prtch3 ; assume we continue on
+ lxi h,extern+1 ; get address of external emulator
+ mov a,h ; se if address = 0 (not implemented)
+ ora l
+ jz prtch3 ; not external, assume we just carry on
+ pchl ; go do external emulation. RET back to caller
+
+prtch3: cpi vtdefd ; are we trapping all non printing characters?
+ jnz prtch4 ; nope, something else
+ lda comchr ; Dumb terminal. Lets test the character
+ cpi cr ; cr then ok
+ jz prtch4 ; its ok
+ cpi lf ; lf then ok
+ jz prtch4
+ cpi tab
+ jz prtch4 ; assume tabs are expanded
+ cpi space ; if less than 20H ignore it
+ rm ; return if a control character
+
+prtch4: call sysflt ; ok to print this character (in E)?
+ ora a
+ jz prtchr ; no, skip it.
+ lda logflg ;Get the log flag.
+ cpi 81H ;[pcc003] Are we logging
+ cz logit ;[pcc003] Do so if needed
+ call selcon ; select console
+ lda prnflg ;Get Print parallel flag
+ ora a
+ cnz outlpt ; output to printer if flag set
+ call outcon ; output to console.
+ lxi h,prtcnt ;[pcc008] point to prt fairness count
+ inr m ;[pcc008] bump
+ mov a,m ;[pcc008] get it in a
+ cpi prfair+1 ;[pcc008] time to be fair?
+ jm prtchr ;[pcc008] no, go around again.
+ mvi m,0 ;[pcc008] reset count
+ lda comchr ;[6] restore that character read from comm line
+ ret ;[pcc008] and return
+
+; I don't think we want to print xon/xoff - this should be
+; flow control only across the link between us and the host.
+; (besides, IBM host xon's don't make sense to most micros)
+; remember xon/xoff state in xofflg (zero = xon, non-zero = xoff)
+prtxon: xra a ;Yes, reset XOFF flag
+prtxof: sta xofflg
+ jmp prtchr ; look for another character
+; ;[pcc005] Log file routines
+
+;[pcc005]
+; logopn - open the log file
+; Open the log file and append to it if it already exists
+; or create one if not.
+
+logopn:
+ mvi a,ctrlz ;[9] ignore control-z in log files
+ cmp e ;[9] well, was it?
+ rz ;[9] yes, to ignore it.
+ lxi h,lognam ;[pcc012] copy name
+ lxi d,fcb ;[pcc012] to fcb
+ lxi b,12 ;[pcc012] 12 bytes
+ call mover ;[pcc012] copy it
+ call appfil ;[pcc012] open file for appending
+ jmp logerr ;[pcc012] error
+ lxi h,logflg ;[pcc005] point to log flag
+ mvi a,80H ;[pcc005] file open flag
+ ora m ;[pcc005] or in contents of logflg
+ mov m,a ;[pcc005] and store back
+ lxi d,inms28 ;[pcc005] assume logging is on
+ cpi 81H ;[pcc005] check
+ jz prtstr ;[pcc005] print msg if true
+ lxi d,inms27 ;[pcc005] no, must be suspended
+ jmp prtstr ;[pcc005] print and return
+
+;
+; logit - output character in E to log file.
+; we assume the host recognizes xon/xoff. (we probably shouldn't)
+; modem port is selected.
+; preserves de
+; called by: prtchr
+
+logit: lxi h,chrcnt ;[pcc012] point to buffer count
+ dcr m ;[pcc012] and decrement
+ jp logit1 ;[pcc012] continue if ok
+ push d ;[pcc012] save de
+ call outadv ;[pcc012] advance buffer if in memory
+ call logwrt ;[pcc012] sigh, time to write to disk
+ pop d ;[pcc012] restore de
+ lda logflg ;[pcc012] get logging flag
+ ora a ;[pcc012] Did we quit because of an error
+ rz ;[pcc012] return now if so
+logit1: lhld bufpnt ;[pcc012] get buffer pointer
+ mov m,e ;Store the char.
+ inx h
+ shld bufpnt
+ ret ;[pcc012] and return
+
+;[pcc012]
+; logwrt - write to log file with XON/XOFF since it may take a while.
+
+logwrt: call sndxoff ;[7] send and xoff to host
+ call outbuf ;[pcc012] output the buffer and advance
+ call logerr ;[pcc005] quit if error
+ call sndxon ;[send an xon to host
+ ret ;[pcc012]
+
+;[pcc005]
+; logcls - Close the log file and reset the flag
+
+logcls: lxi d,infms6 ;[pcc005] Tell user we are closing file.
+ call prtstr ;[pcc005]
+ call clofil ;[pcc012] and do it
+ jmp logerr ;[pcc005] jump if error
+ lxi h,logflg ;[pcc005] point to flag
+ mov a,m ;[pcc005] get it
+ ani 7FH ;[pcc005] clear the open bit
+ mov m,a ;[pcc005] and store back
+ ret ;[pcc005]
+
+;[pcc005]
+; logerr - here on a variety of logging errors
+; just close the file and disable logging
+; called from logopn,logptr,logcls
+
+logerr: lxi d,erms22 ;[pcc005] Error message
+ call prtstr ;[pcc005] print it
+ mvi c,closf ;[pcc005] Close the file.
+ lxi d,fcb ;[pcc012]
+ call bdos ;[pcc005]
+ xra a ;[pcc005] clear logflg
+ sta logflg ;[pcc005] so don't try again
+ ret ;[pcc005]
+;
+;
+; VT52 emulation.
+; called by: prtchr
+; A/ contents of escflg (guaranteed non-zero)
+; E/ current character
+; modem is selected.
+;
+vt52: cpi 1 ; first character after escape?
+ jnz vt52y ; no, must be doing cursor positioning.
+;
+; E contains the character that followed the escape.
+; valid characters are:
+; A - cursor up
+; B - cursor down
+; C - cursor right
+; D - cursor left
+; F - enter graphics mode (hard to do on a non-vt52)
+; G - exit graphics mode
+; H - home
+; I - reverse linefeed
+; J - erase to end of screen
+; K - erase to end of line
+; Y - cursor positioning leadin
+; Z - identify terminal as VT52
+; [ - enter hold-screen mode (not supported)
+; \ - exit hold-screen mode (not supported)
+; > - enter alternate-keypad mode? (not supported)
+; = - exit alternate-keypad mode? (not supported)
+;
+; Invalid sequences are handled as the VT52 does - the escape and
+; the following character are swallowed, never to be seen again.
+; For <esc>E, the translation table may contain just '$' (no action),
+; or may be used as clear-and-home, as in the Heath/Zenith H19.
+;
+ mov a,e ; get the second character of the sequence.
+ cpi 'Y' ; if cursor lead-in handle it.
+ jnz vt52a ; if not, go on.
+ mvi a,2 ; state = 2: row follows.
+ sta escflg ; update the flag.
+ ret ; back for another character
+
+vt52a: cpi 'Z' ; VT52 ID query?
+ jz vt52id ; yes. claim to be one.
+ cpi 'A' ;Less than an 'A'?
+ jm vtig ;Yes - ignore.
+ cpi 'K'+1 ;Greater than 'K'?
+ jp vtig ;Yes - ignore.
+ sui 'A' ;Else make into index.
+ rlc ;Multiply by four.
+ rlc ;(Shift left twice.)
+ lhld pttab ;Load base addr of table.
+ mov e,a ;Move a into de pair.
+ mvi d,00H ;Zero out high byte.
+ dad d ;Double add index+offset.
+ xchg ;Exchange de with hl.
+ call selcon ; select console
+ call prtstr ;and syscall.
+vtig: ;Ignore escape sequence.
+ xra a ;Reset the ol' escape flag.
+ sta escflg
+ ret ;Return home.
+
+; here for <esc>Z. Tell the host we're a VT52. (Sure we are...)
+vt52id: mvi a,esc ; response is escape...
+ call setpar ; (need correct parity)
+ mov e,a
+ call outmdm ; (console already selected)
+ mvi a,'/' ; ... slash ...
+ call setpar ; (with parity)
+ mov e,a
+ call outmdm
+ mvi a,'K' ; ... K.
+ call setpar
+ mov e,a
+ call outmdm
+ jmp vtig ; clear escape-sequence flag and return.
+
+; here when escflg isn't 0 or 1 - processing cursor positioning sequence.
+vt52y: cpi 2 ; looking for row? (y-coordinate)
+ jnz vt52x ; no, must be column.
+ mov a,e ; yes. get coordinate
+ sui (' '-1) ; convert from ascii (1 = top line)
+ sta vtyval ; store for later
+ mvi a,3 ; advance to next state (x coord)
+ sta escflg ; store it
+ ret ; try for another character
+
+; here when escflag isn't 0, 1, or 2 - it must be 3. (right?)
+; E holds the last character of the cursor positioning sequence.
+vt52x: xra a ; end of escape sequence, reset state.
+ sta escflg
+ mov a,e ; get column (' ' is left margin)
+ sui (' '-1) ; make left margin be one
+ mov c,a ; stash column in c
+ lda vtyval ; get row number
+ mov b,a ; in b
+ call selcon ; select console
+ call csrpos ; call system-dependent cursor positioner
+ ret ; all through.
+;
+;
+; conchr - copy character from console to comm line, processing
+; (kermit's) escape sequences.
+; Enter and exit with console selected.
+; nonskip return: transparent mode terminated.
+; skip return: still in transparent mode.
+; called by: rexmit, telnet
+
+conchr: call inpcon ;Try to get a character from the console
+ ani 07FH ;Keep only 7 bits
+ jz rskp ;Null means nothing there.
+ mov e,a ;Move the char for comparison.
+ sta lstchr ;Save it
+ lda escchr ;Get the escape char.
+ cmp e ;Is it an escape char?
+ jz intchr ;If so go process it.
+ call selmdm ; select the modem
+ mov a,e ;Get the char.
+ call setpar ;Set parity (if any).
+ mov e,a ;Restore it.
+ push d ; need to save e in case we are half dplx [5]
+ call outmdm ;Output the char to the port.
+ pop d ; Just in case we are half dplx [5]
+ call selcon ; reselect console
+ lda ecoflg ;Get the echo flag.
+ ora a ;Is it turned on?
+ jz rskp ;If not we're done here.
+ mov a,e ;Get the char.
+ ani 7FH ;Turn off the parity bit.
+ mov e,a
+ call outcon ; echo the character.
+ jmp rskp ; use skip return
+;
+; transparent escape character has been typed. dispatch on second
+; character. (console is still selected)
+; here from: conchr
+
+intchr: call inpcon ; get another character from the console
+ ora a ; zero means no character available yet.
+ jz intchr ; If so, loop until we get a char.
+ mov b,a ;Save the actual char.
+ cpi ctrlc ;is it Control-C?
+ jz contc ;yes
+ ani 137O ;Convert to upper case.
+ cpi 'C' ;Is it close?
+ jnz intch0 ;If not proceed.
+contc: lxi d,infms9 ;Say we are back.
+ call prtstr
+ call syscls ; call system-dependent close routine
+ lda logflg ;Get the log flag.
+ ora a ;[pcc005] Check if open
+ cm logcls ;[pcc005] Close if needed
+ ret
+
+;Here if not a 'C' or '^C'
+
+intch0: cpi 'S' ;Is it status?
+ jnz inch01 ;If not, proceed.
+ call stat01 ;Print out the status stuff.
+ call prcrlf ;[pcc011] add a crlf
+ jmp rskp ;return from conchr
+
+inch01:
+inch03: mov a,b ;Get the char.
+ cpi '?' ;Is it a help request?
+ jnz intch1 ;If not, go to the next check.
+inch3a: lda logflg ;[pcc003] Logging flag
+ ora a ;[pcc003] see if active
+ jp inch04 ;[pcc005] jump if no file open
+ lxi d,loghlp ;[pcc003] yes, tell about R AND Q
+ call prtstr ;[pcc003]
+inch04: lxi d,inthlp ;If so, get the address of the help message.
+ call prtstr
+ call sysinh ; print system-dependent help message
+ lxi d,inhlp1 ; Tell about doubling the escape character
+ call prtstr
+ call escpr ;Print escape character
+ lxi d,inhlp2 ;Print the rest
+ call prtstr
+ jmp intchr ;Get another char.
+
+intch1: mov a,b ;Get the character.
+ cpi '0' ;Is it '0', to send a null?
+ jnz intch3 ;No.
+ xra a ;Yes, send an ASCII zero.
+ call setpar ; with the correct parity
+ mov e,a
+ call selmdm ; (to the modem...)
+ call outmdm
+ call selcon ; return with console selected
+ jmp rskp
+
+intch3: lda escchr ;Get the escape char.
+ cmp b ;Is it the escape char?
+ jnz intch4 ;[pcc002] jump if not
+ mov a,b ;Get the char.
+ call setpar
+ mov e,a ;Restore it.
+ call selmdm
+ call outmdm ;Output it.
+ call selcon ;We promised console would be selected...
+ jmp rskp ;Return, we are done here.
+intch4: mov a,b ;[pcc002] get it again
+ ani 137o ;[pcc002] in upper case
+ cpi 'P' ;[pcc002] toggle printer?
+ jnz intch5 ;[pcc003] nope
+ lda prnflg ;[pcc002] get printer flag
+ xri 01h ;[pcc002] complement it
+ sta prnflg ;[pcc002] and put back
+ jmp rskp ;[pcc002]
+intch5: lda logflg ;[pcc003] get log flag
+ ora a ;[pcc003] See if open
+ jp intch7 ;[pcc003] no, skip R and Q
+ mov a,b ;[pcc003] get back chr
+ ani 137o ;[pcc003] make upper case
+ cpi 'R' ;[pcc003] Is it R
+ jnz intch6 ;[pcc003] Jump if not
+ mvi a,81H ;[pcc003] set flag for logging
+ sta logflg ;[pcc003] put it back
+ lxi d,inms28 ;[pcc003] message
+ call prtstr ;[pcc003]
+ jmp rskp ;[pcc003] done
+intch6: cpi 'Q' ;[pcc003] Quit logging?
+ jnz intch7 ;[pcc003] no
+ mvi a,82H ;[pcc003] flag for open, but suspended
+ sta logflg ;[pcc003] store away
+ lxi d,inms27 ;[pcc003] keep them informed
+ call prtstr ;[pcc003]
+ jmp rskp ;[pcc003]
+intch7: ;[pcc003]
+
+intchz: mov a,b ; not recognized. get saved copy back.
+ push psw ;[8] save as we will want to test for 'D'
+ call sysint ; interpret system-dependent sequences
+ jmp intchy ; done. [10] Now see if D. If so, do a C.
+ pop psw ;[10] tidy stack
+ mvi e,'G'-100O ;Otherwise send a beep.
+ call outcon ; to the console.
+ jmp rskp
+
+intchy: pop psw ;[10] adjust stack
+ ani 5fh ;[10] strip parity, make it upper case
+ cpi 'D' ;[10] was it a D?
+ jz contc ;[10] yup, so to the equivalent of an escape-C
+ jmp rskp
+;
+; Little code to allow some expansion of code without changing
+; every futher address, only up to the end of this file.
+; TO BE REMOVED FOR RELEASE!
+
+; org ($+100h) AND 0FF00H
+IF lasm
+ LINK CPSCPM
+ENDIF;lasm
diff --git a/cpsutl.asm b/cpsutl.asm
index 3081232..9d7244e 100644
--- a/cpsutl.asm
+++ b/cpsutl.asm
@@ -1,1227 +1,1227 @@
-; CPSUTL.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; Utility routines, pure and impure data.
-;
-; revision history:
-;
-;edit 31, 21-Mar-1991 by MF. Implement edit 30 without checking takflg after
-; "r1tch1" as we are **always** TAKEing from a file if we get to that
-; point in the code. Makes for simplicity.
-;edit 30, 27-Feb-1991 by MF. When TAKEing characters from a TAKE-file,
-; view semicolons as normal characters (not command separators).
-; This will allow such commands as REMOTE DELETE *.*;* to work
-; properly from TAKE-files without having to revert to old code in
-; cpsrem.asm at "remcl0" to decode Remote command arguments. TAKE-files
-; ought not (in my opinion) to have multiple commands per line anyway.
-;edit 29, 30-Jan-1991 by MF. Fix bug in IN1CHR which decremented "chrcnt"
-; once too often after a call to INBUF (which predecrements it
-; already). This, along with a fix in CPSTT.ASM, fixes a bug in the
-; TRANSMIT command wherein certain characters in the file were not
-; being transmitted. This bug was reported to me by Lance Tagliapietra
-; of the University of Wisconsin at Platteville, WI (Email:
-; <TAGLANCE@ucs.UWPLATT.EDU>).
-; (he suggested not predecrementing "chrcnt" in INBUF" but this
-; breaks code in routine "GTCHR" from CPSPK1.ASM so it's better
-; to modify IN1CHR in this module and XMIT in CPSTT.ASM).
-;edit 28, 30-Nov-1990 by MF. Modify routine "p20ln" to use "pausit" routine
-; rather than explicitly checking for Console input to eliminate
-; redundant code. Also fix spelling in "p20ln"'s comments.
-;edit 27, 9-Sep-90 by MF. Put RET in routine PAUSIT per CPKERM.BWR.
-; edit 26, September, 1987. Added pause-it routine to wait for a user keysroke.
-;
-; edit 25, August 19, 1987 by OBSchou. Fixed a few bugs here and there.
-;
-; edit 24, April 8, 1987 by OBSchou. Added routine to return one character
-; from a section of several sectors worth of file. This routine needed
-; for TRANSMIT.
-;
-; edit 23, March 11, 1986 by OBSchou for Richard Russell
-; Bug in the TAKE code, such that a new sector was read in after 256
-; bytes, and not the CPM value. A jnz is now jp in the test to see if
-; the file buffer has bben exhausted. Many thanks for finding this
-; bug. I have never used TAKE files more than 128 bytes long.
-;
-; edit 22, January 28, 1986 by OBSchou.
-; split off the data areas from CPSUTL to CPSDAT.ASM (All in line
-; with keeping individual files relatively small)
-;
-; edit 21 August, 1986 by OBSchou. Sorted a few more bugs in printer buffer
-; etc. Have yet to try this with a real printer The code, apart from
-; actually printing works OK.
-;
-; edit 26 20 August, 1986 by OBSchou for Godfrey Nix:
-; edit 8-Aug-86 by Godfrey N. Nix [gnn] Nottingham University
-; Added two extra bytes for storage of the send and receive
-; start-of-packet characters. Used by CP4PKT, and altered
-; by SET option in CP4MIT. Also added message strings for
-; use by show routines. Added remote filename buffer and length byte.
-;
-; edit 11: June 20, 1986 by OBSchou. Added multi-fcbs for the DIR command
-; together with some bug clearing and new routines. Had to move
-; the overlay to 5000h as we ran out of space...
-;
-; edit 10: June 16, 1986 OBSchou. Added a pseudo clock and check for printer
-; ready whenever one enters BDOS... This may slow things down a little
-; but adds in (hopefully) pseudo background printing...
-;
-; edit 9 30-May-86 OBSchou. Added XON/XOFF routines here for the world
-; at large to use. Also added two new entries in the overlay tables.
-; One to give the address of the family of machines using the overlay,
-; the other to the routine for giving printer status.
-;
-; edit 8: 27-May-86 OBSchou. Added code to check BDOS calls for info from
-; the console. If so, and the take flag (takflg) is set then we
-; substitute our own characters. Simple, a little tatty...
-; Also added bits for SET CASE-SENSITIVE and SET FLOW=CONTROL, and
-; removed the XMIT rubbish. This is a prelude to better TRANSMIT
-;
-; edit 7: 22 April, 1986 by OBSchou Lohghborough University
-; Prlude to more changee, this time make overlay address to 4000h
-; May revert back to ($+0ffh) AND 0ff00h as address for overlay.
-; This gives us space to make quite a few modifications to the system
-; dependent part without much fear of having to change this overlay
-; address. Should also fix the Osborne problem of having to have io
-; routines ii memory above 16k. I know I should not be introducing
-; such system dependent rot here, but it wont be too difficult to fill
-; memory to 4000h.
-;
-; edit 6: February 6, 1985
-; Added a storage location for the port value (PORT, just below
-; SPEED) which is used by the port status routine, and moved the
-; printer copy flag (PRNFLG:) into the communications area so
-; that the machine dependant overlay can toggle it. [Hal Hostetler]
-; Added ffussy flag for filename checking. Generate the version
-; string from 'verno', which is set in CP4KER, because CP4KER has the
-; list of modules and their edit numbers. [Charles Carvalho]
-;
-; edit 5: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
-;
-;pcc002 28-Dec-84 modules:cp4tt,cp4utl
-; Add connect mode <esc>P command to toggle printer on
-; and off. Conflicts with "official" recommended commands
-; in protocol manual, but I don't think CP/M will ever get
-; a PUSH command.
-;
-;pcc003-pcc005 2-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl
-; These edits must all be installed together and change the way
-; logging is handled. The log file spec is moved to a separate
-; fcb, and not opened until an actual CONNECT command is given.
-; This takes care of a NASTY bug that if you used any other file
-; command between the LOG and CONNECT, the log file would get
-; written over the last file used. This also allows logging to
-; be "permanently" enabled until an CLOSE (new command) for all
-; CONNECT sessions, like most other kermits do. If a log file
-; already exists, it will be appended to. Also add two new
-; CONNECT mode commands <esc>Q to suspend logging and <esc>R to
-; resume. <esc>R means something else during TRANSMIT, but
-; logging is never on then, so there shouldn't be any conflict.
-; I also changed the write code, so that it can handle one more
-; character after the XOFF is send to stop the host. This allows
-; a little "slop" for systems that don't stop immediately (such
-; as TOPS10), but it didn't help much.
-;
-;pcc006 2-jan-85 VJC modules:cp4cmd,cp4utl
-; Problems with "?" in filespecs. On reparse, may cause action
-; flag to be reset at wrong point, requiring multiple <CR>'s
-; to terminate the line or other weird stuff. Also need to
-; check flag and complain if wild-cards illegal.
-;
-;pcc008 2-Jan-85 vjc modules:cp4def,cp4tt,cp4utl
-; Keyboard input during CONNECT mode can get locked out if
-; there is enough input from the modem port to keep prtchr
-; busy. This can happen for example, if the printer is running
-; at the same speed as the modem line, leaving you helpless to
-; turn it off or abort the host. Add a fairness count, so that
-; at least every prfair characters we look at console input.
-;
-;pcc012 4-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl
-; Use the big buffer for the log file. Move the log file back
-; into the common fcb and only save the drive, name, and
-; extension between connects. Add new routines to cp4utl to
-; create or append to an existing file, and to conditionally
-; advance buffers only if in memory. Remove edit pcc003 that
-; allows one more character after the xoff, since it didn't
-; really work very well and does not fit in well with the way
-; the buffer advancing routines are set up. If someone still
-; thinks this would be useful, it could be put back in with a
-; little more work.
-;
-; While testing this edit, I also noticed another bug that
-; the command parsing routines do not limit or check the
-; length of command lines or file specs, trashing what ever
-; comes after them. Currently because of where the fcb and
-; command buffer are located, this does not usually cause a
-; problem, but could if an extremely long line was typed in,
-; or in the future multiple fcbs defined elsewhere in memory
-; were used. Maybe this should be put on the bug list
-; somewhere.
-;
-;pcc013 8-Jan-85 vjc modules:cp4mit,cp4utl,cp4typ
-; Replace CLOSE command to cancel session logging to SET
-; LOGGING ON/OFF. This seems to fit in with the command
-; structure better. Default the log file to KERMIT.LOG
-; incase no previous LOG command. Logging is also enabled
-; by LOG command, as before.
-;
-; edit 4: September 9, 1984
-; Move command tables and associated help text to CP4MIT. Add
-; makfil/clofil routines and modify outbuf to write files in big
-; chunks. Update Kermit's version to 4.03.
-;
-; edit 3: August 21, 1984
-; Make inbuf read files in big chunks to minimize disk start/stop
-; delays. Buffer size and address is specified by system-dependent
-; overlay.
-;
-; edit 2: August 3, 1984
-; move "mover" to CP4SYS to allow use of Z80 block move instruction.
-;
-; edit 1: July 27, 1984
-; extracted from CP4MIT.M80 edit 2, as part of LASM support. This is
-; the last file linked for the system-independent code.
-;
-utlver: db 'CPSUTL.ASM (31) 21-Mar-1991$'
-
-; Set the parity for a character in A.
-; called by: spack, rexmit, logit, vt52, conchr, intchr
-
-setpar: push h ;Save HL.
- push b
- lxi h,parity
- mov c,m ;Get the parity routine.
- mvi b,0
- lxi h,parjmp ;Get the first address.
- dad b
- pchl
-
-parjmp: jmp even
- jmp mark
- jmp none
- jmp odd
- jmp spacep
-
-none: jmp parret ;Don't touch the parity bit.
-
-even: ani 7FH ;Strip parity.
- jpe parret ;Already even, leave it.
- ori 80H ;Make it even parity.
- jmp parret
-
-mark: ori 80H ;Turn on the parity bit.
- jmp parret
-
-odd: ani 7FH ;Strip parity.
- jpo parret ;Already odd, leave it.
- ori 80H ;Make it odd parity.
- jmp parret
-
-spacep: ani 7FH ;Turn off the parity bit.
- jmp parret
-
-parret: pop b
- pop h ;Restore HL.
- ret
-;
-; Print the escape char.
-; called by: stat01, telnet, intchr
-
-escpr: lda escchr ;Get the escape char.
-escpr1: cpi ' ' ;Is it a control char?
- jp escpr2
- push psw ; save the character
- lxi d,inms10 ;Output "Control-".
- call prtstr
- pop psw ; restore the character
- ori 100O ;De-controlify.
-escpr2: mvi c,conout ;Output the char
- mov e,a
- call bdos
- ret
-
-; fetch keyword; if unsuccessful, return to command level.
-; called by: kermit, setcom
-
-keycmd: mvi a,cmkey
- call comnd
- jmp keycm2 ;no match
- ret
-
-keycm2: lxi d,ermes1 ;"Unrecognized Command"
- call prtstr
- jmp kermit ;Do it again.
-
-; request confirmation; if unsuccessful, return to command level
-; called by: bye, exit, help, log, setcom, show, status, send,
-; finish, logout, telnet
-
-cfmcmd: mvi a,cmcfm
- call comnd
- jmp kermt3 ;"Not confirmed"
- ret
-;
-
-; This routine prints the number in HL on the screen in decimal.
-; Uses all ACs.
-; called by: cp4sys, read, send, updrtr, dir, user
-
-nout: mvi a,'0' ; fill tempx with zeros
- call filltmp
-
- lxi b,-10 ;Get some useful constants.
-nout1: lxi d,-1
-
-nout2: dad b ;Subtract as many 10s as possible.
- inx d ;Count them.
- jc nout2 ;If some left keep going.
- push h ;save remainder - 10
- xchg ;Swap the remainder and the quotient.
- mov a,h ;Get the number of 10s found.
- ora l ;check for quotient non zero
- cnz nout1 ;If non zero, recurse.
- pop h ;Get the remainder - 10
- mov a,l ;in a
- adi '0'+10 ;Make the number printable and add the 10 back
- call shiftmp ; cycle temp registers
- sta temp1 ; and save digit
- mov e,a ;Output the digit.
- lda nquiet ; are we to be quiet?
- ana a
- rnz ; yup, so return here rather than frm bdos
- mvi c,conout
- jmp bdos
-
-; prcrlf - print a CR/LF. (Saves no registers.) [Toad Hall]
-; prtstr - print string pointed to by DE (now in overlay section.. see prtstx)
-; called by: lots of places.
-prcrlf: lxi d,crlf ;Point to the CR/LF
- jmp prtstr ; Use the one in the overlay
-
-; prtstx is funtionally the same as prtstr in the overaly but is here as
-; we may need a print a string routine in case the overlay is
-; either incorrect version or simply not present.
-prtstx: ; PRTSTR moved to overlay, but we do need the
- ; same function for writing the sign-on
- ; message and error message if the overlay
- ;is not present. Thence prtstx
- mvi c,prstr ; output string
- jmp bdos ;a CALL followed by a RET becomes a JMP
-
-
-; Jumping to this location is like retskp. It assumes the instruction
-; after the call is a jmp addr.
-; here from: many places.
-rskp: pop h ;Get the return address.
- inx h ;Increment by three.
- inx h
- inx h
- pchl
-
-; Jumping here is the same as a ret. 'jmp r' is used after routines
-; that have skip returns, where the non-skip instruction must be 3 bytes.
-; here from: many places.
-r: ret
-
-; Pause-it routine. Informs the user to press any key to continue
-; and then waits for a key input. Called by the any routine
-; with more than, say, 20 lines of output.
-
-pausit: lxi d,anymes ; ask user to press any key to continue
- call prtstr
-pausi1: call ckcon ; see if a key typed
- ana a
- jz pausi1 ; loop until a key has been pressed.
-
- ret
-
-;
-; Open a file for reading (with inbuf). The filename is already
-; in fcb; upon return, the end of file flag is cleared and chrcnt
-; is set to zero, so inbuf will be called to get a buffer when we
-; next attempt to get a character.
-; called by: sinit, seof
-
-getfil: xra a
- sta chrcnt ;Buffer is empty.
- sta seccnt ;No sectors buffered.
- sta eoflag ;Not the end of file.
- sta endsts ;No EOF/error pending.
- sta fcb+0CH ;Zero the extent.
- sta fcb+0EH ;Must be zero for MAKEF or OPENF.
- sta fcb+20H ;Zero the current record.
- mvi c,openf ;Open the file.
- lxi d,fcb
- call bdos
- ret
-
-; Get next sector. If necessary, read some more from disk.
-; preserves bc, de, hl
-; returns nonskip if EOF or error;
-; returns skip with chrcnt and bufpnt updated if success.
-; called by: gtchr, get1xc (from xmt/transmit)
-
-inbuf: lda eoflag ;Have we reached the end?
- ora a
- rnz ;Return if so.
- push b
- push d
- push h
-inbuf1: lda seccnt ; Do we have any sectors left?
- ora a
- jz inbuf3 ; If not, go get some more.
-inbuf2: lhld nxtbuf ; Yes. Get address of next sector
- shld bufpnt ; Update current buffer pointer
- lxi b,bufsiz ; Get number of bytes in sector
- dad b ; Update HL to point to next sector
- shld nxtbuf ; Save for next time
- dcr a ; Decrement count of buffered sectors
- sta seccnt ; Put it back
- mvi a,bufsiz-1 ; Number of bytes in buffer (pre-decremented)
- sta chrcnt ; Store for our caller
- pop h
- pop d
- pop b
- jmp rskp ; Return success
-
-; We don't have any sectors buffered. If we've already hit an error or
-; EOF, return that status to the user.
-
-inbuf3: lda endsts ; Check status from previous read
- ora a
- jz inbuf4 ; It was OK. Get some more sectors.
- sta eoflag ; End of file or error. Set the flag.
- xra a
- sta chrcnt ; Say no characters in buffer.
- pop h
- pop d
- pop b
- ret ; Return failure
-
-; Read sectors until we fill the buffer or get an error or EOF, then return
-; the first buffer to the user. (seccnt is zero)
-
-inbuf4: lhld bufadr ; Get address of big buffer
- shld nxtbuf ; Store as next buffer address to give user
-inbuf5: shld bufpnt ; Store as next buffer address to read into
- xchg ; Move buffer address to DE
- mvi c,setdma ; Tell CP/M where to put the data
- call bdos ; ...
- mvi c,readf ; Read a record.
- lxi d,fcb
- call bdos
- sta endsts ; Save ending status
- ora a ; 00H => read O.K
- jnz inbuf6 ; EOF/error: stop reading.
- lxi h,seccnt ; Success. Get addr of sector count
- inr m ; Bump sector count by one
- lda bufsec ; Get max number of sectors in buffer
- cmp m ; Are we there yet?
- jz inbuf7 ; Yes, can't read any more.
- lhld bufpnt ; No, try for another. Get buffer address,
- lxi d,bufsiz ; and size of sector,
- dad d ; giving next buffer address in HL
- jmp inbuf5 ; Go read another sector.
-
-; We hit EOF or got an error. Put the DMA address back where it belongs,
-; then go see if we have any sectors (before the one that got the error)
-; to return to the caller. Nxtbuf points to the first good sector, if
-; any; seccnt contains the count of good sectors.
-
-inbuf6: call rstdma
- jmp inbuf1 ; Go see if we have some data to return
-
-; We've filled the big buffer. Reset the DMA address, then go return a
-; sector to the caller. nxtbuf points to the beginning of the buffer;
-; seccnt contains the number of sectors successfully read (except that
-; if we've read 256 sectors, seccnt contains zero, so we can't just go
-; to inbuf1).
-
-inbuf7: call rstdma ;[pcc012]
- lda seccnt ; Get sector count again.
- jmp inbuf2 ; Return a sector.
-
-; IN1CHR - get a single character from the file. Taken code from old
-; TRANSMIT routine.
-in1chr:
- lda eoflag ;EOF encountered?
- ora a
- rnz ; Yes, finish.
- lxi d,cmdbuf ; Use comnd buffer as line buffer.
- lhld bufpnt ; Get current buffer pointer.
- lda chrcnt ; Get current byte count
- mov b,a ; in B
-in1ch1: dcr b ; Assume there's a character there
- jp in1ch2 ; If there was, proceed.
- call inbuf ; There wasn't. Try for another buffer.
- jmp in1che ; End of file.
- lhld bufpnt ; Got another buffer. Get new pointer in HL
- lda chrcnt ; and new byte count
- mov b,a ; in B
-;[MF]The modification below was made 30-Jan-1991 per report from
-;[MF]Lance Tagliapietra from the University of Wisconsin at Platteville
-;[MF]The following instruction should not be executed as the character counter
-;[MF]has already been decremented by INBUF.
-; dcr b ; we are reading in a character, so less one
-in1ch2: mov a,b ; save new count
- sta chrcnt
- mov a,m ; Get a character from disk buffer.
- inx h
- shld bufpnt ; save new pointer
- ani 7FH ; Mask 7 bits.
- jz in1ch1 ; Skip nulls.
- ret ; character in a
-
-
-in1che: mvi a,0ffh ; dubious about this one...
- sta eoflag
- ret ; set end of file flag...?????
-
-; ;[pcc012]
-; appfil - Create or append to an existing file. File name is in FCB.
-; Non-skip return if could not be done. Skip return with file
-; open and bufpnt pointing to end of file.
-; called by logopn
-appfil: xra a ;[pcc012] zero out stuff for open
- sta fcb+0CH ;[pcc012] extent
- sta fcb+0EH ;[pcc012] Must be zero for MAKEF or OPENF.
- sta fcb+20H ;[pcc012] Zero the current record.
- mvi c,openf ;[pcc012] Try to open the file
- lxi d,fcb ;[pcc012]
- call bdos ;[pcc012]
- cpi 0FFH ;[pcc012] Did we find it?
- jz makfi1 ;[pcc012] If not, go create it
- mvi c,cflsz ;[pcc012] Compute the file size
- lxi d,fcb ;[pcc012]
- call bdos ;[pcc012]
- lhld fcb+21H ;[pcc012] random record pointer
- mov a,h ;[pcc012] See if zero length file
- ora l ;[pcc012]
- jz makfi2 ;[pcc012] set up pointers if null file
- dcx h ;[pcc012] backup to last record written
- shld fcb+21H ;[pcc012] store rec ptr back
- lhld bufadr ;[pcc012] get buffer address
- xchg ;[pcc012] to DE
- mvi c,setdma ;[pcc012] set dma address
- call bdos ;[pcc012] for read
- mvi c,rrand ;[pcc012] read the last block
- lxi d,fcb ;[pcc012]
- call bdos ;[pcc012]
- ora a ;[pcc012] check results
- jnz rstdma ;[pcc012] reset dma and return if error
- lhld bufadr ;[pcc012] get address again
- lxi d,bufsiz ;[pcc012] and and size
- mvi a,'Z'-40H ;[pcc012] control-Z for comparison
-appcz: cmp m ;[pcc012] Is this the EOF?
- jz appxit ;[pcc012] Jump if yes
- inx h ;[pcc012] no, bump
- dcr e ;[pcc012] and grind
- jnz appcz ;[pcc012] until find or buffer empty
-appxit: shld bufpnt ;[pcc012] store buffer pointer
- dad d ;[pcc012] compute next buffer adr
- shld nxtbuf ;[pcc012] and store
- mov a,e ;[pcc012] updated chr count
- sta chrcnt ;[pcc012]
- xra a ;[pcc012] reset sector count
- sta seccnt ;[pcc012]
- call rstdma ;[pcc012] reset normal dma
- jmp rskp ;[pcc012] and give good return
-
-; Create a file, deleting any previous version. The filename is in
-; fcb.
-; Returns nonskip if file could not be created.
-; If successful, takes skip return with bufpnt and chrcnt initialized
-; for output; buffers should be output via outbuf.
-; called by: gofil
-makfil: mvi c,delf ; delete the file if it exists.
- lxi d,fcb
- call bdos
- xra a
- sta fcb+0CH ; zero the extent.
- sta fcb+0EH ; must be zero for MAKEF or OPENF.
- sta fcb+20H ; zero the current record.
-;[pcc012] here from appfil above if file does not exist
-makfi1: mvi c,makef ;[pcc012] now create it.
- lxi d,fcb
- call bdos
- cpi 0FFH ; is the disk full?
- rz ; take error return if so.
-; success. set up pointers and counters for multisector buffering.
-;[pcc012] also here from appfil if found zero length file
-makfi2: lhld bufadr ;[pcc012] find beginning of buffer space.
- shld bufpnt ; make it current buffer.
- lxi d,bufsiz ; get sector size.
- dad d ; find beginning of next buffer.
- shld nxtbuf ; store for later.
- mov a,e ; store buffer size
- sta chrcnt ; for caller.
- xra a
- sta seccnt ; no sectors stored yet.
- jmp rskp ; take success return.
-
-;[pcc012]
-; outadv - conditionally advance output buffer if disk write not needed.
-; preserves BC
-; skip return with with next output buffer set up
-; non-skip return if memory buffer full and must write to disk.
-; called by:logit
-
-outadv: push b ;[pcc012] save BC as advertised
- lxi h,seccnt ;[pcc012] point to sectors buffered
- inr m ;[pcc012] count this one
- lda bufsec ;[pcc012] how many we can hold
- cmp m ;[pcc012] check if full
- jnz outbf2 ;[pcc012] continue if not
- dcr m ;[pcc012] full, un-advance sector count
- pop b ;[pcc012] restore bc
- ret ;[pcc012] and give non-skip return
-
-; get a fresh output buffer, flushing big buffer if necessary.
-; returns nonskip if disk full.
-; if successful, returns skip with bufpnt and chrcnt updated. Note
-; that chrcnt holds one less than the buffer size.
-; preserves BC.
-; called by: ptchr,logwrt
-
-outbuf: push b
- lxi h,seccnt ; count another buffered sector
- inr m ; ...
- lda bufsec ; get number of sectors we can hold
- cmp m ; full?
- jnz outbf2 ; if not, set up pointers and return
- call outmbf ; flush the big buffer
- jmp outbf9 ; disk error.
-;[pcc012] also here from outadv to advance buffer
-outbf2: lhld nxtbuf ; get pointer to fresh buffer
- shld bufpnt ; store for caller
- lxi d,bufsiz ; advance our pointer to next buffer
- dad d
- shld nxtbuf
- mvi a,bufsiz-1 ; get buffer size (pre-decremented)
- sta chrcnt ; store for caller
- pop b
- jmp rskp ; return success.
-
-outbf9: pop b ; clean up stack
- ret ; and take error return.
-
-; flush incore output buffers.
-; returns nonskip if disk full.
-; if successful, returns skip with nxtbuf reset to start of buffer and
-; seccnt zero.
-; destroys all ac's.
-; called by: outbuf, clofil.
-
-outmbf: lhld bufadr ; get start of buffer
- shld nxtbuf ; store for next fill cycle
- shld bufpnt ; store for empty loop
-outmb2: lhld bufpnt ; get address of current sector
- xchg ; into DE
- lxi h,bufsiz ; advance HL to next sector
- dad d ; ...
- shld bufpnt ; and store for later
- mvi c,setdma
- call bdos ; point CP/M at current sector
- lxi d,fcb
- mvi c,writef
- call bdos ; output the sector
- ora a ; test for error (A non-zero)
- jnz rstdma ;[pcc012] reset dma and take nonskip return if so
- lxi h,seccnt
- dcr m ; count down buffered sectors
- jnz outmb2 ; loop if more saved
- call rstdma ;[pcc012] restore normal dma
- jmp rskp ; return success.
-
-; output current buffer, flush incore buffers, and close output file.
-; returns nonskip if disk full; skip if successful.
-; called by: rdata
-
-clofil:
- lda chrcnt ; get the number of chars left in the buffer.
- cpi bufsiz ; Virgin buffer?
- jz clofl3 ; yes, don't output it.
- lhld bufpnt ; get the buffer pointer.
-clofl1: dcr a ; lower the count.
- jm clofl2 ; if full then stop.
- mvi m,'Z'-100O ; put in a ^Z for EOF.
- inx h ; point to the next space.
- jmp clofl1
-
-clofl2: call outbuf ; output the last buffer.
- jmp r ; give up if the disk is full.
-clofl3: lda seccnt ; any sectors buffered in memory?
- ora a
- jz clofl4 ; if not, don't try to flush.
- call outmbf ; flush buffers
- jmp r ; disk full.
-clofl4: mvi c,closf ; close up the file.
- lxi d,fcb
- call bdos
- jmp rskp ; return success.
-
-
-; Reset DMA address to the default buffer
-; called from inbuf,appfil,outmbf
-rstdma: lxi d,buff ;[pcc012]
- mvi c,setdma ;[pcc012]
- jmp bdos ;[pcc012]
-
-; [8] Intercept BDOS calls to check for console input
-; This leads to simple trapping for input from disk rather than from the
-; keyboard, alowing commands to be stored in a TAKE file.
-; Printer is tested for readiness, and the second fuzzy clock is updated.
-bdos: ;call print ; print a character to the printer if needed
- ;call clock ; update the clock
- push psw ; we will need this register
- lda takflg ; are we taking from a
- ana a ; file or from command line
- jz notake ; no, so do usual BDOS stuff
- mov a,c ; get bdos function
- cpi conin ; is it console in?
- jz bd1in ; get a single character
- cpi dconio ; direct console in or out?
- jz bd1io ; test further for inpu or output
- cpi rdstr ; read the console buffer?
- jz bdcbuf ; then do it
- cpi consta ; get the console status?
- jz bdcst ; anything left in buffer?
-notake: pop psw ; else we have a kosher BDOS call
- jmp 0005h ; Absolute address = BDOS entry point
-;
-bd1in: ; get a single character from take file
- pop psw ; restore stack
- call r1tchr ; read a single take character
- ret ; and return. We dont expand tabs,
- ; check for xon/off or backspaces.
- ;Make sure the take file is error free?
-;
-bd1io: ;get or put a single character from/to console
- mov a,e ; get e. If 0ffh then input else output
- inr a ; if 0 then input
- jnz notake ; its for output, so let notake restore stack
- pop psw ; otherwise we do it
- call r1tchr ; read a single take character
- ret ; and return from out BDOS
-;
-bdcbuf: ; read a line of edited (?) input from the console
- pop psw ; restore stack
- inx d ; point to nc
-bdosc1: call r1tchr ; get a character
- cpi cr ; if a cr then return
- jz nomore
- cpi lf ; ignore line feeds
- jz bdosc1 ; so get another character
- push psw ; we will want it later
- mvi h,0
- ldax d ; get nc, the no of characters in buffer
- mov l,a ; now use as index from de+2
- mvi h,0
- inx d ; de is now de + 2
- dad d
- pop psw ; Told you we will want this
- mov m,a
- dcx d ; point again to nc
- xchg ; make hl point to memory
- inr m ; update pointer nc
- xchg ; restore it
- jmp bdosc1
-nomore: dcx d ; restore de to point to buffer
- ret
-
-bdcst: ; get the console status. Returns a 00 if at eof
- pop psw
- push h ; now save de, hl for return
- push d ;
- lxi d,takdma ; make a point to next byte...
- lhld takptr ; pointer from dma address. There will always
- dad d ; be at least one byte, as the buffer is
- mov a,m ; ...
- pop d ; filled only if a read empties it.
- pop h ; restore hl, de
- cpi cntlz ; end of file?
- mvi a,0ffh ; say there is
- rnz ; if it is not a cntl z
- jmp closet ; otherwise, close take file etc
-
-r1tchr: ; read a single character from the take file or command line
- push h
- push d ; save in case of return
- lda takflg ; see if character is to come from file or line
- ani 1 ; if bit zero set, from take file
- jz r1lchr ; get character from the command line
- lxi d,takdma
- lhld takptr ; get next data byte
- dad d
- mov a,m
- lhld takptr ; cos it's destroyed with dad
- inx h
- shld takptr ; update pointer
- call p1tchr ; print it (so the user sees it)
- push psw ; save the read data for a while
- mov a,l ; if l = 0 then read another sector
- ana a
- jp r1tch1 ;[23] was jnz. jp => 128 byte sectors
- call rnsect ;read next sector
-r1tch1: pop psw ; now, is this a cntl-z.. in whic case
- pop d ; also these...
- pop h
- cpi lf ; skip if a line feed
- jz r1tchr ;
-;[MF][31][30]Following lines commented out so semicolons are not considered
-;[MF][31][30]command separators and thus are considered part of the command
-;[MF][31][30]so commands like REMOTE DELETE *.*;* work correctly.
-; cpi semico ; see if its a semicolon
-; jnz r1tch2 ; no, ignore it
-; mvi a,cr ; else say its a cr (in case of command lines)
-r1tch2: cpi cntlz ; end of file??
- rnz
-
-
-c1tchr: call closet ; close file etc, then
- mvi a,cr ; fake a carriage return chr
- ; ( => clears kermit comnd line)
-c1tch1: ret ; and hope that editing etc not required.
-
-r1lchr: ; read a single character from the command line
- lxi d,cbuff ; point to buffer
- lda cbptr ; get pointer for next character
- mov l,a
- lda cbuff ; get total number of characters there
- cmp l ; ... less current character
- jp r1lch1 ; if positive, we have more characters
- lda takflg ; no more, so reset command line bit (bit 4)
- ani 0efh
- sta takflg
- mvi a,cntlz ; fudge an end of file
- push psw ; save for common exit (r1tch1)
- jmp r1tch1
-;
-r1lch1: mov a,l ; get count back again
- mvi h,0
- dad d ; get offset to character
- inr a
- sta cbptr
- mov a,m ; get next character
- cpi semico ; if a semicolon, make it a carriage return
- jnz r1lch2
- mvi a,cr
-r1lch2: call p1tchr ; send a copy to the console
- push psw ; save it for r1tch1
- jmp r1tch1 ; common exit
-
-
-; rnsect - read the next take sector from disk to the take dma address
-; if there is no more then close the file too
-rnsect: push b
- push d
- push h ; save in case we need these later
- mvi c,setdma
- lxi d,takdma ; set a next read from disk
- call bdos ; recursive...
- mvi c,readf
- lxi d,takfcb
- call bdos
- ana a
- cnz closet ; if returned value not zero, assume eof
- lxi h,0
- shld takptr ; pointer restored
- call rstdma ; reset the dma address for fussy routines (this one)
- pop h
- pop d
- pop b
- ret
-
-; closet - close the take file and set the take flag to 0 (ie no takes)
-;
-closet: lda takflg ; reset the take file bit (bit 0)
- ani 0feh
- sta takflg ; close the take file, and restore the flag
- mvi c,closf
- lxi d,takfcb
- call bdos
- call rstdma ; in case we did not do it above, reset dma
- ret
-
-;
-; clock - is a 32 bit counter incremented every BDOS call. It serves as a
-; timer of sorts and allows a background clock to tick away..
-clock: push psw ; we need flags and hl
- push h
- lhld clkbit ; get the counter
- inx h ;
- shld clkbit
- mov a,h
- ora l ; do we need to update the next lot of clock bits?
- jnz clockx
- lhld clkbit+2 ; if carry up the top 16 bits
- inx h
- shld clkbit+2
-clockx: pop h
- pop psw
- ret
-
-; p1tchr - print a character in accumulator directly to the console
-; bypassing the bdos trap above.
-
-p1tchr: cpi lf ; if a lf ignore it
- jz p1tchx
- cpi cr ; ditto carriage returns
- jz p1tchx
- cpi cntlz ; control z
- jz p1tchx ; then dont write it out
- push psw ; we do not want to loose it, do we?
- push b
- push d
- push h ; 'cos you never know what bdos does...
- mov e,a
- mvi c,conout ; direct console io
- call 5 ; absolute address as we skip the trap
- pop h
- pop d
- pop b ; ... and we need some of these regs.
- pop psw ;
-p1tchx: ret ; and return
-
-
-
-; outprn - This routine sends charactes to the printer if the latter is ready,
-; or to a buffer if the printer is not ready. If the buffer is nearly
-; full, an XOFF is sent to the host, asking it to be quiet. The buffer
-; is emptied by a series of calls in the connect state only.
-; If the buffer is made nearly empty, then an XON is sent to the host.
-;
-outprn: mov a,e ; get the character to send back to a
- sta prntmp ; we need all registers.
- jmp outprx ; -testing-testing-testing- avoid buffer
-;
-outp0: call tstfree ; see how many spaces free
- cpi 2 ; (free spaces in a on return)
- jp outp1 ; enough free spaces, so keep going
- call print ; else see if we can print summat
- jmp outp0 ; and try again
-;
-outp1: cpi 4 ; common test - if three or less then send xoff
- cm sndxoff
-outpr2: mov a,b ; inc ptr and check for wrap around
- call wrapt
- mov b,a ; input pointer to b
- sta prnbuf+1 ; save the new pointer away
- lxi h,prnbuf+2 ; point to first real data entry in buffer
- call inchl ; add offset in a to hl
- lda prntmp ; get th character to save away
- mov m,a ; save the data away
- ret
-
-; outprx - send character in a to the printer. (We have checked to see if
-; the printer is ready)
-; called by outprn, print
-outprx: mov e,a ; character has to be in e register
- call outlpt ; send it to printer
- ret ; assume we print it
-
-; TSTFREE - see how many free spacse there are in the buffer
-; - returns with free space in a, ip pointer in b, op pointer in c
-szecyc equ 127 ; 128 bytes in buffer (less for debugging)
-;
-tstfree:
- lda prnbuf ; get output pointer
- mov c,a ;.. to c
- lda prnbuf+1 ; and input pointer ...
- mov b,a ; ... to b
-;
-;
-; Now comes the tricky bit. We must establish whether there is less than
-; three characters left in the buffer. There are two conditions to test for
-; 1) the input pointer is a higher value than the output pointer
-; 2) the input pointer has been wrapped round and is less than the output pointer
-; ie
-; |-------|-------|---------------------------------------------|
-; Buffer |o/p ptr|i/p ptr| Buffer proper filling ---> |
-; |-------|-------|------|-------------|-----------|------------|
-; i/p2 o/p i/p1
-;
-; If ip = ip1 then if
-; (size of buffer - ip ptr + op ptr) < 3 send xoff
-; If ip = ip2 then if
-; (op ptr - input ptr ) < 3 send xoff
-;
-; First decide whice one applies
-
- mov a,b ; get ip ptr
- sub c ; see if op ptr > ip ptr (case 2)
- jm outp2 ; yup, so do case two
- mvi a,szecyc ; else do buffer - ip + op
- sub b
- add c
- jmp outpx ; do common test
-outp2: mov a,c ; get op pointer
- sub b ; less input pointer
-outpx: ret ; with free space in a
-;
-;
-;
-; print - get a character from the buffer and print it if the printer
-; is ready for it. If the buffer clears more than 3 spare characters
-; and an xoff has been sent, then send an xon again.
-print: push h ; save for rainy days
- push d
- push b
- push psw ; .. as we may need flags etc....
- lda initflg ; First check if the system has initialised
- ana a
- jz printx ; If system not set up then skip
-; nop
-; nop
-; nop ; debugging only...
- call ckprtr ; check to see if printer is ready...
- ana a ; not zero => ok
- jz printx ; else skipit.
-; nop
-; nop
-; nop ; skip the jump for debugging
- lxi h,prnbuf
- mov a,m ; get input pointer
- inx h ; test against output pointer
- cmp m ; if = then buffer empty
- jz printx ; so quit
- dcx h ;pointer to output pointer
- call wrapt ; check for wrap around
- sta prnbuf ; save new pointer
- inx h
- inx h ;
- call inchl ; add output pointer to hl
- mov c,m ; get byte
- lda hosths ; have we told host to be quiet?
- cpi xoff ; if = xoff then we have
- jnz print1 ; nope, so just print it..
- push b ; save the character to print
- call tstfree ; see how many free bytes in buffer
- pop b
- cpi 4 ; 3 characters left?
- jz printx
- push b
- call sndxon ; send an xon to host and wake it up.
- pop b
-print1: mov a,c ; we are gonna print a character, so ...
- call outprx ; get it to a (as required by outprx) and print it
-printx:
- pop psw
- pop b
- pop d
- pop h ; restore regs.
- ret
-
-;
-; Utilities for the cyclical buffer. Returns a 0ffh if printer ready,
-; else 0h. Called by outprn, print
-
-ckprtr:
- call lptstat ; no registers saved
-; mvi a,0 ; FOR DEBUGGING PURPOSES
-; nop
- ret
-;
-
-inchl: push psw ; we do maths through this register
- add l
- mov l,a
- mvi a,0
- adc h
- mov h,a
- pop psw ; hl = a + hl
- ret
-
-; wrapt - checks the offset in a with the limits of the buffer.
-; returns next address or if wrap around then 0 (start of buffer)
-wrapt: push b
- inr a
- mov b,a ; save new a into b for now
- mvi a,szecyc ; test for size of buffer
- sub b
- mov a,b
- pop b ; restore bc regs again
- rnz
- xra a ; if wrap around, then reset pointer
- ret ; return with next address pointer to in a
-
-; sndxoff - send an xoff to the host and save the xoff character in hosths
-; saves all regs. is called by logwrt, outprn
-sndxoff:
- push psw
- push b
- push d
- push h ; some calling routines may be sensitive...
- lda floctl ; are we doing flow control?
- ana a
- jz sndxf ; no, so dont bother.
- mvi a,xoff ;^S to stop the host while we write the buffer.
- sta hosths ; save it so we know we have sent it
- call setpar ; set correct parity...
- mov e,a
- call outmdm ; output it.
- lxi d,ofsnt ; say we have sent an xoff
- call prtstr
-sndxf: pop h
- pop d
- pop b
- pop psw ; some routines touchy
- ret
-ofsnt: db cr,lf,'[XOFF sent to host]',cr,lf,'$'
-
-; sndxon - send an xon to the host and clear the hosths flag. saves everything
-; called by logwrt, print
-sndxon: push psw
- push b
- push d
- push h
- lda floctl ; are we doing flow control?
- ana a
- jz sndxn
- xra a
- sta hosths ; no xoff to hos any more
- mvi a,xon ;^Q to restart the host
- call setpar ; set appropriate parity
- mov e,a
- call outmdm ; send it.
- lxi d,onsnt
- call prtstr ; say xon sent to host...
-sndxn: pop h
- pop d
- pop b
- pop psw
- ret ; shame we dont do a pushall/popall subroutine...
-onsnt: db cr,lf,'[XON sent to host]',cr,lf,'$'
-;
-; Routines to clear (or rather fill) TEMPnnn space with the data in A
-; and to shift it all along one (filltmp an shiftmp respectively)
-filltmp:
- push b
- push d
- push h ; save all
- lxi h,temp1
- mvi b,10 ; ten locations to fill
-fillp: mov m,a
- inx h
- dcr b ; loop til all done
- jnz fillp
- pop h
- pop d
- pop b ; restore all
- ret
-
-shiftmp:
- push psw ; save all again
- push b
- push d
- push h
- lxi d,temp9
- lxi h,temp10
- mvi b,9 ; shift nine times
-shiftl: ldax d ; from tempx
- mov m,a ; to tempx+1
- dcx d
- dcx h ; mover does not work as that increments
- dcr b
- jnz shiftl
- pop h
- pop d
- pop b
- pop psw
- ret ; else all done
-
-; getun - get the user number to temp1 (lsd) and temp2 (msd)
-;
-getun: mvi a,0ffh ; tell nout to be quiet
- sta nquiet
- mvi c,usrcod
- mvi e,0ffh ; get current user from bdos
- call bdos
- mov l,a ; put into hl
- mvi h,0
- call nout ; decimalise it (decimalise???)
- xra a
- sta nquiet ; let nout print again
- ret
-
-; ckcon - Do a direct console IO (read) to see if there is any input
-; returns with a=0 (no input) or character (input received)
-; Assume that all regs may be destroy.
-ckcon: mvi e,0ffh ; direct console input
- mvi c,dconio
- call bdos
- ret ; and return with wahtever returned in a
-
-
-
-;
-; subbc - Subtract the unsigned number in bc from the unsigned number
-; in HL with the answer in HL. Flags altered, all
-; other registers left intact.
-subbc: sta temp1 ; hl = hl - bc.. we need the accumulator
- mov a,l
- sub c
- mov l,a
- mov a,h
- sbb b
- mov h,a
- lda temp1 ; restore loop counter but not flags
- ret
-
-; P20LN - Routine to print a string at (DE) and count the number of
-; line feeds. Pause after 20 lines printed.
-p20ln: xra a ; clear the line counter
- sta lincnt
-p20ln1: ldax d ; get character to print
- inx d
- cpi '$' ; if a dollar we have done
- rz
- push d
- push psw ; save pointer and character to print
- mov e,a
- call outcon ; send character
- pop psw
- pop d ; restore pointers etc
- cpi lf ; was that last character a line feed?
- jnz p20ln1 ; no, so carry on
- lda lincnt ; yup, so update counter
- inr a
- sta lincnt
- cpi 20 ; 20 lines printed?
- jnz p20ln1 ; not yet
- push d ; we need DE
-; lxi d,anymes ; pause a while [MF]removed
-; call prtstr ; write the message [MF]
-;p20ln2: call ckcon ; wait for any input [MF]
-; ana a ;[MF]
-; jz p20ln2 ;[MF]
- call pausit ;[MF] pause a while
- pop d
- jmp p20ln ; and continue
-
-
-; Little code to allow some expansion of code without changing
-; every futher address, only up to the end of this file.
-; TO BE REMOVED FOR RELEASE!
-
-; org ($+100h) AND 0FF00H
-
-; link to the data area (was part of CPSUTL.ASM)
-
-IF lasm
- LINK CPSDAT
-ENDIF ;lasm
+; CPSUTL.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; Utility routines, pure and impure data.
+;
+; revision history:
+;
+;edit 31, 21-Mar-1991 by MF. Implement edit 30 without checking takflg after
+; "r1tch1" as we are **always** TAKEing from a file if we get to that
+; point in the code. Makes for simplicity.
+;edit 30, 27-Feb-1991 by MF. When TAKEing characters from a TAKE-file,
+; view semicolons as normal characters (not command separators).
+; This will allow such commands as REMOTE DELETE *.*;* to work
+; properly from TAKE-files without having to revert to old code in
+; cpsrem.asm at "remcl0" to decode Remote command arguments. TAKE-files
+; ought not (in my opinion) to have multiple commands per line anyway.
+;edit 29, 30-Jan-1991 by MF. Fix bug in IN1CHR which decremented "chrcnt"
+; once too often after a call to INBUF (which predecrements it
+; already). This, along with a fix in CPSTT.ASM, fixes a bug in the
+; TRANSMIT command wherein certain characters in the file were not
+; being transmitted. This bug was reported to me by Lance Tagliapietra
+; of the University of Wisconsin at Platteville, WI (Email:
+; <TAGLANCE@ucs.UWPLATT.EDU>).
+; (he suggested not predecrementing "chrcnt" in INBUF" but this
+; breaks code in routine "GTCHR" from CPSPK1.ASM so it's better
+; to modify IN1CHR in this module and XMIT in CPSTT.ASM).
+;edit 28, 30-Nov-1990 by MF. Modify routine "p20ln" to use "pausit" routine
+; rather than explicitly checking for Console input to eliminate
+; redundant code. Also fix spelling in "p20ln"'s comments.
+;edit 27, 9-Sep-90 by MF. Put RET in routine PAUSIT per CPKERM.BWR.
+; edit 26, September, 1987. Added pause-it routine to wait for a user keysroke.
+;
+; edit 25, August 19, 1987 by OBSchou. Fixed a few bugs here and there.
+;
+; edit 24, April 8, 1987 by OBSchou. Added routine to return one character
+; from a section of several sectors worth of file. This routine needed
+; for TRANSMIT.
+;
+; edit 23, March 11, 1986 by OBSchou for Richard Russell
+; Bug in the TAKE code, such that a new sector was read in after 256
+; bytes, and not the CPM value. A jnz is now jp in the test to see if
+; the file buffer has bben exhausted. Many thanks for finding this
+; bug. I have never used TAKE files more than 128 bytes long.
+;
+; edit 22, January 28, 1986 by OBSchou.
+; split off the data areas from CPSUTL to CPSDAT.ASM (All in line
+; with keeping individual files relatively small)
+;
+; edit 21 August, 1986 by OBSchou. Sorted a few more bugs in printer buffer
+; etc. Have yet to try this with a real printer The code, apart from
+; actually printing works OK.
+;
+; edit 26 20 August, 1986 by OBSchou for Godfrey Nix:
+; edit 8-Aug-86 by Godfrey N. Nix [gnn] Nottingham University
+; Added two extra bytes for storage of the send and receive
+; start-of-packet characters. Used by CP4PKT, and altered
+; by SET option in CP4MIT. Also added message strings for
+; use by show routines. Added remote filename buffer and length byte.
+;
+; edit 11: June 20, 1986 by OBSchou. Added multi-fcbs for the DIR command
+; together with some bug clearing and new routines. Had to move
+; the overlay to 5000h as we ran out of space...
+;
+; edit 10: June 16, 1986 OBSchou. Added a pseudo clock and check for printer
+; ready whenever one enters BDOS... This may slow things down a little
+; but adds in (hopefully) pseudo background printing...
+;
+; edit 9 30-May-86 OBSchou. Added XON/XOFF routines here for the world
+; at large to use. Also added two new entries in the overlay tables.
+; One to give the address of the family of machines using the overlay,
+; the other to the routine for giving printer status.
+;
+; edit 8: 27-May-86 OBSchou. Added code to check BDOS calls for info from
+; the console. If so, and the take flag (takflg) is set then we
+; substitute our own characters. Simple, a little tatty...
+; Also added bits for SET CASE-SENSITIVE and SET FLOW=CONTROL, and
+; removed the XMIT rubbish. This is a prelude to better TRANSMIT
+;
+; edit 7: 22 April, 1986 by OBSchou Lohghborough University
+; Prlude to more changee, this time make overlay address to 4000h
+; May revert back to ($+0ffh) AND 0ff00h as address for overlay.
+; This gives us space to make quite a few modifications to the system
+; dependent part without much fear of having to change this overlay
+; address. Should also fix the Osborne problem of having to have io
+; routines ii memory above 16k. I know I should not be introducing
+; such system dependent rot here, but it wont be too difficult to fill
+; memory to 4000h.
+;
+; edit 6: February 6, 1985
+; Added a storage location for the port value (PORT, just below
+; SPEED) which is used by the port status routine, and moved the
+; printer copy flag (PRNFLG:) into the communications area so
+; that the machine dependant overlay can toggle it. [Hal Hostetler]
+; Added ffussy flag for filename checking. Generate the version
+; string from 'verno', which is set in CP4KER, because CP4KER has the
+; list of modules and their edit numbers. [Charles Carvalho]
+;
+; edit 5: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
+;
+;pcc002 28-Dec-84 modules:cp4tt,cp4utl
+; Add connect mode <esc>P command to toggle printer on
+; and off. Conflicts with "official" recommended commands
+; in protocol manual, but I don't think CP/M will ever get
+; a PUSH command.
+;
+;pcc003-pcc005 2-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl
+; These edits must all be installed together and change the way
+; logging is handled. The log file spec is moved to a separate
+; fcb, and not opened until an actual CONNECT command is given.
+; This takes care of a NASTY bug that if you used any other file
+; command between the LOG and CONNECT, the log file would get
+; written over the last file used. This also allows logging to
+; be "permanently" enabled until an CLOSE (new command) for all
+; CONNECT sessions, like most other kermits do. If a log file
+; already exists, it will be appended to. Also add two new
+; CONNECT mode commands <esc>Q to suspend logging and <esc>R to
+; resume. <esc>R means something else during TRANSMIT, but
+; logging is never on then, so there shouldn't be any conflict.
+; I also changed the write code, so that it can handle one more
+; character after the XOFF is send to stop the host. This allows
+; a little "slop" for systems that don't stop immediately (such
+; as TOPS10), but it didn't help much.
+;
+;pcc006 2-jan-85 VJC modules:cp4cmd,cp4utl
+; Problems with "?" in filespecs. On reparse, may cause action
+; flag to be reset at wrong point, requiring multiple <CR>'s
+; to terminate the line or other weird stuff. Also need to
+; check flag and complain if wild-cards illegal.
+;
+;pcc008 2-Jan-85 vjc modules:cp4def,cp4tt,cp4utl
+; Keyboard input during CONNECT mode can get locked out if
+; there is enough input from the modem port to keep prtchr
+; busy. This can happen for example, if the printer is running
+; at the same speed as the modem line, leaving you helpless to
+; turn it off or abort the host. Add a fairness count, so that
+; at least every prfair characters we look at console input.
+;
+;pcc012 4-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl
+; Use the big buffer for the log file. Move the log file back
+; into the common fcb and only save the drive, name, and
+; extension between connects. Add new routines to cp4utl to
+; create or append to an existing file, and to conditionally
+; advance buffers only if in memory. Remove edit pcc003 that
+; allows one more character after the xoff, since it didn't
+; really work very well and does not fit in well with the way
+; the buffer advancing routines are set up. If someone still
+; thinks this would be useful, it could be put back in with a
+; little more work.
+;
+; While testing this edit, I also noticed another bug that
+; the command parsing routines do not limit or check the
+; length of command lines or file specs, trashing what ever
+; comes after them. Currently because of where the fcb and
+; command buffer are located, this does not usually cause a
+; problem, but could if an extremely long line was typed in,
+; or in the future multiple fcbs defined elsewhere in memory
+; were used. Maybe this should be put on the bug list
+; somewhere.
+;
+;pcc013 8-Jan-85 vjc modules:cp4mit,cp4utl,cp4typ
+; Replace CLOSE command to cancel session logging to SET
+; LOGGING ON/OFF. This seems to fit in with the command
+; structure better. Default the log file to KERMIT.LOG
+; incase no previous LOG command. Logging is also enabled
+; by LOG command, as before.
+;
+; edit 4: September 9, 1984
+; Move command tables and associated help text to CP4MIT. Add
+; makfil/clofil routines and modify outbuf to write files in big
+; chunks. Update Kermit's version to 4.03.
+;
+; edit 3: August 21, 1984
+; Make inbuf read files in big chunks to minimize disk start/stop
+; delays. Buffer size and address is specified by system-dependent
+; overlay.
+;
+; edit 2: August 3, 1984
+; move "mover" to CP4SYS to allow use of Z80 block move instruction.
+;
+; edit 1: July 27, 1984
+; extracted from CP4MIT.M80 edit 2, as part of LASM support. This is
+; the last file linked for the system-independent code.
+;
+utlver: db 'CPSUTL.ASM (31) 21-Mar-1991$'
+
+; Set the parity for a character in A.
+; called by: spack, rexmit, logit, vt52, conchr, intchr
+
+setpar: push h ;Save HL.
+ push b
+ lxi h,parity
+ mov c,m ;Get the parity routine.
+ mvi b,0
+ lxi h,parjmp ;Get the first address.
+ dad b
+ pchl
+
+parjmp: jmp even
+ jmp mark
+ jmp none
+ jmp odd
+ jmp spacep
+
+none: jmp parret ;Don't touch the parity bit.
+
+even: ani 7FH ;Strip parity.
+ jpe parret ;Already even, leave it.
+ ori 80H ;Make it even parity.
+ jmp parret
+
+mark: ori 80H ;Turn on the parity bit.
+ jmp parret
+
+odd: ani 7FH ;Strip parity.
+ jpo parret ;Already odd, leave it.
+ ori 80H ;Make it odd parity.
+ jmp parret
+
+spacep: ani 7FH ;Turn off the parity bit.
+ jmp parret
+
+parret: pop b
+ pop h ;Restore HL.
+ ret
+;
+; Print the escape char.
+; called by: stat01, telnet, intchr
+
+escpr: lda escchr ;Get the escape char.
+escpr1: cpi ' ' ;Is it a control char?
+ jp escpr2
+ push psw ; save the character
+ lxi d,inms10 ;Output "Control-".
+ call prtstr
+ pop psw ; restore the character
+ ori 100O ;De-controlify.
+escpr2: mvi c,conout ;Output the char
+ mov e,a
+ call bdos
+ ret
+
+; fetch keyword; if unsuccessful, return to command level.
+; called by: kermit, setcom
+
+keycmd: mvi a,cmkey
+ call comnd
+ jmp keycm2 ;no match
+ ret
+
+keycm2: lxi d,ermes1 ;"Unrecognized Command"
+ call prtstr
+ jmp kermit ;Do it again.
+
+; request confirmation; if unsuccessful, return to command level
+; called by: bye, exit, help, log, setcom, show, status, send,
+; finish, logout, telnet
+
+cfmcmd: mvi a,cmcfm
+ call comnd
+ jmp kermt3 ;"Not confirmed"
+ ret
+;
+
+; This routine prints the number in HL on the screen in decimal.
+; Uses all ACs.
+; called by: cp4sys, read, send, updrtr, dir, user
+
+nout: mvi a,'0' ; fill tempx with zeros
+ call filltmp
+
+ lxi b,-10 ;Get some useful constants.
+nout1: lxi d,-1
+
+nout2: dad b ;Subtract as many 10s as possible.
+ inx d ;Count them.
+ jc nout2 ;If some left keep going.
+ push h ;save remainder - 10
+ xchg ;Swap the remainder and the quotient.
+ mov a,h ;Get the number of 10s found.
+ ora l ;check for quotient non zero
+ cnz nout1 ;If non zero, recurse.
+ pop h ;Get the remainder - 10
+ mov a,l ;in a
+ adi '0'+10 ;Make the number printable and add the 10 back
+ call shiftmp ; cycle temp registers
+ sta temp1 ; and save digit
+ mov e,a ;Output the digit.
+ lda nquiet ; are we to be quiet?
+ ana a
+ rnz ; yup, so return here rather than frm bdos
+ mvi c,conout
+ jmp bdos
+
+; prcrlf - print a CR/LF. (Saves no registers.) [Toad Hall]
+; prtstr - print string pointed to by DE (now in overlay section.. see prtstx)
+; called by: lots of places.
+prcrlf: lxi d,crlf ;Point to the CR/LF
+ jmp prtstr ; Use the one in the overlay
+
+; prtstx is funtionally the same as prtstr in the overaly but is here as
+; we may need a print a string routine in case the overlay is
+; either incorrect version or simply not present.
+prtstx: ; PRTSTR moved to overlay, but we do need the
+ ; same function for writing the sign-on
+ ; message and error message if the overlay
+ ;is not present. Thence prtstx
+ mvi c,prstr ; output string
+ jmp bdos ;a CALL followed by a RET becomes a JMP
+
+
+; Jumping to this location is like retskp. It assumes the instruction
+; after the call is a jmp addr.
+; here from: many places.
+rskp: pop h ;Get the return address.
+ inx h ;Increment by three.
+ inx h
+ inx h
+ pchl
+
+; Jumping here is the same as a ret. 'jmp r' is used after routines
+; that have skip returns, where the non-skip instruction must be 3 bytes.
+; here from: many places.
+r: ret
+
+; Pause-it routine. Informs the user to press any key to continue
+; and then waits for a key input. Called by the any routine
+; with more than, say, 20 lines of output.
+
+pausit: lxi d,anymes ; ask user to press any key to continue
+ call prtstr
+pausi1: call ckcon ; see if a key typed
+ ana a
+ jz pausi1 ; loop until a key has been pressed.
+
+ ret
+
+;
+; Open a file for reading (with inbuf). The filename is already
+; in fcb; upon return, the end of file flag is cleared and chrcnt
+; is set to zero, so inbuf will be called to get a buffer when we
+; next attempt to get a character.
+; called by: sinit, seof
+
+getfil: xra a
+ sta chrcnt ;Buffer is empty.
+ sta seccnt ;No sectors buffered.
+ sta eoflag ;Not the end of file.
+ sta endsts ;No EOF/error pending.
+ sta fcb+0CH ;Zero the extent.
+ sta fcb+0EH ;Must be zero for MAKEF or OPENF.
+ sta fcb+20H ;Zero the current record.
+ mvi c,openf ;Open the file.
+ lxi d,fcb
+ call bdos
+ ret
+
+; Get next sector. If necessary, read some more from disk.
+; preserves bc, de, hl
+; returns nonskip if EOF or error;
+; returns skip with chrcnt and bufpnt updated if success.
+; called by: gtchr, get1xc (from xmt/transmit)
+
+inbuf: lda eoflag ;Have we reached the end?
+ ora a
+ rnz ;Return if so.
+ push b
+ push d
+ push h
+inbuf1: lda seccnt ; Do we have any sectors left?
+ ora a
+ jz inbuf3 ; If not, go get some more.
+inbuf2: lhld nxtbuf ; Yes. Get address of next sector
+ shld bufpnt ; Update current buffer pointer
+ lxi b,bufsiz ; Get number of bytes in sector
+ dad b ; Update HL to point to next sector
+ shld nxtbuf ; Save for next time
+ dcr a ; Decrement count of buffered sectors
+ sta seccnt ; Put it back
+ mvi a,bufsiz-1 ; Number of bytes in buffer (pre-decremented)
+ sta chrcnt ; Store for our caller
+ pop h
+ pop d
+ pop b
+ jmp rskp ; Return success
+
+; We don't have any sectors buffered. If we've already hit an error or
+; EOF, return that status to the user.
+
+inbuf3: lda endsts ; Check status from previous read
+ ora a
+ jz inbuf4 ; It was OK. Get some more sectors.
+ sta eoflag ; End of file or error. Set the flag.
+ xra a
+ sta chrcnt ; Say no characters in buffer.
+ pop h
+ pop d
+ pop b
+ ret ; Return failure
+
+; Read sectors until we fill the buffer or get an error or EOF, then return
+; the first buffer to the user. (seccnt is zero)
+
+inbuf4: lhld bufadr ; Get address of big buffer
+ shld nxtbuf ; Store as next buffer address to give user
+inbuf5: shld bufpnt ; Store as next buffer address to read into
+ xchg ; Move buffer address to DE
+ mvi c,setdma ; Tell CP/M where to put the data
+ call bdos ; ...
+ mvi c,readf ; Read a record.
+ lxi d,fcb
+ call bdos
+ sta endsts ; Save ending status
+ ora a ; 00H => read O.K
+ jnz inbuf6 ; EOF/error: stop reading.
+ lxi h,seccnt ; Success. Get addr of sector count
+ inr m ; Bump sector count by one
+ lda bufsec ; Get max number of sectors in buffer
+ cmp m ; Are we there yet?
+ jz inbuf7 ; Yes, can't read any more.
+ lhld bufpnt ; No, try for another. Get buffer address,
+ lxi d,bufsiz ; and size of sector,
+ dad d ; giving next buffer address in HL
+ jmp inbuf5 ; Go read another sector.
+
+; We hit EOF or got an error. Put the DMA address back where it belongs,
+; then go see if we have any sectors (before the one that got the error)
+; to return to the caller. Nxtbuf points to the first good sector, if
+; any; seccnt contains the count of good sectors.
+
+inbuf6: call rstdma
+ jmp inbuf1 ; Go see if we have some data to return
+
+; We've filled the big buffer. Reset the DMA address, then go return a
+; sector to the caller. nxtbuf points to the beginning of the buffer;
+; seccnt contains the number of sectors successfully read (except that
+; if we've read 256 sectors, seccnt contains zero, so we can't just go
+; to inbuf1).
+
+inbuf7: call rstdma ;[pcc012]
+ lda seccnt ; Get sector count again.
+ jmp inbuf2 ; Return a sector.
+
+; IN1CHR - get a single character from the file. Taken code from old
+; TRANSMIT routine.
+in1chr:
+ lda eoflag ;EOF encountered?
+ ora a
+ rnz ; Yes, finish.
+ lxi d,cmdbuf ; Use comnd buffer as line buffer.
+ lhld bufpnt ; Get current buffer pointer.
+ lda chrcnt ; Get current byte count
+ mov b,a ; in B
+in1ch1: dcr b ; Assume there's a character there
+ jp in1ch2 ; If there was, proceed.
+ call inbuf ; There wasn't. Try for another buffer.
+ jmp in1che ; End of file.
+ lhld bufpnt ; Got another buffer. Get new pointer in HL
+ lda chrcnt ; and new byte count
+ mov b,a ; in B
+;[MF]The modification below was made 30-Jan-1991 per report from
+;[MF]Lance Tagliapietra from the University of Wisconsin at Platteville
+;[MF]The following instruction should not be executed as the character counter
+;[MF]has already been decremented by INBUF.
+; dcr b ; we are reading in a character, so less one
+in1ch2: mov a,b ; save new count
+ sta chrcnt
+ mov a,m ; Get a character from disk buffer.
+ inx h
+ shld bufpnt ; save new pointer
+ ani 7FH ; Mask 7 bits.
+ jz in1ch1 ; Skip nulls.
+ ret ; character in a
+
+
+in1che: mvi a,0ffh ; dubious about this one...
+ sta eoflag
+ ret ; set end of file flag...?????
+
+; ;[pcc012]
+; appfil - Create or append to an existing file. File name is in FCB.
+; Non-skip return if could not be done. Skip return with file
+; open and bufpnt pointing to end of file.
+; called by logopn
+appfil: xra a ;[pcc012] zero out stuff for open
+ sta fcb+0CH ;[pcc012] extent
+ sta fcb+0EH ;[pcc012] Must be zero for MAKEF or OPENF.
+ sta fcb+20H ;[pcc012] Zero the current record.
+ mvi c,openf ;[pcc012] Try to open the file
+ lxi d,fcb ;[pcc012]
+ call bdos ;[pcc012]
+ cpi 0FFH ;[pcc012] Did we find it?
+ jz makfi1 ;[pcc012] If not, go create it
+ mvi c,cflsz ;[pcc012] Compute the file size
+ lxi d,fcb ;[pcc012]
+ call bdos ;[pcc012]
+ lhld fcb+21H ;[pcc012] random record pointer
+ mov a,h ;[pcc012] See if zero length file
+ ora l ;[pcc012]
+ jz makfi2 ;[pcc012] set up pointers if null file
+ dcx h ;[pcc012] backup to last record written
+ shld fcb+21H ;[pcc012] store rec ptr back
+ lhld bufadr ;[pcc012] get buffer address
+ xchg ;[pcc012] to DE
+ mvi c,setdma ;[pcc012] set dma address
+ call bdos ;[pcc012] for read
+ mvi c,rrand ;[pcc012] read the last block
+ lxi d,fcb ;[pcc012]
+ call bdos ;[pcc012]
+ ora a ;[pcc012] check results
+ jnz rstdma ;[pcc012] reset dma and return if error
+ lhld bufadr ;[pcc012] get address again
+ lxi d,bufsiz ;[pcc012] and and size
+ mvi a,'Z'-40H ;[pcc012] control-Z for comparison
+appcz: cmp m ;[pcc012] Is this the EOF?
+ jz appxit ;[pcc012] Jump if yes
+ inx h ;[pcc012] no, bump
+ dcr e ;[pcc012] and grind
+ jnz appcz ;[pcc012] until find or buffer empty
+appxit: shld bufpnt ;[pcc012] store buffer pointer
+ dad d ;[pcc012] compute next buffer adr
+ shld nxtbuf ;[pcc012] and store
+ mov a,e ;[pcc012] updated chr count
+ sta chrcnt ;[pcc012]
+ xra a ;[pcc012] reset sector count
+ sta seccnt ;[pcc012]
+ call rstdma ;[pcc012] reset normal dma
+ jmp rskp ;[pcc012] and give good return
+
+; Create a file, deleting any previous version. The filename is in
+; fcb.
+; Returns nonskip if file could not be created.
+; If successful, takes skip return with bufpnt and chrcnt initialized
+; for output; buffers should be output via outbuf.
+; called by: gofil
+makfil: mvi c,delf ; delete the file if it exists.
+ lxi d,fcb
+ call bdos
+ xra a
+ sta fcb+0CH ; zero the extent.
+ sta fcb+0EH ; must be zero for MAKEF or OPENF.
+ sta fcb+20H ; zero the current record.
+;[pcc012] here from appfil above if file does not exist
+makfi1: mvi c,makef ;[pcc012] now create it.
+ lxi d,fcb
+ call bdos
+ cpi 0FFH ; is the disk full?
+ rz ; take error return if so.
+; success. set up pointers and counters for multisector buffering.
+;[pcc012] also here from appfil if found zero length file
+makfi2: lhld bufadr ;[pcc012] find beginning of buffer space.
+ shld bufpnt ; make it current buffer.
+ lxi d,bufsiz ; get sector size.
+ dad d ; find beginning of next buffer.
+ shld nxtbuf ; store for later.
+ mov a,e ; store buffer size
+ sta chrcnt ; for caller.
+ xra a
+ sta seccnt ; no sectors stored yet.
+ jmp rskp ; take success return.
+
+;[pcc012]
+; outadv - conditionally advance output buffer if disk write not needed.
+; preserves BC
+; skip return with with next output buffer set up
+; non-skip return if memory buffer full and must write to disk.
+; called by:logit
+
+outadv: push b ;[pcc012] save BC as advertised
+ lxi h,seccnt ;[pcc012] point to sectors buffered
+ inr m ;[pcc012] count this one
+ lda bufsec ;[pcc012] how many we can hold
+ cmp m ;[pcc012] check if full
+ jnz outbf2 ;[pcc012] continue if not
+ dcr m ;[pcc012] full, un-advance sector count
+ pop b ;[pcc012] restore bc
+ ret ;[pcc012] and give non-skip return
+
+; get a fresh output buffer, flushing big buffer if necessary.
+; returns nonskip if disk full.
+; if successful, returns skip with bufpnt and chrcnt updated. Note
+; that chrcnt holds one less than the buffer size.
+; preserves BC.
+; called by: ptchr,logwrt
+
+outbuf: push b
+ lxi h,seccnt ; count another buffered sector
+ inr m ; ...
+ lda bufsec ; get number of sectors we can hold
+ cmp m ; full?
+ jnz outbf2 ; if not, set up pointers and return
+ call outmbf ; flush the big buffer
+ jmp outbf9 ; disk error.
+;[pcc012] also here from outadv to advance buffer
+outbf2: lhld nxtbuf ; get pointer to fresh buffer
+ shld bufpnt ; store for caller
+ lxi d,bufsiz ; advance our pointer to next buffer
+ dad d
+ shld nxtbuf
+ mvi a,bufsiz-1 ; get buffer size (pre-decremented)
+ sta chrcnt ; store for caller
+ pop b
+ jmp rskp ; return success.
+
+outbf9: pop b ; clean up stack
+ ret ; and take error return.
+
+; flush incore output buffers.
+; returns nonskip if disk full.
+; if successful, returns skip with nxtbuf reset to start of buffer and
+; seccnt zero.
+; destroys all ac's.
+; called by: outbuf, clofil.
+
+outmbf: lhld bufadr ; get start of buffer
+ shld nxtbuf ; store for next fill cycle
+ shld bufpnt ; store for empty loop
+outmb2: lhld bufpnt ; get address of current sector
+ xchg ; into DE
+ lxi h,bufsiz ; advance HL to next sector
+ dad d ; ...
+ shld bufpnt ; and store for later
+ mvi c,setdma
+ call bdos ; point CP/M at current sector
+ lxi d,fcb
+ mvi c,writef
+ call bdos ; output the sector
+ ora a ; test for error (A non-zero)
+ jnz rstdma ;[pcc012] reset dma and take nonskip return if so
+ lxi h,seccnt
+ dcr m ; count down buffered sectors
+ jnz outmb2 ; loop if more saved
+ call rstdma ;[pcc012] restore normal dma
+ jmp rskp ; return success.
+
+; output current buffer, flush incore buffers, and close output file.
+; returns nonskip if disk full; skip if successful.
+; called by: rdata
+
+clofil:
+ lda chrcnt ; get the number of chars left in the buffer.
+ cpi bufsiz ; Virgin buffer?
+ jz clofl3 ; yes, don't output it.
+ lhld bufpnt ; get the buffer pointer.
+clofl1: dcr a ; lower the count.
+ jm clofl2 ; if full then stop.
+ mvi m,'Z'-100O ; put in a ^Z for EOF.
+ inx h ; point to the next space.
+ jmp clofl1
+
+clofl2: call outbuf ; output the last buffer.
+ jmp r ; give up if the disk is full.
+clofl3: lda seccnt ; any sectors buffered in memory?
+ ora a
+ jz clofl4 ; if not, don't try to flush.
+ call outmbf ; flush buffers
+ jmp r ; disk full.
+clofl4: mvi c,closf ; close up the file.
+ lxi d,fcb
+ call bdos
+ jmp rskp ; return success.
+
+
+; Reset DMA address to the default buffer
+; called from inbuf,appfil,outmbf
+rstdma: lxi d,buff ;[pcc012]
+ mvi c,setdma ;[pcc012]
+ jmp bdos ;[pcc012]
+
+; [8] Intercept BDOS calls to check for console input
+; This leads to simple trapping for input from disk rather than from the
+; keyboard, alowing commands to be stored in a TAKE file.
+; Printer is tested for readiness, and the second fuzzy clock is updated.
+bdos: ;call print ; print a character to the printer if needed
+ ;call clock ; update the clock
+ push psw ; we will need this register
+ lda takflg ; are we taking from a
+ ana a ; file or from command line
+ jz notake ; no, so do usual BDOS stuff
+ mov a,c ; get bdos function
+ cpi conin ; is it console in?
+ jz bd1in ; get a single character
+ cpi dconio ; direct console in or out?
+ jz bd1io ; test further for inpu or output
+ cpi rdstr ; read the console buffer?
+ jz bdcbuf ; then do it
+ cpi consta ; get the console status?
+ jz bdcst ; anything left in buffer?
+notake: pop psw ; else we have a kosher BDOS call
+ jmp 0005h ; Absolute address = BDOS entry point
+;
+bd1in: ; get a single character from take file
+ pop psw ; restore stack
+ call r1tchr ; read a single take character
+ ret ; and return. We dont expand tabs,
+ ; check for xon/off or backspaces.
+ ;Make sure the take file is error free?
+;
+bd1io: ;get or put a single character from/to console
+ mov a,e ; get e. If 0ffh then input else output
+ inr a ; if 0 then input
+ jnz notake ; its for output, so let notake restore stack
+ pop psw ; otherwise we do it
+ call r1tchr ; read a single take character
+ ret ; and return from out BDOS
+;
+bdcbuf: ; read a line of edited (?) input from the console
+ pop psw ; restore stack
+ inx d ; point to nc
+bdosc1: call r1tchr ; get a character
+ cpi cr ; if a cr then return
+ jz nomore
+ cpi lf ; ignore line feeds
+ jz bdosc1 ; so get another character
+ push psw ; we will want it later
+ mvi h,0
+ ldax d ; get nc, the no of characters in buffer
+ mov l,a ; now use as index from de+2
+ mvi h,0
+ inx d ; de is now de + 2
+ dad d
+ pop psw ; Told you we will want this
+ mov m,a
+ dcx d ; point again to nc
+ xchg ; make hl point to memory
+ inr m ; update pointer nc
+ xchg ; restore it
+ jmp bdosc1
+nomore: dcx d ; restore de to point to buffer
+ ret
+
+bdcst: ; get the console status. Returns a 00 if at eof
+ pop psw
+ push h ; now save de, hl for return
+ push d ;
+ lxi d,takdma ; make a point to next byte...
+ lhld takptr ; pointer from dma address. There will always
+ dad d ; be at least one byte, as the buffer is
+ mov a,m ; ...
+ pop d ; filled only if a read empties it.
+ pop h ; restore hl, de
+ cpi cntlz ; end of file?
+ mvi a,0ffh ; say there is
+ rnz ; if it is not a cntl z
+ jmp closet ; otherwise, close take file etc
+
+r1tchr: ; read a single character from the take file or command line
+ push h
+ push d ; save in case of return
+ lda takflg ; see if character is to come from file or line
+ ani 1 ; if bit zero set, from take file
+ jz r1lchr ; get character from the command line
+ lxi d,takdma
+ lhld takptr ; get next data byte
+ dad d
+ mov a,m
+ lhld takptr ; cos it's destroyed with dad
+ inx h
+ shld takptr ; update pointer
+ call p1tchr ; print it (so the user sees it)
+ push psw ; save the read data for a while
+ mov a,l ; if l = 0 then read another sector
+ ana a
+ jp r1tch1 ;[23] was jnz. jp => 128 byte sectors
+ call rnsect ;read next sector
+r1tch1: pop psw ; now, is this a cntl-z.. in whic case
+ pop d ; also these...
+ pop h
+ cpi lf ; skip if a line feed
+ jz r1tchr ;
+;[MF][31][30]Following lines commented out so semicolons are not considered
+;[MF][31][30]command separators and thus are considered part of the command
+;[MF][31][30]so commands like REMOTE DELETE *.*;* work correctly.
+; cpi semico ; see if its a semicolon
+; jnz r1tch2 ; no, ignore it
+; mvi a,cr ; else say its a cr (in case of command lines)
+r1tch2: cpi cntlz ; end of file??
+ rnz
+
+
+c1tchr: call closet ; close file etc, then
+ mvi a,cr ; fake a carriage return chr
+ ; ( => clears kermit comnd line)
+c1tch1: ret ; and hope that editing etc not required.
+
+r1lchr: ; read a single character from the command line
+ lxi d,cbuff ; point to buffer
+ lda cbptr ; get pointer for next character
+ mov l,a
+ lda cbuff ; get total number of characters there
+ cmp l ; ... less current character
+ jp r1lch1 ; if positive, we have more characters
+ lda takflg ; no more, so reset command line bit (bit 4)
+ ani 0efh
+ sta takflg
+ mvi a,cntlz ; fudge an end of file
+ push psw ; save for common exit (r1tch1)
+ jmp r1tch1
+;
+r1lch1: mov a,l ; get count back again
+ mvi h,0
+ dad d ; get offset to character
+ inr a
+ sta cbptr
+ mov a,m ; get next character
+ cpi semico ; if a semicolon, make it a carriage return
+ jnz r1lch2
+ mvi a,cr
+r1lch2: call p1tchr ; send a copy to the console
+ push psw ; save it for r1tch1
+ jmp r1tch1 ; common exit
+
+
+; rnsect - read the next take sector from disk to the take dma address
+; if there is no more then close the file too
+rnsect: push b
+ push d
+ push h ; save in case we need these later
+ mvi c,setdma
+ lxi d,takdma ; set a next read from disk
+ call bdos ; recursive...
+ mvi c,readf
+ lxi d,takfcb
+ call bdos
+ ana a
+ cnz closet ; if returned value not zero, assume eof
+ lxi h,0
+ shld takptr ; pointer restored
+ call rstdma ; reset the dma address for fussy routines (this one)
+ pop h
+ pop d
+ pop b
+ ret
+
+; closet - close the take file and set the take flag to 0 (ie no takes)
+;
+closet: lda takflg ; reset the take file bit (bit 0)
+ ani 0feh
+ sta takflg ; close the take file, and restore the flag
+ mvi c,closf
+ lxi d,takfcb
+ call bdos
+ call rstdma ; in case we did not do it above, reset dma
+ ret
+
+;
+; clock - is a 32 bit counter incremented every BDOS call. It serves as a
+; timer of sorts and allows a background clock to tick away..
+clock: push psw ; we need flags and hl
+ push h
+ lhld clkbit ; get the counter
+ inx h ;
+ shld clkbit
+ mov a,h
+ ora l ; do we need to update the next lot of clock bits?
+ jnz clockx
+ lhld clkbit+2 ; if carry up the top 16 bits
+ inx h
+ shld clkbit+2
+clockx: pop h
+ pop psw
+ ret
+
+; p1tchr - print a character in accumulator directly to the console
+; bypassing the bdos trap above.
+
+p1tchr: cpi lf ; if a lf ignore it
+ jz p1tchx
+ cpi cr ; ditto carriage returns
+ jz p1tchx
+ cpi cntlz ; control z
+ jz p1tchx ; then dont write it out
+ push psw ; we do not want to loose it, do we?
+ push b
+ push d
+ push h ; 'cos you never know what bdos does...
+ mov e,a
+ mvi c,conout ; direct console io
+ call 5 ; absolute address as we skip the trap
+ pop h
+ pop d
+ pop b ; ... and we need some of these regs.
+ pop psw ;
+p1tchx: ret ; and return
+
+
+
+; outprn - This routine sends charactes to the printer if the latter is ready,
+; or to a buffer if the printer is not ready. If the buffer is nearly
+; full, an XOFF is sent to the host, asking it to be quiet. The buffer
+; is emptied by a series of calls in the connect state only.
+; If the buffer is made nearly empty, then an XON is sent to the host.
+;
+outprn: mov a,e ; get the character to send back to a
+ sta prntmp ; we need all registers.
+ jmp outprx ; -testing-testing-testing- avoid buffer
+;
+outp0: call tstfree ; see how many spaces free
+ cpi 2 ; (free spaces in a on return)
+ jp outp1 ; enough free spaces, so keep going
+ call print ; else see if we can print summat
+ jmp outp0 ; and try again
+;
+outp1: cpi 4 ; common test - if three or less then send xoff
+ cm sndxoff
+outpr2: mov a,b ; inc ptr and check for wrap around
+ call wrapt
+ mov b,a ; input pointer to b
+ sta prnbuf+1 ; save the new pointer away
+ lxi h,prnbuf+2 ; point to first real data entry in buffer
+ call inchl ; add offset in a to hl
+ lda prntmp ; get th character to save away
+ mov m,a ; save the data away
+ ret
+
+; outprx - send character in a to the printer. (We have checked to see if
+; the printer is ready)
+; called by outprn, print
+outprx: mov e,a ; character has to be in e register
+ call outlpt ; send it to printer
+ ret ; assume we print it
+
+; TSTFREE - see how many free spacse there are in the buffer
+; - returns with free space in a, ip pointer in b, op pointer in c
+szecyc equ 127 ; 128 bytes in buffer (less for debugging)
+;
+tstfree:
+ lda prnbuf ; get output pointer
+ mov c,a ;.. to c
+ lda prnbuf+1 ; and input pointer ...
+ mov b,a ; ... to b
+;
+;
+; Now comes the tricky bit. We must establish whether there is less than
+; three characters left in the buffer. There are two conditions to test for
+; 1) the input pointer is a higher value than the output pointer
+; 2) the input pointer has been wrapped round and is less than the output pointer
+; ie
+; |-------|-------|---------------------------------------------|
+; Buffer |o/p ptr|i/p ptr| Buffer proper filling ---> |
+; |-------|-------|------|-------------|-----------|------------|
+; i/p2 o/p i/p1
+;
+; If ip = ip1 then if
+; (size of buffer - ip ptr + op ptr) < 3 send xoff
+; If ip = ip2 then if
+; (op ptr - input ptr ) < 3 send xoff
+;
+; First decide whice one applies
+
+ mov a,b ; get ip ptr
+ sub c ; see if op ptr > ip ptr (case 2)
+ jm outp2 ; yup, so do case two
+ mvi a,szecyc ; else do buffer - ip + op
+ sub b
+ add c
+ jmp outpx ; do common test
+outp2: mov a,c ; get op pointer
+ sub b ; less input pointer
+outpx: ret ; with free space in a
+;
+;
+;
+; print - get a character from the buffer and print it if the printer
+; is ready for it. If the buffer clears more than 3 spare characters
+; and an xoff has been sent, then send an xon again.
+print: push h ; save for rainy days
+ push d
+ push b
+ push psw ; .. as we may need flags etc....
+ lda initflg ; First check if the system has initialised
+ ana a
+ jz printx ; If system not set up then skip
+; nop
+; nop
+; nop ; debugging only...
+ call ckprtr ; check to see if printer is ready...
+ ana a ; not zero => ok
+ jz printx ; else skipit.
+; nop
+; nop
+; nop ; skip the jump for debugging
+ lxi h,prnbuf
+ mov a,m ; get input pointer
+ inx h ; test against output pointer
+ cmp m ; if = then buffer empty
+ jz printx ; so quit
+ dcx h ;pointer to output pointer
+ call wrapt ; check for wrap around
+ sta prnbuf ; save new pointer
+ inx h
+ inx h ;
+ call inchl ; add output pointer to hl
+ mov c,m ; get byte
+ lda hosths ; have we told host to be quiet?
+ cpi xoff ; if = xoff then we have
+ jnz print1 ; nope, so just print it..
+ push b ; save the character to print
+ call tstfree ; see how many free bytes in buffer
+ pop b
+ cpi 4 ; 3 characters left?
+ jz printx
+ push b
+ call sndxon ; send an xon to host and wake it up.
+ pop b
+print1: mov a,c ; we are gonna print a character, so ...
+ call outprx ; get it to a (as required by outprx) and print it
+printx:
+ pop psw
+ pop b
+ pop d
+ pop h ; restore regs.
+ ret
+
+;
+; Utilities for the cyclical buffer. Returns a 0ffh if printer ready,
+; else 0h. Called by outprn, print
+
+ckprtr:
+ call lptstat ; no registers saved
+; mvi a,0 ; FOR DEBUGGING PURPOSES
+; nop
+ ret
+;
+
+inchl: push psw ; we do maths through this register
+ add l
+ mov l,a
+ mvi a,0
+ adc h
+ mov h,a
+ pop psw ; hl = a + hl
+ ret
+
+; wrapt - checks the offset in a with the limits of the buffer.
+; returns next address or if wrap around then 0 (start of buffer)
+wrapt: push b
+ inr a
+ mov b,a ; save new a into b for now
+ mvi a,szecyc ; test for size of buffer
+ sub b
+ mov a,b
+ pop b ; restore bc regs again
+ rnz
+ xra a ; if wrap around, then reset pointer
+ ret ; return with next address pointer to in a
+
+; sndxoff - send an xoff to the host and save the xoff character in hosths
+; saves all regs. is called by logwrt, outprn
+sndxoff:
+ push psw
+ push b
+ push d
+ push h ; some calling routines may be sensitive...
+ lda floctl ; are we doing flow control?
+ ana a
+ jz sndxf ; no, so dont bother.
+ mvi a,xoff ;^S to stop the host while we write the buffer.
+ sta hosths ; save it so we know we have sent it
+ call setpar ; set correct parity...
+ mov e,a
+ call outmdm ; output it.
+ lxi d,ofsnt ; say we have sent an xoff
+ call prtstr
+sndxf: pop h
+ pop d
+ pop b
+ pop psw ; some routines touchy
+ ret
+ofsnt: db cr,lf,'[XOFF sent to host]',cr,lf,'$'
+
+; sndxon - send an xon to the host and clear the hosths flag. saves everything
+; called by logwrt, print
+sndxon: push psw
+ push b
+ push d
+ push h
+ lda floctl ; are we doing flow control?
+ ana a
+ jz sndxn
+ xra a
+ sta hosths ; no xoff to hos any more
+ mvi a,xon ;^Q to restart the host
+ call setpar ; set appropriate parity
+ mov e,a
+ call outmdm ; send it.
+ lxi d,onsnt
+ call prtstr ; say xon sent to host...
+sndxn: pop h
+ pop d
+ pop b
+ pop psw
+ ret ; shame we dont do a pushall/popall subroutine...
+onsnt: db cr,lf,'[XON sent to host]',cr,lf,'$'
+;
+; Routines to clear (or rather fill) TEMPnnn space with the data in A
+; and to shift it all along one (filltmp an shiftmp respectively)
+filltmp:
+ push b
+ push d
+ push h ; save all
+ lxi h,temp1
+ mvi b,10 ; ten locations to fill
+fillp: mov m,a
+ inx h
+ dcr b ; loop til all done
+ jnz fillp
+ pop h
+ pop d
+ pop b ; restore all
+ ret
+
+shiftmp:
+ push psw ; save all again
+ push b
+ push d
+ push h
+ lxi d,temp9
+ lxi h,temp10
+ mvi b,9 ; shift nine times
+shiftl: ldax d ; from tempx
+ mov m,a ; to tempx+1
+ dcx d
+ dcx h ; mover does not work as that increments
+ dcr b
+ jnz shiftl
+ pop h
+ pop d
+ pop b
+ pop psw
+ ret ; else all done
+
+; getun - get the user number to temp1 (lsd) and temp2 (msd)
+;
+getun: mvi a,0ffh ; tell nout to be quiet
+ sta nquiet
+ mvi c,usrcod
+ mvi e,0ffh ; get current user from bdos
+ call bdos
+ mov l,a ; put into hl
+ mvi h,0
+ call nout ; decimalise it (decimalise???)
+ xra a
+ sta nquiet ; let nout print again
+ ret
+
+; ckcon - Do a direct console IO (read) to see if there is any input
+; returns with a=0 (no input) or character (input received)
+; Assume that all regs may be destroy.
+ckcon: mvi e,0ffh ; direct console input
+ mvi c,dconio
+ call bdos
+ ret ; and return with wahtever returned in a
+
+
+
+;
+; subbc - Subtract the unsigned number in bc from the unsigned number
+; in HL with the answer in HL. Flags altered, all
+; other registers left intact.
+subbc: sta temp1 ; hl = hl - bc.. we need the accumulator
+ mov a,l
+ sub c
+ mov l,a
+ mov a,h
+ sbb b
+ mov h,a
+ lda temp1 ; restore loop counter but not flags
+ ret
+
+; P20LN - Routine to print a string at (DE) and count the number of
+; line feeds. Pause after 20 lines printed.
+p20ln: xra a ; clear the line counter
+ sta lincnt
+p20ln1: ldax d ; get character to print
+ inx d
+ cpi '$' ; if a dollar we have done
+ rz
+ push d
+ push psw ; save pointer and character to print
+ mov e,a
+ call outcon ; send character
+ pop psw
+ pop d ; restore pointers etc
+ cpi lf ; was that last character a line feed?
+ jnz p20ln1 ; no, so carry on
+ lda lincnt ; yup, so update counter
+ inr a
+ sta lincnt
+ cpi 20 ; 20 lines printed?
+ jnz p20ln1 ; not yet
+ push d ; we need DE
+; lxi d,anymes ; pause a while [MF]removed
+; call prtstr ; write the message [MF]
+;p20ln2: call ckcon ; wait for any input [MF]
+; ana a ;[MF]
+; jz p20ln2 ;[MF]
+ call pausit ;[MF] pause a while
+ pop d
+ jmp p20ln ; and continue
+
+
+; Little code to allow some expansion of code without changing
+; every futher address, only up to the end of this file.
+; TO BE REMOVED FOR RELEASE!
+
+; org ($+100h) AND 0FF00H
+
+; link to the data area (was part of CPSUTL.ASM)
+
+IF lasm
+ LINK CPSDAT
+ENDIF ;lasm
diff --git a/cpswld.asm b/cpswld.asm
index 8be6558..1accb42 100644
--- a/cpswld.asm
+++ b/cpswld.asm
@@ -1,222 +1,222 @@
-; CPSWLD.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; Multi-file access subroutine. Allows processing of multiple files
-; (i.e., *.ASM) from disk. This routine builds the proper name in the
-; FCB each time it is called. This command would be used in such pro-
-; grams such as modem transfer, tape save, etc. in which you want to
-; process single or multiple files.
-; Note that it will fail if more than 256 entries match the wildcard.
-;
-; revision history:
-; edit 4: June 20, 1986, by OBSchou. Added stuff at top and tail of routine
-; to support multiple FCBs. If the routine get to mfn01 (Search for next)
-; then the next file found gets its fcb added to the buffer. Once no
-; more files have been found, the mfflg3 flag is set non-zero.
-; The first thing to test on entry is whether a disk access
-; is needed. Either way, the routine should return the next file name
-; in the fcb, or return with the carry flag set if there are no more
-; files to do. Once there is a carry flag set for the return, all
-; temporary flags are reset. Get all that?
-;
-; edit 3: July 27, 1984
-; support LASM: remove exclamation points, link to CP4CMD.
-;
-; edit 2: June 7, 1984 (CJC)
-; formatting and documentation; add module version string; redo movfcb,
-; in preparation for moving DMA buffer (later...).
-;
-; edit 1: May, 1984 (CJC)
-; extracted from CPMBASE.M80 version 3.9; modifications are described
-; in the accompanying .UPD file.
-;
-wldver: db 'CPSWLD.ASM (4) 20-Jun-86$'
-
-; The FCB will be set up with the next name, ready to do normal
-; processing (OPEN, READ, etc.) when routine is called.
-;
-; Carry is set if no more names can be found
-;
-; MFFLG1 is count/switch [0 for first time thru, pos for all others]
-; MFFLG2 is counted down for each successive GETNEXT file call
-; MFFLG3 is set to the last remaining FCBs buffered once Search for next
-; file fails with files in the buffer.
-;
-; Technique used is to repeat SFIRST/SNEXT sequence N+1 times for each
-; successive call, till sequence fails. CP/M does NOT allow disk-handling
-; between SFIRST and SNEXT.
-; called by: send, seof, dir
-
-mfname: ora a ; clear carry
- push b ;Save registers
- push d
- push h
- jmp mfnam0 ; skip over the next bit (which is entered from elsewhere)
-
-;[4] Get the FCB counter and see if we have any fcbs already.
-mfnam1: lxi h,fcb0
- shld xfcbptr ; reset the pointer if we are to return an FCB
-
-mfnam0: lda fcbcnt
- ana a ; if none, then we may have to get some from disk
- jz mfn00 ; see later on
- lhld xfcbptr ; we have some, so give the next one to the user
- lxi d,fcb ; move from (hl) to (de) for length bc
- lxi b,12
- call mover
- xra a
- sta fcbext ; clear fcb extents and such
- sta fcbrno ; like record number
- lhld xfcbptr ; point to next fcb
- lxi d,fcblen
- dad d ; yup
- shld xfcbptr
- lda fcbcnt
- dcr a
- sta fcbcnt ; decrease the number of fcbs we have
- xra a ; clear carry
- jmp mffix1 ; and exit as if were all done
-
-mfn00: lda mfflg3 ; no more FCBs for the user, any more on disk?
- ana a
- jnz mffix2 ; no, then set the carry flag to say so.
- lxi h,fcb0 ; now reset the fcb pointers and counter
- shld xfcbptr
- xra a
- sta fcbcnt
-;[4] end of this addition. See below as well.
-
-
- mvi c,setdma ;Init DMA addr, FCB
- lxi d,80H
- call bdos
- xra a ;A = 0
- sta fcbext ;clear extension
- lda mfflg1 ;find out if "second" call in row
- ora a
- jnz mfn01 ;Were here before
- sta mfflg2
- lxi h,fcb
- lxi d,mfreq
- lxi b,12
- call mover ;.from FCB to MFREQ
- mvi c,SFIRST ;Search first
- lxi d,fcb
- call bdos
- jmp mfn02 ;and check results
-
-mfn01: dcr a
- sta mfflg2 ;store down-counter
- lxi h,mfreq ;SFIRST REQ name
- lxi d,fcb
- lxi b,12
- call mover ;.from MFREQ to FCB
- mvi c,sfirst ;Search first old one,we got it before
- lxi d,fcb
- call bdos ;no error's expected -we got that before
-mfn01a:
- mvi c,snext ;Search next
- call bdos
-mfn02: push psw
- lda mfflg2 ;get "repeat file counter"
- ora a
- jz mfn02a ;if zero, check if SNEXT had ERROR
- dcr a ;count down
- sta mfflg2 ;store back
- pop psw ;no error-check, we got it before
- jmp mfn01a ;next SNEXT
-
-mfn02a: pop psw
- ora a
- jm mffi2a ;No (more) found
- call movfcb ;move data to fcb
- lda mfreq ;the original disk-designator
- sta fcb ;back into fcb
- lda mfflg1 ;get file-flag
- inr a ;increment
- sta mfflg1 ;and store for next go-around
- mvi a,0 ;Setup FCB
- sta fcbext ;clean up FCB for OPEN etc
- sta fcbrno
- lhld xfcbptr ;[4] like here
- xchg
- lxi h,fcb ;[4] from fcb space
- lxi b,12
- call mover
- lhld xfcbptr ;[4] now lets update the pointers
- lxi d,fcblen
- dad d
- shld xfcbptr ;[4] new pointer
- lda fcbcnt ;[4] now the fcb counter
- inr a
- sta fcbcnt
- cpi maxfcb ;[4] any more spare space?
- jp mfnam1 ;[4] nope, so get first fcb and return
- lxi d,fcb ; else restore the file to serach for
- lxi h,mfreq
- lxi b,12 ; copy the original fcb to fcb
- call mover
- jmp mfn01a ; and look for next match.
-
-mffix1: pop h ;restore registers
- pop d
- pop b
- ret ;and return
-
-mffi2a:
- sta mfflg3 ;[4] no more FCBs from disks to be had, but
- lda fcbcnt ;[4]we have some in the buffer, havet we?
- ana a
- jnz mfnam1 ;[4] yes, so all's ok. Get an fcb and return,
-
-mffix2: xra a
- sta mfflg3 ;[4] clear the new flag (=no more fcbs at all)
- sta mfflg2 ;[4] may as well do the others, as we're not comming again
- sta mfflg1 ;[4]
- stc ;set carry
- jmp mffix1 ;return with CARRY set
-
-; copy directory entry to FCB
-; called with A/ entry number in directory (0-3)
-; directory block in DMA buffer (buff)
-
-movfcb: add a
- add a
- add a
- add a
- add a ;* 32
- mov c,a ; copy offset to bc
- mvi b,0 ; (high byte is zero)
- lxi h,buff ; get start of disk buffer
- dad b ; calculate start of directory entry
- lxi d,fcb
- lxi b,12
- call mover
- ret
-
-; Data storage for MFNAME (multi-file access)
-mfreq: DS 12 ;Requested name
-mfflg1: DB 0 ;First time thru flag for MFNAME
-mfflg2: DB 0 ;Down counter for MFNAME
-mfflg3: DB 0 ;[4] Non zero if no more FCBs from disk,
- ;[4] but we still have some in buffer
-;
-IF lasm
- LINK CPSCMD
-ENDIF;lasm
-
+; CPSWLD.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; Multi-file access subroutine. Allows processing of multiple files
+; (i.e., *.ASM) from disk. This routine builds the proper name in the
+; FCB each time it is called. This command would be used in such pro-
+; grams such as modem transfer, tape save, etc. in which you want to
+; process single or multiple files.
+; Note that it will fail if more than 256 entries match the wildcard.
+;
+; revision history:
+; edit 4: June 20, 1986, by OBSchou. Added stuff at top and tail of routine
+; to support multiple FCBs. If the routine get to mfn01 (Search for next)
+; then the next file found gets its fcb added to the buffer. Once no
+; more files have been found, the mfflg3 flag is set non-zero.
+; The first thing to test on entry is whether a disk access
+; is needed. Either way, the routine should return the next file name
+; in the fcb, or return with the carry flag set if there are no more
+; files to do. Once there is a carry flag set for the return, all
+; temporary flags are reset. Get all that?
+;
+; edit 3: July 27, 1984
+; support LASM: remove exclamation points, link to CP4CMD.
+;
+; edit 2: June 7, 1984 (CJC)
+; formatting and documentation; add module version string; redo movfcb,
+; in preparation for moving DMA buffer (later...).
+;
+; edit 1: May, 1984 (CJC)
+; extracted from CPMBASE.M80 version 3.9; modifications are described
+; in the accompanying .UPD file.
+;
+wldver: db 'CPSWLD.ASM (4) 20-Jun-86$'
+
+; The FCB will be set up with the next name, ready to do normal
+; processing (OPEN, READ, etc.) when routine is called.
+;
+; Carry is set if no more names can be found
+;
+; MFFLG1 is count/switch [0 for first time thru, pos for all others]
+; MFFLG2 is counted down for each successive GETNEXT file call
+; MFFLG3 is set to the last remaining FCBs buffered once Search for next
+; file fails with files in the buffer.
+;
+; Technique used is to repeat SFIRST/SNEXT sequence N+1 times for each
+; successive call, till sequence fails. CP/M does NOT allow disk-handling
+; between SFIRST and SNEXT.
+; called by: send, seof, dir
+
+mfname: ora a ; clear carry
+ push b ;Save registers
+ push d
+ push h
+ jmp mfnam0 ; skip over the next bit (which is entered from elsewhere)
+
+;[4] Get the FCB counter and see if we have any fcbs already.
+mfnam1: lxi h,fcb0
+ shld xfcbptr ; reset the pointer if we are to return an FCB
+
+mfnam0: lda fcbcnt
+ ana a ; if none, then we may have to get some from disk
+ jz mfn00 ; see later on
+ lhld xfcbptr ; we have some, so give the next one to the user
+ lxi d,fcb ; move from (hl) to (de) for length bc
+ lxi b,12
+ call mover
+ xra a
+ sta fcbext ; clear fcb extents and such
+ sta fcbrno ; like record number
+ lhld xfcbptr ; point to next fcb
+ lxi d,fcblen
+ dad d ; yup
+ shld xfcbptr
+ lda fcbcnt
+ dcr a
+ sta fcbcnt ; decrease the number of fcbs we have
+ xra a ; clear carry
+ jmp mffix1 ; and exit as if were all done
+
+mfn00: lda mfflg3 ; no more FCBs for the user, any more on disk?
+ ana a
+ jnz mffix2 ; no, then set the carry flag to say so.
+ lxi h,fcb0 ; now reset the fcb pointers and counter
+ shld xfcbptr
+ xra a
+ sta fcbcnt
+;[4] end of this addition. See below as well.
+
+
+ mvi c,setdma ;Init DMA addr, FCB
+ lxi d,80H
+ call bdos
+ xra a ;A = 0
+ sta fcbext ;clear extension
+ lda mfflg1 ;find out if "second" call in row
+ ora a
+ jnz mfn01 ;Were here before
+ sta mfflg2
+ lxi h,fcb
+ lxi d,mfreq
+ lxi b,12
+ call mover ;.from FCB to MFREQ
+ mvi c,SFIRST ;Search first
+ lxi d,fcb
+ call bdos
+ jmp mfn02 ;and check results
+
+mfn01: dcr a
+ sta mfflg2 ;store down-counter
+ lxi h,mfreq ;SFIRST REQ name
+ lxi d,fcb
+ lxi b,12
+ call mover ;.from MFREQ to FCB
+ mvi c,sfirst ;Search first old one,we got it before
+ lxi d,fcb
+ call bdos ;no error's expected -we got that before
+mfn01a:
+ mvi c,snext ;Search next
+ call bdos
+mfn02: push psw
+ lda mfflg2 ;get "repeat file counter"
+ ora a
+ jz mfn02a ;if zero, check if SNEXT had ERROR
+ dcr a ;count down
+ sta mfflg2 ;store back
+ pop psw ;no error-check, we got it before
+ jmp mfn01a ;next SNEXT
+
+mfn02a: pop psw
+ ora a
+ jm mffi2a ;No (more) found
+ call movfcb ;move data to fcb
+ lda mfreq ;the original disk-designator
+ sta fcb ;back into fcb
+ lda mfflg1 ;get file-flag
+ inr a ;increment
+ sta mfflg1 ;and store for next go-around
+ mvi a,0 ;Setup FCB
+ sta fcbext ;clean up FCB for OPEN etc
+ sta fcbrno
+ lhld xfcbptr ;[4] like here
+ xchg
+ lxi h,fcb ;[4] from fcb space
+ lxi b,12
+ call mover
+ lhld xfcbptr ;[4] now lets update the pointers
+ lxi d,fcblen
+ dad d
+ shld xfcbptr ;[4] new pointer
+ lda fcbcnt ;[4] now the fcb counter
+ inr a
+ sta fcbcnt
+ cpi maxfcb ;[4] any more spare space?
+ jp mfnam1 ;[4] nope, so get first fcb and return
+ lxi d,fcb ; else restore the file to serach for
+ lxi h,mfreq
+ lxi b,12 ; copy the original fcb to fcb
+ call mover
+ jmp mfn01a ; and look for next match.
+
+mffix1: pop h ;restore registers
+ pop d
+ pop b
+ ret ;and return
+
+mffi2a:
+ sta mfflg3 ;[4] no more FCBs from disks to be had, but
+ lda fcbcnt ;[4]we have some in the buffer, havet we?
+ ana a
+ jnz mfnam1 ;[4] yes, so all's ok. Get an fcb and return,
+
+mffix2: xra a
+ sta mfflg3 ;[4] clear the new flag (=no more fcbs at all)
+ sta mfflg2 ;[4] may as well do the others, as we're not comming again
+ sta mfflg1 ;[4]
+ stc ;set carry
+ jmp mffix1 ;return with CARRY set
+
+; copy directory entry to FCB
+; called with A/ entry number in directory (0-3)
+; directory block in DMA buffer (buff)
+
+movfcb: add a
+ add a
+ add a
+ add a
+ add a ;* 32
+ mov c,a ; copy offset to bc
+ mvi b,0 ; (high byte is zero)
+ lxi h,buff ; get start of disk buffer
+ dad b ; calculate start of directory entry
+ lxi d,fcb
+ lxi b,12
+ call mover
+ ret
+
+; Data storage for MFNAME (multi-file access)
+mfreq: DS 12 ;Requested name
+mfflg1: DB 0 ;First time thru flag for MFNAME
+mfflg2: DB 0 ;Down counter for MFNAME
+mfflg3: DB 0 ;[4] Non zero if no more FCBs from disk,
+ ;[4] but we still have some in buffer
+;
+IF lasm
+ LINK CPSCMD
+ENDIF;lasm
+
diff --git a/cpxapp.asm b/cpxapp.asm
index be4abd5..434e440 100644
--- a/cpxapp.asm
+++ b/cpxapp.asm
@@ -1,749 +1,749 @@
-IF NOT lasm
-.printx * CPXAPP.ASM *
-ENDIF ;NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the system-dependent code and data for KERMIT.
-; It will be probably be broken into independent files to generate
-; overlays for the various systems, one or more overlay possible
-; from each file. For now, we will leave it in one piece.
-;
-; revision history:
-; edit 2, 22 July, 1987 by OBSchou. Massaged code to work with CPXCOM.ASM
-;
-; edit 1, 2nd June, 1987 by OBSchou. Extracted all Apple related code.
-;
-;
-; Family is the string used in VERSION to say which of several
-; smaller overlay files are used. These are (will be) derived from
-; the juge CPXSYS.ASM file, in which case we will never get here.
-; Just a Dollar, but put a sting in for a family of machines.
-;
-family: db 'CPXAPP.ASM (2) 22-jul-87$' ; Used for family versions....
-;
-
-IF apple
-.printx * Assembling KERMIT-80 for the Apple ][ *
-ENDIF;apple
-IF apmmdm
-.printx * with Z80 Softcard & Micromodem II *
-ENDIF;apmmdm
-IF ap6551
-.printx * with Z80 Softcard & 6551 ACIA *
-ENDIF;ap6551
-IF ap6850;[32]
-.printx * with Z80 Softcard & 6850 ACIA *
-ENDIF;ap6850 [32]
-IF apcps;[22]
-.printx * with Softcard & CPS Multifunction card *
-ENDIF;apcps
-
-;
-
-IF ap6551 OR ap6850 OR apcps;[9] [14]
- ;jb eg. Apple SSC, Videx PSIO, Basis 108
-apslot EQU 2 ;jb set equal to slot containing serial card
- ;jb set to 1 for Basis built-in port
-ENDIF;jb ap6551 [9] apcps ap6850 [14]
-IF ap6850 ;[14] offset in slot I/O space for ACIA registers
- ;e.g. PACT=00,01: AIO-I=05,04: AIO-II=0D,0C: Aristocard=0B,0A
-apdat EQU 0DH ;data reg.=0E080h+apslot*10h*apdat
-apstat EQU 0CH ;comm/stat reg.=0E080h+apslot*10h+apstat
-ENDIF;ap6850
-
-
-IF apmmdm
-;APPLE Slot 2 contains Micromodem II.
-MNPORT EQU 0E0A7H ;Communications Port.
-mnprts EQU 0E0A6H ;Communications Port Status.
-mnmodm EQU 0E0A5H ;Modem Control Port.
-orgmod EQU 8EH ;Modem Originate Mode.
-OUTPUT EQU 02H ;Output Buffer Empty.
-INPUT EQU 01H ;Input Register Full.
-apinc1 EQU 03H ;First Init Character for 6850 ACIA (Reset)
-apinc2 EQU 11H ;Second Init Character for ACIA (8-bits)
-apoffh EQU 80H ;Set if OFFHOOK
-AP300 EQU 1 ;300 Baud
-z80 EQU TRUE ;Z80 Softcard
-ENDIF;apmmdm
-
-IF ap6551 ;jb
-mnport EQU 0E088H+(10H*apslot) ;jb Communications Port.
-mnprts EQU 0E089H+(10H*apslot) ;jb Communications Port Status.
-mnprtc EQU 0E08BH+(10H*apslot) ;jb Communications Control
-mnprtm EQU 0E08AH+(10H*apslot) ;jb Communications Master (command)
-output EQU 10H ;jb Output Buffer Empty.
-input EQU 08H ;jb Input Register Full.
-mncinb EQU 18H ;jb Control Port Initialization Byte
- ;jb (8-bit, no parity, 1-stop, 1200 baud)
-mnminb EQU 0BH ;jb Master Port Initialization Byte
- ;jb (DTR, RTS, no interrupts)
-z80 EQU TRUE ;Z80 Softcard
-ENDIF;ap6551
-
-IF ap6850 ;[32]
-mnport EQU 0E080H+(10H*apslot)+apdat ;Communications Port.
-mnprts EQU 0E080H+(10H*apslot)+apstat ;Communications Port Status.
-OUTPUT EQU 02H ;Output Buffer Empty.
-INPUT EQU 01H ;Input Register Full.
-apinc1 EQU 03H ;First Init Character for 6850 ACIA (Reset)
-apinc2 EQU 15H ;Second Init Character for ACIA (8 data, 1 stop bit)
-z80 EQU TRUE ;Z80 Softcard
-ENDIF;[32] ap6850
-
-IF apcps ;[22]
-mnport EQU 0E0FAH+(100H*apslot) ; Communications Port.
-mnprts EQU 0E0FBH+(100H*apslot) ; Communications Port Status.
-mnprtc EQU 0E0FEH+(100H*apslot) ; Communications Control
-output EQU 1 ; Output Buffer Empty.
-input EQU 2 ; Input Register Full.
-TxEmpty EQU 04h ; Transmitter empty flag
-apmod1 EQU 4EH ; Mode Byte 1 (1 stop, no parity,8-bit, 16x)
- ; Mode Byte 2 is speed control byte
-apcmd EQU 37H ; Command Byte (RTS,Error reset,RxE,DTR,TxE)
-z80 EQU TRUE ;Z80 Softcard
-ENDIF;[22] apcps
-
-IF apple
-defesc EQU ']'-100O ;The default escape character.
-ENDIF;apple
-
-
-; default to VT52-EMULATION ON.
-
-vtval EQU 1
-
-
-
-sysxin: ; continuation of systemm dependent initialisation code
-
-IF ap6551
- lda mnprtc ; read control port
- ani 0fH ; extract low order nybble
- sta speed ; store as comm line speed
- sta speed+1 ; (16 bits, to match speed table entries)
- mvi a,mnminb ;jb initialization routine
- sta mnprts ;jb
- sta mnprtm ;jb initialize master (command) port
- mvi a,mncinb ;jb
- sta mnprtc ;jb initialize control port
-ENDIF;ap6551
-
-IF ap6850 ;[32]
- mvi a,apinc1 ;Init ACIA
- sta mnprts
- mvi a,apinc2 ;Set ACIA bits per character
- sta mnprts
-ENDIF;[32] ap6850
-
-IF apcps ;[22]
- lxi h,3737h ;Default 1200 baud
- shld speed ;Store as port speed
- xchg
- call sysspd ;Initialise the port
-ENDIF;[22] apcps
-
- ret ; return from system-dependent routine
-
-;
-
-;
-; system-dependent termination processing
-; If we've changed anything, this is our last chance to put it back.
-sysexit:
-
- ret
-
-;
-; system-dependent processing for start of CONNECT command
-;
-syscon:
-IF apmmdm
- call ckdial ;See if dialing is required.
- jmp kermit ;Go to command loop if aborted.
-ENDIF;apmmdm
-
- ret
-
-conmsg: ; Messages printed when entering transparent (CONNECT) mode:
-;
-
-IF apmmdm
-;This code was mostly taken from
-; APMODEM.ASM V2.1
-; Based on MODEM.ASM by Ward Christensen
-; Modified for the Apple ][ by Gordon Banks 1-Jan-81
-; Micromodem ][ dialer option by Dav Holle 2-Feb-81
-; Code modified for KERMIT by Scott Robinson 14-Oct-82
-;
-;Come here to see if we need to dial a number.
-;
-ckdial: lda mnport ;access the data port
- lda mnprts ;check status
- ani 4 ;do we already have carrier?
- jz rskp ;Yes, just continue
- xra a ;Hangup Phone for starters
- sta mnmodm
- lxi b,1000 ;Delay for a second
- call delay
- mvi a,8FH ;orgmod+ap300+apoffh
- sta holdd ;storing mode for after dialing
- mvi A,8DH ;Go Offhook to start dialing sequence
- sta mnmodm
- mvi a,apinc1 ;Init ACIA
- sta mnport
- mvi a,apinc2 ;Set ACIA bits per character
- sta mnport
-
- lxi b,2500 ;wait 2.5 seconds for dial tone
- call delay
- lxi d,dialms ;Ask the user for the number
- call prtstr
-;
-gtdial: mvi c,conin ;Get a character
- call bdos
- push psw ;save it
- cpi 30H ;is it big enough to dial?
- jc dialed ;no
- cpi 3AH ;is it too big to dial?
- jnc dialed ;yes
- ani 0FH ;ok, it's a digit, get its value
- jnz dialnz ;dial nonzero digits as-is
- mvi A,10 ;dial zero as ten
-;
-dialnz: mov e,a ;count pulses in E-reg
-dopuls: mvi a,0DH ;put it on-hook
- sta mnmodm
- lxi b,61 ;61-millisec pulse
- call delay
- mvi a,8DH ;take it off-hook again...
- sta mnmodm
- lxi b,39 ;39-millisec delay between pulses
- call delay
- dcr e ;any more pulses to do?
- jnz dopuls ;yep, do 'em
- lxi b,600 ;delay 600 msecs between digits
- call delay
-;
-dialed: pop psw ;get back the char
- cpi cr ;do we have a CR (done dialing)?
- jnz gtdial ;no, keep on dialin'
- lxi d,dialm2
- call prtstr
-
-tictoc: mvi c,dconio ;Direct console input.
- mvi e,0FFH
- call bdos
- ora a ;Have a charcter?
- jnz nodial ;If so we abort
- lda mnport ;access the data port
- lda mnprts ;get modem status
- ani 4 ;carrier?
- jnz tictoc ;No
-;
- lda holdd ;get the old modem control byte
- sta mnmodm ;turn our carrier on
-
- lxi d,dialm3
- call prtstr
- jmp rskp
-nodial: xra a ;Hangup the modem.
- sta mnmodm
- ret ;Return to abort the command.
-;
-holdd: db 0 ;Modem setup code
-dialms: DB 'Number to Dial: $'
-dialm2: DB CR,LF,'Awaiting Carrier....(any key aborts)$'
-dialm3: DB cr,lf,'Connected.',CR,LF,'$'
-;
-;DELAY wait for the number of millisecs in B,C
-;
-delay: push b ;save B,C
- push d ;save D,E
- inr b ;bump B for later DCR
-;
-delay1: mvi e,126 ;delay count for 1 millisec (Apple Z80
- ;clock=2.041MHz)
-;
-delay2: dcr e ;count
- jnz delay2 ;down
-;
- dcr c ;more millisecs?
- jnz delay1 ;yes
- dcr b ;no - more in hi byte?
- jnz delay1 ;yes
- pop d ;no, restore D,E
- pop b ; restore B,C
- ret
-ENDIF;apmmdm
-;
-
-;
-; syscls - system-dependent close routine
-; called when exiting transparent session.
-;
-syscls:
- ret
-;
-
-;
-; sysinh - help for system-dependent special functions.
-; called in response to <escape>?, after listing all the
-; system-independent escape sequences.
-;
-sysinh:
-IF apmmdm OR apcps OR ap6850 ;
- lxi d,inhlps ; we got options...
- call prtstr ; print them.
-ENDIF ;apmmdm OR apcps OR ap6850
-
- ret
-
-
-;additional, system-dependent help for transparent mode
-; (two-character escape sequences)
-inhlps:
-
-IF apcps OR ap6850
- db cr,lf,'B Transmit a BREAK'
-ENDIF;apcps OR ap6850
-
-IF apmmdm
- db cr,lf,'D Drop the line'
-ENDIF;apmmdm
-
- db '$' ;[hh] table terminator
-
-;
-; sysint - system dependent special functions
-; called when transparent escape character has been typed;
-; the second character of the sequence is in A (and in B).
-; returns:
-; non-skip: sequence has been processed
-; skip: sequence was not recognized
-sysint: ani 137O ; convert lower case to upper, for testing...
-IF apmmdm
- cpi 'D' ;Disconnect Modem?
- jnz intc00 ;No.
- xra a ;Yes, hangup the modem
- sta mnmodm
- ret ; command has been executed
-intc00:
-ENDIF;apmmdm
-
-IF ap6850 OR apcps ; [22] [25] ... some more
- cpi 'B' ; send break?
- jz sendbr ; yes, go do it. return nonskip when through.
-ENDIF;[22] ap6850 OR apcps
-
- jmp rskp ; take skip return - command not recognized.
-
-
-;
-
-IF ap6850 ;[32]
-sendbr:
-;
-; Ensure that the transmitter has finished sending buffered chars
-sndbr1: lda mnprts ; get UART status
- ani output ; everything sent?
- jz sndbr1 ; no, wait a bit more
-;
-; Begin sending a break
- mvi a,apinc2
- ori 60h ;transmit break level, CTS high
- sta mnprts
-;
-; Wait for 250 milliseconds (using hundredths second delay routine)
- mvi a,25
- call delay
-;
-; Resume normal operation
- mvi a,apinc2
- sta mnprts
-;
- ret ;done
-ENDIF;[32] ap6850
-
-IF apcps ;[22]
-sendbr:
-;
-; Ensure that the transmitter has finished sending buffered chars
-sndbr1: lda mnprts ; get UART status
- ani TxEmpty ; everything sent?
- jz sndbr1 ; no, wait a bit more
-;
-; Unmask command register
- mvi a,80h
- sta mnprtc
-;
-; Begin sending a break by setting bit in UART command register
- mvi a,3Fh ; Set TxEna, DTR, RxEna, SBreak, ErrRst, RTS
- sta mnprts
-;
-; Wait for 250 milliseconds (using hundredths second delay routine)
- mvi a,25
- call delay
-;
-; Resume normal operation by clearing the SendBreak command bit
- mvi a,37h ;Set TxEna, DTR, RxEna, ErrRst, RTS
- sta mnprts
-;
-; Remask command register
- mvi a,0
- sta mnprtc
-;
- ret ;done
-ENDIF;[22] apcps
-
-;
-
-;
-; sysflt - system-dependent filter
-; called with character in E.
-; if this character should not be printed, return with A = zero.
-; preserves bc, de, hl.
-; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-sysflt:
- mov a,e ; get character for testing
-
- ret
-
-; mdmflt - modem filter [30]
-; called with character to be sent to printer in E
-; with parity set as appropriate.
-; return with accumulator = 0 do do nothing,
-; <> 0 to send char in E.
-mdmflt:
- mov a,e ;[30] get character to test
- ret
-
-
-
-; prtflt - printer filter [30]
-; called with character to be sent to printer in E
-; returns with a = 0 to do nothing
-; a <> 0 to print it.
-;
-; this routine for those printer that automatically insert
-; a lf on cr, or cr for lf. Should this be shifted to
-; the system indep. stuff, in say 4.06?
-prtflt:
- mov a,e ; [30] get character to test
-
- ret
-
-
-;
-
-;
-; system-dependent processing for BYE command.
-; for apmmdm, heath, and lobo, hang up the phone.
-sysbye:
-IF apmmdm
- xra a ;Hangup our end, too.
- sta mnmodm
-ENDIF;apmmdm
-
- ret
-;
-
-; This is the system-dependent command to change the baud rate.
-; DE contains the two-byte value from the baud rate table; this
-; value is also stored in 'speed'.
-sysspd:
-
-; Set the speed for Apple with 6551 ACIA
-IF ap6551
- lda mnprtc ;jb read control port
- ani 0F0H ;jb zap low order nybble
- ora e ;jb put rate in low order nybble
- sta mnprtc ;jb send to control port
- ret
-ENDIF;ap6551
-
-; Set the speed for Apple with CPS Multifunction card
-IF apcps ;[22]
- mvi a,80h
- sta mnprtc
- lda mnprts ;read command register to reset 2651
- mvi a,apmod1 ;first mode byte
- sta mnport
- mvi a,4 ;waste some time before sending second byte
-spdwt: dcr a ; 4 T-states
- jnz spdwt ; 10 T-states
- mov a,e ;second mode byte is speed byte
- sta mnport
- mvi a,apcmd ;command byte
- sta mnprts
- xra a
- sta mnprtc
- ret
-ENDIF;[22] apcps
-
-
-IF ap6551 ;jb
-spdtbl: db 0DH ;jb 13 entries
- db 03H,'110$', 03H,03H ;jb
- db 04H,'1200$', 08H,08H ;jb
- db 05H,'134.5$', 04H,04H ;jb
- db 03H,'150$', 05H,05H ;jb
- db 04H,'1800$', 09H,09H ;jb
- db 05H,'19200$', 0FH,0FH ;jb
- db 04H,'2400$', 0AH,0AH ;jb
- db 03H,'300$', 06H,06H ;jb
- db 04H,'3600$', 0BH,0BH ;jb
- db 04H,'4800$', 0CH,0CH ;jb
- db 03H,'600$', 07H,07H ;jb
- db 04H,'7200$', 0DH,0DH ;jb
- db 04H,'9600$', 0EH,0EH ;jb
-
-sphtbl: db cr,lf,' 110 134.5 150 300 600 1200 1800'
- db cr,lf,' 2400 3600 4800 7200 9600 19200$'
-ENDIF;ap6551
-
-IF apcps ;[22]
-spdtbl: db 10H ; 16 entries
- db 03H,'110$', 32h,32h
- db 04H,'1200$', 37h,37h
- db 05H,'134.5$', 33h,33h
- db 03H,'150$', 34h,34h
- db 04H,'1800$', 38h,38h
- db 05H,'19200$', 3fh,3fh
- db 04H,'2000$', 39h,39h
- db 04H,'2400$', 3ah,3ah
- db 03H,'300$', 35h,35h
- db 04H,'3600$', 3bh,3bh
- db 04H,'4800$', 3ch,3ch
- db 02H,'50$', 30h,30h
- db 03H,'600$', 36h,36h
- db 04H,'7200$', 3dh,3dh
- db 02H,'75$', 31h,31h
- db 04H,'9600$', 3eh,3eh
-
-sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
- db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'
-ENDIF;[22] apcps
-
-
-
-; The following conditionals were once a huge if not statement. There
-; wasn't enough room to add the lobo to the list, so it had to be broken
-; into 2, which you can't do with an if not. I redid it as two ifs and
-; applied them to those that wouldn't set baud. [Hal Hostetler]
-IF apmmdm OR ap6850 ;[32]
-spdtbl equ 0 ; SET BAUD not supported.
-sphtbl equ 0
-ENDIF;appmdm OR ap6850 [32]
-;
-;
-; no ports available for Apple
-prttbl EQU 0 ;SET PORT not supported
-prhtbl EQU 0
-
-;
-;
-
-; This is the system-dependent SET PORT command.
-; HL contains the argument from the command table.
-sysprt:
-
- ret
-;
-
-;
-; selmdm - select modem port
-; selcon - select console port
-; selmdm is called before using inpmdm or outmdm;
-; selcon is called before using inpcon or outcon.
-; For iobyt systems, diddle the I/O byte to select console or comm port;
-; For Decision I, switches Multi I/O board to console or modem serial
-; port. [Toad Hall]
-; For the rest, does nothing.
-; preserves bc, de, hl.
-selmdm:
- ret
-
-selcon:
- ret
-;
-
-; Get character from console, or return zero.
-; result is returned in A. destroys bc, de, hl.
-;
-inpcon:
- mvi c,dconio ;Direct console I/O BDOS call.
- mvi e,0FFH ;Input.
- call BDOS
- ret
-;
-
-;
-; Output character in E to the console.
-; destroys bc, de, hl
-;
-outcon:
-
- mvi c,dconio ;Console output bdos call.
- call bdos ;Output the char to the console.
- ret
-;
-
-;
-; outmdm - output a char from E to the modem.
-; the parity bit has been set as necessary.
-; returns nonskip; bc, de, hl preserved.
-outmdm:
-IF apple
- push h
-outmd1: lxi h,mnprts ;address of the port status register
-outmd2: mov a,m ; get port status in A
- ani output ;Loop till ready.
- jz outmd2
-outmd3: lxi h,mnport ;address of port data register
- mov m,e ; write the character
- pop h
- ret
-ENDIF;apple
-
-
-
-
-;
-
-;
-; get character from modem; return zero if none available.
-; for IOBYT systems, the modem port has already been selected.
-; destroys bc, de, hl.
-inpmdm:
-IF apple
-inpmd1: lda mnprts ;Get the port status into A.
- ani input ;See if the input ready bit is on.
- rz ;If not then return.
-inpmd2: lda mnport ;If so, get the char.
-ENDIF;apple
-
-
-ret ; return with character in A
-
-
-;
-; flsmdm - flush comm line.
-; Modem is selected.
-; Currently, just gets characters until none are available.
-
-flsmdm: call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-;
-
-;
-; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not.
-lptstat:
- xra a
- ret
-
-;
-; outlpt - output character in E to printer
-; console is selected.
-; preserves de.
-outlpt:
- push d ; save DE in either case
- call prtflt ; go through printer filter [30]
- ana a ; if A = 0 do nothing,
- jz outlp1 ; [30] if a=0 do nothing
-
- mvi c,lstout
- call bdos ;Char to printer
-
-outlp1: pop d ; restore saved register pair
- ret
-;
-
-;
-; Screen manipulation routines
-; csrpos - move to row B, column C
-;
-; csrpos for terminals that use a leadin sequence followed
-; by (row + 31.) and (column + 31.)
-;
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,h ; get row
- adi (' '-1) ; space is row one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,l ; get column
- adi (' '-1) ; space is column one
- mov e,a
- jmp outcon ; output it and return
-
-;
-; delchr - make delete look like a backspace. Unless delete is a printing
-; character, we just need to print a backspace. (we'll output clrspc
-; afterwards)
-; For Kaypro and Vector General, delete puts a blotch on the screen.
-; For Apple and Osborne 1, delete moves but doesn't print.
-delchr:
-
- lxi d,delstr
- jmp prtstr
-
-; erase the character at the current cursor position
-clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the current line
-clrlin: lxi d,eralin
- jmp prtstr
-
-; erase the whole screen, and go home. preserves b (but not c)
-clrtop: lxi d,erascr
- jmp prtstr
-
-IF apple
-sysver: db 'Apple II CP/M$'
-outlin: db ('^'-100O),esc,'Y',cr,lf,' $'
-erascr: db ('^'-100O),esc,'Y$' ;Clear screen and go home.
-eralin: db cr,esc,'T$' ;Clear line.
-delstr: db bs,bs,'$' ; Adjust for delete
-curldn: db esc,'=$' ;Cursor lead-in
-ttab: ;Table start location.
-ta: db ('K'-100O),'$',0,0 ;Cursor up.
-tb: db 12O,'$',0,0 ;Cursor down.
-tc: db ('F'-100O),'$',0,0 ;Cursor right.
-td: db '$',0,0,0 ;(can't) Cursor left
-te: db '$',0,0,0 ;(can't) Clear display
-tf: db '$',0,0,0 ;(can't) Enter graphics mode
-tg: db '$',0,0,0 ;(can't) Exit graphics mode
-th: db ('^'-100O),'$',0,0 ;Cursor home.
-ti: db ('K'-100O),'$',0,0 ;Reverse linefeed.
-tj: db esc,'Y$',0 ;Clear to end of screen.
-tk: db esc,'T$',0 ;Clear to end of line.
-ENDIF;apple
-
-ovlend equ $ ; End of overlay
-
- END
+IF NOT lasm
+.printx * CPXAPP.ASM *
+ENDIF ;NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the system-dependent code and data for KERMIT.
+; It will be probably be broken into independent files to generate
+; overlays for the various systems, one or more overlay possible
+; from each file. For now, we will leave it in one piece.
+;
+; revision history:
+; edit 2, 22 July, 1987 by OBSchou. Massaged code to work with CPXCOM.ASM
+;
+; edit 1, 2nd June, 1987 by OBSchou. Extracted all Apple related code.
+;
+;
+; Family is the string used in VERSION to say which of several
+; smaller overlay files are used. These are (will be) derived from
+; the juge CPXSYS.ASM file, in which case we will never get here.
+; Just a Dollar, but put a sting in for a family of machines.
+;
+family: db 'CPXAPP.ASM (2) 22-jul-87$' ; Used for family versions....
+;
+
+IF apple
+.printx * Assembling KERMIT-80 for the Apple ][ *
+ENDIF;apple
+IF apmmdm
+.printx * with Z80 Softcard & Micromodem II *
+ENDIF;apmmdm
+IF ap6551
+.printx * with Z80 Softcard & 6551 ACIA *
+ENDIF;ap6551
+IF ap6850;[32]
+.printx * with Z80 Softcard & 6850 ACIA *
+ENDIF;ap6850 [32]
+IF apcps;[22]
+.printx * with Softcard & CPS Multifunction card *
+ENDIF;apcps
+
+;
+
+IF ap6551 OR ap6850 OR apcps;[9] [14]
+ ;jb eg. Apple SSC, Videx PSIO, Basis 108
+apslot EQU 2 ;jb set equal to slot containing serial card
+ ;jb set to 1 for Basis built-in port
+ENDIF;jb ap6551 [9] apcps ap6850 [14]
+IF ap6850 ;[14] offset in slot I/O space for ACIA registers
+ ;e.g. PACT=00,01: AIO-I=05,04: AIO-II=0D,0C: Aristocard=0B,0A
+apdat EQU 0DH ;data reg.=0E080h+apslot*10h*apdat
+apstat EQU 0CH ;comm/stat reg.=0E080h+apslot*10h+apstat
+ENDIF;ap6850
+
+
+IF apmmdm
+;APPLE Slot 2 contains Micromodem II.
+MNPORT EQU 0E0A7H ;Communications Port.
+mnprts EQU 0E0A6H ;Communications Port Status.
+mnmodm EQU 0E0A5H ;Modem Control Port.
+orgmod EQU 8EH ;Modem Originate Mode.
+OUTPUT EQU 02H ;Output Buffer Empty.
+INPUT EQU 01H ;Input Register Full.
+apinc1 EQU 03H ;First Init Character for 6850 ACIA (Reset)
+apinc2 EQU 11H ;Second Init Character for ACIA (8-bits)
+apoffh EQU 80H ;Set if OFFHOOK
+AP300 EQU 1 ;300 Baud
+z80 EQU TRUE ;Z80 Softcard
+ENDIF;apmmdm
+
+IF ap6551 ;jb
+mnport EQU 0E088H+(10H*apslot) ;jb Communications Port.
+mnprts EQU 0E089H+(10H*apslot) ;jb Communications Port Status.
+mnprtc EQU 0E08BH+(10H*apslot) ;jb Communications Control
+mnprtm EQU 0E08AH+(10H*apslot) ;jb Communications Master (command)
+output EQU 10H ;jb Output Buffer Empty.
+input EQU 08H ;jb Input Register Full.
+mncinb EQU 18H ;jb Control Port Initialization Byte
+ ;jb (8-bit, no parity, 1-stop, 1200 baud)
+mnminb EQU 0BH ;jb Master Port Initialization Byte
+ ;jb (DTR, RTS, no interrupts)
+z80 EQU TRUE ;Z80 Softcard
+ENDIF;ap6551
+
+IF ap6850 ;[32]
+mnport EQU 0E080H+(10H*apslot)+apdat ;Communications Port.
+mnprts EQU 0E080H+(10H*apslot)+apstat ;Communications Port Status.
+OUTPUT EQU 02H ;Output Buffer Empty.
+INPUT EQU 01H ;Input Register Full.
+apinc1 EQU 03H ;First Init Character for 6850 ACIA (Reset)
+apinc2 EQU 15H ;Second Init Character for ACIA (8 data, 1 stop bit)
+z80 EQU TRUE ;Z80 Softcard
+ENDIF;[32] ap6850
+
+IF apcps ;[22]
+mnport EQU 0E0FAH+(100H*apslot) ; Communications Port.
+mnprts EQU 0E0FBH+(100H*apslot) ; Communications Port Status.
+mnprtc EQU 0E0FEH+(100H*apslot) ; Communications Control
+output EQU 1 ; Output Buffer Empty.
+input EQU 2 ; Input Register Full.
+TxEmpty EQU 04h ; Transmitter empty flag
+apmod1 EQU 4EH ; Mode Byte 1 (1 stop, no parity,8-bit, 16x)
+ ; Mode Byte 2 is speed control byte
+apcmd EQU 37H ; Command Byte (RTS,Error reset,RxE,DTR,TxE)
+z80 EQU TRUE ;Z80 Softcard
+ENDIF;[22] apcps
+
+IF apple
+defesc EQU ']'-100O ;The default escape character.
+ENDIF;apple
+
+
+; default to VT52-EMULATION ON.
+
+vtval EQU 1
+
+
+
+sysxin: ; continuation of systemm dependent initialisation code
+
+IF ap6551
+ lda mnprtc ; read control port
+ ani 0fH ; extract low order nybble
+ sta speed ; store as comm line speed
+ sta speed+1 ; (16 bits, to match speed table entries)
+ mvi a,mnminb ;jb initialization routine
+ sta mnprts ;jb
+ sta mnprtm ;jb initialize master (command) port
+ mvi a,mncinb ;jb
+ sta mnprtc ;jb initialize control port
+ENDIF;ap6551
+
+IF ap6850 ;[32]
+ mvi a,apinc1 ;Init ACIA
+ sta mnprts
+ mvi a,apinc2 ;Set ACIA bits per character
+ sta mnprts
+ENDIF;[32] ap6850
+
+IF apcps ;[22]
+ lxi h,3737h ;Default 1200 baud
+ shld speed ;Store as port speed
+ xchg
+ call sysspd ;Initialise the port
+ENDIF;[22] apcps
+
+ ret ; return from system-dependent routine
+
+;
+
+;
+; system-dependent termination processing
+; If we've changed anything, this is our last chance to put it back.
+sysexit:
+
+ ret
+
+;
+; system-dependent processing for start of CONNECT command
+;
+syscon:
+IF apmmdm
+ call ckdial ;See if dialing is required.
+ jmp kermit ;Go to command loop if aborted.
+ENDIF;apmmdm
+
+ ret
+
+conmsg: ; Messages printed when entering transparent (CONNECT) mode:
+;
+
+IF apmmdm
+;This code was mostly taken from
+; APMODEM.ASM V2.1
+; Based on MODEM.ASM by Ward Christensen
+; Modified for the Apple ][ by Gordon Banks 1-Jan-81
+; Micromodem ][ dialer option by Dav Holle 2-Feb-81
+; Code modified for KERMIT by Scott Robinson 14-Oct-82
+;
+;Come here to see if we need to dial a number.
+;
+ckdial: lda mnport ;access the data port
+ lda mnprts ;check status
+ ani 4 ;do we already have carrier?
+ jz rskp ;Yes, just continue
+ xra a ;Hangup Phone for starters
+ sta mnmodm
+ lxi b,1000 ;Delay for a second
+ call delay
+ mvi a,8FH ;orgmod+ap300+apoffh
+ sta holdd ;storing mode for after dialing
+ mvi A,8DH ;Go Offhook to start dialing sequence
+ sta mnmodm
+ mvi a,apinc1 ;Init ACIA
+ sta mnport
+ mvi a,apinc2 ;Set ACIA bits per character
+ sta mnport
+
+ lxi b,2500 ;wait 2.5 seconds for dial tone
+ call delay
+ lxi d,dialms ;Ask the user for the number
+ call prtstr
+;
+gtdial: mvi c,conin ;Get a character
+ call bdos
+ push psw ;save it
+ cpi 30H ;is it big enough to dial?
+ jc dialed ;no
+ cpi 3AH ;is it too big to dial?
+ jnc dialed ;yes
+ ani 0FH ;ok, it's a digit, get its value
+ jnz dialnz ;dial nonzero digits as-is
+ mvi A,10 ;dial zero as ten
+;
+dialnz: mov e,a ;count pulses in E-reg
+dopuls: mvi a,0DH ;put it on-hook
+ sta mnmodm
+ lxi b,61 ;61-millisec pulse
+ call delay
+ mvi a,8DH ;take it off-hook again...
+ sta mnmodm
+ lxi b,39 ;39-millisec delay between pulses
+ call delay
+ dcr e ;any more pulses to do?
+ jnz dopuls ;yep, do 'em
+ lxi b,600 ;delay 600 msecs between digits
+ call delay
+;
+dialed: pop psw ;get back the char
+ cpi cr ;do we have a CR (done dialing)?
+ jnz gtdial ;no, keep on dialin'
+ lxi d,dialm2
+ call prtstr
+
+tictoc: mvi c,dconio ;Direct console input.
+ mvi e,0FFH
+ call bdos
+ ora a ;Have a charcter?
+ jnz nodial ;If so we abort
+ lda mnport ;access the data port
+ lda mnprts ;get modem status
+ ani 4 ;carrier?
+ jnz tictoc ;No
+;
+ lda holdd ;get the old modem control byte
+ sta mnmodm ;turn our carrier on
+
+ lxi d,dialm3
+ call prtstr
+ jmp rskp
+nodial: xra a ;Hangup the modem.
+ sta mnmodm
+ ret ;Return to abort the command.
+;
+holdd: db 0 ;Modem setup code
+dialms: DB 'Number to Dial: $'
+dialm2: DB CR,LF,'Awaiting Carrier....(any key aborts)$'
+dialm3: DB cr,lf,'Connected.',CR,LF,'$'
+;
+;DELAY wait for the number of millisecs in B,C
+;
+delay: push b ;save B,C
+ push d ;save D,E
+ inr b ;bump B for later DCR
+;
+delay1: mvi e,126 ;delay count for 1 millisec (Apple Z80
+ ;clock=2.041MHz)
+;
+delay2: dcr e ;count
+ jnz delay2 ;down
+;
+ dcr c ;more millisecs?
+ jnz delay1 ;yes
+ dcr b ;no - more in hi byte?
+ jnz delay1 ;yes
+ pop d ;no, restore D,E
+ pop b ; restore B,C
+ ret
+ENDIF;apmmdm
+;
+
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+ ret
+;
+
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing all the
+; system-independent escape sequences.
+;
+sysinh:
+IF apmmdm OR apcps OR ap6850 ;
+ lxi d,inhlps ; we got options...
+ call prtstr ; print them.
+ENDIF ;apmmdm OR apcps OR ap6850
+
+ ret
+
+
+;additional, system-dependent help for transparent mode
+; (two-character escape sequences)
+inhlps:
+
+IF apcps OR ap6850
+ db cr,lf,'B Transmit a BREAK'
+ENDIF;apcps OR ap6850
+
+IF apmmdm
+ db cr,lf,'D Drop the line'
+ENDIF;apmmdm
+
+ db '$' ;[hh] table terminator
+
+;
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:
+; non-skip: sequence has been processed
+; skip: sequence was not recognized
+sysint: ani 137O ; convert lower case to upper, for testing...
+IF apmmdm
+ cpi 'D' ;Disconnect Modem?
+ jnz intc00 ;No.
+ xra a ;Yes, hangup the modem
+ sta mnmodm
+ ret ; command has been executed
+intc00:
+ENDIF;apmmdm
+
+IF ap6850 OR apcps ; [22] [25] ... some more
+ cpi 'B' ; send break?
+ jz sendbr ; yes, go do it. return nonskip when through.
+ENDIF;[22] ap6850 OR apcps
+
+ jmp rskp ; take skip return - command not recognized.
+
+
+;
+
+IF ap6850 ;[32]
+sendbr:
+;
+; Ensure that the transmitter has finished sending buffered chars
+sndbr1: lda mnprts ; get UART status
+ ani output ; everything sent?
+ jz sndbr1 ; no, wait a bit more
+;
+; Begin sending a break
+ mvi a,apinc2
+ ori 60h ;transmit break level, CTS high
+ sta mnprts
+;
+; Wait for 250 milliseconds (using hundredths second delay routine)
+ mvi a,25
+ call delay
+;
+; Resume normal operation
+ mvi a,apinc2
+ sta mnprts
+;
+ ret ;done
+ENDIF;[32] ap6850
+
+IF apcps ;[22]
+sendbr:
+;
+; Ensure that the transmitter has finished sending buffered chars
+sndbr1: lda mnprts ; get UART status
+ ani TxEmpty ; everything sent?
+ jz sndbr1 ; no, wait a bit more
+;
+; Unmask command register
+ mvi a,80h
+ sta mnprtc
+;
+; Begin sending a break by setting bit in UART command register
+ mvi a,3Fh ; Set TxEna, DTR, RxEna, SBreak, ErrRst, RTS
+ sta mnprts
+;
+; Wait for 250 milliseconds (using hundredths second delay routine)
+ mvi a,25
+ call delay
+;
+; Resume normal operation by clearing the SendBreak command bit
+ mvi a,37h ;Set TxEna, DTR, RxEna, ErrRst, RTS
+ sta mnprts
+;
+; Remask command register
+ mvi a,0
+ sta mnprtc
+;
+ ret ;done
+ENDIF;[22] apcps
+
+;
+
+;
+; sysflt - system-dependent filter
+; called with character in E.
+; if this character should not be printed, return with A = zero.
+; preserves bc, de, hl.
+; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
+sysflt:
+ mov a,e ; get character for testing
+
+ ret
+
+; mdmflt - modem filter [30]
+; called with character to be sent to printer in E
+; with parity set as appropriate.
+; return with accumulator = 0 do do nothing,
+; <> 0 to send char in E.
+mdmflt:
+ mov a,e ;[30] get character to test
+ ret
+
+
+
+; prtflt - printer filter [30]
+; called with character to be sent to printer in E
+; returns with a = 0 to do nothing
+; a <> 0 to print it.
+;
+; this routine for those printer that automatically insert
+; a lf on cr, or cr for lf. Should this be shifted to
+; the system indep. stuff, in say 4.06?
+prtflt:
+ mov a,e ; [30] get character to test
+
+ ret
+
+
+;
+
+;
+; system-dependent processing for BYE command.
+; for apmmdm, heath, and lobo, hang up the phone.
+sysbye:
+IF apmmdm
+ xra a ;Hangup our end, too.
+ sta mnmodm
+ENDIF;apmmdm
+
+ ret
+;
+
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; this
+; value is also stored in 'speed'.
+sysspd:
+
+; Set the speed for Apple with 6551 ACIA
+IF ap6551
+ lda mnprtc ;jb read control port
+ ani 0F0H ;jb zap low order nybble
+ ora e ;jb put rate in low order nybble
+ sta mnprtc ;jb send to control port
+ ret
+ENDIF;ap6551
+
+; Set the speed for Apple with CPS Multifunction card
+IF apcps ;[22]
+ mvi a,80h
+ sta mnprtc
+ lda mnprts ;read command register to reset 2651
+ mvi a,apmod1 ;first mode byte
+ sta mnport
+ mvi a,4 ;waste some time before sending second byte
+spdwt: dcr a ; 4 T-states
+ jnz spdwt ; 10 T-states
+ mov a,e ;second mode byte is speed byte
+ sta mnport
+ mvi a,apcmd ;command byte
+ sta mnprts
+ xra a
+ sta mnprtc
+ ret
+ENDIF;[22] apcps
+
+
+IF ap6551 ;jb
+spdtbl: db 0DH ;jb 13 entries
+ db 03H,'110$', 03H,03H ;jb
+ db 04H,'1200$', 08H,08H ;jb
+ db 05H,'134.5$', 04H,04H ;jb
+ db 03H,'150$', 05H,05H ;jb
+ db 04H,'1800$', 09H,09H ;jb
+ db 05H,'19200$', 0FH,0FH ;jb
+ db 04H,'2400$', 0AH,0AH ;jb
+ db 03H,'300$', 06H,06H ;jb
+ db 04H,'3600$', 0BH,0BH ;jb
+ db 04H,'4800$', 0CH,0CH ;jb
+ db 03H,'600$', 07H,07H ;jb
+ db 04H,'7200$', 0DH,0DH ;jb
+ db 04H,'9600$', 0EH,0EH ;jb
+
+sphtbl: db cr,lf,' 110 134.5 150 300 600 1200 1800'
+ db cr,lf,' 2400 3600 4800 7200 9600 19200$'
+ENDIF;ap6551
+
+IF apcps ;[22]
+spdtbl: db 10H ; 16 entries
+ db 03H,'110$', 32h,32h
+ db 04H,'1200$', 37h,37h
+ db 05H,'134.5$', 33h,33h
+ db 03H,'150$', 34h,34h
+ db 04H,'1800$', 38h,38h
+ db 05H,'19200$', 3fh,3fh
+ db 04H,'2000$', 39h,39h
+ db 04H,'2400$', 3ah,3ah
+ db 03H,'300$', 35h,35h
+ db 04H,'3600$', 3bh,3bh
+ db 04H,'4800$', 3ch,3ch
+ db 02H,'50$', 30h,30h
+ db 03H,'600$', 36h,36h
+ db 04H,'7200$', 3dh,3dh
+ db 02H,'75$', 31h,31h
+ db 04H,'9600$', 3eh,3eh
+
+sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
+ db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'
+ENDIF;[22] apcps
+
+
+
+; The following conditionals were once a huge if not statement. There
+; wasn't enough room to add the lobo to the list, so it had to be broken
+; into 2, which you can't do with an if not. I redid it as two ifs and
+; applied them to those that wouldn't set baud. [Hal Hostetler]
+IF apmmdm OR ap6850 ;[32]
+spdtbl equ 0 ; SET BAUD not supported.
+sphtbl equ 0
+ENDIF;appmdm OR ap6850 [32]
+;
+;
+; no ports available for Apple
+prttbl EQU 0 ;SET PORT not supported
+prhtbl EQU 0
+
+;
+;
+
+; This is the system-dependent SET PORT command.
+; HL contains the argument from the command table.
+sysprt:
+
+ ret
+;
+
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; For iobyt systems, diddle the I/O byte to select console or comm port;
+; For Decision I, switches Multi I/O board to console or modem serial
+; port. [Toad Hall]
+; For the rest, does nothing.
+; preserves bc, de, hl.
+selmdm:
+ ret
+
+selcon:
+ ret
+;
+
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+ mvi c,dconio ;Direct console I/O BDOS call.
+ mvi e,0FFH ;Input.
+ call BDOS
+ ret
+;
+
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+
+ mvi c,dconio ;Console output bdos call.
+ call bdos ;Output the char to the console.
+ ret
+;
+
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+outmdm:
+IF apple
+ push h
+outmd1: lxi h,mnprts ;address of the port status register
+outmd2: mov a,m ; get port status in A
+ ani output ;Loop till ready.
+ jz outmd2
+outmd3: lxi h,mnport ;address of port data register
+ mov m,e ; write the character
+ pop h
+ ret
+ENDIF;apple
+
+
+
+
+;
+
+;
+; get character from modem; return zero if none available.
+; for IOBYT systems, the modem port has already been selected.
+; destroys bc, de, hl.
+inpmdm:
+IF apple
+inpmd1: lda mnprts ;Get the port status into A.
+ ani input ;See if the input ready bit is on.
+ rz ;If not then return.
+inpmd2: lda mnport ;If so, get the char.
+ENDIF;apple
+
+
+ret ; return with character in A
+
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+
+flsmdm: call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+;
+
+;
+; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not.
+lptstat:
+ xra a
+ ret
+
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+outlpt:
+ push d ; save DE in either case
+ call prtflt ; go through printer filter [30]
+ ana a ; if A = 0 do nothing,
+ jz outlp1 ; [30] if a=0 do nothing
+
+ mvi c,lstout
+ call bdos ;Char to printer
+
+outlp1: pop d ; restore saved register pair
+ ret
+;
+
+;
+; Screen manipulation routines
+; csrpos - move to row B, column C
+;
+; csrpos for terminals that use a leadin sequence followed
+; by (row + 31.) and (column + 31.)
+;
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; restore coordinates
+ mov a,h ; get row
+ adi (' '-1) ; space is row one
+ mov e,a
+ push h
+ call outcon ; output row
+ pop h
+ mov a,l ; get column
+ adi (' '-1) ; space is column one
+ mov e,a
+ jmp outcon ; output it and return
+
+;
+; delchr - make delete look like a backspace. Unless delete is a printing
+; character, we just need to print a backspace. (we'll output clrspc
+; afterwards)
+; For Kaypro and Vector General, delete puts a blotch on the screen.
+; For Apple and Osborne 1, delete moves but doesn't print.
+delchr:
+
+ lxi d,delstr
+ jmp prtstr
+
+; erase the character at the current cursor position
+clrspc: mvi e,' '
+ call outcon
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the current line
+clrlin: lxi d,eralin
+ jmp prtstr
+
+; erase the whole screen, and go home. preserves b (but not c)
+clrtop: lxi d,erascr
+ jmp prtstr
+
+IF apple
+sysver: db 'Apple II CP/M$'
+outlin: db ('^'-100O),esc,'Y',cr,lf,' $'
+erascr: db ('^'-100O),esc,'Y$' ;Clear screen and go home.
+eralin: db cr,esc,'T$' ;Clear line.
+delstr: db bs,bs,'$' ; Adjust for delete
+curldn: db esc,'=$' ;Cursor lead-in
+ttab: ;Table start location.
+ta: db ('K'-100O),'$',0,0 ;Cursor up.
+tb: db 12O,'$',0,0 ;Cursor down.
+tc: db ('F'-100O),'$',0,0 ;Cursor right.
+td: db '$',0,0,0 ;(can't) Cursor left
+te: db '$',0,0,0 ;(can't) Clear display
+tf: db '$',0,0,0 ;(can't) Enter graphics mode
+tg: db '$',0,0,0 ;(can't) Exit graphics mode
+th: db ('^'-100O),'$',0,0 ;Cursor home.
+ti: db ('K'-100O),'$',0,0 ;Reverse linefeed.
+tj: db esc,'Y$',0 ;Clear to end of screen.
+tk: db esc,'T$',0 ;Clear to end of line.
+ENDIF;apple
+
+ovlend equ $ ; End of overlay
+
+ END
diff --git a/cpxbbi.asm b/cpxbbi.asm
index ffbdc14..47bd82d 100644
--- a/cpxbbi.asm
+++ b/cpxbbi.asm
@@ -1,618 +1,618 @@
-IF NOT lasm
-.printx * CPXBBI.ASM *
-ENDIF ;NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.08
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-;
-;
-; revision history:
-;
-;edit 4, 7-Jan-1991 by MF. Added code to support the Ampro Little Board.
-; The code was contributed by Jay S. Rouman; 913 North Drive;
-; Mt. Pleasant, MI 48858 (voice (517)773-7887).
-; edit 3, 23 July by OBSchou to massage file to suit CPXCOM.ASM
-;
-; edit 2 23 May 1987 by C.J.MILES@UMRCC.
-; Reorganised file to be similar in structure to that
-; of the Amstrad sys-dep file. Added hangup in clear
-; screen options in CONNECT mode.
-;
-; edit 1 10 May 1987 by Chris Miles (C.J.MILES@UMRCC)
-; Removed Kaypro, Xerox and Big Board from CPXSYS.ASM
-; and grouped them into this file as CPXBBI.ASM.
-;
-;
-;
-; Original code broken off and modified by:
-;
-; Chris Miles
-; 344, Claremont Road,
-; Rusholme,
-; MANCHESTER,
-; M14 6WB.
-;
-; Tel: (061) 226 7839
-;
-
-;
-; *** MAIN CODE START ***
-;
-;
-; Keep module name, edit number, and last revision date in memory.
-
-sysedt: db 'CPXSYS.ASM (35) 01-Dec-86$'
-family: db 'CPXBBI.ASM (4) 7-Jan-1991$'
-
-
-; Assembly time message announcing which version we're building
-
-IF kpii
-.printx * Assembling Kaypro II KERMIT-80 *
-ENDIF
-
-IF xer820
-.printx * Assembling Xerox 820 KERMIT-80 *
-ENDIF
-
-IF bbII
-.printx * Assembling BigBoard II KERMIT-80 *
-ENDIF
-
-IF ampro
-.printx * Assembling Ampro Little Board KERMIT-80 *
-ENDIF
-
-z80 EQU TRUE ; They all use Z80s
-
-IF xer820
-defesc EQU ']'-100O ;The default escape character for Xerox
-ENDIF;xer820
-
-IF kpII
-defesc EQU '\'-100O ;The default escape character for Kaypro
-ENDIF;kpII
-
-; If one of the above, default to VT52-EMULATION ON.
-IF kpII OR xer820
-vtval EQU 1
-ENDIF;kpII OR xer820
-
-
-;
-; Specific machine hardware information
-;
-IF bbI
-mnport equ 04h ; Modem data port
-mnprts equ 06h ; Modem status port
-output equ 04h ; Transmit buffer empty
-input equ 01h ; Receive data available
-baudrt equ 00h ; Baud rate port for channel A
-ENDIF;bbI
-
-
-IF bbII
-mnport equ 80h ; Modem data port (SIO channel A)
-mnprts equ 81h ; Modem status port
-output equ 04h ; Transmit buffer empty
-input equ 01h ; Receive data available
-baudrt equ 89h ; Baud rate port for channel A
-ENDIF;bbII
-
-IF ampro
-mnport equ 88h ; Modem data port (SIO channel B)
-mnprts equ 8Ch ; Modem status port
-output equ 04h ; Transmit buffer empty
-input equ 01h ; Receive data available
-baudrt equ 50h ; Baud rate port for channel B
-ENDIF;ampro
-;
-
-sysxin: ;continuation of system initialisation code
- lxi d,siotbl ; Load the address of the status able
- mvi c,siolen ; Length of status table
-siolup: ; Loop back here for each command byte
- ldax d ; Load the first byte into A
- inx d ; Index the pointer
- out mnprts ; Send it to the status port
- dcr c ; Decrement the byte counter
- jnz siolup ; Jump back for more commands
- ret ; return from system-dependent routine
-
-; List of commands to set up SIO channel A for asynchronous operation.
-
-siotbl: DB 18H ; Channel reset
- DB 18H ; another, in case register 0 wasn't selected
- DB 04H ; Select register 4
- DB 44H ; 1 stop bit, clock*16
- DB 01H ; Select register 1
- DB 00H ; No interrupts enabled
- DB 03H ; Select register 3
- DB 0C1H ; Rx enable, 8 bit Rx character
- DB 05H ; Select register 5
- DB 0EAH ; Tx enable, 8 bit Tx character,
- ; raise DTR and RTS
-siolen equ $-siotbl ; length of command list
-
-
-;
-; sysexit - System-dependent termination processing
-; if we've changed anything, this is our last
-; chance to put it back.
-;
-sysexit:
- ret
-
-;
-; syscon - System-dependent processing for start
-; of CONNECT command.
-;
-syscon:
- lxi d,conmsg
- call prtstr
- ret
-
-conmsg: ; Messages printed when entering transparent (CONNECT) mode:
- db cr,lf,'$'
-;
-; syscls - system-dependent close routine
-; called when exiting transparent session.
-;
-syscls:
- ret
-;
-; sysinh - help for system-dependent special functions.
-; called in response to <escape>?, after listing
-; all the system-independent escape sequences.
-;
-sysinh:
- lxi d,inhlps ; we got options...
- call prtstr ; print them.
- ret
-
-
-; additional, system-dependent help for transparent mode
-; (two-character escape sequences)
-inhlps:
- db cr,lf,'B Transmit a BREAK'
- db cr,lf,'H Hangup using DTR'
- db cr,lf,'W Wipe screen clear'
- db '$'
-
-; sysint - system dependent special functions
-; called when transparent escape character has been typed;
-; the second character of the sequence is in A (and in B).
-; returns:-
-; non-skip: sequence has been processed
-; skip : sequence was not recognized
-;
-sysint: ani 137O ; convert lower case to upper, for testing...
- cpi 'B' ; send break ?
- jz sendbr ; then jump to send break routine
- cpi 'H' ; hang up ?
- jz hangup ; then jump to hangup routine
- cpi 'W' ; clear screen ?
- jz clrtop ; then jump to clear screen routine
- jmp rskp ; take skip return - command not recognized.
-
-;
-; Hangup and Break routines
-;
-hangup:
- mvi d,0ah ; set up hangup bit mask
- mvi e,255 ; time for hangup is 2 1/2 secs
- jmp setbit ; skip Tx empty test
-
-sendbr:
- mvi d,9ah ; set up break bit mask
- mvi e,30 ; time for break is 300 ms
-
-sndbr1: mvi a,1 ; select Read Register 1
- out mnprts
- in mnprts ; read the contents
- ani 1 ; test "all done" flag
- jz sndbr1 ; loop until it's nonzero.
-;
-; Next, set the break or DTR bit on the SIO
-;
-setbit:
- mvi a,5 ; select Write Register 5
- out mnprts
- mvi a,6ah ; Tx enable, 8 bit Tx character,
- ora d ; OR with appropriate bit mask
- out mnprts ;
-;
-; Now, delay for duration of hangup or break
- mov a,e ; delay count
- call delay
-;
-; Time's up. Put transmitter back in normal state and return.
- mvi a,5 ; select Write Register 5
- out mnprts
- mvi a,0eah ; Tx enable, 8 bit Tx character,
- out mnprts ;.
- ret ; done.
-
-; sysflt - system-dependent filter
-; called with character in E.
-; if this character should not be printed, return with A = zero.
-; preserves bc, de, hl.
-; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-;
-sysflt:
- mov a,e ; get character for testing
- ret
-
-;
-; sysbye - system-dependent processing for BYE command.
-;
-sysbye:
- ret
-;
-; This is the system-dependent command to change the baud rate.
-; DE contains the two-byte value from the baud rate table; this
-; value is also stored in 'speed'.
-;
-sysspd:
-
-; Set the speed for bigboard II
-IF bbII
- di ; don't let anything between the data bytes
- mvi a,01000111b ; get the command byte (load time constant)
- out baudrt ; output it to CTC
- mov a,e ; Get the parsed value.
- out baudrt ; Tell the baud rate generator.
- ei ; end of critical section
- ret
-ENDIF;bbII
-
-
-; Set the speed for bigboard I
-IF bbI
- mov a,e ; get the parsed value
- out baudrt ; Tell the baud rate generator.
- ret
-ENDIF;bbI
-
-; set the speed for the Ampro Little Board
-if ampro
- mvi e,3fh ; offset to port b ctc 3f hex bytes
- call getbios
- mvi a,47h ; counter mode,ctc reset,value follows
- mov m,a ; store value
- lda speed+1 ; get ctc divisor
- inx h ; location of ctc divisor
- mov m,a ; store new divisor
-;
-; set up wr4 clock divisor according to mspeed
-;
- mvi e,50h ; offset to dart wr4
- call getbios
- mvi a,3fh ; mask for wr4 clock bits
- ana m ; mask off bits
- mov m,a ; and save to wr4
- lda speed ; get clock flag
- ora a ; set flags, zero = 300 bps
- mvi a,80h ; x32 clock bit
- jz lbps ; setup wr4 for 300 bps x32 clock
-;
-; set up wr4 value for 1200 bps x16 clock 'hl' has wr4 loc
-;
-hbps: mvi a,40h ; x16 clock
-;
-; setup wr4 value for 300 bps x32 clock 'hl' has wr4 loc
-;
-lbps: ora m ; set clock bits saving parity
- mov m,a ; store new clock divisor to wr4 value
-;
-; initialize sio/dart
-;
-intsio: lxi h,intend
- push h ; set up for return
- mvi e,36h ; offset to ioinit
- call getbios
- pchl ; we pushed return address
-intend: ret
-
-;
-; return bios location in 'hl' called with offset in 'e'
-;
-getbios:
- lhld 1 ; get bios location
- mvi d,0 ; clear 'd'
- dad d
- ret
-;
-ENDIF;ampro
-
-;
-; Speed tables
-; (Note that speed tables MUST be in alphabetical order for later
-; lookup procedures, and must begin with a value showing the total
-; number of entries. The speed help tables are just for us poor
-; humans.
-
-; db string length,string,divisor (2 identical bytes or 1 word)
-; [Toad Hall]
-
-IF bbI
-spdtbl: db 10h ;16 entries
- db 03h,'110$', 02h,02h
- db 04h,'1200$', 07h,07h
- db 05h,'134.5$', 03h,03h
- db 03h,'150$', 04h,04h
- db 04h,'1800$', 08h,08h
- db 05h,'19200$', 0fh,0fh
- db 04h,'2000$', 09h,09h
- db 04h,'2400$', 0ah,0ah
- db 03h,'300$', 05h,05h
- db 04h,'3600$', 0bh,0bh
- db 04h,'4800$', 0ch,0ch
- db 02h,'50$', 00h,00h
- db 03h,'600$', 06h,06h
- db 04h,'7200$', 0dh,0dh
- db 02h,'75$', 01h,01h
- db 04h,'9600$', 0eh,0eh
-
-sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
- db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'
-ENDIF;bbI
-
-IF bbII
-spdtbl: db 8 ; 8 entries
- db 04h,'1200$', 20h,20h
- db 05h,'19200$', 02h,02h
- db 04h,'2400$', 10h,10h
- db 03h,'300$', 80h,80h
- db 05h,'38400$', 01h,01h
- db 04h,'4800$', 08h,08h
- db 03h,'600$', 40h,40h
- db 04h,'9600$', 04h,04h
-
-sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600 19200 38400$'
-ENDIF;bbII
-
-
-IF ampro
-spdtbl: db 6 ; 6 entries
- db 04h,'1200$', 1,104
- db 04h,'2400$', 1,52
- db 03h,'300$', 0,208
- db 04h,'4800$', 1,26
- db 03h,'600$', 1,208
- db 04h,'9600$', 1,13
-
-sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$'
-ENDIF;ampro
-
-; This is the system-dependent SET PORT command.
-; HL contains the argument from the command table.
-;
-sysprt:
- ret
-;
-
-prttbl equ 0 ; SET PORT is not supported
-prhtbl equ 0
-
-;
-; selmdm - select modem port
-; selcon - select console port
-; selmdm is called before using inpmdm or outmdm;
-; selcon is called before using inpcon or outcon.
-; preserves BC, DE, HL.
-;
-selmdm:
-selcon:
- ret
-;
-; Get character from console, or return zero.
-; result is returned in A. destroys bc, de, hl.
-;
-inpcon:
- mvi c,dconio ;Direct console I/O BDOS call.
- mvi e,0FFH ;Input.
- call BDOS
- ret
-;
-;
-; Output character in E to the console.
-; destroys bc, de, hl
-;
-outcon:
-
- mvi c,dconio ;Console output bdos call.
- call bdos ;Output the char to the console.
-
- ret
-;
-;
-; outmdm - output a char from E to the modem.
-; the parity bit has been set as necessary.
-; returns nonskip; bc, de, hl preserved.
-outmdm:
- in mnprts ;Get the output done flag.
- ani output ;Is it set?
- jz outmdm ;If not, loop until it is.
- mov a,e
- out mnport ;Output it.
- ret
-
-
-;
-; get character from modem; return zero if none available.
-; destroys bc, de, hl.
-inpmdm:
- in mnprts ;Get the port status into A.
- ani input ;See if the input ready bit is on.
- rz ;If not then return.
- in mnport ;If so, get the char.
-
- ret ; return with character in A
-
-
-;
-; flsmdm - flush comm line.
-; Modem is selected.
-; Currently, just gets characters until none are available.
-
-flsmdm: call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-;
-; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not.
-lptstat:
- xra a ; assume it is ok.. this may not be necessary
- ret
-
-;
-; outlpt - output character in E to printer
-; console is selected.
-; preserves de.
-outlpt:
- push d ; save DE in either case
- ana a ; if A = 0 do nothing,
- jz outlp1 ; [30] if a=0 do nothing
- mvi c,lstout
- call bdos ;Char to printer
-outlp1: pop d ; restore saved register pair
- ret
-;
-
-;
-; Screen manipulation routines
-; csrpos - move to row B, column C
-;
-; csrpos for terminals that use a leadin sequence followed
-; by (row + 31.) and (column + 31.)
-;
-IF NOT (bbII OR ampro) ;[obs I think ]
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,h ; get row
- adi (' '-1) ; space is row one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,l ; get column
- adi (' '-1) ; space is column one
- mov e,a
- jmp outcon ; output it and return
-ENDIF ; NOT bbII OR ampro
-
-;
-; delchr - make delete look like a backspace. Unless delete is a
-; printing character, we just need to print a backspace
-; (we'll output clrsp afterwards)
-delchr:
-
-IF bbI
- lxi d,delstr
- jmp prtstr
-ENDIF;bbI
-
-
-IF NOT bbI
- mvi e,bs ;get a backspace
- jmp outcon
-ENDIF;NOT bbI
-
-; erase the character at the current cursor position
-clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the current line
-clrlin: lxi d,eralin
- jmp prtstr
-
-; erase the whole screen, and go home. preserves b (but not c)
-clrtop: lxi d,erascr
- jmp prtstr
-
-; If its a BigBoard or Ampro, we need a terminal, so link to CPXVDU.ASM
-IF bbII
-sysver: db 'Big Board II$'
-ENDIF;bbII
-
-IF ampro
-sysver: db 'Ampro Little Board$'
-ENDIF;ampro
-
-IF (bbII AND lasm) ; we need a terminal as well
-LINK CPXVDU.ASM
-ENDIF ;(bbII AND lasm)
-
-IF (ampro AND lasm) ; we need a terminal as well
-LINK CPXVDU.ASM
-ENDIF ;(ampro AND lasm)
-
-;If here, we are Kaypro or Xerox 820, or if from M80, we should skip
-; a few lines if Bigboard.
-
-IF kpii
-sysver:
-ttytyp: db 'Kaypro II$'
-outlin: db subt,cr,lf,tab,tab,'$'
-erascr: db subt,'$' ;Clear screen and home.
-eralin: db cr,18H,'$' ;Clear line.
-curldn: db esc,'=$' ;Cursor lead-in
-delstr: db bs,' ',bs,bs,'$' ; adjust for echoing delete character
-ttab: ;Table start location.
-ta: db 0BH,'$',0,0 ;Cursor up.
-tb: db 0AH,'$',0,0 ;Cursor down.
-tc: db 0CH,'$',0,0 ;Cursor right.
-td: db bs,'$',0,0 ;Cursor left
-te: db subt,'$',0,0 ;Clear display
-tf: db esc,'G$',0 ; Enter Graphics Mode (select Greek)
-tg: db esc,'A$',0 ; Exit Graphics mode (select ASCII)
-th: db 1EH,'$',0,0 ; Cursor home. [UTK016]
-ti: db esc,'E','$',0 ; Reverse linefeed. (insert line)
-tj: db 'W'-100O,'$',0,0 ; Clear to end of screen.
-tk: db 'X'-100O,'$',0,0 ; Clear to end of line.
-ENDIF ; kpii
-;
-
-IF xer820
-ttytyp:
-sysver: db 'Xerox 820$'
-outlin: db subt,cr,lf,tab,tab,'$'
-erascr: db subt,'$' ;Clear screen and home.
-eralin: db cr,18H,'$' ;Clear line.
-curldn: db esc,'=$' ;Cursor lead-in
-delstr: db bs,' ',bs,bs,'$' ; adjust for echoing delete character
-ttab: ;Table start location.
-ta: db 0BH,'$',0,0 ;Cursor up.
-tb: db 0AH,'$',0,0 ;Cursor down.
-tc: db 0CH,'$',0,0 ;Cursor right.
-td: db bs,'$',0,0 ;Cursor left
-te: db subt,'$',0,0 ;Clear display
-tf: db '$',0,0,0 ; Enter Graphics Mode (can't)
-tg: db '$',0,0,0 ; Exit Graphics mode (can't)
-th: db 1EH,'$',0,0 ; Cursor home. [UTK016]
-ti: db 0BH,'$',0,0 ; Reverse linefeed. (cursor up)
-tj: db 11H,'$',0,0 ; Clear to end of screen.
-tk: db 18H,'$',0,0 ; Clear to end of line.
-ENDIF ; xer820
-ovlend equ $ ; End of overlay
-
- END
+IF NOT lasm
+.printx * CPXBBI.ASM *
+ENDIF ;NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.08
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+;
+;
+; revision history:
+;
+;edit 4, 7-Jan-1991 by MF. Added code to support the Ampro Little Board.
+; The code was contributed by Jay S. Rouman; 913 North Drive;
+; Mt. Pleasant, MI 48858 (voice (517)773-7887).
+; edit 3, 23 July by OBSchou to massage file to suit CPXCOM.ASM
+;
+; edit 2 23 May 1987 by C.J.MILES@UMRCC.
+; Reorganised file to be similar in structure to that
+; of the Amstrad sys-dep file. Added hangup in clear
+; screen options in CONNECT mode.
+;
+; edit 1 10 May 1987 by Chris Miles (C.J.MILES@UMRCC)
+; Removed Kaypro, Xerox and Big Board from CPXSYS.ASM
+; and grouped them into this file as CPXBBI.ASM.
+;
+;
+;
+; Original code broken off and modified by:
+;
+; Chris Miles
+; 344, Claremont Road,
+; Rusholme,
+; MANCHESTER,
+; M14 6WB.
+;
+; Tel: (061) 226 7839
+;
+
+;
+; *** MAIN CODE START ***
+;
+;
+; Keep module name, edit number, and last revision date in memory.
+
+sysedt: db 'CPXSYS.ASM (35) 01-Dec-86$'
+family: db 'CPXBBI.ASM (4) 7-Jan-1991$'
+
+
+; Assembly time message announcing which version we're building
+
+IF kpii
+.printx * Assembling Kaypro II KERMIT-80 *
+ENDIF
+
+IF xer820
+.printx * Assembling Xerox 820 KERMIT-80 *
+ENDIF
+
+IF bbII
+.printx * Assembling BigBoard II KERMIT-80 *
+ENDIF
+
+IF ampro
+.printx * Assembling Ampro Little Board KERMIT-80 *
+ENDIF
+
+z80 EQU TRUE ; They all use Z80s
+
+IF xer820
+defesc EQU ']'-100O ;The default escape character for Xerox
+ENDIF;xer820
+
+IF kpII
+defesc EQU '\'-100O ;The default escape character for Kaypro
+ENDIF;kpII
+
+; If one of the above, default to VT52-EMULATION ON.
+IF kpII OR xer820
+vtval EQU 1
+ENDIF;kpII OR xer820
+
+
+;
+; Specific machine hardware information
+;
+IF bbI
+mnport equ 04h ; Modem data port
+mnprts equ 06h ; Modem status port
+output equ 04h ; Transmit buffer empty
+input equ 01h ; Receive data available
+baudrt equ 00h ; Baud rate port for channel A
+ENDIF;bbI
+
+
+IF bbII
+mnport equ 80h ; Modem data port (SIO channel A)
+mnprts equ 81h ; Modem status port
+output equ 04h ; Transmit buffer empty
+input equ 01h ; Receive data available
+baudrt equ 89h ; Baud rate port for channel A
+ENDIF;bbII
+
+IF ampro
+mnport equ 88h ; Modem data port (SIO channel B)
+mnprts equ 8Ch ; Modem status port
+output equ 04h ; Transmit buffer empty
+input equ 01h ; Receive data available
+baudrt equ 50h ; Baud rate port for channel B
+ENDIF;ampro
+;
+
+sysxin: ;continuation of system initialisation code
+ lxi d,siotbl ; Load the address of the status able
+ mvi c,siolen ; Length of status table
+siolup: ; Loop back here for each command byte
+ ldax d ; Load the first byte into A
+ inx d ; Index the pointer
+ out mnprts ; Send it to the status port
+ dcr c ; Decrement the byte counter
+ jnz siolup ; Jump back for more commands
+ ret ; return from system-dependent routine
+
+; List of commands to set up SIO channel A for asynchronous operation.
+
+siotbl: DB 18H ; Channel reset
+ DB 18H ; another, in case register 0 wasn't selected
+ DB 04H ; Select register 4
+ DB 44H ; 1 stop bit, clock*16
+ DB 01H ; Select register 1
+ DB 00H ; No interrupts enabled
+ DB 03H ; Select register 3
+ DB 0C1H ; Rx enable, 8 bit Rx character
+ DB 05H ; Select register 5
+ DB 0EAH ; Tx enable, 8 bit Tx character,
+ ; raise DTR and RTS
+siolen equ $-siotbl ; length of command list
+
+
+;
+; sysexit - System-dependent termination processing
+; if we've changed anything, this is our last
+; chance to put it back.
+;
+sysexit:
+ ret
+
+;
+; syscon - System-dependent processing for start
+; of CONNECT command.
+;
+syscon:
+ lxi d,conmsg
+ call prtstr
+ ret
+
+conmsg: ; Messages printed when entering transparent (CONNECT) mode:
+ db cr,lf,'$'
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+ ret
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing
+; all the system-independent escape sequences.
+;
+sysinh:
+ lxi d,inhlps ; we got options...
+ call prtstr ; print them.
+ ret
+
+
+; additional, system-dependent help for transparent mode
+; (two-character escape sequences)
+inhlps:
+ db cr,lf,'B Transmit a BREAK'
+ db cr,lf,'H Hangup using DTR'
+ db cr,lf,'W Wipe screen clear'
+ db '$'
+
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:-
+; non-skip: sequence has been processed
+; skip : sequence was not recognized
+;
+sysint: ani 137O ; convert lower case to upper, for testing...
+ cpi 'B' ; send break ?
+ jz sendbr ; then jump to send break routine
+ cpi 'H' ; hang up ?
+ jz hangup ; then jump to hangup routine
+ cpi 'W' ; clear screen ?
+ jz clrtop ; then jump to clear screen routine
+ jmp rskp ; take skip return - command not recognized.
+
+;
+; Hangup and Break routines
+;
+hangup:
+ mvi d,0ah ; set up hangup bit mask
+ mvi e,255 ; time for hangup is 2 1/2 secs
+ jmp setbit ; skip Tx empty test
+
+sendbr:
+ mvi d,9ah ; set up break bit mask
+ mvi e,30 ; time for break is 300 ms
+
+sndbr1: mvi a,1 ; select Read Register 1
+ out mnprts
+ in mnprts ; read the contents
+ ani 1 ; test "all done" flag
+ jz sndbr1 ; loop until it's nonzero.
+;
+; Next, set the break or DTR bit on the SIO
+;
+setbit:
+ mvi a,5 ; select Write Register 5
+ out mnprts
+ mvi a,6ah ; Tx enable, 8 bit Tx character,
+ ora d ; OR with appropriate bit mask
+ out mnprts ;
+;
+; Now, delay for duration of hangup or break
+ mov a,e ; delay count
+ call delay
+;
+; Time's up. Put transmitter back in normal state and return.
+ mvi a,5 ; select Write Register 5
+ out mnprts
+ mvi a,0eah ; Tx enable, 8 bit Tx character,
+ out mnprts ;.
+ ret ; done.
+
+; sysflt - system-dependent filter
+; called with character in E.
+; if this character should not be printed, return with A = zero.
+; preserves bc, de, hl.
+; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
+;
+sysflt:
+ mov a,e ; get character for testing
+ ret
+
+;
+; sysbye - system-dependent processing for BYE command.
+;
+sysbye:
+ ret
+;
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; this
+; value is also stored in 'speed'.
+;
+sysspd:
+
+; Set the speed for bigboard II
+IF bbII
+ di ; don't let anything between the data bytes
+ mvi a,01000111b ; get the command byte (load time constant)
+ out baudrt ; output it to CTC
+ mov a,e ; Get the parsed value.
+ out baudrt ; Tell the baud rate generator.
+ ei ; end of critical section
+ ret
+ENDIF;bbII
+
+
+; Set the speed for bigboard I
+IF bbI
+ mov a,e ; get the parsed value
+ out baudrt ; Tell the baud rate generator.
+ ret
+ENDIF;bbI
+
+; set the speed for the Ampro Little Board
+if ampro
+ mvi e,3fh ; offset to port b ctc 3f hex bytes
+ call getbios
+ mvi a,47h ; counter mode,ctc reset,value follows
+ mov m,a ; store value
+ lda speed+1 ; get ctc divisor
+ inx h ; location of ctc divisor
+ mov m,a ; store new divisor
+;
+; set up wr4 clock divisor according to mspeed
+;
+ mvi e,50h ; offset to dart wr4
+ call getbios
+ mvi a,3fh ; mask for wr4 clock bits
+ ana m ; mask off bits
+ mov m,a ; and save to wr4
+ lda speed ; get clock flag
+ ora a ; set flags, zero = 300 bps
+ mvi a,80h ; x32 clock bit
+ jz lbps ; setup wr4 for 300 bps x32 clock
+;
+; set up wr4 value for 1200 bps x16 clock 'hl' has wr4 loc
+;
+hbps: mvi a,40h ; x16 clock
+;
+; setup wr4 value for 300 bps x32 clock 'hl' has wr4 loc
+;
+lbps: ora m ; set clock bits saving parity
+ mov m,a ; store new clock divisor to wr4 value
+;
+; initialize sio/dart
+;
+intsio: lxi h,intend
+ push h ; set up for return
+ mvi e,36h ; offset to ioinit
+ call getbios
+ pchl ; we pushed return address
+intend: ret
+
+;
+; return bios location in 'hl' called with offset in 'e'
+;
+getbios:
+ lhld 1 ; get bios location
+ mvi d,0 ; clear 'd'
+ dad d
+ ret
+;
+ENDIF;ampro
+
+;
+; Speed tables
+; (Note that speed tables MUST be in alphabetical order for later
+; lookup procedures, and must begin with a value showing the total
+; number of entries. The speed help tables are just for us poor
+; humans.
+
+; db string length,string,divisor (2 identical bytes or 1 word)
+; [Toad Hall]
+
+IF bbI
+spdtbl: db 10h ;16 entries
+ db 03h,'110$', 02h,02h
+ db 04h,'1200$', 07h,07h
+ db 05h,'134.5$', 03h,03h
+ db 03h,'150$', 04h,04h
+ db 04h,'1800$', 08h,08h
+ db 05h,'19200$', 0fh,0fh
+ db 04h,'2000$', 09h,09h
+ db 04h,'2400$', 0ah,0ah
+ db 03h,'300$', 05h,05h
+ db 04h,'3600$', 0bh,0bh
+ db 04h,'4800$', 0ch,0ch
+ db 02h,'50$', 00h,00h
+ db 03h,'600$', 06h,06h
+ db 04h,'7200$', 0dh,0dh
+ db 02h,'75$', 01h,01h
+ db 04h,'9600$', 0eh,0eh
+
+sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
+ db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'
+ENDIF;bbI
+
+IF bbII
+spdtbl: db 8 ; 8 entries
+ db 04h,'1200$', 20h,20h
+ db 05h,'19200$', 02h,02h
+ db 04h,'2400$', 10h,10h
+ db 03h,'300$', 80h,80h
+ db 05h,'38400$', 01h,01h
+ db 04h,'4800$', 08h,08h
+ db 03h,'600$', 40h,40h
+ db 04h,'9600$', 04h,04h
+
+sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600 19200 38400$'
+ENDIF;bbII
+
+
+IF ampro
+spdtbl: db 6 ; 6 entries
+ db 04h,'1200$', 1,104
+ db 04h,'2400$', 1,52
+ db 03h,'300$', 0,208
+ db 04h,'4800$', 1,26
+ db 03h,'600$', 1,208
+ db 04h,'9600$', 1,13
+
+sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$'
+ENDIF;ampro
+
+; This is the system-dependent SET PORT command.
+; HL contains the argument from the command table.
+;
+sysprt:
+ ret
+;
+
+prttbl equ 0 ; SET PORT is not supported
+prhtbl equ 0
+
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; preserves BC, DE, HL.
+;
+selmdm:
+selcon:
+ ret
+;
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+ mvi c,dconio ;Direct console I/O BDOS call.
+ mvi e,0FFH ;Input.
+ call BDOS
+ ret
+;
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+
+ mvi c,dconio ;Console output bdos call.
+ call bdos ;Output the char to the console.
+
+ ret
+;
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+outmdm:
+ in mnprts ;Get the output done flag.
+ ani output ;Is it set?
+ jz outmdm ;If not, loop until it is.
+ mov a,e
+ out mnport ;Output it.
+ ret
+
+
+;
+; get character from modem; return zero if none available.
+; destroys bc, de, hl.
+inpmdm:
+ in mnprts ;Get the port status into A.
+ ani input ;See if the input ready bit is on.
+ rz ;If not then return.
+ in mnport ;If so, get the char.
+
+ ret ; return with character in A
+
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+
+flsmdm: call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+;
+; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not.
+lptstat:
+ xra a ; assume it is ok.. this may not be necessary
+ ret
+
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+outlpt:
+ push d ; save DE in either case
+ ana a ; if A = 0 do nothing,
+ jz outlp1 ; [30] if a=0 do nothing
+ mvi c,lstout
+ call bdos ;Char to printer
+outlp1: pop d ; restore saved register pair
+ ret
+;
+
+;
+; Screen manipulation routines
+; csrpos - move to row B, column C
+;
+; csrpos for terminals that use a leadin sequence followed
+; by (row + 31.) and (column + 31.)
+;
+IF NOT (bbII OR ampro) ;[obs I think ]
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; restore coordinates
+ mov a,h ; get row
+ adi (' '-1) ; space is row one
+ mov e,a
+ push h
+ call outcon ; output row
+ pop h
+ mov a,l ; get column
+ adi (' '-1) ; space is column one
+ mov e,a
+ jmp outcon ; output it and return
+ENDIF ; NOT bbII OR ampro
+
+;
+; delchr - make delete look like a backspace. Unless delete is a
+; printing character, we just need to print a backspace
+; (we'll output clrsp afterwards)
+delchr:
+
+IF bbI
+ lxi d,delstr
+ jmp prtstr
+ENDIF;bbI
+
+
+IF NOT bbI
+ mvi e,bs ;get a backspace
+ jmp outcon
+ENDIF;NOT bbI
+
+; erase the character at the current cursor position
+clrspc: mvi e,' '
+ call outcon
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the current line
+clrlin: lxi d,eralin
+ jmp prtstr
+
+; erase the whole screen, and go home. preserves b (but not c)
+clrtop: lxi d,erascr
+ jmp prtstr
+
+; If its a BigBoard or Ampro, we need a terminal, so link to CPXVDU.ASM
+IF bbII
+sysver: db 'Big Board II$'
+ENDIF;bbII
+
+IF ampro
+sysver: db 'Ampro Little Board$'
+ENDIF;ampro
+
+IF (bbII AND lasm) ; we need a terminal as well
+LINK CPXVDU.ASM
+ENDIF ;(bbII AND lasm)
+
+IF (ampro AND lasm) ; we need a terminal as well
+LINK CPXVDU.ASM
+ENDIF ;(ampro AND lasm)
+
+;If here, we are Kaypro or Xerox 820, or if from M80, we should skip
+; a few lines if Bigboard.
+
+IF kpii
+sysver:
+ttytyp: db 'Kaypro II$'
+outlin: db subt,cr,lf,tab,tab,'$'
+erascr: db subt,'$' ;Clear screen and home.
+eralin: db cr,18H,'$' ;Clear line.
+curldn: db esc,'=$' ;Cursor lead-in
+delstr: db bs,' ',bs,bs,'$' ; adjust for echoing delete character
+ttab: ;Table start location.
+ta: db 0BH,'$',0,0 ;Cursor up.
+tb: db 0AH,'$',0,0 ;Cursor down.
+tc: db 0CH,'$',0,0 ;Cursor right.
+td: db bs,'$',0,0 ;Cursor left
+te: db subt,'$',0,0 ;Clear display
+tf: db esc,'G$',0 ; Enter Graphics Mode (select Greek)
+tg: db esc,'A$',0 ; Exit Graphics mode (select ASCII)
+th: db 1EH,'$',0,0 ; Cursor home. [UTK016]
+ti: db esc,'E','$',0 ; Reverse linefeed. (insert line)
+tj: db 'W'-100O,'$',0,0 ; Clear to end of screen.
+tk: db 'X'-100O,'$',0,0 ; Clear to end of line.
+ENDIF ; kpii
+;
+
+IF xer820
+ttytyp:
+sysver: db 'Xerox 820$'
+outlin: db subt,cr,lf,tab,tab,'$'
+erascr: db subt,'$' ;Clear screen and home.
+eralin: db cr,18H,'$' ;Clear line.
+curldn: db esc,'=$' ;Cursor lead-in
+delstr: db bs,' ',bs,bs,'$' ; adjust for echoing delete character
+ttab: ;Table start location.
+ta: db 0BH,'$',0,0 ;Cursor up.
+tb: db 0AH,'$',0,0 ;Cursor down.
+tc: db 0CH,'$',0,0 ;Cursor right.
+td: db bs,'$',0,0 ;Cursor left
+te: db subt,'$',0,0 ;Clear display
+tf: db '$',0,0,0 ; Enter Graphics Mode (can't)
+tg: db '$',0,0,0 ; Exit Graphics mode (can't)
+th: db 1EH,'$',0,0 ; Cursor home. [UTK016]
+ti: db 0BH,'$',0,0 ; Reverse linefeed. (cursor up)
+tj: db 11H,'$',0,0 ; Clear to end of screen.
+tk: db 18H,'$',0,0 ; Clear to end of line.
+ENDIF ; xer820
+ovlend equ $ ; End of overlay
+
+ END
diff --git a/cpxbee.asm b/cpxbee.asm
index 7333c2a..883bce2 100644
--- a/cpxbee.asm
+++ b/cpxbee.asm
@@ -1,996 +1,996 @@
-IF NOT lasm
-.printx * CPXBEE.ASM *
-ENDIF ;NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.09
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-;
-;
-; revision history:
-;
-; edit 1, 1st September 1990
-; Original version by Russell Lang <rjl@monu1.cc.monash.edu.au>
-; The 'microbee' is designed and manufactured in Australia
-; by Microbee Systems Ltd (previously Applied Technology).
-; The microprocessor is a Z80 at 3.375MHz.
-; The video screen is memory mapped from 0F000h to 0F7FFh,
-; with Programmable Characters 80-FF from 0F800h to 0FFFFh.
-; The serial and parallel ports are implemented using a Z80 PIO.
-; The early model microbees were ROM-Basic computers with up
-; to 32k of battery backed RAM. Later models dropped the
-; ROM-Basic and added disk drives and CP/M. The disk systems
-; include the 56k (64k) APC (5.25" drives), 64k Computer-In-A-Book
-; (3.5"), 128k Dynamic (5.25" or 3.5"), 256TC (3.5").
-;
-; This version of kermit was developed on a 56k APC.
-; It has been tested on 56k, 64k, 128k and 256k Microbees.
-;
-; The serial port is implemented in software NOT hardware.
-; A special transmit routine allows simultaneous receiving
-; for all speeds except 75/1200, 1200/75, 4800, 9600.
-; The receive routine is interrupt driven with a 2 kbyte buffer.
-; The 9600 bit/s speed is marginal on receive - if the transmitter
-; is slightly fast (more than about 1%), the serial routine will
-; not have enough time to put the character in the buffer before
-; the next character arrives.
-
-
-;
-; *** MAIN CODE START ***
-;
-;
-; Keep module name, edit number, and last revision date in memory.
-
-sysedt: db 'CPXSYS.ASM (35) 01-Dec-86$'
-family: db 'CPXBEE.ASM (1) 01-Sep-90$'
-
-
-; Assembly time message announcing which version we're building
-
-.printx * Assembling Microbee Kermit-80 *
-
-z80 EQU TRUE ; They all use Z80s
-
-defesc EQU ']'-100O ;The default escape character for Microbee
-
-vtval EQU 0 ; use default emulation which is adm3a superset
-
-;
-sysxin: ;continuation of system initialisation code
- ; set up baud rate
- lxi h,t300
- shld speed
- xchg
- call setbaud
- ; change the interrupt vector so that we intercept rs232 input
- db 0EDh,57h ;ld a,i ;get old interrupt reg
- sta oldint
- mvi a,int ;new value
- db 0EDh,47h ;ld i,a
- ret ; return from system-dependent routine
-
-
-;
-; sysexit - System-dependent termination processing
-; if we've changed anything, this is our last
-; chance to put it back.
-;
-sysexit:
- lda oldint ;restore old interrupt reg
- db 0EDh,47h ;ld i,a
- ret
-
-;
-; syscon - System-dependent processing for start
-; of CONNECT command.
-;
-syscon:
- lxi d,conmsg
- call prtstr
- ret
-
-conmsg: ; Messages printed when entering transparent (CONNECT) mode:
- db cr,lf,'$'
-;
-; syscls - system-dependent close routine
-; called when exiting transparent session.
-;
-syscls:
- ret
-;
-; sysinh - help for system-dependent special functions.
-; called in response to <escape>?, after listing
-; all the system-independent escape sequences.
-;
-sysinh:
- lxi d,inhlps ; we got options...
- call prtstr ; print them.
- ret
-
-
-; additional, system-dependent help for transparent mode
-; (two-character escape sequences)
-inhlps:
- db cr,lf,'B Transmit a BREAK (0.3s)'
- db cr,lf,'L Transmit a LONG BREAK (1.8s)'
- db cr,lf,'W Wipe screen clear'
- db '$'
-
-; sysint - system dependent special functions
-; called when transparent escape character has been typed;
-; the second character of the sequence is in A (and in B).
-; returns:-
-; non-skip: sequence has been processed
-; skip : sequence was not recognized
-;
-sysint: ani 137O ; convert lower case to upper, for testing...
- cpi 'B' ; send break ?
- jz sendbr ; then jump to send break routine
- cpi 'L' ; long break ?
- jz longbr ; then jump to long break routine
- cpi 'W' ; clear screen ?
- jz clrtop ; then jump to clear screen routine
- jmp rskp ; take skip return - command not recognized.
-
-;
-; Break routines
-;
-longbr:
- mvi e,180 ; time for long break is 1800 ms
- jmp setbit
-
-sendbr:
- mvi e,30 ; time for break is 300 ms
-
-setbit:
- in portb
- ani 0dfh ; mask with tx bit
- out portb
-;
-; Now, delay for duration of hangup or break
- mov a,e ; delay count
- call delay
-;
-; Time's up. Put transmitter back in normal state and return.
- in portb
- ori 20h ; mask with tx bit
- out portb
- ret ; done.
-
-; sysflt - system-dependent filter
-; called with character in E.
-; if this character should not be printed, return with A = zero.
-; preserves bc, de, hl.
-; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-;
-sysflt:
- mov a,e ; get character for testing
- ret
-
-;
-; sysbye - system-dependent processing for BYE command.
-;
-sysbye:
- ret
-
-;
-; This is the system-dependent command to change the baud rate.
-; DE contains the two-byte value from the baud rate table; this
-; value is also stored in 'speed'.
-;
-sysspd:
- call setbaud
- ret
-
-;
-; Speed tables
-; (Note that speed tables MUST be in alphabetical order for later
-; lookup procedures, and must begin with a value showing the total
-; number of entries. The speed help tables are just for us poor
-; humans.
-
-; db string length,string,divisor (2 identical bytes or 1 word)
-; [Toad Hall]
-
-spdtbl: db 11 ;11 entries
- db 03h,'110$'
- dw t110
- db 04h,'1200$'
- dw t1200
- db 07h,'1200/75$'
- dw t1275
- db 03h,'150$'
- dw t150
- db 04h,'2400$'
- dw t2400
- db 03h,'300$'
- dw t300
- db 04h,'4800$'
- dw t4800
- db 03h,'600$'
- dw t600
- db 02h,'75$'
- dw t75
- db 07h,'75/1200$'
- dw t7512
- db 04h,'9600$'
- dw t9600
-
-sphtbl: db cr,lf,'75 75/1200 110 150 300 600 1200 1200/75'
- db ' 2400 4800 9600$'
-
-
-;
-; This is the system-dependent SET PORT command.
-sysprt:
- ret
-
-prttbl equ 0 ; SET PORT is not supported
-prhtbl equ 0
-
-
-;
-; selmdm - select modem port
-; selcon - select console port
-; selmdm is called before using inpmdm or outmdm;
-; selcon is called before using inpcon or outcon.
-; preserves BC, DE, HL.
-;
-selmdm:
-selcon:
- ret
-;
-; Get character from console, or return zero.
-; result is returned in A. destroys bc, de, hl.
-;
-inpcon:
- mvi c,dconio ;Direct console I/O BDOS call.
- mvi e,0FFH ;Input.
- call BDOS
- ret
-;
-;
-; Output character in E to the console.
-; destroys bc, de, hl
-;
-outcon:
-
- mvi c,dconio ;Console output bdos call.
- call bdos ;Output the char to the console.
- ret
-
-
-
-;
-;
-; outmdm - output a char from E to the modem.
-; the parity bit has been set as necessary.
-; returns nonskip; bc, de, hl preserved.
-outmdm:
-;
- push psw
- push b
- push d
- push h
- mov a,e
- lxi h,outm2 ; return address
- push h
- lhld txcall
- pchl ; send to rs232 port
-outm2: pop h
- pop d
- pop b
- pop psw
- ret
-
-
-;
-; get character from modem; return zero if none available.
-; bc, de, hl preserved.
-inpmdm:
- call rsin ; get char if available
- ret ; return with character in A
-
-
-;
-; flsmdm - flush comm line.
-; Modem is selected.
-; Currently, just gets characters until none are available.
-flsmdm: call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-
-;
-; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
-lptstat:
- lda pflag
- ret
-
-;
-; outlpt - output character in E to printer
-; console is selected.
-; preserves de.
-outlpt:
- push d ; save DE in either case
- ana a ; if A = 0 do nothing,
- jz outlp1 ; [30] if a=0 do nothing
- mov a,e
- call parout
-outlp1: pop d ; restore saved register pair
- ret
-
-
-;
-;
-; Screen manipulation routines
-; csrpos - move to row B, column C
-;
-; csrpos for terminals that use a leadin sequence followed
-; by (row + 31.) and (column + 31.)
-;
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,h ; get row
- adi (' '-1) ; space is row one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,l ; get column
- adi (' '-1) ; space is column one
- mov e,a
- jmp outcon ; output it and return
-
-;
-; delchr - make delete look like a backspace. Unless delete is a
-; printing character, we just need to print a backspace
-; (we'll output clrsp afterwards)
-delchr:
- lxi d,delstr
- jmp prtstr
-
-
-; erase the character at the current cursor position
-clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the current line
-clrlin: lxi d,eralin
- jmp prtstr
-
-; erase the whole screen, and go home
-clrtop: lxi d,erascr
- jmp prtstr
-
-
-sysver: db 'Microbee$'
-outlin: db 1AH,cr,lf,tab,'$' ;(Clear screen, home cursor)
-erascr: db 1AH,'$' ;Clear screen and go home.
-eralin: db cr,esc,'T$' ;Clear line.
-delstr: db bs,'$' ; Adjust for delete
-curldn: db esc,'=$' ;Cursor lead-in
-ttab: ;Table start location.
-ta: db ('K'-100O),'$',0,0 ;Cursor up.
-tb: db 12O,'$',0,0 ;Cursor down.
-tc: db ('L'-100O),'$',0,0 ;Cursor right.
-td: db bs,'$',0,0 ;Cursor left.
-te: db subt,'$',0,0 ;Clear screen.
-tf: db '$',0,0,0 ;(can't) Enter graphics mode
-tg: db '$',0,0,0 ;(can't) Exit graphics mode
-th: db ('^'-100O),'$',0,0 ;Cursor home.
-ti: db ('K'-100O),'$',0,0 ;Reverse linefeed.
-tj: db esc,'Y$',0 ;Clear to end of screen.
-tk: db esc,'T$',0 ;Clear to end of line.
-
-
-;Microbee software serial port routines
-porta equ 0
-portb equ 2
-
-
-; interrupt vectors
-; We change the Z80 Interrupt register to point to these vectors.
-; Instead of trying to identify a particular Microbee system,
-; we just put vectors here for all systems.
-;
-; known vectors are:
-; 48h : 56k (64k apc) - tested 19-Jun-1990
-; 48k : 64k - tested 01-Sep-1990
-; 50h : dreamdisk (3rd party disk for Microbee)
-; e0h : 128k - tested 19-Jun-1990
-; e0h : 256k - tested 01-Sep-1990
-
- org ($ and 0ff00h) + 100h
-int equ $/256 ; byte for interrupt register
-
- dw inta ; printer vector
- dw intb ; rs232 vector
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
- dw inta
- dw intb
-
-
-; tables for baud rates
-t75: db 124,13 ; full delay
- db 55,7 ; semi delay
- db 168,255 ; txrx delay
- dw trout ; address of subroutine to transmit char
-t7512: db 124,13 ; 75R/1200T
- db 55,7
- db 194,1 ; txout delay
- dw txout
-t110: db 129,9
- db 55,5
- db 5,217
- dw trout
-t150: db 59,7
- db 23,4
- db 2,158
- dw trout
-t300: db 26,4
- db 134,2
- db 3,75
- dw trout
-t600: db 139,2
- db 191,1
- db 2,34
- dw trout
-t1200: db 195,1
- db 90,1
- db 3,13
- dw trout
-t1275: db 195,1 ; 1200R/75T
- db 90,1
- db 124,13
- dw txout
-t2400: db 94,1
- db 40,1
- db 2,3
- dw trout
-t4800: db 44,1
- db 15,1
- db 44,1
- dw txout
-t9600: db 19,1
- db 1,1
- db 19,1
- dw txout
-
-
-; copy table entries to locations used by serial routines
-setbaud:
- lxi h,fulldel
- mvi b,8
-setb2: ldax d
- mov m,a
- inx h
- inx d
- dcr b
- jnz setb2
- ret
-
-
-;transmit character in E
-; destroys all regs
-txout: mvi b,ntotal ;total number of bits to send
- di
- in portb ;c = portb with tx bit zeroed
- ani 0dfh
- mov c,a
- ora a ;carry=0 (start bit)
-txout2: mov a,c ; 4T
- jnc txout4 ;10T skip if space
- ori 20h ; 3T (average) set mark
-txout4: out portb ;11T
- lhld txrxdel ;16T
-txout6: dcr l ;delay
- jnz txout6
- dcr h
- jnz txout6 ; 14*L + 14*H + 3584*(H-1)
- stc ; 4T carry=1 (stop bit)
- mov a,e ; 4T shift next bit to carry
- rar ; 4T
- mov e,a ; 4T
- dcr b ; 4T
- jnz txout2 ;10T
- ;loop = 74T + (delay loop)
- ei
- ret
-
-
-;
-;transmit character in E
-;simultaneous receive char if necessary
-trout: mov a,e
- mvi b,ndata
- lxi h,0
-tro2: rrc ;shift tx char to hl
- mov c,a
- mov a,l
- ral
- mov l,a
- mov a,h
- ral
- mov h,a
- mov a,c ;recover
- dcr b
- jnz tro2
-tro10: mvi b,tqfudge ;adjust char in hl to align with
- ;tx bit of portb
-tro12: stc ; pad out
- mov a,l
- ral
- mov l,a
- mov a,h
- ral
- mov h,a
- dcr b
- jnz tro12
- mvi a,0ffh ;flag to say we are not receiving
- sta trtemp ;save it
- mvi d,tqbit ;total number of qtr bits to send
- in portb ;b = portb with tx bit zeroed
- ani 0dfh
- mov b,a
- mvi e,0 ;we are not receiving yet
-tro14: in portb
- ori 8h ;test CTS
- jz tro14 ;loop till Clear To Send
- out 09h ;Color Wait OFF
- di
- call qbit
- lda trtemp ;are we receiving
- ora a
- jnz tro22 ;skip if not
- in portb ;is last bit a mark?
- ori 10h
- jz tro18 ;skip if mark (don't wait for stop)
- lhld fulldel ;delay to stop bit
-tro16: dcr l
- jnz tro16
- dcr h
- jnz tro16
-tro18: lhld wptr ; check buffer
- xchg
- lhld rptr
- dcx d ; decrement queue pointer
- mov a,d
- ora e
- jnz tro20 ; skip if no queue wrap around
- lxi d,maxque-1 ; wrap around
-tro20: mov a,l ; sub hl,de
- sub e
- mov l,a
- mov a,h
- sbb d
- mov h,a
- ora l ; check for zero
- jz tro22 ; skip if buffer full
- xchg
- shld wptr ; update queue
- lxi d,rqueue
- dad d
- mov m,c ; put char in queue
-tro22: ei
- ret ;ret
-
-
-; routine for quarter bit timing
-; for transmit and simultaneous receive
-; total execution time is 223T + L*14T + H*34T
-qbit: call txrx ;17T + 162T
- lda txrxdel ;13T
-qbit2: dcr a ; 4T
- jnz qbit2 ;10T
- lda txrxdel+1 ;13T
-qbit4: dcr a ; 4T
- nop ; 4T
- nop ; 4T
- nop ; 4T
- nop ; 4T
- nop ; 4T
- jnz qbit4 ;10T
- mov a,d ; 4T Check if still sending or receiving
- ora e ; 4T
- jnz qbit ;10T
- ret
-
-
-;simultaneous transmit/receive
-;do next quarter bit
-; regs: b = portb with tx bit zeroed
-; c = character being received
-; d = number of qtr bits remaining to send
-; e = number of qtr bits remaining to receive (0 if not receiving)
-; hl = character being transmitted
-;this subroutine always executes in 162T (or 163T)
-txrx: mov a,d ; 4T qtr bits remaining to send
- ora a ; 4T
- jz txrx12 ;10T skip if no bits remaining (may be receiving)
- ani 03h ; 7T a complete bit?
- jnz txrx10 ;10T skip if not
- dad h ;11T shift tx bit to bit 5 of h
- mov a,h ; 4T
- ani 20h ; 7T extract tx bit
- ora b ; 4T combine with portb
- out portb ;11T send it
-txrx2: dcr d ; 4T one less qtr bit to send
- ;76T total
-;now receive part
-txrx4: mov a,e ; 4T qtr bits remaining to receive
- ora a ; 4T
- jz txrx16 ;10T skip if not receiving
- ani 3h ; 7T a complete bit?
- jnz txrx14 ;10T skip if not
- in portb ;11T get input
- ani 10h ; 7T extract rx bit
- sui 1 ; 7T bit to carry
- mov a,c ; 4T bit to c
- rar ; 4T
- mov c,a ; 4T
-txrx6: dcr e ; 4T one less qtr bit to receive
-txrx8: ret ;10T
- ;86T total
-
-;come here if transmitting, but not a complete bit
-;delay to match up execution times
-txrx10:
- ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ori 00h ; 7T
- jmp txrx2 ;10T
-
-;come here if not sending (but still receiving)
-;delay to match up execution times
-txrx12: ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- jmp txrx4 ;10T
-
-;come here if receiving (but not a complete bit)
-;delay to match up execution time
-txrx14: ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ori 00h ; 7T
- jmp txrx6 ;10T
-
-;come here if not receiving
-txrx16: in portb ;11T check if start bit
- ani 10h ; 7T
- jz txrx18 ;10T skip if mark
- mvi e,rqbit ; 7T get quarter bit count for receive
- xra a ; 4T
- sta trtemp ;13T store flag to say we are receiving
- ori a ; 7T delay (should be 6T)
- ret ;10T
-
-txrx18: ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- ora a ; 4T
- jmp txrx8 ;10T
-
-
-
-
-; RS232 input interrupt routine
-; stores received character in queue
-; ;semi delay starts here
-intb: ;20T (approx.) for interrupt
- push psw ;11T
- push b ;11T
- push d ;11T
- push h ;11T
- in portb ;11T
- ani 10h ; 7T test input for start bit
- jz intb16 ;10T skip if no start bit.
- out 09h ;11T
- lhld semidel ;16T half bit delay
-intb2: dcr l ; 4T
- jnz intb2 ;10T inner loop 14T*L
- dcr h ; 4T
- jnz intb2 ;10T outer loop (14*H + 256*14*(H-1))T
- mvi e,8 ; 6T number of data bits
- ;semi delay ends here (125T + delay loop)
- ;full delay starts here
-intb4: lhld fulldel ;16T full bit delay
-intb6: dcr l
- jnz intb6
- dcr h
- jnz intb6 ; 14*L + 14*H + 3584*(H-1)
- in portb ;11T test input
- ani 10h ; 7T
- sui 1 ; 7T input bit to carry
- mov a,c ; 4T
- rar ; 4T
- mov c,a ; 4T and then to C
- dcr e ; 4T bit count
- jnz intb4 ;10T loop till all data bits collected
- ;full delay ends here (67T + delay loop)
- in portb
- ani 10h
- jz intb12 ; skip if mark
- lhld fulldel ; wait for stop bit
-intb10: dcr l
- jnz intb10
- dcr h
- jnz intb10
-intb12: lhld wptr ; check buffer
- xchg
- lhld rptr
- dcx d ; decrement queue pointer
- mov a,d
- ora e
- jnz intb14 ; skip if no queue wrap around
- lxi d,maxque-1 ; wrap around
-intb14: mov a,l ; sub hl,de
- sub e
- mov l,a
- mov a,h
- sbb d
- mov h,a
- ora l ; check for zero
- jz intb16 ; skip if buffer full
- xchg
- shld wptr ; update queue
- lxi d,rqueue
- dad d
- mov m,c ; put char in queue
-intb16: pop h
- pop d
- pop b
- pop psw
- ei
- db 0EDh,4Dh ;reti
-
-;
-; get char from serial port buffer.
-; exit: A=char or Z if no char
-rsin: push d
- push h
- lhld rptr
- xchg
- lhld wptr
- mov a,l ;sub hl,de
- sub e
- mov l,a
- mov a,h
- sbb d
- mov h,a
- ora l ;check for zero
- jnz rsi4 ;get char
-rsi2: pop h
- pop d
- ret
-
-rsi4: push psw
- dcx d ; decrement queue pointer
- mov a,d
- ora e
- jnz rsi6 ; skip if no queue wrap around
- lxi d,maxque-1 ; wrap around
-rsi6: pop psw
- xchg
- shld rptr
- lxi d,rqueue
- dad d
- mov e,m ;get char from queue
- ori 0ffh ;set NZ
- mov a,e
- jmp rsi2
-
-; printer routines
-
-inta: sta ptemp
- mvi a,0
- sta pflag
- lda ptemp
- ei
- db 0EDh,4Dh ;reti
-
-parout: push h
- lxi h,pflag
-par2: db 0CBh,46h ;bit 0,(hl)
- jnz par2
- mvi m,0ffh
- out porta
- pop h
- ret
-
-; data storage
-
-oldint: db 0 ; storage for old i reg
-trtemp: db 0
-ptemp: db 0 ;temp storage used by inta interrupt
-pflag: db 0 ;0ffh if waiting for printer. 00h if ready
-
-;receive queue pointers
-maxque equ 2048 ; receiver queue size
-rptr: dw maxque-1
-wptr: dw maxque-1
-
-;transmit
-ndata equ 8 ; 8 data bits
-nstrt equ 1 ; 1 start bit
-nstop equ 1 ; 1 stop bit
-ntotal equ nstrt+ndata+nstop
-rqbit equ 4*(nstrt+ndata) ;number of quarter bits to receive
-tqbit equ 4*(nstrt+ndata+nstop) ;number of quarter bits to transmit
-tqfudge equ 13-nstrt-ndata
-
-;H=0 or L=0 behave as 256
-;receive delays.
-fulldel: dw 0 ; 3584(H-1) + 14H + 14L + 67 cycles
-semidel: dw 0 ; 3584(H-1) + 14H + 14L + 125 cycles
-;1/4 bit transmit and simultaneous tx/rx delay 34H + 14L + 223 cycles
-;or full bit delay 3584(H-1) + 14H + 14L + 74 cycles
-txrxdel: dw 0 ;
-txcall: dw trout ; address of subroutine to transmit char
-
-; receiver queue
-rqueue: ds maxque
-
-
-ovlend equ $ ; End of overlay
-
-IF lasm
- END
-ENDIF
+IF NOT lasm
+.printx * CPXBEE.ASM *
+ENDIF ;NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.09
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+;
+;
+; revision history:
+;
+; edit 1, 1st September 1990
+; Original version by Russell Lang <rjl@monu1.cc.monash.edu.au>
+; The 'microbee' is designed and manufactured in Australia
+; by Microbee Systems Ltd (previously Applied Technology).
+; The microprocessor is a Z80 at 3.375MHz.
+; The video screen is memory mapped from 0F000h to 0F7FFh,
+; with Programmable Characters 80-FF from 0F800h to 0FFFFh.
+; The serial and parallel ports are implemented using a Z80 PIO.
+; The early model microbees were ROM-Basic computers with up
+; to 32k of battery backed RAM. Later models dropped the
+; ROM-Basic and added disk drives and CP/M. The disk systems
+; include the 56k (64k) APC (5.25" drives), 64k Computer-In-A-Book
+; (3.5"), 128k Dynamic (5.25" or 3.5"), 256TC (3.5").
+;
+; This version of kermit was developed on a 56k APC.
+; It has been tested on 56k, 64k, 128k and 256k Microbees.
+;
+; The serial port is implemented in software NOT hardware.
+; A special transmit routine allows simultaneous receiving
+; for all speeds except 75/1200, 1200/75, 4800, 9600.
+; The receive routine is interrupt driven with a 2 kbyte buffer.
+; The 9600 bit/s speed is marginal on receive - if the transmitter
+; is slightly fast (more than about 1%), the serial routine will
+; not have enough time to put the character in the buffer before
+; the next character arrives.
+
+
+;
+; *** MAIN CODE START ***
+;
+;
+; Keep module name, edit number, and last revision date in memory.
+
+sysedt: db 'CPXSYS.ASM (35) 01-Dec-86$'
+family: db 'CPXBEE.ASM (1) 01-Sep-90$'
+
+
+; Assembly time message announcing which version we're building
+
+.printx * Assembling Microbee Kermit-80 *
+
+z80 EQU TRUE ; They all use Z80s
+
+defesc EQU ']'-100O ;The default escape character for Microbee
+
+vtval EQU 0 ; use default emulation which is adm3a superset
+
+;
+sysxin: ;continuation of system initialisation code
+ ; set up baud rate
+ lxi h,t300
+ shld speed
+ xchg
+ call setbaud
+ ; change the interrupt vector so that we intercept rs232 input
+ db 0EDh,57h ;ld a,i ;get old interrupt reg
+ sta oldint
+ mvi a,int ;new value
+ db 0EDh,47h ;ld i,a
+ ret ; return from system-dependent routine
+
+
+;
+; sysexit - System-dependent termination processing
+; if we've changed anything, this is our last
+; chance to put it back.
+;
+sysexit:
+ lda oldint ;restore old interrupt reg
+ db 0EDh,47h ;ld i,a
+ ret
+
+;
+; syscon - System-dependent processing for start
+; of CONNECT command.
+;
+syscon:
+ lxi d,conmsg
+ call prtstr
+ ret
+
+conmsg: ; Messages printed when entering transparent (CONNECT) mode:
+ db cr,lf,'$'
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+ ret
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing
+; all the system-independent escape sequences.
+;
+sysinh:
+ lxi d,inhlps ; we got options...
+ call prtstr ; print them.
+ ret
+
+
+; additional, system-dependent help for transparent mode
+; (two-character escape sequences)
+inhlps:
+ db cr,lf,'B Transmit a BREAK (0.3s)'
+ db cr,lf,'L Transmit a LONG BREAK (1.8s)'
+ db cr,lf,'W Wipe screen clear'
+ db '$'
+
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:-
+; non-skip: sequence has been processed
+; skip : sequence was not recognized
+;
+sysint: ani 137O ; convert lower case to upper, for testing...
+ cpi 'B' ; send break ?
+ jz sendbr ; then jump to send break routine
+ cpi 'L' ; long break ?
+ jz longbr ; then jump to long break routine
+ cpi 'W' ; clear screen ?
+ jz clrtop ; then jump to clear screen routine
+ jmp rskp ; take skip return - command not recognized.
+
+;
+; Break routines
+;
+longbr:
+ mvi e,180 ; time for long break is 1800 ms
+ jmp setbit
+
+sendbr:
+ mvi e,30 ; time for break is 300 ms
+
+setbit:
+ in portb
+ ani 0dfh ; mask with tx bit
+ out portb
+;
+; Now, delay for duration of hangup or break
+ mov a,e ; delay count
+ call delay
+;
+; Time's up. Put transmitter back in normal state and return.
+ in portb
+ ori 20h ; mask with tx bit
+ out portb
+ ret ; done.
+
+; sysflt - system-dependent filter
+; called with character in E.
+; if this character should not be printed, return with A = zero.
+; preserves bc, de, hl.
+; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
+;
+sysflt:
+ mov a,e ; get character for testing
+ ret
+
+;
+; sysbye - system-dependent processing for BYE command.
+;
+sysbye:
+ ret
+
+;
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; this
+; value is also stored in 'speed'.
+;
+sysspd:
+ call setbaud
+ ret
+
+;
+; Speed tables
+; (Note that speed tables MUST be in alphabetical order for later
+; lookup procedures, and must begin with a value showing the total
+; number of entries. The speed help tables are just for us poor
+; humans.
+
+; db string length,string,divisor (2 identical bytes or 1 word)
+; [Toad Hall]
+
+spdtbl: db 11 ;11 entries
+ db 03h,'110$'
+ dw t110
+ db 04h,'1200$'
+ dw t1200
+ db 07h,'1200/75$'
+ dw t1275
+ db 03h,'150$'
+ dw t150
+ db 04h,'2400$'
+ dw t2400
+ db 03h,'300$'
+ dw t300
+ db 04h,'4800$'
+ dw t4800
+ db 03h,'600$'
+ dw t600
+ db 02h,'75$'
+ dw t75
+ db 07h,'75/1200$'
+ dw t7512
+ db 04h,'9600$'
+ dw t9600
+
+sphtbl: db cr,lf,'75 75/1200 110 150 300 600 1200 1200/75'
+ db ' 2400 4800 9600$'
+
+
+;
+; This is the system-dependent SET PORT command.
+sysprt:
+ ret
+
+prttbl equ 0 ; SET PORT is not supported
+prhtbl equ 0
+
+
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; preserves BC, DE, HL.
+;
+selmdm:
+selcon:
+ ret
+;
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+ mvi c,dconio ;Direct console I/O BDOS call.
+ mvi e,0FFH ;Input.
+ call BDOS
+ ret
+;
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+
+ mvi c,dconio ;Console output bdos call.
+ call bdos ;Output the char to the console.
+ ret
+
+
+
+;
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+outmdm:
+;
+ push psw
+ push b
+ push d
+ push h
+ mov a,e
+ lxi h,outm2 ; return address
+ push h
+ lhld txcall
+ pchl ; send to rs232 port
+outm2: pop h
+ pop d
+ pop b
+ pop psw
+ ret
+
+
+;
+; get character from modem; return zero if none available.
+; bc, de, hl preserved.
+inpmdm:
+ call rsin ; get char if available
+ ret ; return with character in A
+
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+flsmdm: call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+
+;
+; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
+lptstat:
+ lda pflag
+ ret
+
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+outlpt:
+ push d ; save DE in either case
+ ana a ; if A = 0 do nothing,
+ jz outlp1 ; [30] if a=0 do nothing
+ mov a,e
+ call parout
+outlp1: pop d ; restore saved register pair
+ ret
+
+
+;
+;
+; Screen manipulation routines
+; csrpos - move to row B, column C
+;
+; csrpos for terminals that use a leadin sequence followed
+; by (row + 31.) and (column + 31.)
+;
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; restore coordinates
+ mov a,h ; get row
+ adi (' '-1) ; space is row one
+ mov e,a
+ push h
+ call outcon ; output row
+ pop h
+ mov a,l ; get column
+ adi (' '-1) ; space is column one
+ mov e,a
+ jmp outcon ; output it and return
+
+;
+; delchr - make delete look like a backspace. Unless delete is a
+; printing character, we just need to print a backspace
+; (we'll output clrsp afterwards)
+delchr:
+ lxi d,delstr
+ jmp prtstr
+
+
+; erase the character at the current cursor position
+clrspc: mvi e,' '
+ call outcon
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the current line
+clrlin: lxi d,eralin
+ jmp prtstr
+
+; erase the whole screen, and go home
+clrtop: lxi d,erascr
+ jmp prtstr
+
+
+sysver: db 'Microbee$'
+outlin: db 1AH,cr,lf,tab,'$' ;(Clear screen, home cursor)
+erascr: db 1AH,'$' ;Clear screen and go home.
+eralin: db cr,esc,'T$' ;Clear line.
+delstr: db bs,'$' ; Adjust for delete
+curldn: db esc,'=$' ;Cursor lead-in
+ttab: ;Table start location.
+ta: db ('K'-100O),'$',0,0 ;Cursor up.
+tb: db 12O,'$',0,0 ;Cursor down.
+tc: db ('L'-100O),'$',0,0 ;Cursor right.
+td: db bs,'$',0,0 ;Cursor left.
+te: db subt,'$',0,0 ;Clear screen.
+tf: db '$',0,0,0 ;(can't) Enter graphics mode
+tg: db '$',0,0,0 ;(can't) Exit graphics mode
+th: db ('^'-100O),'$',0,0 ;Cursor home.
+ti: db ('K'-100O),'$',0,0 ;Reverse linefeed.
+tj: db esc,'Y$',0 ;Clear to end of screen.
+tk: db esc,'T$',0 ;Clear to end of line.
+
+
+;Microbee software serial port routines
+porta equ 0
+portb equ 2
+
+
+; interrupt vectors
+; We change the Z80 Interrupt register to point to these vectors.
+; Instead of trying to identify a particular Microbee system,
+; we just put vectors here for all systems.
+;
+; known vectors are:
+; 48h : 56k (64k apc) - tested 19-Jun-1990
+; 48k : 64k - tested 01-Sep-1990
+; 50h : dreamdisk (3rd party disk for Microbee)
+; e0h : 128k - tested 19-Jun-1990
+; e0h : 256k - tested 01-Sep-1990
+
+ org ($ and 0ff00h) + 100h
+int equ $/256 ; byte for interrupt register
+
+ dw inta ; printer vector
+ dw intb ; rs232 vector
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+ dw inta
+ dw intb
+
+
+; tables for baud rates
+t75: db 124,13 ; full delay
+ db 55,7 ; semi delay
+ db 168,255 ; txrx delay
+ dw trout ; address of subroutine to transmit char
+t7512: db 124,13 ; 75R/1200T
+ db 55,7
+ db 194,1 ; txout delay
+ dw txout
+t110: db 129,9
+ db 55,5
+ db 5,217
+ dw trout
+t150: db 59,7
+ db 23,4
+ db 2,158
+ dw trout
+t300: db 26,4
+ db 134,2
+ db 3,75
+ dw trout
+t600: db 139,2
+ db 191,1
+ db 2,34
+ dw trout
+t1200: db 195,1
+ db 90,1
+ db 3,13
+ dw trout
+t1275: db 195,1 ; 1200R/75T
+ db 90,1
+ db 124,13
+ dw txout
+t2400: db 94,1
+ db 40,1
+ db 2,3
+ dw trout
+t4800: db 44,1
+ db 15,1
+ db 44,1
+ dw txout
+t9600: db 19,1
+ db 1,1
+ db 19,1
+ dw txout
+
+
+; copy table entries to locations used by serial routines
+setbaud:
+ lxi h,fulldel
+ mvi b,8
+setb2: ldax d
+ mov m,a
+ inx h
+ inx d
+ dcr b
+ jnz setb2
+ ret
+
+
+;transmit character in E
+; destroys all regs
+txout: mvi b,ntotal ;total number of bits to send
+ di
+ in portb ;c = portb with tx bit zeroed
+ ani 0dfh
+ mov c,a
+ ora a ;carry=0 (start bit)
+txout2: mov a,c ; 4T
+ jnc txout4 ;10T skip if space
+ ori 20h ; 3T (average) set mark
+txout4: out portb ;11T
+ lhld txrxdel ;16T
+txout6: dcr l ;delay
+ jnz txout6
+ dcr h
+ jnz txout6 ; 14*L + 14*H + 3584*(H-1)
+ stc ; 4T carry=1 (stop bit)
+ mov a,e ; 4T shift next bit to carry
+ rar ; 4T
+ mov e,a ; 4T
+ dcr b ; 4T
+ jnz txout2 ;10T
+ ;loop = 74T + (delay loop)
+ ei
+ ret
+
+
+;
+;transmit character in E
+;simultaneous receive char if necessary
+trout: mov a,e
+ mvi b,ndata
+ lxi h,0
+tro2: rrc ;shift tx char to hl
+ mov c,a
+ mov a,l
+ ral
+ mov l,a
+ mov a,h
+ ral
+ mov h,a
+ mov a,c ;recover
+ dcr b
+ jnz tro2
+tro10: mvi b,tqfudge ;adjust char in hl to align with
+ ;tx bit of portb
+tro12: stc ; pad out
+ mov a,l
+ ral
+ mov l,a
+ mov a,h
+ ral
+ mov h,a
+ dcr b
+ jnz tro12
+ mvi a,0ffh ;flag to say we are not receiving
+ sta trtemp ;save it
+ mvi d,tqbit ;total number of qtr bits to send
+ in portb ;b = portb with tx bit zeroed
+ ani 0dfh
+ mov b,a
+ mvi e,0 ;we are not receiving yet
+tro14: in portb
+ ori 8h ;test CTS
+ jz tro14 ;loop till Clear To Send
+ out 09h ;Color Wait OFF
+ di
+ call qbit
+ lda trtemp ;are we receiving
+ ora a
+ jnz tro22 ;skip if not
+ in portb ;is last bit a mark?
+ ori 10h
+ jz tro18 ;skip if mark (don't wait for stop)
+ lhld fulldel ;delay to stop bit
+tro16: dcr l
+ jnz tro16
+ dcr h
+ jnz tro16
+tro18: lhld wptr ; check buffer
+ xchg
+ lhld rptr
+ dcx d ; decrement queue pointer
+ mov a,d
+ ora e
+ jnz tro20 ; skip if no queue wrap around
+ lxi d,maxque-1 ; wrap around
+tro20: mov a,l ; sub hl,de
+ sub e
+ mov l,a
+ mov a,h
+ sbb d
+ mov h,a
+ ora l ; check for zero
+ jz tro22 ; skip if buffer full
+ xchg
+ shld wptr ; update queue
+ lxi d,rqueue
+ dad d
+ mov m,c ; put char in queue
+tro22: ei
+ ret ;ret
+
+
+; routine for quarter bit timing
+; for transmit and simultaneous receive
+; total execution time is 223T + L*14T + H*34T
+qbit: call txrx ;17T + 162T
+ lda txrxdel ;13T
+qbit2: dcr a ; 4T
+ jnz qbit2 ;10T
+ lda txrxdel+1 ;13T
+qbit4: dcr a ; 4T
+ nop ; 4T
+ nop ; 4T
+ nop ; 4T
+ nop ; 4T
+ nop ; 4T
+ jnz qbit4 ;10T
+ mov a,d ; 4T Check if still sending or receiving
+ ora e ; 4T
+ jnz qbit ;10T
+ ret
+
+
+;simultaneous transmit/receive
+;do next quarter bit
+; regs: b = portb with tx bit zeroed
+; c = character being received
+; d = number of qtr bits remaining to send
+; e = number of qtr bits remaining to receive (0 if not receiving)
+; hl = character being transmitted
+;this subroutine always executes in 162T (or 163T)
+txrx: mov a,d ; 4T qtr bits remaining to send
+ ora a ; 4T
+ jz txrx12 ;10T skip if no bits remaining (may be receiving)
+ ani 03h ; 7T a complete bit?
+ jnz txrx10 ;10T skip if not
+ dad h ;11T shift tx bit to bit 5 of h
+ mov a,h ; 4T
+ ani 20h ; 7T extract tx bit
+ ora b ; 4T combine with portb
+ out portb ;11T send it
+txrx2: dcr d ; 4T one less qtr bit to send
+ ;76T total
+;now receive part
+txrx4: mov a,e ; 4T qtr bits remaining to receive
+ ora a ; 4T
+ jz txrx16 ;10T skip if not receiving
+ ani 3h ; 7T a complete bit?
+ jnz txrx14 ;10T skip if not
+ in portb ;11T get input
+ ani 10h ; 7T extract rx bit
+ sui 1 ; 7T bit to carry
+ mov a,c ; 4T bit to c
+ rar ; 4T
+ mov c,a ; 4T
+txrx6: dcr e ; 4T one less qtr bit to receive
+txrx8: ret ;10T
+ ;86T total
+
+;come here if transmitting, but not a complete bit
+;delay to match up execution times
+txrx10:
+ ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ori 00h ; 7T
+ jmp txrx2 ;10T
+
+;come here if not sending (but still receiving)
+;delay to match up execution times
+txrx12: ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ jmp txrx4 ;10T
+
+;come here if receiving (but not a complete bit)
+;delay to match up execution time
+txrx14: ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ori 00h ; 7T
+ jmp txrx6 ;10T
+
+;come here if not receiving
+txrx16: in portb ;11T check if start bit
+ ani 10h ; 7T
+ jz txrx18 ;10T skip if mark
+ mvi e,rqbit ; 7T get quarter bit count for receive
+ xra a ; 4T
+ sta trtemp ;13T store flag to say we are receiving
+ ori a ; 7T delay (should be 6T)
+ ret ;10T
+
+txrx18: ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ ora a ; 4T
+ jmp txrx8 ;10T
+
+
+
+
+; RS232 input interrupt routine
+; stores received character in queue
+; ;semi delay starts here
+intb: ;20T (approx.) for interrupt
+ push psw ;11T
+ push b ;11T
+ push d ;11T
+ push h ;11T
+ in portb ;11T
+ ani 10h ; 7T test input for start bit
+ jz intb16 ;10T skip if no start bit.
+ out 09h ;11T
+ lhld semidel ;16T half bit delay
+intb2: dcr l ; 4T
+ jnz intb2 ;10T inner loop 14T*L
+ dcr h ; 4T
+ jnz intb2 ;10T outer loop (14*H + 256*14*(H-1))T
+ mvi e,8 ; 6T number of data bits
+ ;semi delay ends here (125T + delay loop)
+ ;full delay starts here
+intb4: lhld fulldel ;16T full bit delay
+intb6: dcr l
+ jnz intb6
+ dcr h
+ jnz intb6 ; 14*L + 14*H + 3584*(H-1)
+ in portb ;11T test input
+ ani 10h ; 7T
+ sui 1 ; 7T input bit to carry
+ mov a,c ; 4T
+ rar ; 4T
+ mov c,a ; 4T and then to C
+ dcr e ; 4T bit count
+ jnz intb4 ;10T loop till all data bits collected
+ ;full delay ends here (67T + delay loop)
+ in portb
+ ani 10h
+ jz intb12 ; skip if mark
+ lhld fulldel ; wait for stop bit
+intb10: dcr l
+ jnz intb10
+ dcr h
+ jnz intb10
+intb12: lhld wptr ; check buffer
+ xchg
+ lhld rptr
+ dcx d ; decrement queue pointer
+ mov a,d
+ ora e
+ jnz intb14 ; skip if no queue wrap around
+ lxi d,maxque-1 ; wrap around
+intb14: mov a,l ; sub hl,de
+ sub e
+ mov l,a
+ mov a,h
+ sbb d
+ mov h,a
+ ora l ; check for zero
+ jz intb16 ; skip if buffer full
+ xchg
+ shld wptr ; update queue
+ lxi d,rqueue
+ dad d
+ mov m,c ; put char in queue
+intb16: pop h
+ pop d
+ pop b
+ pop psw
+ ei
+ db 0EDh,4Dh ;reti
+
+;
+; get char from serial port buffer.
+; exit: A=char or Z if no char
+rsin: push d
+ push h
+ lhld rptr
+ xchg
+ lhld wptr
+ mov a,l ;sub hl,de
+ sub e
+ mov l,a
+ mov a,h
+ sbb d
+ mov h,a
+ ora l ;check for zero
+ jnz rsi4 ;get char
+rsi2: pop h
+ pop d
+ ret
+
+rsi4: push psw
+ dcx d ; decrement queue pointer
+ mov a,d
+ ora e
+ jnz rsi6 ; skip if no queue wrap around
+ lxi d,maxque-1 ; wrap around
+rsi6: pop psw
+ xchg
+ shld rptr
+ lxi d,rqueue
+ dad d
+ mov e,m ;get char from queue
+ ori 0ffh ;set NZ
+ mov a,e
+ jmp rsi2
+
+; printer routines
+
+inta: sta ptemp
+ mvi a,0
+ sta pflag
+ lda ptemp
+ ei
+ db 0EDh,4Dh ;reti
+
+parout: push h
+ lxi h,pflag
+par2: db 0CBh,46h ;bit 0,(hl)
+ jnz par2
+ mvi m,0ffh
+ out porta
+ pop h
+ ret
+
+; data storage
+
+oldint: db 0 ; storage for old i reg
+trtemp: db 0
+ptemp: db 0 ;temp storage used by inta interrupt
+pflag: db 0 ;0ffh if waiting for printer. 00h if ready
+
+;receive queue pointers
+maxque equ 2048 ; receiver queue size
+rptr: dw maxque-1
+wptr: dw maxque-1
+
+;transmit
+ndata equ 8 ; 8 data bits
+nstrt equ 1 ; 1 start bit
+nstop equ 1 ; 1 stop bit
+ntotal equ nstrt+ndata+nstop
+rqbit equ 4*(nstrt+ndata) ;number of quarter bits to receive
+tqbit equ 4*(nstrt+ndata+nstop) ;number of quarter bits to transmit
+tqfudge equ 13-nstrt-ndata
+
+;H=0 or L=0 behave as 256
+;receive delays.
+fulldel: dw 0 ; 3584(H-1) + 14H + 14L + 67 cycles
+semidel: dw 0 ; 3584(H-1) + 14H + 14L + 125 cycles
+;1/4 bit transmit and simultaneous tx/rx delay 34H + 14L + 223 cycles
+;or full bit delay 3584(H-1) + 14H + 14L + 74 cycles
+txrxdel: dw 0 ;
+txcall: dw trout ; address of subroutine to transmit char
+
+; receiver queue
+rqueue: ds maxque
+
+
+ovlend equ $ ; End of overlay
+
+IF lasm
+ END
+ENDIF
diff --git a/cpxcif.asm b/cpxcif.asm
index d4568c4..f6ce1e8 100644
--- a/cpxcif.asm
+++ b/cpxcif.asm
@@ -1,746 +1,746 @@
-IF NOT lasm
-.printx * CPXCIF.ASM *
-ENDIF ;NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the system dependent part for Cifer systems, and
-; is based on code contributed by John Shearwood of Birmingham
-; University. This file was originally CPXTOR.ASM but now an
-; FAMILY file on its own.
-;
-; This file has code that supports Cifer 1886/2886 systems, running
-; either CP/M Version 2.2 or 3.0, and driving the VL or AUX port.
-; xxx is a three letter abbrev. for the system you are adding.
-;
-; revision history:
-;
-; edit 2, 21 July, 1987 by OBSchou to bring it into line for use with
-; CPXCOM.ASM.
-;
-; edit 1, 14 July by OBSchou for John Shearwood of Birmingham University, UK.
-; His edits ar based on the former CPXTOR.ASM family file.
-;
-; edit 4, Apr 7 1987, JA Shearwood. Add support for Cifer Aux port.
-; edit 2, Mar 17 1987, JA Shearwood Add support for Cifer CP/M Plus
-;
-; Keep module name, edit number, and last revision date in memory.
-family: db 'CPXCIF.ASM (2) 14-Jul-87 $'
-;
-; Assembly time message to let me know I'm building the right version.
-; LASM generates an 'S' error along with the message, which is messy, but
-; better than trying to put everything inside a IF m80 OR mac80 conditional,
-; because LASM doesn't like nested IF's, either.
-
-IF cifer
-.printx * Assembling Kermit-80 for Cifer 1886 *
-ENDIF
-
-IF cifer3
-.printx * with CP/M Plus
-ENDIF
-
-IF cifaux
-.printx * with AUX port
-ENDIF
-
-;
-;=========================================================================
-; I/O Byte assignments (2-bit fields for 4 devices at loc 3)
-;
-;bits 6+7 LIST field
-; 0 LIST is Teletype device (TTY:)
-; 1 LIST is CRT device (CRT:)
-; 2 LIST is Lineprinter (LPT:)
-; 3 LIST is user defined (UL1:)
-;
-;bits 4+5 PUNCH field
-; 0 PUNCH is Teletype device (TTY:)
-; 1 PUNCH is high speed punch (PUN:)
-; 2 PUNCH is user defined #1 (UP1:)
-; 3 PUNCH is user defined #2 (UP2:)
-;
-;bits 2+3 READER field
-; 0 READER is Teletype device (TTY:)
-; 1 READER is high speed reader (RDR:)
-; 2 READER is user defined #1 (UR1:)
-; 3 READER is user defined #2 (UR2:)
-;
-;bits 0+1 CONSOLE field
-; 0 CONSOLE is console printer (TTY:)
-; 1 CONSOLE is CRT device (CRT:)
-; 2 CONSOLE is in Batch-mode (BAT:);READER = Input,
-; LIST = Output
-; 3 CONSOLE is user defined (UC1:)
-;
-;=========================================================================
-
-iobyte EQU 03H ;Location of I/O byte
-
-IF cifer ;[13]
-batio equ 80h ; tty: as console
-defio equ 81h ; crt: as console
-z80 SET TRUE ; although it really is...
-ENDIF;cifer [13]
-
-defesc EQU ']'-100O ;The default escape character.
-
-; Select initial setting for VT-52 emulation flag.
-vtval EQU 1
-
-IF iobyt ; only CP/M 2.2 and VL port use coniob in CPXCOM
- ; rest use this one
-coniob: db 0 ; default console bit pattern
-ENDIF ;iobyt
-
-
-
-sysxin: ;system initialisation not covered by sysinit
- mvi a,defio
- sta coniob
-
-IF cifer AND NOT cifaux ; [JAS] Not if AUX port
- lxi d,ciferi
- call prtstr
-ENDIF ;cifer AND NOT cifaux
-
-IF cifaux ; [JAS] Only Aux Port
- lhld 00047h ; Get address of CIOPS table
- lxi d,6fh
- dad d ; Calculate address of SETLNSPD
- shld cifiop
- inx h
- inx h
- inx h
- shld ciflod ; Next entry LODEF
- lxi d,81h-72h
- dad d ; Calculate address of LIDEF
- shld ciflid
- lhld 00045h ; Get address of SYSPTRS table
- lxi d,12h ; Offset for LIDEF pointer
- dad d ; Add to table address
- mov e,m ; Get low byte LIDEF pointer
- inx h
- mov d,m ; Get high byte LIDEF pointer
- push d
- inx h ; LIPARM pointer next
- mov a,m ; Get low byte of LIPARM pointer
- sta ciptbl ; Keep
- inx h
- mov a,m ; Get high byte
- sta ciptbl+1 ; Keep
- lxi d,1eh-15h ; Offset to LODEF
- dad d
- mov e,m ; Low byte
- inx h
- mov d,m ; High byte
- inx h ; LOPARM is next entry
- mov a,m
- sta coptbl ; Keep low byte LOPARM
- inx h
- mov a,m
- sta coptbl+1 ; Keep high byte
-; Now set up port for no parity 8 bits xon/xoff protocol both ways
- xchg ; LODEF into hl register
- push h ; Needed later
- mvi a,0
- mov m,a ; Clear byte 0
- inx h
- mov m,a ; Clear byte 1
- inx h
- mvi a,099h ; XON/XOFF protocol, 8bits, no parity
- mov m,a ; Flag into byte 2
- pop h ; Restore address of LODEF
-ciflod equ $+1
- call $ ; LODEF routine (poked above)
- pop h ; LIDEF (PUSHed from de earlier)
- push h ; Needed later
- mvi a,0
- mov m,a ; Clear byte 0
- inx h
- mov m,a ; Clear byte 1
- inx h
- mvi a,099h ; XON/XOFF protocol, 8bits, no parity
- mov m,a ; Flag into byte 2
- pop h ; Restore address of LIDEF
-ciflid equ $+1
- call $ ; LIDEF routine (poked above)
- lhld ciptbl ; Get current input speed
- mov a,m
- sta speed
- sta speed+1
- mov e,a
- mov d,a
- call sysspd ; Make sure ip and op are the same
-ENDIF; cifer AND cifaux
-
- ret ; return from system-dependent routine
-
-;
-;
-; system-dependent termination processing
-; If we've changed anything, this is our last chance to put it back.
-sysexit:
-
-IF cifer AND NOT cifaux
- lxi d,cifero
- call prtstr
-ENDIF;cifer AND NOT cifaux
-
- ret
-
-;
-; system-dependent processing for start of CONNECT command
-;
-syscon:
- ret
-
-conmsg: ; Messages printed when entering transparent (CONNECT) mode:
-;
-;
-; syscls - system-dependent close routine
-; called when exiting transparent session.
-;
-syscls:
- ret
-;
-;
-; sysinh - help for system-dependent special functions.
-; called in response to <escape>?, after listing all the
-; system-independent escape sequences.
-;
-sysinh: lxi d,inhlps ; we got options...
- call prtstr ; print them.
-
- ret
-
-
-;additional, system-dependent help for transparent mode
-; (two-character escape sequences)
-inhlps:
-
-; [16] [18] have added super brain and Torch to the list of Breaking machines.
-
-IF (cifer AND NOT cifaux)
- db cr,lf,'B Transmit a BREAK'
-ENDIF ;(cifer AND NOT cifaux)
- db '$' ;[hh] table terminator
-
-;
-; sysint - system dependent special functions
-; called when transparent escape character has been typed;
-; the second character of the sequence is in A (and in B).
-; returns:
-; non-skip: sequence has been processed
-; skip: sequence was not recognized
-sysint: ani 137O ; convert lower case to upper, for testing...
-
-; [19] have added superbrain and torch to the list
-
-IF (cifer AND NOT cifaux)
- cpi 'B' ; send break?
- jz sendbr ; yes, go do it. return nonskip when through.
-ENDIF ;(cifer AND NOT cifaux)
-
- jmp rskp ; take skip return - command not recognized.
-
-;
-
-IF (cifer AND NOT cifaux)
-sendbr: lxi d,brkmes ; send a break by sending esc * "
- call prtstr ; send to screen => breaks to port
- ret
-ENDIF;cifer
-
-; sysflt - system-dependent filter.
-; called with the character in E.
-; preserves bc, de, hl.
-; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-sysflt:
- mov a,e ; get character for testing
- ret
-
-; mdmflt - modem filter [30]
-; called with character to be sent to printer in E
-; with parity set as appropriate.
-; return with accumulator = 0 do do nothing,
-; <> 0 to send char in E.
-mdmflt:
- mov a,e ;[30] get character to test
- ret
-
-
-
-; prtflt - printer filter [30]
-; called with character to be sent to printer in E
-; returns with a = 0 to do nothing
-; a <> 0 to print it.
-;
-; this routine for those printer that automatically insert
-; a lf on cr, or cr for lf. Should this be shifted to
-; the system indep. stuff, in say 4.06?
-prtflt:
- mov a,e ; [30] get character to test
- ret
-
-
-;
-;
-; system-dependent processing for BYE command.
-; for apmmdm, heath, and lobo, hang up the phone.
-sysbye:
- ret
-;
-; This is the system-dependent command to change the baud rate.
-; DE contains the two-byte value from the baud rate table; this
-; value is also stored in 'speed'.
-sysspd:
-
-IF (cifer AND NOT cifaux); This one is wierd..
- ; send an escape string to the screen to set rate.
- push d ; Save the data returned
- lxi d,cifbrt ; send the start of the escape string (esc ?)
- call prtstr ;
- pop psw ; get data into a (and flags>..)
- inr a ; need to send (a+1-1) 'N' to screen
- push psw ; we will need the data again
- call cifnos ; send a set of Ns to the screen
- pop psw ; (which then sets the VL line on the screen
- call cifnos ; processor card)
- call prcrlf ; cr will terminate.. a crlf is handy
- ret
-
-cifnos: dcr a ; if result = 0 then done
- jz cifno1 ; if done then say 'Y' for yes.
- push psw
- mvi e,'N' ; else send a string of Ns to screen processor
- mvi c,dconio
- call bdos
- pop psw
- jmp cifnos
-cifno1: mvi e,'Y'
- mvi c,dconio
- call bdos
- ret ; sent a sring of 0 or more N then a Y
-
-cifbrt: db esc,'?$' ; start setting baud rate string
-ENDIF ;cifer AND NOT cifaux
-
-IF cifaux; [JAS] Set baud rate by massaging LIPARM/LOPARM and calling
- ;CIOPS routine
-; Set up speed byte in first location of tables
- lhld coptbl ; Now sort out baud rate
- mov a,e ; That's output speed
- mov m,a
- xchg
- lhld ciptbl
- mov m,a ; Input speed
-; Call CIOPS routine SETLNSPD with tables in appropriate rp's
-cifiop equ $+1
- call $ ; Poked by sysinit
- ret
-
-coptbl: dw 0
-ciptbl: dw 0
-ENDIF; cifaux
-
-;
-; Speed tables
-; (Note that speed tables MUST be in alphabetical order for later
-; lookup procedures, and must begin with a value showing the total
-; number of entries. The speed help tables are just for us poor
-; humans.
-
-; db string length,string,divisor (2 identical bytes or 1 word)
-; [Toad Hall]
-
-IF cifer
-spdtbl: db 10h ;16 entries
- db 03h,'110$', 02h,02h
- db 04h,'1200$', 07h,07h
- db 05h,'134.5$', 03h,03h
- db 03h,'150$', 04h,04h
- db 04h,'1800$', 08h,08h
- db 05h,'19200$', 0fh,0fh
- db 04h,'2000$', 09h,09h
- db 04h,'2400$', 0ah,0ah
- db 03h,'300$', 05h,05h
- db 04h,'3600$', 0bh,0bh
- db 04h,'4800$', 0ch,0ch
- db 02h,'50$', 00h,00h
- db 03h,'600$', 06h,06h
- db 04h,'7200$', 0dh,0dh
- db 02h,'75$', 01h,01h
- db 04h,'9600$', 0eh,0eh
-
-sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
- db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'
-ENDIF;cifer
-
-; The following conditionals were once a huge if not statement. There
-; wasn't enough room to add the lobo to the list, so it had to be broken
-; into 2, which you can't do with an if not. I redid it as two ifs and
-; applied them to those that wouldn't set baud. [Hal Hostetler]
-;
-; This is the system-dependent SET PORT command.
-; HL contains the argument from the command table.
-sysprt:
-IF iobyt
- mov a,m ;Get the I/O byte
- sta prtiob ;Save the desired IO byte for this port
- inx h ;Point at next entry
- mov a,m ;Get the output function
- sta prtfun ;Save it
-ENDIF;iobyt
-
- ret
-;
-;
-;
-; Port tables for GENERIC CPM 2.2
-IF gener
-; help text
-prhtbl: db cr,lf,'CRT device'
- db cr,lf,'PTR device'
- db cr,lf,'TTY device'
- db cr,lf,'UC1 device'
- db cr,lf,'UR1 device'
- db cr,lf,'UR2 device$'
-
-; command table
-prttbl: db 06H ;Six devices to choose from
- db 03H,'CRT$'
- dw crtptb
- db 03H,'PTR$'
- dw ptrptb
- db 03H,'TTY$'
- dw ttyptb
- db 03H,'UC1$'
- dw uc1ptb
- db 03H,'UR1$'
- dw ur1ptb
- db 03H,'UR2$'
- dw ur2ptb
-
-; port entry table
-; table entries are:
-; db iobyte-value, BDOS output function, reserved
-crtptb: db crtio,conout,0
-ptrptb: db ptrio,punout,0
-ttyptb: db ttyio,conout,0
-uc1ptb: db uc1io,conout,0
-ur1ptb: db ur1io,punout,0
-ur2ptb: db ur2io,punout,0
-ENDIF;gener
-
-;
-;
-IF cifer ; no ports yet...
-prttbl EQU 0
-prhtbl EQU 0 ;
-ENDIF; cifer
-
-IF iobyt
-prtfun: db punout ;Function to use for output to comm port
-prtiob: db batio ;I/O byte to use for communicating
-ENDIF;iobyt
-
-IF NOT (iobyt OR lobo OR cifer) ;[hh]
-prttbl equ 0 ; SET PORT is not supported
-prhtbl equ 0
-ENDIF;NOT (iobyt OR lobo OR cifer)
-
-;
-;
-; selmdm - select modem port
-; selcon - select console port
-; selmdm is called before using inpmdm or outmdm;
-; selcon is called before using inpcon or outcon.
-; For iobyt systems, diddle the I/O byte to select console or comm port;
-; For Decision I, switches Multi I/O board to console or modem serial
-; port. [Toad Hall]
-; For the rest, does nothing.
-; preserves bc, de, hl.
-selmdm:
-IF iobyt
- lda prtiob ;Set up for output to go to the comm port
- sta iobyte ;Switch byte directly
-ENDIF;iobyt
-
- ret
-
-selcon:
-IF iobyt
- lda coniob ;Set up for output to go to the console port
- sta iobyte ;Switch directly
-ENDIF;iobyt
-
- ret
-;
-; Get character from console, or return zero.
-; result is returned in A. destroys bc, de, hl.
-;
-inpcon:
-IF NOT iobyt
- mvi c,dconio ;Direct console I/O BDOS call.
- mvi e,0FFH ;Input.
- call BDOS
-ENDIF;NOT iobyt
-
-IF iobyt
- call bconst ;Get the status
- ora a ;Anything there?
- rz ;No, forget it
- call bconin ;Yes, get the character
-ENDIF;iobyt
- ret
-;
-;
-; Output character in E to the console.
-; destroys bc, de, hl
-;
-outcon:
-
-IF NOT iobyt
- mvi c,dconio ;Console output bdos call.
- call bdos ;Output the char to the console.
-ENDIF;NOT iobyt
-
-IF iobyt
- mov c,e ;Character
- call bcnout ;to Console
-ENDIF;iobyt
- ret
-;
-;
-; outmdm - output a char from E to the modem.
-; the parity bit has been set as necessary.
-; returns nonskip; bc, de, hl preserved.
-outmdm:
-IF inout
- in mnprts ;Get the output done flag.
- ani output ;Is it set?
- jz outmdm ;If not, loop until it is.
- mov a,e
- out mnport ;Output it.
- ret
-ENDIF;inout
-
-IF iobyt
-;**** Note that we enter from outpkt with the I/O byte already set up for
-; output to go to the comm port
- push h
- push b
- lda prtfun ;Get the output function
- mov c,a ;Into C
- call bdos ;And output the character
- pop b
- pop h
- ret
-ENDIF;iobyt
-
-IF cifer3 ; [JAS]
- push h
- push b
- mvi c,auxout ;Output to the aux output device
- call bdos
- pop b
- pop h
- ret
-ENDIF;cifer3
-
-
-;
-;
-; get character from modem; return zero if none available.
-; for IOBYT systems, the modem port has already been selected.
-; destroys bc, de, hl.
-inpmdm:
-IF iobyt
- call bconst ;Is Char at COMM-Port?
- ora a ;something there?
- rz ; return if nothing there
- call bconin ; data present. read data.
-ENDIF;iobyt
-
-IF inout
-;Note: modem port should already be selected for mdI. [Toad Hall]
- in mnprts ;Get the port status into A.
- ani input ;See if the input ready bit is on.
- rz ;If not then return.
- in mnport ;If so, get the char.
-ENDIF;inout
-
-IF cifer3 ; [JAS]
- mvi c,auxist
- call bdos ;is char at auxin?
- ora a ;something there?
- rz ;no
- mvi c,auxin
- call bdos ;read char from auxin
-ENDIF;cifer3
-
-ret ; return with character in A
-
-
-;
-; flsmdm - flush comm line.
-; Modem is selected.
-; Currently, just gets characters until none are available.
-
-flsmdm: call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-
-
-;
-;
-; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
-lptstat:
-IF iobyte ;[33]
- call bprtst ; get status
-ENDIF ;iobyte[33]
-IF NOT iobyte ;[33]
- xra a ; assume it is ok.. this may not be necessary
-ENDIF ;iobyte [33]
- ret
-;
-;
-; outlpt - output character in E to printer
-; console is selected.
-; preserves de.
-outlpt:
- push d ; save DE in either case
- call prtflt ; go through printer filter [30]
- ana a ; if A = 0 do nothing,
- jz outlp1 ; [30] if a=0 do nothing
-
-IF NOT iobyte
- mvi c,lstout
- call bdos ;Char to printer
-ENDIF;NOT iobyt
-IF iobyt
- mov c,e
- call blsout
-ENDIF;iobyt
-
-outlp1: pop d ; restore saved register pair
- ret
-;
-;
-; Screen manipulation routines
-; csrpos - move to row B, column C
-;
-; csrpos for terminals that use a leadin sequence followed
-; by (row + 31.) and (column + 31.)
-;
-IF cifer ; [14] cifer does it colums then rows.. swap b and c
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,l ; [obs] get column
- adi (' '-1) ; space is column one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,h ; [obs] get row
- adi (' '-1) ; space is row one
- mov e,a
- jmp outcon ; output it and return
-ENDIF; cifer
-
-;
-;
-; delchr - make delete look like a backspace. Unless delete is a printing
-; character, we just need to print a backspace. (we'll output clrspc
-; afterwards)
-; For Kaypro and Vector General, delete puts a blotch on the screen.
-; For Apple and Osborne 1, delete moves but doesn't print.
-delchr:
- mvi e,bs
- call outcon
-
-; erase the character at the current cursor position
-clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the current line
-clrlin: lxi d,eralin
- jmp prtstr
-
-; erase the whole screen, and go home. preserves b (but not c)
-clrtop: lxi d,erascr
- jmp prtstr
-
-
-IF cifer AND NOT cifaux ;[13]
-ttytyp: db 'Cifer 1886 (Parity set to space only)$'
-ENDIF; cifer AND NOT cifaux
-
-IF cifaux ;JAS
-ttytyp: db ' Cifer 1886 $'
-ENDIF; cifaux
-
-IF cifer ;[JAS]
-sysver: db ' Cifer 1886 $' ;
-outlin: db esc,'J',cr,lf,tab,tab,'$'
-eralin: db esc,'^K$' ;Clear to end of line.
-erascr: db esc,'J$' ;Clear screen and go home.
-curldn: db esc,'P$' ;Cursor lead-in
-ttab: ;Table start location.
-ta: db esc,'A$',0 ;Cursor up.
-tb: db esc,'@$',0 ;Cursor down.
-tc: db esc,'C$',0 ;Cursor right.
-td: db esc,'D$',0 ;Cursor left.
-te: db esc,'J',0,0 ;Clear screen and home cursor
-tf: db '$',0,0,0 ;(can't) Enter Graphics mode
-tg: db '$',0,0,0 ;(can't) Exit Graphics mode
-th: db esc,'H$',0 ;Cursor home.
-ti: db esc,'@$',0 ;reverse linfeed
-tj: db esc,'B$',0 ;Clear to end of screen
-tk: db esc,'K$',0 ;Clear to end of line.
-ENDIF;cifer
-;
-IF cifer AND NOT cifaux ;[JAS]
-; Setup string for the Cifer.. called as a prtstr param. from sysinit
-ciferi: db esc,'/' ;Setup cifer for on line
- db esc,'*[' ; direct mode on
- db esc,'%' ; protocol on host line on
- db esc,'*~x' ; protocol is xon/xoff
- db esc,'*(' ; protocol out on host is xon/xoff
- db esc,'? NNNY',cr ; set VL port to space parity
- ; It cannot do NONE.. Thanks a lot
- db '$' ; all done
-; Finish string for the Cifer.. called as a prtstr param. from sysexit
-cifero: db esc,'&' ; Host input protocol off
- db esc,'*)' ; Host output protocol off
- db esc,'*]' ; Direct mode off
- db esc,'\' ; Setup cifer for off line
- db '$'
-; Break string for cifer VL port.
-brkmes: db esc,'*"$' ;Send a break command string
-ENDIF;cifer AND NOT cifaux [13]
-
-ovlend equ $ ; End of overlay
-
- END
-
+IF NOT lasm
+.printx * CPXCIF.ASM *
+ENDIF ;NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the system dependent part for Cifer systems, and
+; is based on code contributed by John Shearwood of Birmingham
+; University. This file was originally CPXTOR.ASM but now an
+; FAMILY file on its own.
+;
+; This file has code that supports Cifer 1886/2886 systems, running
+; either CP/M Version 2.2 or 3.0, and driving the VL or AUX port.
+; xxx is a three letter abbrev. for the system you are adding.
+;
+; revision history:
+;
+; edit 2, 21 July, 1987 by OBSchou to bring it into line for use with
+; CPXCOM.ASM.
+;
+; edit 1, 14 July by OBSchou for John Shearwood of Birmingham University, UK.
+; His edits ar based on the former CPXTOR.ASM family file.
+;
+; edit 4, Apr 7 1987, JA Shearwood. Add support for Cifer Aux port.
+; edit 2, Mar 17 1987, JA Shearwood Add support for Cifer CP/M Plus
+;
+; Keep module name, edit number, and last revision date in memory.
+family: db 'CPXCIF.ASM (2) 14-Jul-87 $'
+;
+; Assembly time message to let me know I'm building the right version.
+; LASM generates an 'S' error along with the message, which is messy, but
+; better than trying to put everything inside a IF m80 OR mac80 conditional,
+; because LASM doesn't like nested IF's, either.
+
+IF cifer
+.printx * Assembling Kermit-80 for Cifer 1886 *
+ENDIF
+
+IF cifer3
+.printx * with CP/M Plus
+ENDIF
+
+IF cifaux
+.printx * with AUX port
+ENDIF
+
+;
+;=========================================================================
+; I/O Byte assignments (2-bit fields for 4 devices at loc 3)
+;
+;bits 6+7 LIST field
+; 0 LIST is Teletype device (TTY:)
+; 1 LIST is CRT device (CRT:)
+; 2 LIST is Lineprinter (LPT:)
+; 3 LIST is user defined (UL1:)
+;
+;bits 4+5 PUNCH field
+; 0 PUNCH is Teletype device (TTY:)
+; 1 PUNCH is high speed punch (PUN:)
+; 2 PUNCH is user defined #1 (UP1:)
+; 3 PUNCH is user defined #2 (UP2:)
+;
+;bits 2+3 READER field
+; 0 READER is Teletype device (TTY:)
+; 1 READER is high speed reader (RDR:)
+; 2 READER is user defined #1 (UR1:)
+; 3 READER is user defined #2 (UR2:)
+;
+;bits 0+1 CONSOLE field
+; 0 CONSOLE is console printer (TTY:)
+; 1 CONSOLE is CRT device (CRT:)
+; 2 CONSOLE is in Batch-mode (BAT:);READER = Input,
+; LIST = Output
+; 3 CONSOLE is user defined (UC1:)
+;
+;=========================================================================
+
+iobyte EQU 03H ;Location of I/O byte
+
+IF cifer ;[13]
+batio equ 80h ; tty: as console
+defio equ 81h ; crt: as console
+z80 SET TRUE ; although it really is...
+ENDIF;cifer [13]
+
+defesc EQU ']'-100O ;The default escape character.
+
+; Select initial setting for VT-52 emulation flag.
+vtval EQU 1
+
+IF iobyt ; only CP/M 2.2 and VL port use coniob in CPXCOM
+ ; rest use this one
+coniob: db 0 ; default console bit pattern
+ENDIF ;iobyt
+
+
+
+sysxin: ;system initialisation not covered by sysinit
+ mvi a,defio
+ sta coniob
+
+IF cifer AND NOT cifaux ; [JAS] Not if AUX port
+ lxi d,ciferi
+ call prtstr
+ENDIF ;cifer AND NOT cifaux
+
+IF cifaux ; [JAS] Only Aux Port
+ lhld 00047h ; Get address of CIOPS table
+ lxi d,6fh
+ dad d ; Calculate address of SETLNSPD
+ shld cifiop
+ inx h
+ inx h
+ inx h
+ shld ciflod ; Next entry LODEF
+ lxi d,81h-72h
+ dad d ; Calculate address of LIDEF
+ shld ciflid
+ lhld 00045h ; Get address of SYSPTRS table
+ lxi d,12h ; Offset for LIDEF pointer
+ dad d ; Add to table address
+ mov e,m ; Get low byte LIDEF pointer
+ inx h
+ mov d,m ; Get high byte LIDEF pointer
+ push d
+ inx h ; LIPARM pointer next
+ mov a,m ; Get low byte of LIPARM pointer
+ sta ciptbl ; Keep
+ inx h
+ mov a,m ; Get high byte
+ sta ciptbl+1 ; Keep
+ lxi d,1eh-15h ; Offset to LODEF
+ dad d
+ mov e,m ; Low byte
+ inx h
+ mov d,m ; High byte
+ inx h ; LOPARM is next entry
+ mov a,m
+ sta coptbl ; Keep low byte LOPARM
+ inx h
+ mov a,m
+ sta coptbl+1 ; Keep high byte
+; Now set up port for no parity 8 bits xon/xoff protocol both ways
+ xchg ; LODEF into hl register
+ push h ; Needed later
+ mvi a,0
+ mov m,a ; Clear byte 0
+ inx h
+ mov m,a ; Clear byte 1
+ inx h
+ mvi a,099h ; XON/XOFF protocol, 8bits, no parity
+ mov m,a ; Flag into byte 2
+ pop h ; Restore address of LODEF
+ciflod equ $+1
+ call $ ; LODEF routine (poked above)
+ pop h ; LIDEF (PUSHed from de earlier)
+ push h ; Needed later
+ mvi a,0
+ mov m,a ; Clear byte 0
+ inx h
+ mov m,a ; Clear byte 1
+ inx h
+ mvi a,099h ; XON/XOFF protocol, 8bits, no parity
+ mov m,a ; Flag into byte 2
+ pop h ; Restore address of LIDEF
+ciflid equ $+1
+ call $ ; LIDEF routine (poked above)
+ lhld ciptbl ; Get current input speed
+ mov a,m
+ sta speed
+ sta speed+1
+ mov e,a
+ mov d,a
+ call sysspd ; Make sure ip and op are the same
+ENDIF; cifer AND cifaux
+
+ ret ; return from system-dependent routine
+
+;
+;
+; system-dependent termination processing
+; If we've changed anything, this is our last chance to put it back.
+sysexit:
+
+IF cifer AND NOT cifaux
+ lxi d,cifero
+ call prtstr
+ENDIF;cifer AND NOT cifaux
+
+ ret
+
+;
+; system-dependent processing for start of CONNECT command
+;
+syscon:
+ ret
+
+conmsg: ; Messages printed when entering transparent (CONNECT) mode:
+;
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+ ret
+;
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing all the
+; system-independent escape sequences.
+;
+sysinh: lxi d,inhlps ; we got options...
+ call prtstr ; print them.
+
+ ret
+
+
+;additional, system-dependent help for transparent mode
+; (two-character escape sequences)
+inhlps:
+
+; [16] [18] have added super brain and Torch to the list of Breaking machines.
+
+IF (cifer AND NOT cifaux)
+ db cr,lf,'B Transmit a BREAK'
+ENDIF ;(cifer AND NOT cifaux)
+ db '$' ;[hh] table terminator
+
+;
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:
+; non-skip: sequence has been processed
+; skip: sequence was not recognized
+sysint: ani 137O ; convert lower case to upper, for testing...
+
+; [19] have added superbrain and torch to the list
+
+IF (cifer AND NOT cifaux)
+ cpi 'B' ; send break?
+ jz sendbr ; yes, go do it. return nonskip when through.
+ENDIF ;(cifer AND NOT cifaux)
+
+ jmp rskp ; take skip return - command not recognized.
+
+;
+
+IF (cifer AND NOT cifaux)
+sendbr: lxi d,brkmes ; send a break by sending esc * "
+ call prtstr ; send to screen => breaks to port
+ ret
+ENDIF;cifer
+
+; sysflt - system-dependent filter.
+; called with the character in E.
+; preserves bc, de, hl.
+; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
+sysflt:
+ mov a,e ; get character for testing
+ ret
+
+; mdmflt - modem filter [30]
+; called with character to be sent to printer in E
+; with parity set as appropriate.
+; return with accumulator = 0 do do nothing,
+; <> 0 to send char in E.
+mdmflt:
+ mov a,e ;[30] get character to test
+ ret
+
+
+
+; prtflt - printer filter [30]
+; called with character to be sent to printer in E
+; returns with a = 0 to do nothing
+; a <> 0 to print it.
+;
+; this routine for those printer that automatically insert
+; a lf on cr, or cr for lf. Should this be shifted to
+; the system indep. stuff, in say 4.06?
+prtflt:
+ mov a,e ; [30] get character to test
+ ret
+
+
+;
+;
+; system-dependent processing for BYE command.
+; for apmmdm, heath, and lobo, hang up the phone.
+sysbye:
+ ret
+;
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; this
+; value is also stored in 'speed'.
+sysspd:
+
+IF (cifer AND NOT cifaux); This one is wierd..
+ ; send an escape string to the screen to set rate.
+ push d ; Save the data returned
+ lxi d,cifbrt ; send the start of the escape string (esc ?)
+ call prtstr ;
+ pop psw ; get data into a (and flags>..)
+ inr a ; need to send (a+1-1) 'N' to screen
+ push psw ; we will need the data again
+ call cifnos ; send a set of Ns to the screen
+ pop psw ; (which then sets the VL line on the screen
+ call cifnos ; processor card)
+ call prcrlf ; cr will terminate.. a crlf is handy
+ ret
+
+cifnos: dcr a ; if result = 0 then done
+ jz cifno1 ; if done then say 'Y' for yes.
+ push psw
+ mvi e,'N' ; else send a string of Ns to screen processor
+ mvi c,dconio
+ call bdos
+ pop psw
+ jmp cifnos
+cifno1: mvi e,'Y'
+ mvi c,dconio
+ call bdos
+ ret ; sent a sring of 0 or more N then a Y
+
+cifbrt: db esc,'?$' ; start setting baud rate string
+ENDIF ;cifer AND NOT cifaux
+
+IF cifaux; [JAS] Set baud rate by massaging LIPARM/LOPARM and calling
+ ;CIOPS routine
+; Set up speed byte in first location of tables
+ lhld coptbl ; Now sort out baud rate
+ mov a,e ; That's output speed
+ mov m,a
+ xchg
+ lhld ciptbl
+ mov m,a ; Input speed
+; Call CIOPS routine SETLNSPD with tables in appropriate rp's
+cifiop equ $+1
+ call $ ; Poked by sysinit
+ ret
+
+coptbl: dw 0
+ciptbl: dw 0
+ENDIF; cifaux
+
+;
+; Speed tables
+; (Note that speed tables MUST be in alphabetical order for later
+; lookup procedures, and must begin with a value showing the total
+; number of entries. The speed help tables are just for us poor
+; humans.
+
+; db string length,string,divisor (2 identical bytes or 1 word)
+; [Toad Hall]
+
+IF cifer
+spdtbl: db 10h ;16 entries
+ db 03h,'110$', 02h,02h
+ db 04h,'1200$', 07h,07h
+ db 05h,'134.5$', 03h,03h
+ db 03h,'150$', 04h,04h
+ db 04h,'1800$', 08h,08h
+ db 05h,'19200$', 0fh,0fh
+ db 04h,'2000$', 09h,09h
+ db 04h,'2400$', 0ah,0ah
+ db 03h,'300$', 05h,05h
+ db 04h,'3600$', 0bh,0bh
+ db 04h,'4800$', 0ch,0ch
+ db 02h,'50$', 00h,00h
+ db 03h,'600$', 06h,06h
+ db 04h,'7200$', 0dh,0dh
+ db 02h,'75$', 01h,01h
+ db 04h,'9600$', 0eh,0eh
+
+sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
+ db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'
+ENDIF;cifer
+
+; The following conditionals were once a huge if not statement. There
+; wasn't enough room to add the lobo to the list, so it had to be broken
+; into 2, which you can't do with an if not. I redid it as two ifs and
+; applied them to those that wouldn't set baud. [Hal Hostetler]
+;
+; This is the system-dependent SET PORT command.
+; HL contains the argument from the command table.
+sysprt:
+IF iobyt
+ mov a,m ;Get the I/O byte
+ sta prtiob ;Save the desired IO byte for this port
+ inx h ;Point at next entry
+ mov a,m ;Get the output function
+ sta prtfun ;Save it
+ENDIF;iobyt
+
+ ret
+;
+;
+;
+; Port tables for GENERIC CPM 2.2
+IF gener
+; help text
+prhtbl: db cr,lf,'CRT device'
+ db cr,lf,'PTR device'
+ db cr,lf,'TTY device'
+ db cr,lf,'UC1 device'
+ db cr,lf,'UR1 device'
+ db cr,lf,'UR2 device$'
+
+; command table
+prttbl: db 06H ;Six devices to choose from
+ db 03H,'CRT$'
+ dw crtptb
+ db 03H,'PTR$'
+ dw ptrptb
+ db 03H,'TTY$'
+ dw ttyptb
+ db 03H,'UC1$'
+ dw uc1ptb
+ db 03H,'UR1$'
+ dw ur1ptb
+ db 03H,'UR2$'
+ dw ur2ptb
+
+; port entry table
+; table entries are:
+; db iobyte-value, BDOS output function, reserved
+crtptb: db crtio,conout,0
+ptrptb: db ptrio,punout,0
+ttyptb: db ttyio,conout,0
+uc1ptb: db uc1io,conout,0
+ur1ptb: db ur1io,punout,0
+ur2ptb: db ur2io,punout,0
+ENDIF;gener
+
+;
+;
+IF cifer ; no ports yet...
+prttbl EQU 0
+prhtbl EQU 0 ;
+ENDIF; cifer
+
+IF iobyt
+prtfun: db punout ;Function to use for output to comm port
+prtiob: db batio ;I/O byte to use for communicating
+ENDIF;iobyt
+
+IF NOT (iobyt OR lobo OR cifer) ;[hh]
+prttbl equ 0 ; SET PORT is not supported
+prhtbl equ 0
+ENDIF;NOT (iobyt OR lobo OR cifer)
+
+;
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; For iobyt systems, diddle the I/O byte to select console or comm port;
+; For Decision I, switches Multi I/O board to console or modem serial
+; port. [Toad Hall]
+; For the rest, does nothing.
+; preserves bc, de, hl.
+selmdm:
+IF iobyt
+ lda prtiob ;Set up for output to go to the comm port
+ sta iobyte ;Switch byte directly
+ENDIF;iobyt
+
+ ret
+
+selcon:
+IF iobyt
+ lda coniob ;Set up for output to go to the console port
+ sta iobyte ;Switch directly
+ENDIF;iobyt
+
+ ret
+;
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+IF NOT iobyt
+ mvi c,dconio ;Direct console I/O BDOS call.
+ mvi e,0FFH ;Input.
+ call BDOS
+ENDIF;NOT iobyt
+
+IF iobyt
+ call bconst ;Get the status
+ ora a ;Anything there?
+ rz ;No, forget it
+ call bconin ;Yes, get the character
+ENDIF;iobyt
+ ret
+;
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+
+IF NOT iobyt
+ mvi c,dconio ;Console output bdos call.
+ call bdos ;Output the char to the console.
+ENDIF;NOT iobyt
+
+IF iobyt
+ mov c,e ;Character
+ call bcnout ;to Console
+ENDIF;iobyt
+ ret
+;
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+outmdm:
+IF inout
+ in mnprts ;Get the output done flag.
+ ani output ;Is it set?
+ jz outmdm ;If not, loop until it is.
+ mov a,e
+ out mnport ;Output it.
+ ret
+ENDIF;inout
+
+IF iobyt
+;**** Note that we enter from outpkt with the I/O byte already set up for
+; output to go to the comm port
+ push h
+ push b
+ lda prtfun ;Get the output function
+ mov c,a ;Into C
+ call bdos ;And output the character
+ pop b
+ pop h
+ ret
+ENDIF;iobyt
+
+IF cifer3 ; [JAS]
+ push h
+ push b
+ mvi c,auxout ;Output to the aux output device
+ call bdos
+ pop b
+ pop h
+ ret
+ENDIF;cifer3
+
+
+;
+;
+; get character from modem; return zero if none available.
+; for IOBYT systems, the modem port has already been selected.
+; destroys bc, de, hl.
+inpmdm:
+IF iobyt
+ call bconst ;Is Char at COMM-Port?
+ ora a ;something there?
+ rz ; return if nothing there
+ call bconin ; data present. read data.
+ENDIF;iobyt
+
+IF inout
+;Note: modem port should already be selected for mdI. [Toad Hall]
+ in mnprts ;Get the port status into A.
+ ani input ;See if the input ready bit is on.
+ rz ;If not then return.
+ in mnport ;If so, get the char.
+ENDIF;inout
+
+IF cifer3 ; [JAS]
+ mvi c,auxist
+ call bdos ;is char at auxin?
+ ora a ;something there?
+ rz ;no
+ mvi c,auxin
+ call bdos ;read char from auxin
+ENDIF;cifer3
+
+ret ; return with character in A
+
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+
+flsmdm: call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+
+
+;
+;
+; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
+lptstat:
+IF iobyte ;[33]
+ call bprtst ; get status
+ENDIF ;iobyte[33]
+IF NOT iobyte ;[33]
+ xra a ; assume it is ok.. this may not be necessary
+ENDIF ;iobyte [33]
+ ret
+;
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+outlpt:
+ push d ; save DE in either case
+ call prtflt ; go through printer filter [30]
+ ana a ; if A = 0 do nothing,
+ jz outlp1 ; [30] if a=0 do nothing
+
+IF NOT iobyte
+ mvi c,lstout
+ call bdos ;Char to printer
+ENDIF;NOT iobyt
+IF iobyt
+ mov c,e
+ call blsout
+ENDIF;iobyt
+
+outlp1: pop d ; restore saved register pair
+ ret
+;
+;
+; Screen manipulation routines
+; csrpos - move to row B, column C
+;
+; csrpos for terminals that use a leadin sequence followed
+; by (row + 31.) and (column + 31.)
+;
+IF cifer ; [14] cifer does it colums then rows.. swap b and c
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; restore coordinates
+ mov a,l ; [obs] get column
+ adi (' '-1) ; space is column one
+ mov e,a
+ push h
+ call outcon ; output row
+ pop h
+ mov a,h ; [obs] get row
+ adi (' '-1) ; space is row one
+ mov e,a
+ jmp outcon ; output it and return
+ENDIF; cifer
+
+;
+;
+; delchr - make delete look like a backspace. Unless delete is a printing
+; character, we just need to print a backspace. (we'll output clrspc
+; afterwards)
+; For Kaypro and Vector General, delete puts a blotch on the screen.
+; For Apple and Osborne 1, delete moves but doesn't print.
+delchr:
+ mvi e,bs
+ call outcon
+
+; erase the character at the current cursor position
+clrspc: mvi e,' '
+ call outcon
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the current line
+clrlin: lxi d,eralin
+ jmp prtstr
+
+; erase the whole screen, and go home. preserves b (but not c)
+clrtop: lxi d,erascr
+ jmp prtstr
+
+
+IF cifer AND NOT cifaux ;[13]
+ttytyp: db 'Cifer 1886 (Parity set to space only)$'
+ENDIF; cifer AND NOT cifaux
+
+IF cifaux ;JAS
+ttytyp: db ' Cifer 1886 $'
+ENDIF; cifaux
+
+IF cifer ;[JAS]
+sysver: db ' Cifer 1886 $' ;
+outlin: db esc,'J',cr,lf,tab,tab,'$'
+eralin: db esc,'^K$' ;Clear to end of line.
+erascr: db esc,'J$' ;Clear screen and go home.
+curldn: db esc,'P$' ;Cursor lead-in
+ttab: ;Table start location.
+ta: db esc,'A$',0 ;Cursor up.
+tb: db esc,'@$',0 ;Cursor down.
+tc: db esc,'C$',0 ;Cursor right.
+td: db esc,'D$',0 ;Cursor left.
+te: db esc,'J',0,0 ;Clear screen and home cursor
+tf: db '$',0,0,0 ;(can't) Enter Graphics mode
+tg: db '$',0,0,0 ;(can't) Exit Graphics mode
+th: db esc,'H$',0 ;Cursor home.
+ti: db esc,'@$',0 ;reverse linfeed
+tj: db esc,'B$',0 ;Clear to end of screen
+tk: db esc,'K$',0 ;Clear to end of line.
+ENDIF;cifer
+;
+IF cifer AND NOT cifaux ;[JAS]
+; Setup string for the Cifer.. called as a prtstr param. from sysinit
+ciferi: db esc,'/' ;Setup cifer for on line
+ db esc,'*[' ; direct mode on
+ db esc,'%' ; protocol on host line on
+ db esc,'*~x' ; protocol is xon/xoff
+ db esc,'*(' ; protocol out on host is xon/xoff
+ db esc,'? NNNY',cr ; set VL port to space parity
+ ; It cannot do NONE.. Thanks a lot
+ db '$' ; all done
+; Finish string for the Cifer.. called as a prtstr param. from sysexit
+cifero: db esc,'&' ; Host input protocol off
+ db esc,'*)' ; Host output protocol off
+ db esc,'*]' ; Direct mode off
+ db esc,'\' ; Setup cifer for off line
+ db '$'
+; Break string for cifer VL port.
+brkmes: db esc,'*"$' ;Send a break command string
+ENDIF;cifer AND NOT cifaux [13]
+
+ovlend equ $ ; End of overlay
+
+ END
+
diff --git a/cpxcom.asm b/cpxcom.asm
index 7c3034e..6123f64 100644
--- a/cpxcom.asm
+++ b/cpxcom.asm
@@ -1,486 +1,486 @@
-IF NOT lasm
-.printx * CPXCOM.ASM *
-ENDIF ; NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains part common code required for most if not all
-; systems. Specifiacally, SYSINIT, INIADR, MOVER, and DELAY to name
-; the most important ones.
-;
-; revision history:
-;
-; edit 1, 21st July 1987 by OBSchou. Regretably, I have had to include
-; some system dependent IFs, mainly for CRT, TORCH and OSI. Inclusion
-; here means simpler family files later on. (Regrettably, the delay
-; loop for APMMDM differs too.)
-;
-; Set the fuzzy timeout value. Range is 1 (VERY short) through 0ffffH to zero
-; (maximum). The actual duration is a function of the loop length and the
-; processor speed. For now, we'll make it zero for everybody, but feel free
-; to change it for your system.
-; [OBS] make it a little less than max, say 1000H. More useful.
-fuzval EQU 1000H
-
-;
-; System-dependent initialization
-; Called once at program start.
-sysinit:
-;
-; [13] Had to move this call to here, as the prtstr routine needs this
-; before the config message is sent out. It has only been moved.
-;
- call iniadr ;Initialize the BIOS addresses
- mvi c,gtiob ;Get current I/O byte
- call bdos ;From CP/M
- sta coniob ;Remember where console is
- mvi c,getvnm ; get the BDOS version number (e.g. 22H, 31H)
- call bdos
- mov a,l
- sta bdosvr ; and store it away for future reference
- lxi d,cfgmsg ; "configured for "
- call prtstr
- lxi d,sysver ; get configuration we're configured for
- call prtstr ; print it.
-;
-; If we're set up to do special terminal handling, say what kind
-; of terminal we expect... (unless it's the generic 'crt')
-IF termin
- lxi d,witmsg ; " with "
- call prtstr
- lxi d,ttytyp ; terminal type
- call prtstr
-ENDIF;termin
- call prcrlf ; print CR/LF
-;
-; now, to work...
-;
-; locate large buffer for multi-sector I/O
-; What we want to do here is find the ccp. Space between ovlend and the ccp
-; is available for buffering, except we don't want to use more than maxsec
-; buffers (if we use too many, the remote end could time out while we're
-; writing to disk). maxsec is system-dependent, but for now we'll just
-; use 8Kbytes. If you get retransmissions and other protocol errors after
-; transferring the first maxsec sectors, lower maxsec.
-
-maxsec EQU (8*1024)/bufsiz ; 8K / number of bytes per sector
-
- lxi h,ovlend ; get start of buffer
- shld bufadr ; store in linkage section
- mvi a,maxsec ; get size of buffer, in sectors
- sta bufsec ; store that, too.
-
- call sysxin ; call system specific init code
-
- ret ; return from system-dependent routine
-
-bdosvr: ds 1 ; space to save the BDOS version number
-IF NOT iobyt
-coniob: ds 1 ; space to save copy of IO byte
-ENDIF ;NOT iobyt
-;
-; This one is hopefully the last "improvement" in view of GENERIC
-;Kermit. It uses for Character-I/O the BIOS-routines ( instead of the
-;"normal" BDOS routines. What does it give us (hopefully) : More speed,
-;higher chance of success ( I/O byte implemented in BIOS [if at all]),
-;but no "extra" device handling - that's done by BDOS.
-;
-; How do we "get" the call-adresses? Location 0 has a JMP Warm-Boot
-;in CP/M which points into the second location of the BIOS JMP-Vector. The
-;next three locations of the JMP-Vector point to the CONSTAT,CONIN,CONOUT
-;BIOS-routines. CONOUT wants the character in C.
-;
-;- Bernie Eiben
-
-iniadr: lhld 1 ;get BIOS Warmstart-address
- lxi d,3 ;next adress is CONSTAT in BIOS
- dad d
- shld bconst+1 ;stuff it into the call-instruction
- lxi d,3 ;next adress is CONIN in BIOS
- dad d
- shld bconin+1 ;
- lxi d,3 ;next adress is CONOUT in BIOS
- dad d
- shld bcnout+1
- lxi d,3 ;next address is LIST in BIOS
- dad d
- shld blsout+1
- lxi d,10*3 ; get printer status routine
- dad d
- shld bprtst
- ret ;And return
-
-bconst: jmp $-$ ;Call BIOS directly (filled in by iniadr)
-
-bconin: jmp $-$ ;Call BIOS directly (filled in by iniadr)
-
-bcnout: jmp $-$ ;Call BIOS directly (filled in by iniadr)
-
-blsout: jmp $-$ ; ....
-
-bprtst: jmp $-$ ; Call BIOS directly for printer status
-
-IF NOT apmmdm ; Shame about this, but the Apple needs a different delay
-;
-;[cjc] Delay routine. Called with time (hundredths of seconds) in A.
-; The inner loop delays 1001 T-states, assuming no wait states are
-; inserted; this is repeated CPUSPD times, for a total delay of just
-; over 0.01 second. (CPUSPD should be set to the system clock rate,
-; in units of 100KHz: for an unmodified Kaypro II, that's 25 for
-; 2.5 MHz. Some enterprising soul could determine whether or not the
-; Kaypro actually inserts a wait state on instruction fetch (a common
-; practice); if so, the magic number at delay2 needs to be decreased.
-; (We also neglect to consider time spent at interrupt level).
-;
-; called by: sendbr
-; destroys BC
-
-delay: mvi c,cpuspd ; Number of times to wait 1000 T-states to
- ; make .01 second delay
-delay2: mvi b,70 ; Number of times to execute inner loop to
- ; make 1000 T-state delay
-delay3: dcr b ; 4 T-states (* 70 * cpuspd)
- jnz delay3 ; 10 T-states (* 70 * cpuspd)
- dcr c ; 4 T-states (* cpuspd)
- jnz delay2 ; 10 T-states (* cpuspd)
- ; total delay: ((14 * 70) + 14) * cpuspd
- ; = 1001 * cpuspd
- dcr a ; 4 T-states
- jnz delay ; 10 T-states
- ret ; grand total: ((1001 * cpuspd) + 14) * a
-ENDIF ; NOT apmmdm
-;
-;
-; Set up screen display for file transfer
-; called with kermit version in DE
-;
-sysscr: push d ; save version for a bit
- lxi d,outlin ; clear screen, position cursor
- call prtstr ; do it
- pop d ; get Kermit's version
-IF NOT (osi OR crt) ; got cursor control?
- call prtstr ; print it
- mvi e,'[' ; open bracket
- call outcon ; print it (close bracket is in outln2)
- lxi d,sysver ; get name and version of system module
- call prtstr
- lxi d,outln2 ; yes, print field names
- call prtstr
- lda dbgflg ; is debugging enabled?
- ora a
- rz ; finished if no debugging
- lxi d,outln3 ; set up debugging fields
- call prtstr
-ENDIF;NOT (osi OR crt)
- ret
-;
-; Calculate free space for current drive
-; returns value in HL
-sysspc:
- lda bdosvr ;cpm3's alloc vect may be in another bank
- cpi 30H ;cpm3 or later?
- jm cp2spc ;no: use cp/m 2 algorithm
- lda fcb ;If no drive, get
- ora a ; logged in drive
- jz dir180
- dcr a ;FCB drive A=1 normalize to be A=0
- jmp dir18a
-
-dir180: mvi c,rddrv
- call bdos
-dir18a: mov e,a ;drive in e
- mvi c,getfs ;get free space BDOS funct
- call bdos ;returns free recs (3 bytes in buff..buff+2)
- mvi b,3 ;conv recs to K by 3 bit shift
-dir18b: xra a ;clear carry
- mvi c,3 ;for 3 bytes
- lxi h,buff+3 ;point to addr + 1
-dir18c: dcx h ;point to less sig. byte
- mov a,m ;get byte
- rar ;carry -> A -> carry
- mov m,a ;put back byte
- dcr c ;for all bytes (carry not mod)
- jnz dir18c
- dcr b ;shift 1 bit 3 times
- jnz dir18b
- mov e,m ;get least sig byte
- inx h
- mov d,m ;get most sig byte
- xchg ;get K free in HL
- ret
-
-; the rest are CP/M 2.2 systems, so use the alloc vector
-cp2spc: mvi c,getalv ;Address of CP/M Allocation Vector
- call bdos
- xchg ;Get its length
- lhld bmax
- inx h
- lxi b,0 ;Initialize Block count to zero
-dir19: push d ;Save allocation address
- ldax d
- mvi e,8 ;set to process 8 blocks
-dir20: ral ;Test bit
- jc dir20a
- inx b
-dir20a: mov d,a ;Save bits
- dcx h
- mov a,l
- ora h
- jz dir21 ;Quit if out of blocks
- mov a,d ;Restore bits
- dcr e ;count down 8 bits
- jnz dir20 ;do another bit
- pop d ;Bump to next count of Allocation Vector
- inx d
- jmp dir19 ;process it
-
-dir21: pop d ;Clear Allocation vector from stack
- mov l,c ;Copy block to 'HL'
- mov h,b
- lda bshiftf ;Get Block Shift Factor
- sui 3 ;Convert from records to thousands
- rz ;Skip shifts if 1K blocks
-dir22: dad h ;Multiply blocks by 'K per Block'
- dcr a
- jnz dir22
- ret
-
-; +----|----|----|----|----|----|----|...
-; 1 |
-; 2 | Kermit-80 v4.0 [system]
-; 3 |
-; 4 |Number of packets: ____
-; 5 |Number of retries: ____
-; 6 |File name: ____________
-; 7 |<error>...
-; 8 |<status>...
-; 9 |RPack: ___(if debugging)...
-; 10 |
-; 11 |SPack: ___(if debugging)...
-; 12 |
-; 13 |Kermit-80 A:> (when finished)
-;
-; For the PX-8, the display looks like:
-; 5 10 15 20 25 30 35 40 45 50 55
-; +----|----|----|----|----|----|----|----|----|----|----|----|----
-; 1 |Kermit-80 v4.05 [Epson PX-8] Number of retries: ____
-; 2 |Number of packets: ____ File name: ________.___
-; 3 |<error>...
-; 4 |<status>...
-; 5 |RPack: ___ (if debugging)...
-; 6 |
-; 7 |SPack: ___ (if debugging)...
-; 8 |
-; 9 |Kermit-80 A:> (when finished)
-;
-
-IF NOT px8 ; [29]
-nppos EQU 4*100h+20
-rtpos EQU 5*100h+20
-fnpos EQU 6*100h+12
-errlin EQU 7
-stlin EQU 8
-rplin EQU 9
-splin EQU 11
-prplin EQU 13
-ENDIF ; NOT px8
-
-IF px8
-nppos EQU 2*100h+20
-rtpos EQU 1*100h+59
-fnpos EQU 2*100h+51
-errlin EQU 3
-stlin EQU 4
-rplin EQU 5
-splin EQU 7
-prplin EQU 9
-ENDIF ; px8 [29]
-
-
-IF NOT (osi OR crt );[26]
-scrnp: lxi b,nppos
- jmp csrpos
-
-scrnrt: lxi b,rtpos
- jmp csrpos
-
-scrfln: lxi b,fnpos
- call csrpos
-clreol:
- lxi d,tk
- jmp prtstr
-
-screrr: lxi b,errlin*100H+1
- call csrpos
- jmp clreol
-
-scrst: lxi b,stlin*100H+1
- call csrpos
- jmp clreol
-
-rppos: lxi b,rplin*100H+8
- call csrpos
- jmp clreol
-
-sppos: lxi b,splin*100H+8
- call csrpos
- jmp clreol
-
-; [29] Modify scrend to make the cursor line conditional on use of debugging
-; This means that in most cases the entire file transfer will fit on PX-8 lcd
-scrend: lda dbgflg
- ora a
- jz scr1nd
- lxi b,prplin*100H+1 ; debugging in use [29]
- jmp scr2nd
-scr1nd: lxi b,rplin*100H+1 ; no debugging
-scr2nd: call csrpos
-clreos: lxi d,tj
- jmp prtstr
-; [29] and nop out the rest for now...
-;
-;scrend: lxi b,prplin*100H+1
-; call csrpos
-;clreos: lxi d,tj
-; jmp prtstr
-ENDIF;NOT (osi OR crt ) [26]
-
-
-IF osi OR crt ; no cursor control
-scrnp: mvi e,' '
- jmp outcon
-
-scrnrt: mvi e,' '
- call outcon
- mvi e,'%'
- jmp outcon
-
-scrfln:
-screrr:
-scrst:
-scrend: jmp prcrlf ;Print CR/LF [Toad Hall]
-
-rppos: lxi d,prpack
- jmp prtstr
-
-sppos: lxi d,pspack
- jmp prtstr
-ENDIF;osi OR crt
-
-; Some frequently-used routines (duplicates of those in CPSMIT):
-; prcrlf - output a CR/LF
-; prtstr - output string in DE
-; rskp - return, skipping over error return
-prcrlf: lxi d,crlf
-prtstr:
-; [17] added this to avoid prtstr.. emulate function 9 call.
-; Works on most machines.
-IF (torch OR px8 OR z80mu)
-;
-; Modified print string as the CP/N (for Nut) system traps control
-; characters in a function 9 call.. rot its cotton socks.
- push h
- push d
- push b
-prtst1:
- ldax d
- inx d
- cpi '$' ; if a dollar then end of string
- jz prtst2
- push d
- mov e,a
- mov c,a ; also to c if its via conout in BIOS
- call outcon ; send it to the screen
- pop d
- jmp prtst1
-
-prtst2: pop b
- pop d
- pop h
- ret ; regs restored.. just in case
-ENDIF ;(torch OR px8 OR z80mu)
-
-IF NOT (torch OR px8 or z80mu) ;ie any machine that can send ctrl chrs via dos call 9
- PUSH H
- PUSH D
- push b
- mvi c,9 ; Dos call 9 (print a string)
- call bdos
- pop b
- POP D
- POP H
- ret ; all done for good machines
-ENDIF ;NOT (torch OR px8 OR z80mu)
-
-;
-; rskp - return to calling address + 3.
-rskp: pop h ; Get the return address
- inx h ; Increment by three
- inx h
- inx h
- pchl
-
-; Copy block of data
-; source in HL, destination in DE, byte count in BC
-; called by: cpxsys, mfname
-;
-mover:
-;IF NOT z80 ; 8080's have to do it the hard way
-;OBS assume its an 8080 for now - this will work on Z80s anyway.
- mov a,m
- stax d
- inx h
- inx d
- dcx b
- mov a,b
- ora c
- jnz mover
-;ENDIF;NOT z80
-;IF z80
-; db 0EDh,0B0h ; Z80 LDIR instruction
-;ENDIF;z80
- ret
-
-;
-; Miscellaneous messages
-;
-crlf: db cr,lf,'$'
-cfgmsg: db 'configured for $'
-witmsg: db ' with $' ; Its included if we get here ('with terminal')
-
-IF NOT (osi OR crt OR px8) ; [29] got cursor control?
-outln2: db ']',cr,lf,cr,lf,'Number of packets:'
- db cr,lf,'Number of retries:'
- db cr,lf,'File name:$'
-ENDIF;NOT (osi OR crt OR px8)
-
-IF px8 ; [29]
-outln2: db '] Number of retries:', cr, lf
- db 'Number of packets: File name:$'
-ENDIF ; px8 [29]
-
-IF NOT (osi OR crt) ; [29]
-outln3: db cr,lf,cr,lf ; debugging messages
- db cr,lf,'Rpack:'
- db cr,lf ; Blank line in case of long packet
- db cr,lf,'Spack:$'
-ENDIF ; NOT (osi OR crt) [29]
-
-IF lasm
-LINK CPXSWT.ASM
-ENDIF ;lasm
-
+IF NOT lasm
+.printx * CPXCOM.ASM *
+ENDIF ; NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains part common code required for most if not all
+; systems. Specifiacally, SYSINIT, INIADR, MOVER, and DELAY to name
+; the most important ones.
+;
+; revision history:
+;
+; edit 1, 21st July 1987 by OBSchou. Regretably, I have had to include
+; some system dependent IFs, mainly for CRT, TORCH and OSI. Inclusion
+; here means simpler family files later on. (Regrettably, the delay
+; loop for APMMDM differs too.)
+;
+; Set the fuzzy timeout value. Range is 1 (VERY short) through 0ffffH to zero
+; (maximum). The actual duration is a function of the loop length and the
+; processor speed. For now, we'll make it zero for everybody, but feel free
+; to change it for your system.
+; [OBS] make it a little less than max, say 1000H. More useful.
+fuzval EQU 1000H
+
+;
+; System-dependent initialization
+; Called once at program start.
+sysinit:
+;
+; [13] Had to move this call to here, as the prtstr routine needs this
+; before the config message is sent out. It has only been moved.
+;
+ call iniadr ;Initialize the BIOS addresses
+ mvi c,gtiob ;Get current I/O byte
+ call bdos ;From CP/M
+ sta coniob ;Remember where console is
+ mvi c,getvnm ; get the BDOS version number (e.g. 22H, 31H)
+ call bdos
+ mov a,l
+ sta bdosvr ; and store it away for future reference
+ lxi d,cfgmsg ; "configured for "
+ call prtstr
+ lxi d,sysver ; get configuration we're configured for
+ call prtstr ; print it.
+;
+; If we're set up to do special terminal handling, say what kind
+; of terminal we expect... (unless it's the generic 'crt')
+IF termin
+ lxi d,witmsg ; " with "
+ call prtstr
+ lxi d,ttytyp ; terminal type
+ call prtstr
+ENDIF;termin
+ call prcrlf ; print CR/LF
+;
+; now, to work...
+;
+; locate large buffer for multi-sector I/O
+; What we want to do here is find the ccp. Space between ovlend and the ccp
+; is available for buffering, except we don't want to use more than maxsec
+; buffers (if we use too many, the remote end could time out while we're
+; writing to disk). maxsec is system-dependent, but for now we'll just
+; use 8Kbytes. If you get retransmissions and other protocol errors after
+; transferring the first maxsec sectors, lower maxsec.
+
+maxsec EQU (8*1024)/bufsiz ; 8K / number of bytes per sector
+
+ lxi h,ovlend ; get start of buffer
+ shld bufadr ; store in linkage section
+ mvi a,maxsec ; get size of buffer, in sectors
+ sta bufsec ; store that, too.
+
+ call sysxin ; call system specific init code
+
+ ret ; return from system-dependent routine
+
+bdosvr: ds 1 ; space to save the BDOS version number
+IF NOT iobyt
+coniob: ds 1 ; space to save copy of IO byte
+ENDIF ;NOT iobyt
+;
+; This one is hopefully the last "improvement" in view of GENERIC
+;Kermit. It uses for Character-I/O the BIOS-routines ( instead of the
+;"normal" BDOS routines. What does it give us (hopefully) : More speed,
+;higher chance of success ( I/O byte implemented in BIOS [if at all]),
+;but no "extra" device handling - that's done by BDOS.
+;
+; How do we "get" the call-adresses? Location 0 has a JMP Warm-Boot
+;in CP/M which points into the second location of the BIOS JMP-Vector. The
+;next three locations of the JMP-Vector point to the CONSTAT,CONIN,CONOUT
+;BIOS-routines. CONOUT wants the character in C.
+;
+;- Bernie Eiben
+
+iniadr: lhld 1 ;get BIOS Warmstart-address
+ lxi d,3 ;next adress is CONSTAT in BIOS
+ dad d
+ shld bconst+1 ;stuff it into the call-instruction
+ lxi d,3 ;next adress is CONIN in BIOS
+ dad d
+ shld bconin+1 ;
+ lxi d,3 ;next adress is CONOUT in BIOS
+ dad d
+ shld bcnout+1
+ lxi d,3 ;next address is LIST in BIOS
+ dad d
+ shld blsout+1
+ lxi d,10*3 ; get printer status routine
+ dad d
+ shld bprtst
+ ret ;And return
+
+bconst: jmp $-$ ;Call BIOS directly (filled in by iniadr)
+
+bconin: jmp $-$ ;Call BIOS directly (filled in by iniadr)
+
+bcnout: jmp $-$ ;Call BIOS directly (filled in by iniadr)
+
+blsout: jmp $-$ ; ....
+
+bprtst: jmp $-$ ; Call BIOS directly for printer status
+
+IF NOT apmmdm ; Shame about this, but the Apple needs a different delay
+;
+;[cjc] Delay routine. Called with time (hundredths of seconds) in A.
+; The inner loop delays 1001 T-states, assuming no wait states are
+; inserted; this is repeated CPUSPD times, for a total delay of just
+; over 0.01 second. (CPUSPD should be set to the system clock rate,
+; in units of 100KHz: for an unmodified Kaypro II, that's 25 for
+; 2.5 MHz. Some enterprising soul could determine whether or not the
+; Kaypro actually inserts a wait state on instruction fetch (a common
+; practice); if so, the magic number at delay2 needs to be decreased.
+; (We also neglect to consider time spent at interrupt level).
+;
+; called by: sendbr
+; destroys BC
+
+delay: mvi c,cpuspd ; Number of times to wait 1000 T-states to
+ ; make .01 second delay
+delay2: mvi b,70 ; Number of times to execute inner loop to
+ ; make 1000 T-state delay
+delay3: dcr b ; 4 T-states (* 70 * cpuspd)
+ jnz delay3 ; 10 T-states (* 70 * cpuspd)
+ dcr c ; 4 T-states (* cpuspd)
+ jnz delay2 ; 10 T-states (* cpuspd)
+ ; total delay: ((14 * 70) + 14) * cpuspd
+ ; = 1001 * cpuspd
+ dcr a ; 4 T-states
+ jnz delay ; 10 T-states
+ ret ; grand total: ((1001 * cpuspd) + 14) * a
+ENDIF ; NOT apmmdm
+;
+;
+; Set up screen display for file transfer
+; called with kermit version in DE
+;
+sysscr: push d ; save version for a bit
+ lxi d,outlin ; clear screen, position cursor
+ call prtstr ; do it
+ pop d ; get Kermit's version
+IF NOT (osi OR crt) ; got cursor control?
+ call prtstr ; print it
+ mvi e,'[' ; open bracket
+ call outcon ; print it (close bracket is in outln2)
+ lxi d,sysver ; get name and version of system module
+ call prtstr
+ lxi d,outln2 ; yes, print field names
+ call prtstr
+ lda dbgflg ; is debugging enabled?
+ ora a
+ rz ; finished if no debugging
+ lxi d,outln3 ; set up debugging fields
+ call prtstr
+ENDIF;NOT (osi OR crt)
+ ret
+;
+; Calculate free space for current drive
+; returns value in HL
+sysspc:
+ lda bdosvr ;cpm3's alloc vect may be in another bank
+ cpi 30H ;cpm3 or later?
+ jm cp2spc ;no: use cp/m 2 algorithm
+ lda fcb ;If no drive, get
+ ora a ; logged in drive
+ jz dir180
+ dcr a ;FCB drive A=1 normalize to be A=0
+ jmp dir18a
+
+dir180: mvi c,rddrv
+ call bdos
+dir18a: mov e,a ;drive in e
+ mvi c,getfs ;get free space BDOS funct
+ call bdos ;returns free recs (3 bytes in buff..buff+2)
+ mvi b,3 ;conv recs to K by 3 bit shift
+dir18b: xra a ;clear carry
+ mvi c,3 ;for 3 bytes
+ lxi h,buff+3 ;point to addr + 1
+dir18c: dcx h ;point to less sig. byte
+ mov a,m ;get byte
+ rar ;carry -> A -> carry
+ mov m,a ;put back byte
+ dcr c ;for all bytes (carry not mod)
+ jnz dir18c
+ dcr b ;shift 1 bit 3 times
+ jnz dir18b
+ mov e,m ;get least sig byte
+ inx h
+ mov d,m ;get most sig byte
+ xchg ;get K free in HL
+ ret
+
+; the rest are CP/M 2.2 systems, so use the alloc vector
+cp2spc: mvi c,getalv ;Address of CP/M Allocation Vector
+ call bdos
+ xchg ;Get its length
+ lhld bmax
+ inx h
+ lxi b,0 ;Initialize Block count to zero
+dir19: push d ;Save allocation address
+ ldax d
+ mvi e,8 ;set to process 8 blocks
+dir20: ral ;Test bit
+ jc dir20a
+ inx b
+dir20a: mov d,a ;Save bits
+ dcx h
+ mov a,l
+ ora h
+ jz dir21 ;Quit if out of blocks
+ mov a,d ;Restore bits
+ dcr e ;count down 8 bits
+ jnz dir20 ;do another bit
+ pop d ;Bump to next count of Allocation Vector
+ inx d
+ jmp dir19 ;process it
+
+dir21: pop d ;Clear Allocation vector from stack
+ mov l,c ;Copy block to 'HL'
+ mov h,b
+ lda bshiftf ;Get Block Shift Factor
+ sui 3 ;Convert from records to thousands
+ rz ;Skip shifts if 1K blocks
+dir22: dad h ;Multiply blocks by 'K per Block'
+ dcr a
+ jnz dir22
+ ret
+
+; +----|----|----|----|----|----|----|...
+; 1 |
+; 2 | Kermit-80 v4.0 [system]
+; 3 |
+; 4 |Number of packets: ____
+; 5 |Number of retries: ____
+; 6 |File name: ____________
+; 7 |<error>...
+; 8 |<status>...
+; 9 |RPack: ___(if debugging)...
+; 10 |
+; 11 |SPack: ___(if debugging)...
+; 12 |
+; 13 |Kermit-80 A:> (when finished)
+;
+; For the PX-8, the display looks like:
+; 5 10 15 20 25 30 35 40 45 50 55
+; +----|----|----|----|----|----|----|----|----|----|----|----|----
+; 1 |Kermit-80 v4.05 [Epson PX-8] Number of retries: ____
+; 2 |Number of packets: ____ File name: ________.___
+; 3 |<error>...
+; 4 |<status>...
+; 5 |RPack: ___ (if debugging)...
+; 6 |
+; 7 |SPack: ___ (if debugging)...
+; 8 |
+; 9 |Kermit-80 A:> (when finished)
+;
+
+IF NOT px8 ; [29]
+nppos EQU 4*100h+20
+rtpos EQU 5*100h+20
+fnpos EQU 6*100h+12
+errlin EQU 7
+stlin EQU 8
+rplin EQU 9
+splin EQU 11
+prplin EQU 13
+ENDIF ; NOT px8
+
+IF px8
+nppos EQU 2*100h+20
+rtpos EQU 1*100h+59
+fnpos EQU 2*100h+51
+errlin EQU 3
+stlin EQU 4
+rplin EQU 5
+splin EQU 7
+prplin EQU 9
+ENDIF ; px8 [29]
+
+
+IF NOT (osi OR crt );[26]
+scrnp: lxi b,nppos
+ jmp csrpos
+
+scrnrt: lxi b,rtpos
+ jmp csrpos
+
+scrfln: lxi b,fnpos
+ call csrpos
+clreol:
+ lxi d,tk
+ jmp prtstr
+
+screrr: lxi b,errlin*100H+1
+ call csrpos
+ jmp clreol
+
+scrst: lxi b,stlin*100H+1
+ call csrpos
+ jmp clreol
+
+rppos: lxi b,rplin*100H+8
+ call csrpos
+ jmp clreol
+
+sppos: lxi b,splin*100H+8
+ call csrpos
+ jmp clreol
+
+; [29] Modify scrend to make the cursor line conditional on use of debugging
+; This means that in most cases the entire file transfer will fit on PX-8 lcd
+scrend: lda dbgflg
+ ora a
+ jz scr1nd
+ lxi b,prplin*100H+1 ; debugging in use [29]
+ jmp scr2nd
+scr1nd: lxi b,rplin*100H+1 ; no debugging
+scr2nd: call csrpos
+clreos: lxi d,tj
+ jmp prtstr
+; [29] and nop out the rest for now...
+;
+;scrend: lxi b,prplin*100H+1
+; call csrpos
+;clreos: lxi d,tj
+; jmp prtstr
+ENDIF;NOT (osi OR crt ) [26]
+
+
+IF osi OR crt ; no cursor control
+scrnp: mvi e,' '
+ jmp outcon
+
+scrnrt: mvi e,' '
+ call outcon
+ mvi e,'%'
+ jmp outcon
+
+scrfln:
+screrr:
+scrst:
+scrend: jmp prcrlf ;Print CR/LF [Toad Hall]
+
+rppos: lxi d,prpack
+ jmp prtstr
+
+sppos: lxi d,pspack
+ jmp prtstr
+ENDIF;osi OR crt
+
+; Some frequently-used routines (duplicates of those in CPSMIT):
+; prcrlf - output a CR/LF
+; prtstr - output string in DE
+; rskp - return, skipping over error return
+prcrlf: lxi d,crlf
+prtstr:
+; [17] added this to avoid prtstr.. emulate function 9 call.
+; Works on most machines.
+IF (torch OR px8 OR z80mu)
+;
+; Modified print string as the CP/N (for Nut) system traps control
+; characters in a function 9 call.. rot its cotton socks.
+ push h
+ push d
+ push b
+prtst1:
+ ldax d
+ inx d
+ cpi '$' ; if a dollar then end of string
+ jz prtst2
+ push d
+ mov e,a
+ mov c,a ; also to c if its via conout in BIOS
+ call outcon ; send it to the screen
+ pop d
+ jmp prtst1
+
+prtst2: pop b
+ pop d
+ pop h
+ ret ; regs restored.. just in case
+ENDIF ;(torch OR px8 OR z80mu)
+
+IF NOT (torch OR px8 or z80mu) ;ie any machine that can send ctrl chrs via dos call 9
+ PUSH H
+ PUSH D
+ push b
+ mvi c,9 ; Dos call 9 (print a string)
+ call bdos
+ pop b
+ POP D
+ POP H
+ ret ; all done for good machines
+ENDIF ;NOT (torch OR px8 OR z80mu)
+
+;
+; rskp - return to calling address + 3.
+rskp: pop h ; Get the return address
+ inx h ; Increment by three
+ inx h
+ inx h
+ pchl
+
+; Copy block of data
+; source in HL, destination in DE, byte count in BC
+; called by: cpxsys, mfname
+;
+mover:
+;IF NOT z80 ; 8080's have to do it the hard way
+;OBS assume its an 8080 for now - this will work on Z80s anyway.
+ mov a,m
+ stax d
+ inx h
+ inx d
+ dcx b
+ mov a,b
+ ora c
+ jnz mover
+;ENDIF;NOT z80
+;IF z80
+; db 0EDh,0B0h ; Z80 LDIR instruction
+;ENDIF;z80
+ ret
+
+;
+; Miscellaneous messages
+;
+crlf: db cr,lf,'$'
+cfgmsg: db 'configured for $'
+witmsg: db ' with $' ; Its included if we get here ('with terminal')
+
+IF NOT (osi OR crt OR px8) ; [29] got cursor control?
+outln2: db ']',cr,lf,cr,lf,'Number of packets:'
+ db cr,lf,'Number of retries:'
+ db cr,lf,'File name:$'
+ENDIF;NOT (osi OR crt OR px8)
+
+IF px8 ; [29]
+outln2: db '] Number of retries:', cr, lf
+ db 'Number of packets: File name:$'
+ENDIF ; px8 [29]
+
+IF NOT (osi OR crt) ; [29]
+outln3: db cr,lf,cr,lf ; debugging messages
+ db cr,lf,'Rpack:'
+ db cr,lf ; Blank line in case of long packet
+ db cr,lf,'Spack:$'
+ENDIF ; NOT (osi OR crt) [29]
+
+IF lasm
+LINK CPXSWT.ASM
+ENDIF ;lasm
+
diff --git a/cpxgni.asm b/cpxgni.asm
index 615103f..51561b0 100644
--- a/cpxgni.asm
+++ b/cpxgni.asm
@@ -1,440 +1,440 @@
-; CPXGNI.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the system-dependent code and data for various
-; Genie 3 CPM kermit
-;
-; This has the Family name of CPXGNI.ASM.
-;
-; revision history (last edit first)
-; edit 3: 27 October, a987 by OBSchou. Massaged file to suit V4.09 structure.
-;
-; Edit 2: Aug 27 1987 GDS Put in code for BREAK and fillited out
-; a lot of unnecessary IF's
-;
-;Edit 1: Nov. 28, 1986 Geof Smith Clinical Research centre Harrow UK.
-
-.printx * Assembling for Eaca Genie 3 *
-;
-drtime EQU 05H ;Default receive time out interval.
-;
-; the basics...
-;
-mnport EQU 0E8H
-mnprts EQU 0EDH
-output EQU 20H
-input EQU 01H
-lctrl EQU 0EBH
-divlsb EQU 0E8H
-divmsb EQU 0E9H
-z80 EQU TRUE
-brkval EQU 40H
-
-defesc EQU ']'-100O ;The default escape character.
-
-
-;Select initial setting for VT-52 emulation flag.
-
-; default to VT52-EMULATION ON.
-;
-vtval EQU 1
-;
-;
-
-; Family is the string used in VERSION to say which of several
-; smaller overlay files are used. These are (will be) derived from
-; the huge CP4SYS.ASM file, in which case we will never get here.
-; Just a Dollar, but put a sting in for a family of machines.
-;
-family:db 'CPXGNI.ASM (3) 27-Oct-87$' ; Used for family versions....
-
-
-
-;
-; System-dependent initialization
-; Called once at program start.
-sysxin:
-;
- ;Set up 9600 bd, 8bit words, no parity 1stop bit
-
- mvi a,83H ;enable DLAB by setting bit 7
- out lctrl ;and outputting to control port
- mvi a,14H ;get word = 20 decimal
- out divlsb ;and put it out
- mvi a,00H ;as two separate
- out divmsb ;bytes
- lda pstore ;get parity etc
- out lctrl ;do it resetting DLAB at same time
-
- ret ; return from system-dependent routine
-
-
-;
-; system-dependent termination processing
-; If we've changed anything, this is our last chance to put it back.
-sysexit:
-
- ret
-
-;
-; system-dependent processing for start of CONNECT command
-;
-syscon:
- ret
-
-conmsg: ; Messages printed when entering transparent (CONNECT) mode:
-;
-
-
-;
-; syscls - system-dependent close routine
-; called when exiting transparent session.
-;
-syscls:
- ret
-;
-
-
-;
-; sysinh - help for system-dependent special functions.
-; called in response to <escape>?, after listing all the
-; system-independent escape sequences.
-;
-sysinh:
- lxi d,inhlps ; we got options...
- call prtstr ; print them.
- ret
-
-
-;additional, system-dependent help for transparent mode
-; (two-character escape sequences)
-inhlps:
-
- db cr,lf,'B Transmit a BREAK'
-
- db '$' ;[hh] table terminator
-
-;
-; sysint - system dependent special functions
-; called when transparent escape character has been typed;
-; the second character of the sequence is in A (and in B).
-; returns:
-; non-skip: sequence has been processed
-; skip: sequence was not recognized
-sysint: ani 137O ; convert lower case to upper, for testing...
- cpi 'B' ; send break?
- jz sendbr ; yes, go do it. return nonskip when through.
-
- jmp rskp ; take skip return - command not recognized.
-
-
-;-------------------------------------------------------------------------------
-sendbr:
-;
-; Ensure that the transmitter has finished sending buffered chars
-sndbr1: in mnprts ; get UART status
- ani output ; everything sent?
- jz sndbr1 ; no, wait a bit more
-;
-; Begin sending a break by setting bit in UART command register
- mvi a,brkval ; SBreak,
- out lctrl
-;
-; Wait for 250 milliseconds (using hundredths second delay routine)
- mvi a,25
- call delay
-;
-; Resume normal operation by clearing the SendBreak command bit
- lda pstore ;and restoring value from parity store
- out mnprts
-;
- ret ;done
-
-;
-;
-
-;
-; sysflt - system-dependent filter
-; called with character in E.
-; if this character should not be printed, return with A = zero.
-; preserves bc, de, hl.
-; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-sysflt:
- mov a,e ; get character for testing
- ret
-
-; mdmflt - modem filter [30]
-; called with character to be sent to modem in E
-; with parity set as appropriate.
-; return with accumulator = 0 do do nothing,
-; <> 0 to send char in E.
-mdmflt: mov a,e ; get character to a
- ret
-
-
-
-; prtflt - printer filter [30]
-; called with character to be sent to printer in E
-; returns with a = 0 to do nothing
-; a <> 0 to print it.
-;
-; this routine for those printer that automatically insert
-; a lf on cr, or cr for lf. Should this be shifted to
-; the system indep. stuff, in say 4.06?
-prtflt:
- mov a,e ; [30] get character to test
- ret
-
-
-;
-
-
-;
-; system-dependent processing for BYE command.
-; for apmmdm, heath, and lobo, hang up the phone.
-sysbye:
- ret
-;
-
-
-; This is the system-dependent command to change the baud rate.
-; DE contains the two-byte value from the baud rate table; this
-; value is also stored in 'speed'.
-sysspd:
-
- ;Set up baud rate 8bit words, no parity 1stop bit
- mvi a,83H ;enable DLAB by setting bit 7
- out lctrl ;and outputting to control port
- mov a,d ;get LSB
- out divlsb ;and put it out
- mov a,e ;get MSB
- out divmsb ;output it as well
- lda pstore ;get parity etc
- out lctrl ;do it resetting DLAB at same time
- ret
-
-pstore: db 03H ;Default value for parity word length and stop bits
-
-spdtbl: db 11h ;17 entries
- db 03h,'110$', 06H,0D1H
- db 04h,'1200$', 00H,0A0H
- db 05h,'134.5$', 05H,94H
- db 03h,'150$', 05H,00H
- db 04h,'1800$', 00H,6BH
- db 05h,'19200$', 00H,0AH
- db 04h,'2000$', 00H,60H
- db 04h,'2400$', 00H,50H
- db 03h,'300$', 02H,80H
- db 04h,'3600$', 00H,35H
- db 05h,'38400$', 00H,05H
- db 04h,'4800$', 00H,28H
- db 02h,'50$', 0FH,00H
- db 03h,'600$', 01H,40H
- db 04h,'7200$', 00H,1BH
- db 02h,'75$', 0AH,00H
- db 04h,'9600$', 00H,14H
-
-sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
- db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200 38400$'
-
-; This is the system-dependent SET PORT command.
-; HL contains the argument from the command table.
-sysprt:
-
- ret
-;
-prttbl equ 0 ; SET PORT not supported
-prhtbl equ 0
-
-;
-
-;
-; selmdm - select modem port
-; selcon - select console port
-; selmdm is called before using inpmdm or outmdm;
-; selcon is called before using inpcon or outcon.
-; For iobyt systems, diddle the I/O byte to select console or comm port;
-; For Decision I, switches Multi I/O board to console or modem serial
-; port. [Toad Hall]
-; For the rest, does nothing.
-; preserves bc, de, hl.
-selmdm:
- ret
-
-selcon:
- ret
-;
-
-
-; Get character from console, or return zero.
-; result is returned in A. destroys bc, de, hl.
-;
-inpcon:
- mvi c,dconio ;Direct console I/O BDOS call.
- mvi e,0FFH ;Input.
- call BDOS
-
- ret
-;
-; Output character in E to the console.
-; destroys bc, de, hl
-;
-outcon:
-
- mvi c,dconio ;Console output bdos call.
- call bdos ;Output the char to the console.
-
- ret
-;
-;
-; outmdm - output a char from E to the modem.
-; the parity bit has been set as necessary.
-; returns nonskip; bc, de, hl preserved.
-outmdm:
-
- in mnprts ;Get the output done flag.
- ani output ;Is it set?
- jz outmdm ;If not, loop until it is.
- mov a,e
- out mnport ;Output it.
- ret
-
-;--------------------------------------------------------------------------
-;
-; get character from modem; return zero if none available.
-; for IOBYT systems, the modem port has already been selected.
-; destroys bc, de, hl.
-inpmdm:
-;Note: modem port should already be selected for mdI. [Toad Hall]
- in mnprts ;Get the port status into A.
- ani input ;See if the input ready bit is on.
- rz ;If not then return.
- in mnport ;If so, get the char.
- ret ; return with character in A
-
-
-;
-; flsmdm - flush comm line.
-; Modem is selected.
-; Currently, just gets characters until none are available.
-
-flsmdm: call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-;-----------------------------------------------------------------------------
-;
-; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
-lptstat:
- xra a ; assume it is ok.. this may not be necessary
- ret
-
-;
-; outlpt - output character in E to printer
-; console is selected.
-; preserves de.
-outlpt:
- push d ; save DE in either case
- call prtflt ; go through printer filter [30]
- ana a ; if A = 0 do nothing,
- jz outlp1 ; [30] if a=0 do nothing
-
- mvi c,lstout
- call bdos ;Char to printer
-outlp1: pop d ; restore saved register pair
- ret
-;------------------------------------------------------------------------------
-;
-; Screen manipulation routines
-; csrpos - move to row B, column C
-;
-; csrpos for terminals that use a leadin sequence followed
-; by (row + 31.) and (column + 31.)
-;
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,h ; get row
- adi (' '-1) ; space is row one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,l ; get column
- adi (' '-1) ; space is column one
- mov e,a
- jmp outcon ; output it and return
-
-;
-; delchr - make delete look like a backspace. Unless delete is a printing
-; character, we just need to print a backspace. (we'll output clrspc
-; afterwards)
-; For Kaypro and Vector General, delete puts a blotch on the screen.
-; For Apple and Osborne 1, delete moves but doesn't print.
-delchr:
-
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the character at the current cursor position
-clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the current line
-clrlin: lxi d,eralin
- jmp prtstr
-
-; erase the whole screen, and go home. preserves b (but not c)
-clrtop: lxi d,erascr
- jmp prtstr
-
-;[2] I see no real saving in having all screens in separate file and
-;therefore have included screen definition here and commented out
-;the link to VDU file
-;
-;Specific definitions for the Genie III screen
-;
-sysver: db 'Eaca Genie III$'
-outlin: db 1aH,cr,lf,' $'
-erascr: db 1AH,'$'
-eralin: db cr,18H,'$'
-curldn: db esc,'=$'
-ttab:
-ta: db 0BH,'$',0,0 ;Cursor up
-tb: db 0AH,'$',0,0 ;Cursor down
-tc: db 0CH,'$',0,0 ;Cursor right
-td: db 08H,'$',0,0 ;Cursor left
-te: db 1AH,'$',0,0 ;Clear display
-tf: db esc,'R$',0 ;Reverse on
-tg: db esc,'S$',0 ;Reverse off
-th: db 1EH,'$',0,0 ;Cursor home
-ti: db 0BH,'$',0,0 ;Reverse linefeed
-tj: db 19H,'$',0,0 ;Clear to end of screen
-tk: db 18H,'$',0,0 ;Clear to end of line
-
-ovlend equ $ ;End of overlay
-
-END
-
-
-
-
-
+; CPXGNI.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the system-dependent code and data for various
+; Genie 3 CPM kermit
+;
+; This has the Family name of CPXGNI.ASM.
+;
+; revision history (last edit first)
+; edit 3: 27 October, a987 by OBSchou. Massaged file to suit V4.09 structure.
+;
+; Edit 2: Aug 27 1987 GDS Put in code for BREAK and fillited out
+; a lot of unnecessary IF's
+;
+;Edit 1: Nov. 28, 1986 Geof Smith Clinical Research centre Harrow UK.
+
+.printx * Assembling for Eaca Genie 3 *
+;
+drtime EQU 05H ;Default receive time out interval.
+;
+; the basics...
+;
+mnport EQU 0E8H
+mnprts EQU 0EDH
+output EQU 20H
+input EQU 01H
+lctrl EQU 0EBH
+divlsb EQU 0E8H
+divmsb EQU 0E9H
+z80 EQU TRUE
+brkval EQU 40H
+
+defesc EQU ']'-100O ;The default escape character.
+
+
+;Select initial setting for VT-52 emulation flag.
+
+; default to VT52-EMULATION ON.
+;
+vtval EQU 1
+;
+;
+
+; Family is the string used in VERSION to say which of several
+; smaller overlay files are used. These are (will be) derived from
+; the huge CP4SYS.ASM file, in which case we will never get here.
+; Just a Dollar, but put a sting in for a family of machines.
+;
+family:db 'CPXGNI.ASM (3) 27-Oct-87$' ; Used for family versions....
+
+
+
+;
+; System-dependent initialization
+; Called once at program start.
+sysxin:
+;
+ ;Set up 9600 bd, 8bit words, no parity 1stop bit
+
+ mvi a,83H ;enable DLAB by setting bit 7
+ out lctrl ;and outputting to control port
+ mvi a,14H ;get word = 20 decimal
+ out divlsb ;and put it out
+ mvi a,00H ;as two separate
+ out divmsb ;bytes
+ lda pstore ;get parity etc
+ out lctrl ;do it resetting DLAB at same time
+
+ ret ; return from system-dependent routine
+
+
+;
+; system-dependent termination processing
+; If we've changed anything, this is our last chance to put it back.
+sysexit:
+
+ ret
+
+;
+; system-dependent processing for start of CONNECT command
+;
+syscon:
+ ret
+
+conmsg: ; Messages printed when entering transparent (CONNECT) mode:
+;
+
+
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+ ret
+;
+
+
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing all the
+; system-independent escape sequences.
+;
+sysinh:
+ lxi d,inhlps ; we got options...
+ call prtstr ; print them.
+ ret
+
+
+;additional, system-dependent help for transparent mode
+; (two-character escape sequences)
+inhlps:
+
+ db cr,lf,'B Transmit a BREAK'
+
+ db '$' ;[hh] table terminator
+
+;
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:
+; non-skip: sequence has been processed
+; skip: sequence was not recognized
+sysint: ani 137O ; convert lower case to upper, for testing...
+ cpi 'B' ; send break?
+ jz sendbr ; yes, go do it. return nonskip when through.
+
+ jmp rskp ; take skip return - command not recognized.
+
+
+;-------------------------------------------------------------------------------
+sendbr:
+;
+; Ensure that the transmitter has finished sending buffered chars
+sndbr1: in mnprts ; get UART status
+ ani output ; everything sent?
+ jz sndbr1 ; no, wait a bit more
+;
+; Begin sending a break by setting bit in UART command register
+ mvi a,brkval ; SBreak,
+ out lctrl
+;
+; Wait for 250 milliseconds (using hundredths second delay routine)
+ mvi a,25
+ call delay
+;
+; Resume normal operation by clearing the SendBreak command bit
+ lda pstore ;and restoring value from parity store
+ out mnprts
+;
+ ret ;done
+
+;
+;
+
+;
+; sysflt - system-dependent filter
+; called with character in E.
+; if this character should not be printed, return with A = zero.
+; preserves bc, de, hl.
+; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
+sysflt:
+ mov a,e ; get character for testing
+ ret
+
+; mdmflt - modem filter [30]
+; called with character to be sent to modem in E
+; with parity set as appropriate.
+; return with accumulator = 0 do do nothing,
+; <> 0 to send char in E.
+mdmflt: mov a,e ; get character to a
+ ret
+
+
+
+; prtflt - printer filter [30]
+; called with character to be sent to printer in E
+; returns with a = 0 to do nothing
+; a <> 0 to print it.
+;
+; this routine for those printer that automatically insert
+; a lf on cr, or cr for lf. Should this be shifted to
+; the system indep. stuff, in say 4.06?
+prtflt:
+ mov a,e ; [30] get character to test
+ ret
+
+
+;
+
+
+;
+; system-dependent processing for BYE command.
+; for apmmdm, heath, and lobo, hang up the phone.
+sysbye:
+ ret
+;
+
+
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; this
+; value is also stored in 'speed'.
+sysspd:
+
+ ;Set up baud rate 8bit words, no parity 1stop bit
+ mvi a,83H ;enable DLAB by setting bit 7
+ out lctrl ;and outputting to control port
+ mov a,d ;get LSB
+ out divlsb ;and put it out
+ mov a,e ;get MSB
+ out divmsb ;output it as well
+ lda pstore ;get parity etc
+ out lctrl ;do it resetting DLAB at same time
+ ret
+
+pstore: db 03H ;Default value for parity word length and stop bits
+
+spdtbl: db 11h ;17 entries
+ db 03h,'110$', 06H,0D1H
+ db 04h,'1200$', 00H,0A0H
+ db 05h,'134.5$', 05H,94H
+ db 03h,'150$', 05H,00H
+ db 04h,'1800$', 00H,6BH
+ db 05h,'19200$', 00H,0AH
+ db 04h,'2000$', 00H,60H
+ db 04h,'2400$', 00H,50H
+ db 03h,'300$', 02H,80H
+ db 04h,'3600$', 00H,35H
+ db 05h,'38400$', 00H,05H
+ db 04h,'4800$', 00H,28H
+ db 02h,'50$', 0FH,00H
+ db 03h,'600$', 01H,40H
+ db 04h,'7200$', 00H,1BH
+ db 02h,'75$', 0AH,00H
+ db 04h,'9600$', 00H,14H
+
+sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
+ db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200 38400$'
+
+; This is the system-dependent SET PORT command.
+; HL contains the argument from the command table.
+sysprt:
+
+ ret
+;
+prttbl equ 0 ; SET PORT not supported
+prhtbl equ 0
+
+;
+
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; For iobyt systems, diddle the I/O byte to select console or comm port;
+; For Decision I, switches Multi I/O board to console or modem serial
+; port. [Toad Hall]
+; For the rest, does nothing.
+; preserves bc, de, hl.
+selmdm:
+ ret
+
+selcon:
+ ret
+;
+
+
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+ mvi c,dconio ;Direct console I/O BDOS call.
+ mvi e,0FFH ;Input.
+ call BDOS
+
+ ret
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+
+ mvi c,dconio ;Console output bdos call.
+ call bdos ;Output the char to the console.
+
+ ret
+;
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+outmdm:
+
+ in mnprts ;Get the output done flag.
+ ani output ;Is it set?
+ jz outmdm ;If not, loop until it is.
+ mov a,e
+ out mnport ;Output it.
+ ret
+
+;--------------------------------------------------------------------------
+;
+; get character from modem; return zero if none available.
+; for IOBYT systems, the modem port has already been selected.
+; destroys bc, de, hl.
+inpmdm:
+;Note: modem port should already be selected for mdI. [Toad Hall]
+ in mnprts ;Get the port status into A.
+ ani input ;See if the input ready bit is on.
+ rz ;If not then return.
+ in mnport ;If so, get the char.
+ ret ; return with character in A
+
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+
+flsmdm: call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+;-----------------------------------------------------------------------------
+;
+; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
+lptstat:
+ xra a ; assume it is ok.. this may not be necessary
+ ret
+
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+outlpt:
+ push d ; save DE in either case
+ call prtflt ; go through printer filter [30]
+ ana a ; if A = 0 do nothing,
+ jz outlp1 ; [30] if a=0 do nothing
+
+ mvi c,lstout
+ call bdos ;Char to printer
+outlp1: pop d ; restore saved register pair
+ ret
+;------------------------------------------------------------------------------
+;
+; Screen manipulation routines
+; csrpos - move to row B, column C
+;
+; csrpos for terminals that use a leadin sequence followed
+; by (row + 31.) and (column + 31.)
+;
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; restore coordinates
+ mov a,h ; get row
+ adi (' '-1) ; space is row one
+ mov e,a
+ push h
+ call outcon ; output row
+ pop h
+ mov a,l ; get column
+ adi (' '-1) ; space is column one
+ mov e,a
+ jmp outcon ; output it and return
+
+;
+; delchr - make delete look like a backspace. Unless delete is a printing
+; character, we just need to print a backspace. (we'll output clrspc
+; afterwards)
+; For Kaypro and Vector General, delete puts a blotch on the screen.
+; For Apple and Osborne 1, delete moves but doesn't print.
+delchr:
+
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the character at the current cursor position
+clrspc: mvi e,' '
+ call outcon
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the current line
+clrlin: lxi d,eralin
+ jmp prtstr
+
+; erase the whole screen, and go home. preserves b (but not c)
+clrtop: lxi d,erascr
+ jmp prtstr
+
+;[2] I see no real saving in having all screens in separate file and
+;therefore have included screen definition here and commented out
+;the link to VDU file
+;
+;Specific definitions for the Genie III screen
+;
+sysver: db 'Eaca Genie III$'
+outlin: db 1aH,cr,lf,' $'
+erascr: db 1AH,'$'
+eralin: db cr,18H,'$'
+curldn: db esc,'=$'
+ttab:
+ta: db 0BH,'$',0,0 ;Cursor up
+tb: db 0AH,'$',0,0 ;Cursor down
+tc: db 0CH,'$',0,0 ;Cursor right
+td: db 08H,'$',0,0 ;Cursor left
+te: db 1AH,'$',0,0 ;Clear display
+tf: db esc,'R$',0 ;Reverse on
+tg: db esc,'S$',0 ;Reverse off
+th: db 1EH,'$',0,0 ;Cursor home
+ti: db 0BH,'$',0,0 ;Reverse linefeed
+tj: db 19H,'$',0,0 ;Clear to end of screen
+tk: db 18H,'$',0,0 ;Clear to end of line
+
+ovlend equ $ ;End of overlay
+
+END
+
+
+
+
+
diff --git a/cpxhea.asm b/cpxhea.asm
index e78d9df..32e6b4e 100644
--- a/cpxhea.asm
+++ b/cpxhea.asm
@@ -1,921 +1,921 @@
-IF NOT lasm
-.printx * CPXHEA.ASM *
-ENDIF ;NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the system-dependent code and data for KERMIT
-; specific to the Heath/Zenith H89 and Z100, the Telcon Zorba,
-; and the OEM ScreenTyper. All but the latter use VT52 (or a
-; replica thereof) for screen output; the ScreenTyper uses the
-; same serial port chip as the H89 (an Intel 8250).
-;
-; revision history:
-;
-; Edit 4, 31-Aug-1989 by Mike Freeman, 301 N.E. 107th Street; Vancouver wa
-; 98685 USA; Telephone (206)574-8221: Added Baud-rate Selection and
-; Break-sending ability for the Telcon Zorba portable.
-;
-; edit 3, 22 July, 1987 by OBSchou to massage code to conform to new set
-; of overlay files (stripping out common code to CPXCOM.ASM)
-;
-; edit 2 by OBSchou to add in old Kermit-80 V3.5 heath-8 code, formerly
-; in CPM directory. Entry from CP/M file:
-;
-; This file contains an upgrade to the CPMBASE.M80 KERMIT
-; to allow setting and display of baud rates, a bug fix in
-; telnet, and an extension of the HELP to show GET (which works
-; in this release, on the H8). Look for the new symbol "h8quad"
-; (for the heath quad i/o board that it uses) in the conditionals.
-; Note that the Heath H8 is NOT the same machine as the H89. The H89
-; code does not run 'as is' on the H8, and does NOT initialize the
-; UART. Also there was a bug in the telnet section that is fixed
-; here, though I expect that it has already been found and fixed
-; by now - this is from the DECUS FALL 83 tape. The comments were
-; stripped out of this file to make it small enough for my H8 to
-; assemble, however, I have put the first section back in to make
-; it easier for you to identify. Thanks for a nice product to use
-; and work on. Major insertions are heavily commented, edit as needed.
-;
-; This modification done by John Mealing, InteCom Inc, 601 Intecom Dr.,
-; Allen, TX 75002 (214)797-9141, x-2493, 5 Nov 84.
-;
-; [OBSchou notes: This is the header, and the bugs in telnet are
-; unknown. telnet routine has been substantially changed anyway with
-; 4.08-4.09 revision. As for the major insertions: they probably went
-; with the 4.xx re-write. I am unable to test this version: can
-; anyone else do so??]
-;
-;
-; edit 01 5th Mar 1987 by M J Carter, Nottingham Uni [majoc]
-; Split off from CPXSYS.ASM, in order to install support for
-; the OEM ScreenTyper. I can't test anything other than the
-; ScreenTyper as I haven't the hardware. Any offers?
-; Thanks are due to Paul Bartlett of John Elmer
-; Electronics Ltd, who provided me with his modified sources
-; for (a slightly antiquated) CP/M 4.05 Kermit on which this
-; is based.
-;
-; Keep module name, edit number, and last revision date in memory.
-;sysedt: db 'CPXSYS.ASM (35) 01-Dec-86 $'
-; [majoc 870305] Now in CPXFRK. I'll have to consult on this ...
-;
-;
-;
-; Assembly time message to let me know I'm building the right version.
-; LASM generates an 'S' error along with the message, which is messy, but
-; better than trying to put everything inside a IF m80 OR mac80 conditional,
-; because LASM doesn't like nested IF's, either.
-
-IF heath
-.printx * Assembling KERMIT-80 for the Heath/Zenith 89 *
-ENDIF
-
-IF h8quad
-.printx * Assembling KERMIT-80 for the Heath-8 with Quad IO board *
-ENDIF
-
-IF z100
-.printx * Assembling KERMIT-80 for the Heath/Zenith Z100 *
-ENDIF
-
-IF telcon
-.printx * Assembling KERMIT-80 for the Telcon Zorba *
-ENDIF
-
-IF scntpr
-.printx * Assembling KERMIT-80 for the OEM ScreenTyper *
-ENDIF
-;
-
-;
-
-IF heath
-mnport EQU 330O ;Modem data port
-ENDIF ; heath
-
-IF h8quad
-mnport EQU 330O ;all port addresses can be set by user -
-mnprts EQU mnport + 05 ; in octal cause heath wrote documents that
-output EQU 20H ; way -- relative addressing on the UART
-input EQU 01H ; registers, just to be nice
-baudls EQU mnport ;ls baud divisor latch when DALB set
-baudms EQU mnport + 1 ;ms baud divisor latch when DALB set
-linctl EQU mnport + 3 ;line control register
-modctl EQU mnport + 4 ;MODEM control register
-dalbon EQU 80H ;enables speed selection
-linset EQU 03H ;force hardware 8 bit, even parity
-;
-; The line control register (linctl) is bit mapped as follows:
-; bit # function value
-; 0,1 select word size 00 -> 5 bit, 10 -> 7 bit
-; 01 -> 6 bit, 11 -> 8 bit
-; 2 select stop bits 0 -> 1 stop bit, 1 -> 1 1/2 for 5 bit,
-; 1 -> 2 for 6 bit words
-; 3 parity enable 0 -> no parity, 1 -> parity as set by 4
-; 4 Even parity select 0 -> Odd parity, 1 -> Even parity
-; 5 Stick parity 1 -> Parity of bit 4 is inverted
-; 6 Break control 1 -> output forced to spacing (break)
-; 7 DALB 1 -> access divisor latches to set baud rate
-;
-; The value in linset is loaded into linctl when KERMIT comes up.
-;
-ms300 EQU 001O ;set for 300 baud as default
-ls300 EQU 200O
-rtsoff EQU 20O ;direct control of modem lines
-rtson EQU 11O
-z80 EQU FALSE ;[2] or is it?
-ENDIF ;h8quad
-
-IF scntpr
-mnport EQU 8 ;Modem data port
-ENDIF ; scntpr
-IF heath OR scntpr
-
-; Definitions for the 8250 ACE
-
-acerbr EQU 0 ; ACE Receiver Buffer Register offset (R/O) (DLAB = 0)
-acethr EQU 0 ; ACE Transmitter Holding Register offset (W/O)
-acedll EQU 0 ; ACE Divisor Latch (Low) (DLAB = 1)
-acedlh EQU 1 ; ACE Divisor Latch (High) (DLAB = 1)
-aceier EQU 1 ; ACE Interrupt Enable Register (DLAB = 0)
-aceiir EQU 2 ; ACE Interrupt Identification Register
-acelcr EQU 3 ; ACE Line Control Register
-acemcr EQU 4 ; ACE Modem Control Register
-acelsr EQU 5 ; ACE Line Status Register offset
-acemsr EQU 6 ; ACE Modem Status Register
-
-ace8bw EQU 00000011b ; 8 bit words
-acesb EQU 01000000b ; set break
-acedla EQU 10000000b ; divisor latch access
-acedtr EQU 00000001b ; data terminal ready
-aceloo EQU 00010000b ; loopback mode
-acedr EQU 00000001b ; data ready
-acethe EQU 00100000b ; transmitter holding register empty
-
-;mnport EQU 330O ;Modem data port
-; [35a: majoc 870305] Shifted up above joint IF, to save nesting.
-mnprts EQU mnport+acelsr ;Modem status port
-output EQU acethe ;Transmitter empty
-input EQU acedr ;Input data available
-z80 EQU TRUE ;H89 uses the Z80
-ENDIF;heath OR scntpr
-
-IF z100
-mnport EQU 0ECH ;Modem data port
-mnprts EQU 0EDH ;Modem status port
-output EQU 01H ;Transmitter empty
-input EQU 02H ;Input data available
-z80 EQU FALSE ;[hh] this one's an 8085.
-ENDIF;z100
-
-
-IF telcon
-MNPORT EQU 20H ;Modem data port
-MNPRTS EQU 21H ;Modem status port
-OUTPUT EQU 01H ;Transmitter empty
-INPUT EQU 02H ;Input data available
-BRPORT EQU 00H ;8254-2 Baud Rate Generator Timer for Port A
-COMMND EQU 03H ;8254-2 Timer Control Port
-z80 EQU TRUE ;[MF]A real Z80
-ENDIF;telcon
-;
-
-IF telcon
-defesc EQU ']'-100O ;The default escape character.
-ENDIF;telcon
-
-IF heath OR h8quad OR z100 OR scntpr
-defesc EQU '\'-100O ;The default is Control \ -- it's easier B.E.
-ENDIF;heath OR h8quad OR z100 OR scntpr
-
-; Select initial setting for VT-52 emulation flag.
-IF (heath OR h8quad OR z100 OR telcon)
-vtval EQU 0 ; we don't need VT52 emulation
-ENDIF;heath OR h8quad OR z100 OR telcon OR vt52 [OBS question - ok for h8quad?]
-; If none of the above, default to VT52-EMULATION ON.
-IF scntpr
-vtval EQU 1 ; we do VT52 emulation
-ENDIF;scntpr
-
-
-;
-; Family is the string used in VERSION to say which of several
-; smaller overlay files are used. These are (will be) derived from
-; the juge CPXSYS.ASM file, in which case we will never get here.
-; Just a Dollar, but put a sting in for a family of machines.
-;
-family: db 'CPXHEA.ASM (4) 31-Aug-1989$' ; Used for family versions....
-
-;
-sysxin: ; continuation of initialisation code
-IF heath OR scntpr
-;
-; System dependent startup for H89 and OEM ScreenTyper
-;
-
- call mdmofl ; keep the line safe from garbage
-
-; First, tell Kermit the modem port's current speed
- in mnport+acelcr
- ori acedla
- out mnport+acelcr ; access the ACE's divisor latch
- in mnport+acedll ; get the low byte
- sta speed
- in mnport+acedlh ; and the high byte
- sta speed+1
-
-; Now set up the port for Kermit
- mvi a,ace8bw ; 8 data bits, 1 stop bit, no parity
- out mnport+acelcr
- in mnport+acemcr
- ori acedtr ; raise DTR (just in case)
- out mnport+acemcr
- call mdmonl ; and put the ACE back on line
- ret
-
-; Take the ACE off line before modifying its state
-mdmofl:
- in mnport+aceier ; save the ACE's interrupt state
- sta iersav
- xra a
- out mnport+aceier ; and disable ACE interrupts
- in mnport+acemcr ; now put the ACE in loopback mode
- ori aceloo
- out mnport+acemcr
- ret
-
-; Put the ACE back on line
-mdmonl:
- in mnport ; flush left-over garbage in the receive buffer
- mvi a,7 ; wait about 2 300-baud character times
- call delay
- in mnport ; and flush more garbage
- in mnport+acemcr ; take the ACE out of loopback mode
- ani 0FFH-aceloo
- out mnport+acemcr
- lda iersav
- out mnport+aceier ; and restore the ACE's interrupt state
- ret
-
-iersav: ds 1
-ENDIF;heath OR scntpr
-
-IF h8quad
-h8init: lxi d,180h ; [2] set up for 300 baud
-h8baud: mvi a,rtsoff ;disable modem for now
- out modctl
- mvi a,dalbon ;set for UART speed programming
- out linctl
- mov a,d ; [2] get ms bits for rate
- out baudms
- mov a,e ; [2] get ls bits for rate
- out baudls
- mvi a,linset ;force 8 bit, no parity and clear dalb
- out linctl
- in mnport ;clear the recieve side
- mvi a,rtson ;get ready
- out modctl ;modem is on and ready to go
-ENDIF ;h8quad
-
- ret ; return from system-dependent routine
-
-;
-;
-; system-dependent termination processing
-; If we've changed anything, this is our last chance to put it back.
-sysexit:
- ret
-
-;
-; system-dependent processing for start of CONNECT command
-;
-syscon:
- ret
-
-conmsg: ; Messages printed when entering transparent (CONNECT) mode:
-;
-;
-; syscls - system-dependent close routine
-; called when exiting transparent session.
-;
-syscls:
- ret
-;
-;
-; sysinh - help for system-dependent special functions.
-; called in response to <escape>?, after listing all the
-; system-independent escape sequences.
-;
-sysinh:
-IF heath OR scntpr OR telcon;[4]
- lxi d,inhlps ; we got options...
- call prtstr ; print them.
-ENDIF;heath OR scntpr OR telcon
-
- ret
-
-
-;additional, system-dependent help for transparent mode
-; (two-character escape sequences)
-inhlps:
-IF heath OR scntpr OR telcon;[4]
- db cr,lf,'B Transmit a BREAK'
-ENDIF;heath OR scntpr OR telcon
-
-IF heath OR scntpr
- db cr,lf,'D Drop the line'
-ENDIF;heath OR scntpr
-
- db '$' ;[hh] table terminator
-
-;
-; sysint - system dependent special functions
-; called when transparent escape character has been typed;
-; the second character of the sequence is in A (and in B).
-; returns:
-; non-skip: sequence has been processed
-; skip: sequence was not recognized
-sysint: ani 137O ; convert lower case to upper, for testing...
-
-IF heath OR scntpr
- cpi 'D' ; drop line?
- jnz intc00 ; no: try next function character
-
-mdmdrp: in mnport+acemcr ; (we also get here from sysbye)
- ani 0FFH-acedtr
- out mnport+acemcr ; yes: drop DTR
- mvi a,50 ; for half a second
- call delay
- in mnport+acemcr
- ori acedtr
- out mnport+acemcr ; and then restore it
- ret
-intc00:
-ENDIF;heath OR scntpr
-
-IF heath OR scntpr OR telcon;[4]
- cpi 'B' ; send break?
- jz sendbr ; yes, go do it. return nonskip when through.
-ENDIF;heath OR scntpr OR telcon
- jmp rskp ; take skip return - command not recognized.
-
-
-;
-IF heath OR scntpr
-;
-; Send BREAK on H89 or ScreenTyper
-;
-sendbr: in mnport+acelcr
- ori acesb
- out mnport+acelcr ; set ACE break condition
- mvi a,30
- call delay ; wait 300 milliseconds
- in mnport+acelcr
- ani 0FFH-acesb
- out mnport+acelcr ; and clear ACE break condition
- ret
-
-ENDIF;heath OR scntpr
-;
-IF telcon ;[4]
-;
-; Send break on Telcon Zorba
-;
-sendbr: mvi a,3fH ;DTR normal, break on
- out mnprts ;Set break on
- mvi a,30 ;Wait 300 ms
- call delay ;...
- mvi a,37h ;DTR normal, tx, rx enabled
- out mnprts ;Restore normal condition
- ret ;and return
-;
-ENDIF ;telcon
-
-;
-;
-; sysflt - system-dependent filter
-; called with character in E.
-; if this character should not be printed, return with A = zero.
-; preserves bc, de, hl.
-; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-sysflt:
- mov a,e ; get character for testing
- ret
-
-; mdmflt - modem filter [30]
-; called with character to be sent to printer in E
-; with parity set as appropriate.
-; return with accumulator = 0 do do nothing,
-; <> 0 to send char in E.
-mdmflt:
- mov a,e ;[30] get character to test
- ret
-
-
-
-; prtflt - printer filter [30]
-; called with character to be sent to printer in E
-; returns with a = 0 to do nothing
-; a <> 0 to print it.
-;
-; this routine for those printer that automatically insert
-; a lf on cr, or cr for lf. Should this be shifted to
-; the system indep. stuff, in say 4.06?
-prtflt:
- mov a,e ; [30] get character to test
- ret
-
-
-;
-;
-; system-dependent processing for BYE command.
-; for apmmdm, heath, scntpr, and lobo, hang up the phone.
-sysbye:
-IF heath OR scntpr
- call mdmdrp ; Sleazy but effective
-ENDIF;heath OR scntpr
-
- ret
-;
-; This is the system-dependent command to change the baud rate.
-; DE contains the two-byte value from the baud rate table; this
-; value is also stored in 'speed'.
-sysspd:
-
-IF heath OR scntpr
-;
-; Set speed for H89
-;
- call mdmofl ; keep the line safe from garbage
- in mnport+acelcr
- ori acedla
- out mnport+acelcr ; access the ACE's divisor latch
- mov a,e ; low byte of speed is in E
- out mnport+acedll ; set the low byte
- mov a,d ; high byte of speed is in D
- out mnport+acedlh ; set the high byte
- in mnport+acelcr
- ani 0FFH-acedla
- out mnport+acelcr ; de-access the ACE's divisor latch
- call mdmonl ; and put the ACE back on line
-ENDIF;heath OR scntpr
-
-IF h8quad ;[2][obs] A bit of guesswork this. Enter with date in de
- call h8baud ; [2] routine is in initialisation bit
-ENDIF ; h8quad[2]
-;
-IF telcon ;[4]
- MVI A,36H ;Set square wave
- OUT COMMND ;...
- MOV A,E ;Get LSB of Baud rate
- OUT BRPORT ;Send to generator
- MOV A,D ;Get msb of baud rate
- OUT BRPORT ;Send to Baud rate generator
-ENDIF ;telcon
-;
- ret
-
-;
-;
-; Speed tables
-; (Note that speed tables MUST be in alphabetical order for later
-; lookup procedures, and must begin with a value showing the total
-; number of entries. The speed help tables are just for us poor
-; humans.
-;
-; db string length,string,divisor (2 identical bytes or 1 word)
-; [Toad Hall]
-
-IF heath
-;
-; Speed selection table for H89 (OK, so I got a little carried away...)
-;
-
-spdtbl: db 19 ; 19 entries
- db 3,'110$'
- dw 1047
- db 4,'1200$'
- dw 96
- db 5,'134.5$'
- dw 857
- db 4,'1800$'
- dw 64
- db 5,'19200$'
- dw 6
- db 3,'200$'
- dw 576
- db 4,'2400$'
- dw 48
- db 3,'300$'
- dw 384
- db 4,'3600$'
- dw 32
- db 5,'38400$'
- dw 3
- db 3,'450$'
- dw 256
- db 4,'4800$'
- dw 24
- db 2,'50$'
- dw 2304
- db 5,'56000$'
- dw 2
- db 3,'600$'
- dw 192
- db 4,'7200$'
- dw 16
- db 2,'75$'
- dw 1536
- db 3,'900$'
- dw 128
- db 4,'9600$'
- dw 12
-
-sphtbl: db cr,lf
- db ' 50 75 110 134.5 200 300 450 600 900 1200'
- db cr,lf,' 1800 2400 3600 4800 7200 9600 19200 38400 56000$'
-ENDIF;heath
-
-IF h8quad
-spdtbl: db 6 ;[2] 6 entries
- db 3,'300$', 1,80h ; divisor for 300 baud
- db 3,'600$', 0,0c0h
- db 4,'1200$', 0,60h
- db 4,'2400$', 0,30h
- db 4,'4800$', 0,18h
- db 4,'9600$', 0,0ch
-;
-; The strings to display the speed selected from the table above
-;
-sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$'
-ENDIF ;h8quad
-
-IF scntpr
-; [35a: majoc 870305]
-;
-; Speed selection table for ScreenTyper
-;
-
-spdtbl: db 14 ; 14 entries
- db 3,'110$'
- dw 470H
- db 4,'1200$'
- dw 68H
- db 5,'134.5$'
- dw 3a1H
- db 4,'1800$'
- dw 45H
- db 5,'19200$' ; This was in PB's table, but not in the
- dw 7H ; accompanying text string. Oversight?
-; db 3,'200$'
-; dw 576
- db 4,'2400$'
- dw 34H
- db 3,'300$'
- dw 1a1H
- db 4,'3600$'
- dw 23H
-; db 5,'38400$'
-; dw 3
-; db 3,'450$'
-; dw 256
- db 4,'4800$'
- dw 1aH
- db 2,'50$'
- dw 964H
-; db 5,'56000$'
-; dw 2
- db 3,'600$'
- dw 0d0H
- db 4,'7200$'
- dw 11H
- db 2,'75$'
- dw 683H
-; db 3,'900$'
-; dw 128
- db 4,'9600$'
- dw 0dH
-
-sphtbl: db cr,lf,' 50 75 110 134.5 300 600 1200'
- db cr,lf,' 1800 2400 3600 4800 7200 9600 (19200?)$'
-ENDIF;scntpr
-;
-IF telcon ;[4]
-;
-; Speed selection tables for the Telcon Zorba (I overdid it, also)
-;
-; **NOTE** that when Kermit is first executed, the baud rate is
-; unknown to Kermit, having been set by CP/M upon cold-boot, SETUP.COM,
-; another communications program, etc. The easiest way to insure that
-; the baud rate is known upon Kermit start-up is to set it
-; in KERMIT.INI.
-;
-spdtbl: db 20 ;[4]Number of entries (some of these
- ;speeds are *weird* but the Zorba
- ;supports them so I'll put them in
- db 3,'110$'
- dw 4545
- db 4,'1200$'
- dw 417
- db 5,'134.5$'
- dw 3717
- db 3,'150$'
- dw 3333
- db 4,'1760$'
- dw 284
- db 4,'1800$'
- dw 278
- db 5,'19200$'
- dw 26
- db 3,'200$'
- dw 2500
- db 4,'2000$'
- dw 250
- db 4,'2400$'
- dw 208
- db 3,'300$'
- dw 1667
- db 4,'3520$'
- dw 142
- db 4,'3600$'
- dw 139
- db 4,'4800$'
- dw 104
- db 2,'50$'
- dw 10000
- db 3,'600$'
- dw 833
- db 4,'62.5$'
- dw 8000
- db 4,'7200$'
- dw 69
- db 2,'75$'
- dw 6667
- db 4,'9600$'
- dw 52
-;
-; Help table
-;
-sphtbl: db cr,lf
- db ' 50 62.5 75 110 134.5 150 200 300 600 1200'
- db cr,lf,' 1760 1800 2000 2400 3520 3600 4800 7200'
- db cr,lf,' 9600 19200$'
-;
-ENDIF ;Telcon
-
-; The following conditionals were once a huge if not statement. There
-; wasn't enough room to add the lobo to the list, so it had to be broken
-; into 2, which you can't do with an if not. I redid it as two ifs and
-; applied them to those that wouldn't set baud. [Hal Hostetler]
-IF z100
-spdtbl equ 0 ; SET BAUD not supported.
-sphtbl equ 0
-ENDIF;z100
-;
-;
-; This is the system-dependent SET PORT command.
-; HL contains the argument from the command table.
-sysprt:
- ret
-;
-prttbl equ 0 ; SET PORT is not supported
-prhtbl equ 0
-;
-;
-;
-; selmdm - select modem port
-; selcon - select console port
-; selmdm is called before using inpmdm or outmdm;
-; selcon is called before using inpcon or outcon.
-; For iobyt systems, diddle the I/O byte to select console or comm port;
-; For Decision I, switches Multi I/O board to console or modem serial
-; port. [Toad Hall]
-; For the rest, does nothing.
-; preserves bc, de, hl.
-selmdm:
- ret
-
-selcon:
- ret
-
-; Get character from console, or return zero.
-; result is returned in A. destroys bc, de, hl.
-;
-inpcon:
-IF NOT iobyt
- mvi c,dconio ;Direct console I/O BDOS call.
- mvi e,0FFH ;Input.
- call BDOS
-ENDIF;NOT iobyt
-
- ret
-;
-;
-; Output character in E to the console.
-; destroys bc, de, hl
-;
-outcon:
-IF NOT iobyt
- mvi c,dconio ;Console output bdos call.
- call bdos ;Output the char to the console.
-ENDIF;NOT iobyt
- ret
-;
-;
-; outmdm - output a char from E to the modem.
-; the parity bit has been set as necessary.
-; returns nonskip; bc, de, hl preserved.
-outmdm:
-IF inout
- in mnprts ;Get the output done flag.
- ani output ;Is it set?
- jz outmdm ;If not, loop until it is.
- mov a,e
- out mnport ;Output it.
- ret
-ENDIF;inout
-
-IF iobyt
-;**** Note that we enter from outpkt with the I/O byte already set up for
-; output to go to the comm port
- push h
- push b
- lda prtfun ;Get the output function
- mov c,a ;Into C
- call bdos ;And output the character
- pop b
- pop h
- ret
-ENDIF;iobyt
-
-;
-;
-; get character from modem; return zero if none available.
-; for IOBYT systems, the modem port has already been selected.
-; destroys bc, de, hl.
-inpmdm:
-IF NOT iobyt ;[2] this routine not in submitted file, so I guess
- ; guess this is what it is supposed to do.
- in mnprts ; input status port
- ani input ; anything t read in?
- rz ; nope
- in mnport ; else read in the data
- ret ; return with character in A
-ENDIF ; NOT iobyte [2]
-
-;
-; flsmdm - flush comm line.
-; Modem is selected.
-; Currently, just gets characters until none are available.
-
-flsmdm: call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-;
-;
-; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not.
-lptstat:
- call bprtst ; assume it is ok.. this may not be necessary
- ret
-
-;
-; outlpt - output character in E to printer
-; console is selected.
-; preserves de.
-outlpt:
- push d ; save DE in either case
- call prtflt ; go through printer filter [30]
- ana a ; if A = 0 do nothing,
- jz outlp1 ; [30] if a=0 do nothing
-
-IF NOT iobyt
- mvi c,lstout
- call bdos ;Char to printer
-ENDIF;NOT iobyt
-outlp1: pop d ; restore saved register pair
- ret
-;
-;
-; Screen manipulation routines
-; csrpos - move to row B, column C
-;
-; csrpos for terminals that use a leadin sequence followed
-; by (row + 31.) and (column + 31.)
-;
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,h ; get row
- adi (' '-1) ; space is row one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,l ; get column
- adi (' '-1) ; space is column one
- mov e,a
- jmp outcon ; output it and return
-
-;
-; delchr - make delete look like a backspace. Unless delete is a printing
-; character, we just need to print a backspace. (we'll output clrspc
-; afterwards)
-; For Kaypro and Vector General, delete puts a blotch on the screen.
-; For Apple and Osborne 1, delete moves but doesn't print.
-delchr:
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the character at the current cursor position
-clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the current line
-clrlin: lxi d,eralin
- jmp prtstr
-
-; erase the whole screen, and go home. preserves b (but not c)
-clrtop: lxi d,erascr
- jmp prtstr
-
-IF telcon
-sysver: db 'Telcon Zorba$'
-ENDIF;telcon
-
-IF heath
-sysver: db 'Heath/Zenith 89$'
-ENDIF;heath
-
-IF h8quad
-sysver: db 'Heath H8 with quad I/O card$'
-ENDIF
-
-IF z100
-sysver: db 'Heath/Zenith Z-100 CP/M$'
-ENDIF;z100
-
-IF scntpr
-; [35a: majoc 870305]
-sysver: db 'OEM ScreenTyper: 4MHz Z80 running OS/M$'
-ENDIF;scntpr
-
-IF heath OR h8quad OR z100 OR telcon
-outlin: db esc,'H',esc,'J',cr,lf,tab,tab,'$'
-erascr: db esc,'H',esc,'J$' ;Clear screen and go home.
-eralin: db cr,esc,'K$' ;Clear line.
-curldn: db esc,'Y$' ;cursor leadin
-ttab: ;Table start location.
-ta: db esc,'A$',0 ;Cursor up.
-tb: db esc,'B$',0 ;Cursor down.
-tc: db esc,'C$',0 ;Cursor right.
-td: db esc,'D$',0 ;Cursor left
-te: db esc,'E$',0 ;Clear display
-tf: db esc,'F$',0 ;Enter Graphics Mode
-tg: db esc,'G$',0 ;Exit Graphics mode
-th: db esc,'H$',0 ;Cursor home.
-ti: db esc,'I$',0 ;Reverse linefeed.
-tj: db esc,'J$',0 ;Clear to end of screen.
-tk: db esc,'K$',0 ;Clear to end of line.
-ENDIF;heath OR h8quad OR z100 OR telcon
-;
-
-IF scntpr ; [35a: majoc 870305]
-outlin: db 1aH, cr, lf, '$'
-erascr: db 1aH, '$' ;Clear screen and go home.
-eralin: db cr,esc,'*$' ;Clear line.
-curldn: db esc,'=$' ;cursor leadin
-ttab: ;Table start location.
-ta: db 1eH,'$',0,0 ;Cursor up.
-tb: db 1fH,'$',0,0 ;Cursor down.
-tc: db 1cH,'$',0,0 ;Cursor right.
-td: db 1dH,'$',0,0 ;Cursor left
-te: db 1aH,'$',0,0 ;Clear display
-tf: db 0,0,0,0 ;(Can't)Enter Graphics Mode
-tg: db 0,0,0,0 ;(Can't)Exit Graphics mode
-th: db 15H,'$',0,0 ;Cursor home.
-ti: db 1eH,'$',0,0 ;Reverse linefeed.
-tj: db esc,'%$',0 ;Clear to end of screen.
-tk: db esc,'*$',0 ;Clear to end of line.
-ENDIF;scntpr
-
-ovlend EQU $ ; End of overlay
- END ; Phew ... [majoc 870305]
+IF NOT lasm
+.printx * CPXHEA.ASM *
+ENDIF ;NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the system-dependent code and data for KERMIT
+; specific to the Heath/Zenith H89 and Z100, the Telcon Zorba,
+; and the OEM ScreenTyper. All but the latter use VT52 (or a
+; replica thereof) for screen output; the ScreenTyper uses the
+; same serial port chip as the H89 (an Intel 8250).
+;
+; revision history:
+;
+; Edit 4, 31-Aug-1989 by Mike Freeman, 301 N.E. 107th Street; Vancouver wa
+; 98685 USA; Telephone (206)574-8221: Added Baud-rate Selection and
+; Break-sending ability for the Telcon Zorba portable.
+;
+; edit 3, 22 July, 1987 by OBSchou to massage code to conform to new set
+; of overlay files (stripping out common code to CPXCOM.ASM)
+;
+; edit 2 by OBSchou to add in old Kermit-80 V3.5 heath-8 code, formerly
+; in CPM directory. Entry from CP/M file:
+;
+; This file contains an upgrade to the CPMBASE.M80 KERMIT
+; to allow setting and display of baud rates, a bug fix in
+; telnet, and an extension of the HELP to show GET (which works
+; in this release, on the H8). Look for the new symbol "h8quad"
+; (for the heath quad i/o board that it uses) in the conditionals.
+; Note that the Heath H8 is NOT the same machine as the H89. The H89
+; code does not run 'as is' on the H8, and does NOT initialize the
+; UART. Also there was a bug in the telnet section that is fixed
+; here, though I expect that it has already been found and fixed
+; by now - this is from the DECUS FALL 83 tape. The comments were
+; stripped out of this file to make it small enough for my H8 to
+; assemble, however, I have put the first section back in to make
+; it easier for you to identify. Thanks for a nice product to use
+; and work on. Major insertions are heavily commented, edit as needed.
+;
+; This modification done by John Mealing, InteCom Inc, 601 Intecom Dr.,
+; Allen, TX 75002 (214)797-9141, x-2493, 5 Nov 84.
+;
+; [OBSchou notes: This is the header, and the bugs in telnet are
+; unknown. telnet routine has been substantially changed anyway with
+; 4.08-4.09 revision. As for the major insertions: they probably went
+; with the 4.xx re-write. I am unable to test this version: can
+; anyone else do so??]
+;
+;
+; edit 01 5th Mar 1987 by M J Carter, Nottingham Uni [majoc]
+; Split off from CPXSYS.ASM, in order to install support for
+; the OEM ScreenTyper. I can't test anything other than the
+; ScreenTyper as I haven't the hardware. Any offers?
+; Thanks are due to Paul Bartlett of John Elmer
+; Electronics Ltd, who provided me with his modified sources
+; for (a slightly antiquated) CP/M 4.05 Kermit on which this
+; is based.
+;
+; Keep module name, edit number, and last revision date in memory.
+;sysedt: db 'CPXSYS.ASM (35) 01-Dec-86 $'
+; [majoc 870305] Now in CPXFRK. I'll have to consult on this ...
+;
+;
+;
+; Assembly time message to let me know I'm building the right version.
+; LASM generates an 'S' error along with the message, which is messy, but
+; better than trying to put everything inside a IF m80 OR mac80 conditional,
+; because LASM doesn't like nested IF's, either.
+
+IF heath
+.printx * Assembling KERMIT-80 for the Heath/Zenith 89 *
+ENDIF
+
+IF h8quad
+.printx * Assembling KERMIT-80 for the Heath-8 with Quad IO board *
+ENDIF
+
+IF z100
+.printx * Assembling KERMIT-80 for the Heath/Zenith Z100 *
+ENDIF
+
+IF telcon
+.printx * Assembling KERMIT-80 for the Telcon Zorba *
+ENDIF
+
+IF scntpr
+.printx * Assembling KERMIT-80 for the OEM ScreenTyper *
+ENDIF
+;
+
+;
+
+IF heath
+mnport EQU 330O ;Modem data port
+ENDIF ; heath
+
+IF h8quad
+mnport EQU 330O ;all port addresses can be set by user -
+mnprts EQU mnport + 05 ; in octal cause heath wrote documents that
+output EQU 20H ; way -- relative addressing on the UART
+input EQU 01H ; registers, just to be nice
+baudls EQU mnport ;ls baud divisor latch when DALB set
+baudms EQU mnport + 1 ;ms baud divisor latch when DALB set
+linctl EQU mnport + 3 ;line control register
+modctl EQU mnport + 4 ;MODEM control register
+dalbon EQU 80H ;enables speed selection
+linset EQU 03H ;force hardware 8 bit, even parity
+;
+; The line control register (linctl) is bit mapped as follows:
+; bit # function value
+; 0,1 select word size 00 -> 5 bit, 10 -> 7 bit
+; 01 -> 6 bit, 11 -> 8 bit
+; 2 select stop bits 0 -> 1 stop bit, 1 -> 1 1/2 for 5 bit,
+; 1 -> 2 for 6 bit words
+; 3 parity enable 0 -> no parity, 1 -> parity as set by 4
+; 4 Even parity select 0 -> Odd parity, 1 -> Even parity
+; 5 Stick parity 1 -> Parity of bit 4 is inverted
+; 6 Break control 1 -> output forced to spacing (break)
+; 7 DALB 1 -> access divisor latches to set baud rate
+;
+; The value in linset is loaded into linctl when KERMIT comes up.
+;
+ms300 EQU 001O ;set for 300 baud as default
+ls300 EQU 200O
+rtsoff EQU 20O ;direct control of modem lines
+rtson EQU 11O
+z80 EQU FALSE ;[2] or is it?
+ENDIF ;h8quad
+
+IF scntpr
+mnport EQU 8 ;Modem data port
+ENDIF ; scntpr
+IF heath OR scntpr
+
+; Definitions for the 8250 ACE
+
+acerbr EQU 0 ; ACE Receiver Buffer Register offset (R/O) (DLAB = 0)
+acethr EQU 0 ; ACE Transmitter Holding Register offset (W/O)
+acedll EQU 0 ; ACE Divisor Latch (Low) (DLAB = 1)
+acedlh EQU 1 ; ACE Divisor Latch (High) (DLAB = 1)
+aceier EQU 1 ; ACE Interrupt Enable Register (DLAB = 0)
+aceiir EQU 2 ; ACE Interrupt Identification Register
+acelcr EQU 3 ; ACE Line Control Register
+acemcr EQU 4 ; ACE Modem Control Register
+acelsr EQU 5 ; ACE Line Status Register offset
+acemsr EQU 6 ; ACE Modem Status Register
+
+ace8bw EQU 00000011b ; 8 bit words
+acesb EQU 01000000b ; set break
+acedla EQU 10000000b ; divisor latch access
+acedtr EQU 00000001b ; data terminal ready
+aceloo EQU 00010000b ; loopback mode
+acedr EQU 00000001b ; data ready
+acethe EQU 00100000b ; transmitter holding register empty
+
+;mnport EQU 330O ;Modem data port
+; [35a: majoc 870305] Shifted up above joint IF, to save nesting.
+mnprts EQU mnport+acelsr ;Modem status port
+output EQU acethe ;Transmitter empty
+input EQU acedr ;Input data available
+z80 EQU TRUE ;H89 uses the Z80
+ENDIF;heath OR scntpr
+
+IF z100
+mnport EQU 0ECH ;Modem data port
+mnprts EQU 0EDH ;Modem status port
+output EQU 01H ;Transmitter empty
+input EQU 02H ;Input data available
+z80 EQU FALSE ;[hh] this one's an 8085.
+ENDIF;z100
+
+
+IF telcon
+MNPORT EQU 20H ;Modem data port
+MNPRTS EQU 21H ;Modem status port
+OUTPUT EQU 01H ;Transmitter empty
+INPUT EQU 02H ;Input data available
+BRPORT EQU 00H ;8254-2 Baud Rate Generator Timer for Port A
+COMMND EQU 03H ;8254-2 Timer Control Port
+z80 EQU TRUE ;[MF]A real Z80
+ENDIF;telcon
+;
+
+IF telcon
+defesc EQU ']'-100O ;The default escape character.
+ENDIF;telcon
+
+IF heath OR h8quad OR z100 OR scntpr
+defesc EQU '\'-100O ;The default is Control \ -- it's easier B.E.
+ENDIF;heath OR h8quad OR z100 OR scntpr
+
+; Select initial setting for VT-52 emulation flag.
+IF (heath OR h8quad OR z100 OR telcon)
+vtval EQU 0 ; we don't need VT52 emulation
+ENDIF;heath OR h8quad OR z100 OR telcon OR vt52 [OBS question - ok for h8quad?]
+; If none of the above, default to VT52-EMULATION ON.
+IF scntpr
+vtval EQU 1 ; we do VT52 emulation
+ENDIF;scntpr
+
+
+;
+; Family is the string used in VERSION to say which of several
+; smaller overlay files are used. These are (will be) derived from
+; the juge CPXSYS.ASM file, in which case we will never get here.
+; Just a Dollar, but put a sting in for a family of machines.
+;
+family: db 'CPXHEA.ASM (4) 31-Aug-1989$' ; Used for family versions....
+
+;
+sysxin: ; continuation of initialisation code
+IF heath OR scntpr
+;
+; System dependent startup for H89 and OEM ScreenTyper
+;
+
+ call mdmofl ; keep the line safe from garbage
+
+; First, tell Kermit the modem port's current speed
+ in mnport+acelcr
+ ori acedla
+ out mnport+acelcr ; access the ACE's divisor latch
+ in mnport+acedll ; get the low byte
+ sta speed
+ in mnport+acedlh ; and the high byte
+ sta speed+1
+
+; Now set up the port for Kermit
+ mvi a,ace8bw ; 8 data bits, 1 stop bit, no parity
+ out mnport+acelcr
+ in mnport+acemcr
+ ori acedtr ; raise DTR (just in case)
+ out mnport+acemcr
+ call mdmonl ; and put the ACE back on line
+ ret
+
+; Take the ACE off line before modifying its state
+mdmofl:
+ in mnport+aceier ; save the ACE's interrupt state
+ sta iersav
+ xra a
+ out mnport+aceier ; and disable ACE interrupts
+ in mnport+acemcr ; now put the ACE in loopback mode
+ ori aceloo
+ out mnport+acemcr
+ ret
+
+; Put the ACE back on line
+mdmonl:
+ in mnport ; flush left-over garbage in the receive buffer
+ mvi a,7 ; wait about 2 300-baud character times
+ call delay
+ in mnport ; and flush more garbage
+ in mnport+acemcr ; take the ACE out of loopback mode
+ ani 0FFH-aceloo
+ out mnport+acemcr
+ lda iersav
+ out mnport+aceier ; and restore the ACE's interrupt state
+ ret
+
+iersav: ds 1
+ENDIF;heath OR scntpr
+
+IF h8quad
+h8init: lxi d,180h ; [2] set up for 300 baud
+h8baud: mvi a,rtsoff ;disable modem for now
+ out modctl
+ mvi a,dalbon ;set for UART speed programming
+ out linctl
+ mov a,d ; [2] get ms bits for rate
+ out baudms
+ mov a,e ; [2] get ls bits for rate
+ out baudls
+ mvi a,linset ;force 8 bit, no parity and clear dalb
+ out linctl
+ in mnport ;clear the recieve side
+ mvi a,rtson ;get ready
+ out modctl ;modem is on and ready to go
+ENDIF ;h8quad
+
+ ret ; return from system-dependent routine
+
+;
+;
+; system-dependent termination processing
+; If we've changed anything, this is our last chance to put it back.
+sysexit:
+ ret
+
+;
+; system-dependent processing for start of CONNECT command
+;
+syscon:
+ ret
+
+conmsg: ; Messages printed when entering transparent (CONNECT) mode:
+;
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+ ret
+;
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing all the
+; system-independent escape sequences.
+;
+sysinh:
+IF heath OR scntpr OR telcon;[4]
+ lxi d,inhlps ; we got options...
+ call prtstr ; print them.
+ENDIF;heath OR scntpr OR telcon
+
+ ret
+
+
+;additional, system-dependent help for transparent mode
+; (two-character escape sequences)
+inhlps:
+IF heath OR scntpr OR telcon;[4]
+ db cr,lf,'B Transmit a BREAK'
+ENDIF;heath OR scntpr OR telcon
+
+IF heath OR scntpr
+ db cr,lf,'D Drop the line'
+ENDIF;heath OR scntpr
+
+ db '$' ;[hh] table terminator
+
+;
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:
+; non-skip: sequence has been processed
+; skip: sequence was not recognized
+sysint: ani 137O ; convert lower case to upper, for testing...
+
+IF heath OR scntpr
+ cpi 'D' ; drop line?
+ jnz intc00 ; no: try next function character
+
+mdmdrp: in mnport+acemcr ; (we also get here from sysbye)
+ ani 0FFH-acedtr
+ out mnport+acemcr ; yes: drop DTR
+ mvi a,50 ; for half a second
+ call delay
+ in mnport+acemcr
+ ori acedtr
+ out mnport+acemcr ; and then restore it
+ ret
+intc00:
+ENDIF;heath OR scntpr
+
+IF heath OR scntpr OR telcon;[4]
+ cpi 'B' ; send break?
+ jz sendbr ; yes, go do it. return nonskip when through.
+ENDIF;heath OR scntpr OR telcon
+ jmp rskp ; take skip return - command not recognized.
+
+
+;
+IF heath OR scntpr
+;
+; Send BREAK on H89 or ScreenTyper
+;
+sendbr: in mnport+acelcr
+ ori acesb
+ out mnport+acelcr ; set ACE break condition
+ mvi a,30
+ call delay ; wait 300 milliseconds
+ in mnport+acelcr
+ ani 0FFH-acesb
+ out mnport+acelcr ; and clear ACE break condition
+ ret
+
+ENDIF;heath OR scntpr
+;
+IF telcon ;[4]
+;
+; Send break on Telcon Zorba
+;
+sendbr: mvi a,3fH ;DTR normal, break on
+ out mnprts ;Set break on
+ mvi a,30 ;Wait 300 ms
+ call delay ;...
+ mvi a,37h ;DTR normal, tx, rx enabled
+ out mnprts ;Restore normal condition
+ ret ;and return
+;
+ENDIF ;telcon
+
+;
+;
+; sysflt - system-dependent filter
+; called with character in E.
+; if this character should not be printed, return with A = zero.
+; preserves bc, de, hl.
+; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
+sysflt:
+ mov a,e ; get character for testing
+ ret
+
+; mdmflt - modem filter [30]
+; called with character to be sent to printer in E
+; with parity set as appropriate.
+; return with accumulator = 0 do do nothing,
+; <> 0 to send char in E.
+mdmflt:
+ mov a,e ;[30] get character to test
+ ret
+
+
+
+; prtflt - printer filter [30]
+; called with character to be sent to printer in E
+; returns with a = 0 to do nothing
+; a <> 0 to print it.
+;
+; this routine for those printer that automatically insert
+; a lf on cr, or cr for lf. Should this be shifted to
+; the system indep. stuff, in say 4.06?
+prtflt:
+ mov a,e ; [30] get character to test
+ ret
+
+
+;
+;
+; system-dependent processing for BYE command.
+; for apmmdm, heath, scntpr, and lobo, hang up the phone.
+sysbye:
+IF heath OR scntpr
+ call mdmdrp ; Sleazy but effective
+ENDIF;heath OR scntpr
+
+ ret
+;
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; this
+; value is also stored in 'speed'.
+sysspd:
+
+IF heath OR scntpr
+;
+; Set speed for H89
+;
+ call mdmofl ; keep the line safe from garbage
+ in mnport+acelcr
+ ori acedla
+ out mnport+acelcr ; access the ACE's divisor latch
+ mov a,e ; low byte of speed is in E
+ out mnport+acedll ; set the low byte
+ mov a,d ; high byte of speed is in D
+ out mnport+acedlh ; set the high byte
+ in mnport+acelcr
+ ani 0FFH-acedla
+ out mnport+acelcr ; de-access the ACE's divisor latch
+ call mdmonl ; and put the ACE back on line
+ENDIF;heath OR scntpr
+
+IF h8quad ;[2][obs] A bit of guesswork this. Enter with date in de
+ call h8baud ; [2] routine is in initialisation bit
+ENDIF ; h8quad[2]
+;
+IF telcon ;[4]
+ MVI A,36H ;Set square wave
+ OUT COMMND ;...
+ MOV A,E ;Get LSB of Baud rate
+ OUT BRPORT ;Send to generator
+ MOV A,D ;Get msb of baud rate
+ OUT BRPORT ;Send to Baud rate generator
+ENDIF ;telcon
+;
+ ret
+
+;
+;
+; Speed tables
+; (Note that speed tables MUST be in alphabetical order for later
+; lookup procedures, and must begin with a value showing the total
+; number of entries. The speed help tables are just for us poor
+; humans.
+;
+; db string length,string,divisor (2 identical bytes or 1 word)
+; [Toad Hall]
+
+IF heath
+;
+; Speed selection table for H89 (OK, so I got a little carried away...)
+;
+
+spdtbl: db 19 ; 19 entries
+ db 3,'110$'
+ dw 1047
+ db 4,'1200$'
+ dw 96
+ db 5,'134.5$'
+ dw 857
+ db 4,'1800$'
+ dw 64
+ db 5,'19200$'
+ dw 6
+ db 3,'200$'
+ dw 576
+ db 4,'2400$'
+ dw 48
+ db 3,'300$'
+ dw 384
+ db 4,'3600$'
+ dw 32
+ db 5,'38400$'
+ dw 3
+ db 3,'450$'
+ dw 256
+ db 4,'4800$'
+ dw 24
+ db 2,'50$'
+ dw 2304
+ db 5,'56000$'
+ dw 2
+ db 3,'600$'
+ dw 192
+ db 4,'7200$'
+ dw 16
+ db 2,'75$'
+ dw 1536
+ db 3,'900$'
+ dw 128
+ db 4,'9600$'
+ dw 12
+
+sphtbl: db cr,lf
+ db ' 50 75 110 134.5 200 300 450 600 900 1200'
+ db cr,lf,' 1800 2400 3600 4800 7200 9600 19200 38400 56000$'
+ENDIF;heath
+
+IF h8quad
+spdtbl: db 6 ;[2] 6 entries
+ db 3,'300$', 1,80h ; divisor for 300 baud
+ db 3,'600$', 0,0c0h
+ db 4,'1200$', 0,60h
+ db 4,'2400$', 0,30h
+ db 4,'4800$', 0,18h
+ db 4,'9600$', 0,0ch
+;
+; The strings to display the speed selected from the table above
+;
+sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$'
+ENDIF ;h8quad
+
+IF scntpr
+; [35a: majoc 870305]
+;
+; Speed selection table for ScreenTyper
+;
+
+spdtbl: db 14 ; 14 entries
+ db 3,'110$'
+ dw 470H
+ db 4,'1200$'
+ dw 68H
+ db 5,'134.5$'
+ dw 3a1H
+ db 4,'1800$'
+ dw 45H
+ db 5,'19200$' ; This was in PB's table, but not in the
+ dw 7H ; accompanying text string. Oversight?
+; db 3,'200$'
+; dw 576
+ db 4,'2400$'
+ dw 34H
+ db 3,'300$'
+ dw 1a1H
+ db 4,'3600$'
+ dw 23H
+; db 5,'38400$'
+; dw 3
+; db 3,'450$'
+; dw 256
+ db 4,'4800$'
+ dw 1aH
+ db 2,'50$'
+ dw 964H
+; db 5,'56000$'
+; dw 2
+ db 3,'600$'
+ dw 0d0H
+ db 4,'7200$'
+ dw 11H
+ db 2,'75$'
+ dw 683H
+; db 3,'900$'
+; dw 128
+ db 4,'9600$'
+ dw 0dH
+
+sphtbl: db cr,lf,' 50 75 110 134.5 300 600 1200'
+ db cr,lf,' 1800 2400 3600 4800 7200 9600 (19200?)$'
+ENDIF;scntpr
+;
+IF telcon ;[4]
+;
+; Speed selection tables for the Telcon Zorba (I overdid it, also)
+;
+; **NOTE** that when Kermit is first executed, the baud rate is
+; unknown to Kermit, having been set by CP/M upon cold-boot, SETUP.COM,
+; another communications program, etc. The easiest way to insure that
+; the baud rate is known upon Kermit start-up is to set it
+; in KERMIT.INI.
+;
+spdtbl: db 20 ;[4]Number of entries (some of these
+ ;speeds are *weird* but the Zorba
+ ;supports them so I'll put them in
+ db 3,'110$'
+ dw 4545
+ db 4,'1200$'
+ dw 417
+ db 5,'134.5$'
+ dw 3717
+ db 3,'150$'
+ dw 3333
+ db 4,'1760$'
+ dw 284
+ db 4,'1800$'
+ dw 278
+ db 5,'19200$'
+ dw 26
+ db 3,'200$'
+ dw 2500
+ db 4,'2000$'
+ dw 250
+ db 4,'2400$'
+ dw 208
+ db 3,'300$'
+ dw 1667
+ db 4,'3520$'
+ dw 142
+ db 4,'3600$'
+ dw 139
+ db 4,'4800$'
+ dw 104
+ db 2,'50$'
+ dw 10000
+ db 3,'600$'
+ dw 833
+ db 4,'62.5$'
+ dw 8000
+ db 4,'7200$'
+ dw 69
+ db 2,'75$'
+ dw 6667
+ db 4,'9600$'
+ dw 52
+;
+; Help table
+;
+sphtbl: db cr,lf
+ db ' 50 62.5 75 110 134.5 150 200 300 600 1200'
+ db cr,lf,' 1760 1800 2000 2400 3520 3600 4800 7200'
+ db cr,lf,' 9600 19200$'
+;
+ENDIF ;Telcon
+
+; The following conditionals were once a huge if not statement. There
+; wasn't enough room to add the lobo to the list, so it had to be broken
+; into 2, which you can't do with an if not. I redid it as two ifs and
+; applied them to those that wouldn't set baud. [Hal Hostetler]
+IF z100
+spdtbl equ 0 ; SET BAUD not supported.
+sphtbl equ 0
+ENDIF;z100
+;
+;
+; This is the system-dependent SET PORT command.
+; HL contains the argument from the command table.
+sysprt:
+ ret
+;
+prttbl equ 0 ; SET PORT is not supported
+prhtbl equ 0
+;
+;
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; For iobyt systems, diddle the I/O byte to select console or comm port;
+; For Decision I, switches Multi I/O board to console or modem serial
+; port. [Toad Hall]
+; For the rest, does nothing.
+; preserves bc, de, hl.
+selmdm:
+ ret
+
+selcon:
+ ret
+
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+IF NOT iobyt
+ mvi c,dconio ;Direct console I/O BDOS call.
+ mvi e,0FFH ;Input.
+ call BDOS
+ENDIF;NOT iobyt
+
+ ret
+;
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+IF NOT iobyt
+ mvi c,dconio ;Console output bdos call.
+ call bdos ;Output the char to the console.
+ENDIF;NOT iobyt
+ ret
+;
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+outmdm:
+IF inout
+ in mnprts ;Get the output done flag.
+ ani output ;Is it set?
+ jz outmdm ;If not, loop until it is.
+ mov a,e
+ out mnport ;Output it.
+ ret
+ENDIF;inout
+
+IF iobyt
+;**** Note that we enter from outpkt with the I/O byte already set up for
+; output to go to the comm port
+ push h
+ push b
+ lda prtfun ;Get the output function
+ mov c,a ;Into C
+ call bdos ;And output the character
+ pop b
+ pop h
+ ret
+ENDIF;iobyt
+
+;
+;
+; get character from modem; return zero if none available.
+; for IOBYT systems, the modem port has already been selected.
+; destroys bc, de, hl.
+inpmdm:
+IF NOT iobyt ;[2] this routine not in submitted file, so I guess
+ ; guess this is what it is supposed to do.
+ in mnprts ; input status port
+ ani input ; anything t read in?
+ rz ; nope
+ in mnport ; else read in the data
+ ret ; return with character in A
+ENDIF ; NOT iobyte [2]
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+
+flsmdm: call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+;
+;
+; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not.
+lptstat:
+ call bprtst ; assume it is ok.. this may not be necessary
+ ret
+
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+outlpt:
+ push d ; save DE in either case
+ call prtflt ; go through printer filter [30]
+ ana a ; if A = 0 do nothing,
+ jz outlp1 ; [30] if a=0 do nothing
+
+IF NOT iobyt
+ mvi c,lstout
+ call bdos ;Char to printer
+ENDIF;NOT iobyt
+outlp1: pop d ; restore saved register pair
+ ret
+;
+;
+; Screen manipulation routines
+; csrpos - move to row B, column C
+;
+; csrpos for terminals that use a leadin sequence followed
+; by (row + 31.) and (column + 31.)
+;
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; restore coordinates
+ mov a,h ; get row
+ adi (' '-1) ; space is row one
+ mov e,a
+ push h
+ call outcon ; output row
+ pop h
+ mov a,l ; get column
+ adi (' '-1) ; space is column one
+ mov e,a
+ jmp outcon ; output it and return
+
+;
+; delchr - make delete look like a backspace. Unless delete is a printing
+; character, we just need to print a backspace. (we'll output clrspc
+; afterwards)
+; For Kaypro and Vector General, delete puts a blotch on the screen.
+; For Apple and Osborne 1, delete moves but doesn't print.
+delchr:
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the character at the current cursor position
+clrspc: mvi e,' '
+ call outcon
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the current line
+clrlin: lxi d,eralin
+ jmp prtstr
+
+; erase the whole screen, and go home. preserves b (but not c)
+clrtop: lxi d,erascr
+ jmp prtstr
+
+IF telcon
+sysver: db 'Telcon Zorba$'
+ENDIF;telcon
+
+IF heath
+sysver: db 'Heath/Zenith 89$'
+ENDIF;heath
+
+IF h8quad
+sysver: db 'Heath H8 with quad I/O card$'
+ENDIF
+
+IF z100
+sysver: db 'Heath/Zenith Z-100 CP/M$'
+ENDIF;z100
+
+IF scntpr
+; [35a: majoc 870305]
+sysver: db 'OEM ScreenTyper: 4MHz Z80 running OS/M$'
+ENDIF;scntpr
+
+IF heath OR h8quad OR z100 OR telcon
+outlin: db esc,'H',esc,'J',cr,lf,tab,tab,'$'
+erascr: db esc,'H',esc,'J$' ;Clear screen and go home.
+eralin: db cr,esc,'K$' ;Clear line.
+curldn: db esc,'Y$' ;cursor leadin
+ttab: ;Table start location.
+ta: db esc,'A$',0 ;Cursor up.
+tb: db esc,'B$',0 ;Cursor down.
+tc: db esc,'C$',0 ;Cursor right.
+td: db esc,'D$',0 ;Cursor left
+te: db esc,'E$',0 ;Clear display
+tf: db esc,'F$',0 ;Enter Graphics Mode
+tg: db esc,'G$',0 ;Exit Graphics mode
+th: db esc,'H$',0 ;Cursor home.
+ti: db esc,'I$',0 ;Reverse linefeed.
+tj: db esc,'J$',0 ;Clear to end of screen.
+tk: db esc,'K$',0 ;Clear to end of line.
+ENDIF;heath OR h8quad OR z100 OR telcon
+;
+
+IF scntpr ; [35a: majoc 870305]
+outlin: db 1aH, cr, lf, '$'
+erascr: db 1aH, '$' ;Clear screen and go home.
+eralin: db cr,esc,'*$' ;Clear line.
+curldn: db esc,'=$' ;cursor leadin
+ttab: ;Table start location.
+ta: db 1eH,'$',0,0 ;Cursor up.
+tb: db 1fH,'$',0,0 ;Cursor down.
+tc: db 1cH,'$',0,0 ;Cursor right.
+td: db 1dH,'$',0,0 ;Cursor left
+te: db 1aH,'$',0,0 ;Clear display
+tf: db 0,0,0,0 ;(Can't)Enter Graphics Mode
+tg: db 0,0,0,0 ;(Can't)Exit Graphics mode
+th: db 15H,'$',0,0 ;Cursor home.
+ti: db 1eH,'$',0,0 ;Reverse linefeed.
+tj: db esc,'%$',0 ;Clear to end of screen.
+tk: db esc,'*$',0 ;Clear to end of line.
+ENDIF;scntpr
+
+ovlend EQU $ ; End of overlay
+ END ; Phew ... [majoc 870305]
diff --git a/cpxlnk.asm b/cpxlnk.asm
index 30dd080..83ac991 100644
--- a/cpxlnk.asm
+++ b/cpxlnk.asm
@@ -1,206 +1,206 @@
-; CPXLNK.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file describes the areas used to communicate between KERMIT
-; and the customizing overlay. It is included by the overlay.
-; This file should be changed only to reflect changes in the
-; system-independent portion of Kermit (enhancements, I hope).
-;
-; revision history:
-;edit 8, 14-Sep-1990 by MF. Added variable "incflg" to hold incomplete-
-; file status for SET INCOMPLETE-FILES command.
-; edit 7: 8 April, 1987 by OBSchou. Added a new entry EXTERN to leap off to
-; code written by the user to emulate any terminal they want. All
-; characters are sent here in stead of conout during connect state.
-; In due course, Ill trap all prtstrs and dconio as well.
-;
-; edit 6: May 30, 1986 by OBSchou. Added two more entries to the link area:
-; first to point to a "family" string giving the family name of the
-; system. If the older CP4SYS.ASM still has the code, then the
-; string is null. Secondly, a JMP to give printer status (should be
-; a BIOS function). If 0 then printer is ready, if 0ffh then printer
-; busy. This makes version 4.07 incompatable with 4.05
-;
-; edit 5: February 6, 1985
-; Added a storage variable, "PORT", for the port-in-use value
-; required for the port status routine (same purpose as SPEED).
-; Also moved the printer copy flag (PRNFLG:) into the commun-
-; ications storage area so machine dependant overlay can access it.
-; [Hal Hostetler]
-; Also, replace assembly-time conditional "ffussy" with run-time
-; switch (CJC).
-;
-; edit 4: August 21, 1984 (CJC)
-; Define a use for the third word of the linkage section: it points
-; to the version string for CP4SYS.ASM. Add flsmdm, to flush comm line
-; on startup. Add bufadr and bufsec for multiple-sector buffer support.
-; Shift the entry section up two bytes so we can exit cleanly from DDT.
-;
-; edit 3: August 3, 1984 (CJC)
-; put "mover" in CP4SYS, so we can do a Z80 block move if so inclined.
-;
-; edit 2: July 10, 1984 (CJC)
-; integrate Toad Hall changes for LASM compatibility: CP4LNK is linked
-; by CP4DEF, and links CP4SYS.
-;
-; edit 1: May, 1984 (CJC)
-; extracted from CPMBASE.M80 version 3.9; modifications are described
-; in the accompanying .UPD file.
-;
-
-; Define the entry section. These addresses contain jumps to
-; useful routines in KERMIT. To show we know what we're doing,
-; we store the length of this section (entsiz) in our linkage
-; section. I didn't use ORG and DS because I don't want zeroes
-; generated for all the space between here and the actual start
-; of cp4sys.
-entry equ 105H ; start of entry section
-kermit equ entry+0 ; reentry address
-nout equ entry+3 ; output HL in decimal
-entsiz equ 2*3 ; 2 entries, so far.
-;
-; End of entry section.
-;
-; Linkage section. This block (through the definition of lnksiz)
-; is used by Kermit to reach the routines and data in the overlay.
-; The section length is stored at the beginning of the overlay
-; area so Kermit can verify that the overlay section is (a) present,
-; (b) in the right place, and (c) the same size as (and therefore
-; presumably the same as) the linkage section Kermit is expecting.
-;
- ASEG
- ORG OVLADR
-;
-lnkflg: dw lnksiz ; linkage information for consistency check.
- dw entsiz ; length of entry table, for same.
- dw swtver ; address of switcher. CPXSYS now a family
- dw family ;*NEW* for V4.08. Address of the family string
-;
-; hooks for system-dependent routines:
-;
-; Input/output routines.
-;
- jmp selmdm ; select modem for I/O
- jmp outmdm ; output character in E to modem
- jmp inpmdm ; read character from modem. return character or 0 in A.
- jmp flsmdm ; flush pending input from modem
- jmp selcon ; select console for I/O
- jmp outcon ; output character in E to console
- jmp inpcon ; read char from console. return character or 0 in A
- jmp outlpt ; output character in E to printer
- jmp lptstat ;*NEW* get the status for the printer.
- ; 0=>ok, 0ffh=> not ok
- jmp 0 ;*NEW for 4.09* Terminal Emulation code (optional)
- ; If terminal is set to EXTERNAL and this address
- ; has been filled, then user uses their own code.
-xbdos: jmp 0 ;*NEW* Address of the BDOS trap in the independent
- ; code. Use this enty for BDOS calls if you want
- ; the printer handler to work properly.
-
-; screen formatting routines
- jmp clrlin ; erase current line
- jmp clrspc ; erase current position (after backspace)
- jmp delchr ; make delete look like backspace
- jmp clrtop ; erase screen and go home
-;
-; these routines are called to display a field on the screen.
- jmp scrend ; move to prompt field
- jmp screrr ; move to error message field
- jmp scrfln ; move to filename field
- jmp scrnp ; move to packet count field
- jmp scrnrt ; move to retry count field
- jmp scrst ; move to status field
- jmp rppos ; move to receive packet field (debug)
- jmp sppos ; move to send packet field (debug)
-;
- jmp sysinit ; program initialization
- jmp sysexit ; program termination
- jmp syscon ; remote session initialization
- jmp syscls ; return to local command level
- jmp sysinh ; help text for interrupt (escape) extensions
- jmp sysint ; interrupt (escape) extensions, including break
- jmp sysflt ; filter for incoming characters.
- ; called with character in E.
- jmp sysbye ; terminate remote session
- jmp sysspd ; baud rate change routine.
- ; called with value from table in DE
- jmp sysprt ; port change routine.
- ; called with value from table in HL
- jmp sysscr ; screen setup for file transfer
- ; called with Kermit's version string in DE
- jmp csrpos ; move cursor to row B, column C
- jmp sysspc ; calculate free space for current drive
- jmp mover ; do block move
- jmp prtstr ; *** NEW *** Link from system indep equivalent
-;
-; Local parameter values
-;
-pttab: dw ttab ; points to local equivalents to VT52 escape sequences
-spdtab: dw spdtbl ; address of baud rate command table, or zero
-spdhlp: dw sphtbl ; address of baud rate help table, or zero
-prttab: dw prttbl ; address of port command table, or zero
-prthlp: dw prhtbl ; address of port help table, or zero
-timout: dw fuzval ; Fuzzy timeout.
-vtflg: db vtval ; VT52 emulation flag
-escchr: db defesc ; Storage for the escape character.
-speed: dw 0FFFFH ; storage for the baud rate (initially unknown)
-port: dw 0FFFFH ; storage for port value (initially unknown) [hh]
-prnflg: db 0 ; printer copy flag [hh]
-dbgflg: db 0 ; debugging flag
-ecoflg: db 0 ; Local echo flag (default off).
-flwflg: db 1 ; File warning flag (default on).
-ibmflg: db 0 ; IBM flag (default off).
-cpmflg: db 0 ;[bt] file-mode flag (default is DEFAULT)
-incflg: db 0 ;[MF]incomplete-file flag (default is DISCARD)
-parity: db defpar ; Parity.
-spsiz: db dspsiz ; Send packet size.
-rpsiz: db drpsiz ; Receive packet size.
-stime: db dstime ; Send time out.
-rtime: db drtime ; Receive time out.
-spad: db dspad ; Send padding.
-rpad: db drpad ; Receive padding.
-spadch: db dspadc ; Send padding char.
-rpadch: db drpadc ; Receive padding char.
-seol: db dseol ; Send EOL char.
-reol: db dreol ; Receive EOL char.
-squote: db dsquot ; Send quote char.
-rquote: db drquot ; Receive quote char.
-chktyp: db dschkt ; Checksum type desired
-tacflg: ; TACtrap status:
-IF tac
- db tacval ; when non-zero, is current TAC intercept character;
-ENDIF;tac
-IF NOT tac
- db 0 ; when zero, TACtrap is off.
-ENDIF;tac
-tacchr: db tacval ; Desired TAC intercept character (even when off)
-bufadr: dw buff ; Address of possibly multi-sector buffer for I/O
-bufsec: db 1 ; Number of sectors big buffer can hold (0 means 256)
-ffussy: db 1 ; if nonzero, don't permit <>.,;?*[] in CP/M filespec.
-; space used by directory command; here because space calculation is
-; (operating) system-dependent
-bmax: ds 2 ; highest block number on drive
-bmask: ds 1 ; (records/block)-1
-bshiftf: ds 1 ; number of shifts to multiply by rec/block
-nnams: ds 1 ; counter for filenames per line
-
-lnksiz equ $-lnkflg ; length of linkage section, for consistency check.
-
-IF lasm ; If we're assembling with LASM,
- LINK CPXCOM ; get the next section.
-ENDIF;lasm
+; CPXLNK.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file describes the areas used to communicate between KERMIT
+; and the customizing overlay. It is included by the overlay.
+; This file should be changed only to reflect changes in the
+; system-independent portion of Kermit (enhancements, I hope).
+;
+; revision history:
+;edit 8, 14-Sep-1990 by MF. Added variable "incflg" to hold incomplete-
+; file status for SET INCOMPLETE-FILES command.
+; edit 7: 8 April, 1987 by OBSchou. Added a new entry EXTERN to leap off to
+; code written by the user to emulate any terminal they want. All
+; characters are sent here in stead of conout during connect state.
+; In due course, Ill trap all prtstrs and dconio as well.
+;
+; edit 6: May 30, 1986 by OBSchou. Added two more entries to the link area:
+; first to point to a "family" string giving the family name of the
+; system. If the older CP4SYS.ASM still has the code, then the
+; string is null. Secondly, a JMP to give printer status (should be
+; a BIOS function). If 0 then printer is ready, if 0ffh then printer
+; busy. This makes version 4.07 incompatable with 4.05
+;
+; edit 5: February 6, 1985
+; Added a storage variable, "PORT", for the port-in-use value
+; required for the port status routine (same purpose as SPEED).
+; Also moved the printer copy flag (PRNFLG:) into the commun-
+; ications storage area so machine dependant overlay can access it.
+; [Hal Hostetler]
+; Also, replace assembly-time conditional "ffussy" with run-time
+; switch (CJC).
+;
+; edit 4: August 21, 1984 (CJC)
+; Define a use for the third word of the linkage section: it points
+; to the version string for CP4SYS.ASM. Add flsmdm, to flush comm line
+; on startup. Add bufadr and bufsec for multiple-sector buffer support.
+; Shift the entry section up two bytes so we can exit cleanly from DDT.
+;
+; edit 3: August 3, 1984 (CJC)
+; put "mover" in CP4SYS, so we can do a Z80 block move if so inclined.
+;
+; edit 2: July 10, 1984 (CJC)
+; integrate Toad Hall changes for LASM compatibility: CP4LNK is linked
+; by CP4DEF, and links CP4SYS.
+;
+; edit 1: May, 1984 (CJC)
+; extracted from CPMBASE.M80 version 3.9; modifications are described
+; in the accompanying .UPD file.
+;
+
+; Define the entry section. These addresses contain jumps to
+; useful routines in KERMIT. To show we know what we're doing,
+; we store the length of this section (entsiz) in our linkage
+; section. I didn't use ORG and DS because I don't want zeroes
+; generated for all the space between here and the actual start
+; of cp4sys.
+entry equ 105H ; start of entry section
+kermit equ entry+0 ; reentry address
+nout equ entry+3 ; output HL in decimal
+entsiz equ 2*3 ; 2 entries, so far.
+;
+; End of entry section.
+;
+; Linkage section. This block (through the definition of lnksiz)
+; is used by Kermit to reach the routines and data in the overlay.
+; The section length is stored at the beginning of the overlay
+; area so Kermit can verify that the overlay section is (a) present,
+; (b) in the right place, and (c) the same size as (and therefore
+; presumably the same as) the linkage section Kermit is expecting.
+;
+ ASEG
+ ORG OVLADR
+;
+lnkflg: dw lnksiz ; linkage information for consistency check.
+ dw entsiz ; length of entry table, for same.
+ dw swtver ; address of switcher. CPXSYS now a family
+ dw family ;*NEW* for V4.08. Address of the family string
+;
+; hooks for system-dependent routines:
+;
+; Input/output routines.
+;
+ jmp selmdm ; select modem for I/O
+ jmp outmdm ; output character in E to modem
+ jmp inpmdm ; read character from modem. return character or 0 in A.
+ jmp flsmdm ; flush pending input from modem
+ jmp selcon ; select console for I/O
+ jmp outcon ; output character in E to console
+ jmp inpcon ; read char from console. return character or 0 in A
+ jmp outlpt ; output character in E to printer
+ jmp lptstat ;*NEW* get the status for the printer.
+ ; 0=>ok, 0ffh=> not ok
+ jmp 0 ;*NEW for 4.09* Terminal Emulation code (optional)
+ ; If terminal is set to EXTERNAL and this address
+ ; has been filled, then user uses their own code.
+xbdos: jmp 0 ;*NEW* Address of the BDOS trap in the independent
+ ; code. Use this enty for BDOS calls if you want
+ ; the printer handler to work properly.
+
+; screen formatting routines
+ jmp clrlin ; erase current line
+ jmp clrspc ; erase current position (after backspace)
+ jmp delchr ; make delete look like backspace
+ jmp clrtop ; erase screen and go home
+;
+; these routines are called to display a field on the screen.
+ jmp scrend ; move to prompt field
+ jmp screrr ; move to error message field
+ jmp scrfln ; move to filename field
+ jmp scrnp ; move to packet count field
+ jmp scrnrt ; move to retry count field
+ jmp scrst ; move to status field
+ jmp rppos ; move to receive packet field (debug)
+ jmp sppos ; move to send packet field (debug)
+;
+ jmp sysinit ; program initialization
+ jmp sysexit ; program termination
+ jmp syscon ; remote session initialization
+ jmp syscls ; return to local command level
+ jmp sysinh ; help text for interrupt (escape) extensions
+ jmp sysint ; interrupt (escape) extensions, including break
+ jmp sysflt ; filter for incoming characters.
+ ; called with character in E.
+ jmp sysbye ; terminate remote session
+ jmp sysspd ; baud rate change routine.
+ ; called with value from table in DE
+ jmp sysprt ; port change routine.
+ ; called with value from table in HL
+ jmp sysscr ; screen setup for file transfer
+ ; called with Kermit's version string in DE
+ jmp csrpos ; move cursor to row B, column C
+ jmp sysspc ; calculate free space for current drive
+ jmp mover ; do block move
+ jmp prtstr ; *** NEW *** Link from system indep equivalent
+;
+; Local parameter values
+;
+pttab: dw ttab ; points to local equivalents to VT52 escape sequences
+spdtab: dw spdtbl ; address of baud rate command table, or zero
+spdhlp: dw sphtbl ; address of baud rate help table, or zero
+prttab: dw prttbl ; address of port command table, or zero
+prthlp: dw prhtbl ; address of port help table, or zero
+timout: dw fuzval ; Fuzzy timeout.
+vtflg: db vtval ; VT52 emulation flag
+escchr: db defesc ; Storage for the escape character.
+speed: dw 0FFFFH ; storage for the baud rate (initially unknown)
+port: dw 0FFFFH ; storage for port value (initially unknown) [hh]
+prnflg: db 0 ; printer copy flag [hh]
+dbgflg: db 0 ; debugging flag
+ecoflg: db 0 ; Local echo flag (default off).
+flwflg: db 1 ; File warning flag (default on).
+ibmflg: db 0 ; IBM flag (default off).
+cpmflg: db 0 ;[bt] file-mode flag (default is DEFAULT)
+incflg: db 0 ;[MF]incomplete-file flag (default is DISCARD)
+parity: db defpar ; Parity.
+spsiz: db dspsiz ; Send packet size.
+rpsiz: db drpsiz ; Receive packet size.
+stime: db dstime ; Send time out.
+rtime: db drtime ; Receive time out.
+spad: db dspad ; Send padding.
+rpad: db drpad ; Receive padding.
+spadch: db dspadc ; Send padding char.
+rpadch: db drpadc ; Receive padding char.
+seol: db dseol ; Send EOL char.
+reol: db dreol ; Receive EOL char.
+squote: db dsquot ; Send quote char.
+rquote: db drquot ; Receive quote char.
+chktyp: db dschkt ; Checksum type desired
+tacflg: ; TACtrap status:
+IF tac
+ db tacval ; when non-zero, is current TAC intercept character;
+ENDIF;tac
+IF NOT tac
+ db 0 ; when zero, TACtrap is off.
+ENDIF;tac
+tacchr: db tacval ; Desired TAC intercept character (even when off)
+bufadr: dw buff ; Address of possibly multi-sector buffer for I/O
+bufsec: db 1 ; Number of sectors big buffer can hold (0 means 256)
+ffussy: db 1 ; if nonzero, don't permit <>.,;?*[] in CP/M filespec.
+; space used by directory command; here because space calculation is
+; (operating) system-dependent
+bmax: ds 2 ; highest block number on drive
+bmask: ds 1 ; (records/block)-1
+bshiftf: ds 1 ; number of shifts to multiply by rec/block
+nnams: ds 1 ; counter for filenames per line
+
+lnksiz equ $-lnkflg ; length of linkage section, for consistency check.
+
+IF lasm ; If we're assembling with LASM,
+ LINK CPXCOM ; get the next section.
+ENDIF;lasm
diff --git a/cpxmrl.asm b/cpxmrl.asm
index 31d6849..fb32692 100644
--- a/cpxmrl.asm
+++ b/cpxmrl.asm
@@ -1,454 +1,454 @@
-IF NOT lasm
-.printx * CPXMRL.ASM *
-ENDIF ; NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; CPXMRL.ASM created 16 July, 1987 from submitted code by William Rose.
-;
-; Kermit system dependent file for Rair Black Box (British Telecom
-; Merlin, ICL PC etc) originally submitted by William Rose, and
-; modified by OBSchou to work with the Kermit-80 V4.08 and later
-; files. Wills original overlay file a stripped down CPXSYS.ASM
-; file.
-;
-; KERSYS.ASM - version 0.6A dated 17 Jun 87.
-;
-; Cutdown CP4SYS.ASM for Telecom Merlin M2215 only. (ICL PC, Rair Black Box)
-;
-; This uses TTY1: only, and cannot alter it's parameters. It resets the
-; interrupt flag to prevent use of the buffer, and is generally a kludge.
-; However it runs at 4800 baud, and tidying the code might get 9600.
-;
-; Revision History (Last entry first)
-;
-; edit 2, 22 July by OBSchou to massage frile to fit with CPXCOM.ASM
-;
-; edit 1, 17 July by OBSchou for Will Rose, to make file suitable for V4.08
-; overlay etc.
-;
-; Keep module name, edit number, and last revision date in memory.
-;
-family: db 'CPXMRL.ASM (2) 22-Jun-87 $' ; Telecom Merlin added
-
-;
-; Assembly time message to let me know I'm building the right version.
-;
-
-IF m2215
- .printx * Assembling Kermit-80 for Merlin M2215 *
-ENDIF
-
-IF m2215 ;equates removed because interrupts stopped port access
-;iobase equ 14h ; base address of TTY1
-;mnport equ iobase ; rx and tx data ports
-;mnprts equ iobase+1 ; status port
-;mnmode equ iobase+2 ; mode port
-;mncmd equ iobase+3 ; PCI command port
-;txrdy equ 1 ; tx ready bit set if free
-;output equ txrdy
-;rxrdy equ 2 ; RX ready bit
-;input equ rxrdy
-z80 equ false ; For Merlin M2215
-ENDIF
-
-
-sysxin: ; Continue system initialisation fro sysinit
-
-IF FALSE ; unable to penetrate the 8085 interrupts
- in mncmd ; clear command register counter
- mvi a,4eh ; 0100$1110 - 1 stop bit, 8 data bits,
- ; / by 16 counter
- out mnmode
- mvi a,30h+7 ; 0011$0000 - select internal rate generator
- ; use 1200 baud by default
- out mnmode
- mvi a,27h ; 0010$0111 - enable tx and rx, RTS and DTR low
- out mncmd
- mvi h, 12
- mvi l, 12
- shld speed ; to show its been set up
-
-ENDIF
-
- ret
-
-porbuf: ds 3 ; original port settings
-
-;
-; system-dependent KERMIT termination processing
-; If we've changed anything, this is our last chance to put it back.
-;
-sysexit:
- ret
-
-;
-; system-dependent processing for start of CONNECT command
-;
-syscon:
- ret
-
-conmsg: ; Messages printed when entering transparent (CONNECT) mode:
-
- db '$'
-
-;
-; syscls - system-dependent close routine
-; called when exiting transparent session.
-;
-syscls:
- ret
-
-;
-; sysinh - help for system-dependent special functions.
-; called in response to <escape>?, after listing all the
-; system-independent escape sequences.
-;
-sysinh:
- ; still can't pentrate interrupts
- ret
-
-; Additional, system-dependent help for transparent mode
-; (two-character escape sequences)
-;
-inhlps:
-
-IF m2215
- db cr, lf, 'B Transmit a BREAK'
-ENDIF
-
- db '$' ; string terminator
-
-;
-; sysint - system dependent special functions
-; called when transparent escape character has been typed;
-; the second character of the sequence is in A (and in B).
-; returns:
-; non-skip: sequence has been processed
-; skip: seqence was not recognized
-;
-sysint: ani 137O ; convert lower case to upper, for testing...
-
-IF FALSE ; as always
- cpi 'B' ; send break ?
- jz sendbr
-ENDIF
- jmp rskp ; take skip return - command not recognised
-
-; Actual commands
-
-IF FALSE ;as always
-sendbr:
- in mnprts
- ani 04h ; make sure shift reg is clear
- jz sendbr
-
- mvi a,2fh ; set for a break
- out mncmd
- mvi a,100 ; wait a bit
- call delay
- mvi a,27h ; restore mode
- out mncmd
-
- ret
-ENDIF
-
- ret
-
-;
-; sysflt - system-dependent filter
-; called with character in E.
-; if this character should not be printed, return with A = zero.
-; preserves bc, de, hl.
-; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-;
-sysflt:
- mov a,e ; get character for testing
- ret
-
-;
-; mdmflt - modem filter
-; called with character to be sent to printer in E
-; with parity set as appropriate.
-; return with accumulator = 0 do do nothing,
-; <> 0 to send char in E.
-mdmflt:
- mov a,e ; get character to test
- ret
-
-;
-; prtflt - printer filter
-; called with character to be sent to printer in E
-; returns with a = 0 to do nothing
-; a <> 0 to print it.
-;
-; this routine for those printer that automatically insert
-; a lf on cr, or cr for lf. Should this be shifted to
-; the system indep. stuff, in say 4.06?
-;
-prtflt:
- mov a,e ; get character to test
-
-IF FALSE ; strip out lf from printer stream
- ani 7fh ; make sure it is parity less
- cpi lf ; is it a line feed?
- rnz ; no, print it
-; xra a ; yes, don't.
-
-ENDIF
-
- ret
-
-;
-; system-dependent processing for BYE command.
-;
-sysbye:
- ret
-
-;
-; This is the system-dependent command to change the baud rate.
-; DE contains the two-byte value from the baud rate table; both
-; bytes of this value are also stored in 'speed'.
-;
-sysspd:
-
-IF FALSE ; as always
- in mncmd ; clear register counter
- mvi a,4eh ; set for 1 stop, 8 data bits
- out mnmode ; save in mode 1 port
- mvi a,30h ; set bits for rate etc..
- add e ; add baud rate (bits 0 - 3)
- out mnmode ; set mode port 2
- mvi a,27h ; set tx/rx ready, RTS CTS active
- out mncmd
- ret
-ENDIF
- ret ; if routine not supported
-;
-; Speed tables
-; (Note that speed tables MUST be in alphabetical order for later
-; lookup procedures, and must begin with a value showing the total
-; number of entries. The speed help tables are just for us poor
-; humans.
-;
-; db string length, string, divisor (2 bytes or 1 word, ab)
-; the data byte a is return in A and E, and b in D
-; only byte 'a' is the key for the table
-
-IF FALSE ; as always
-spdtbl: db 16 ; sixteen entries for PCI
- db 3,'110$', 2,2
- db 4,'1200$', 7,7
- db 3,'134$', 3,3
- db 3,'150$', 4,4
- db 4,'1800$', 8,8
- db 5,'19200$', 15,15
- db 4,'2000$', 9,9
- db 4,'2400$', 10,10
- db 3,'300$', 5,5
- db 4,'3600$', 11,11
- db 4,'4800$', 12,12
- db 2,'50$', 0,0
- db 3,'600$', 6,6
- db 4,'7200$', 13,13
- db 2,'75$', 1,1
- db 4,'9600$', 14,14
-
-sphtbl: db ' 50 75 110 134 150 300 600 1200 '
- db cr,lf,'1800 2000 2400 3600 4800 7200 9600 19200$'
-ENDIF
-
-IF m2215
-spdtbl equ 0 ; routine unsupported
-sphtbl equ 0
-ENDIF
-
-;
-; This is the system-dependent SET PORT command.
-; HL contains the argument from the command table.
-;
-sysprt:
-
-IF m2215
-prttbl equ 0 ; SET PORT is not supported
-prhtbl equ 0 ; Merlin M2215 could, I suppose
-ENDIF
-
-;
-; selmdm - select modem port
-; selcon - select console port
-; selmdm is called before using inpmdm or outmdm;
-; selcon is called before using inpcon or outcon.
-; For iobyt systems, diddle the I/O byte to select console or comm port;
-; For the rest, does nothing.
-; preserves bc, de, hl.
-;
-selmdm:
- ret
-
-selcon:
- ret
-
-;
-; Get character from console, or return zero.
-; result is returned in A. destroys bc, de, hl.
-;
-inpcon:
- call 0f55dh ;CONST BIOS vector
- ora a ;set flags
- rz
- call 0f56eh ;CONIN BIOS vector
- ret
-
-;
-; Output character in E to the console.
-; destroys bc, de, hl
-;
-outcon:
- mov c, e
- call 0f57fh ;CONOUT BIOS vector
- ret
-
-;
-; outmdm - output a char from E to the modem.
-; the parity bit has been set as necessary.
-; returns nonskip; bc, de, hl preserved.
-;
-outmdm:
-
-IF m2215
- push psw
- push h
- push d
- push b
-
- mov c, e
- mvi a, 1 ; ie: tty1:
- mov d, a
- call 0f6a2h ;PUN BIOS vector
-
- pop b
- pop d
- pop h
- pop psw
-ENDIF
-
- ret
-
-;
-; for IOBYT systems, the modem port has already been selected.
-; destroys bc, de, hl.
-;
-inpmdm:
-
-IF m2215
- ; check status
- lda 0fa32h ; ie. tty1:
- ora a
- rz
-
- mvi a, 1 ; RDR BIOS vector
- mov d, a
- call 0f651h
-; ani 7fh
-
- push a
- di
- mvi a, 0
- sta 0fa32h ; remove interrupt flag
- sta 0f2d3h ; zero buffer counter
- lda 0f2d4h
- sta 0f2d5h
- ei
- nop
- pop a
-
- ret
-ENDIF
-
-;
-; flsmdm - flush comm line.
-; Modem is selected.
-; Currently, just gets characters until none are available.
-;
-flsmdm:
-
- call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-
-
-;
-
-;
-; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
-lptstat:
-IF iobyte ;[33]
- call bprtst ; get status
-ENDIF ;iobyte[33]
-
-IF NOT iobyte ;[33]
- xra a ; assume it is ok.. this may not be necessary
-ENDIF ;iobyte [33]
- ret
-;
-; outlpt - output character in E to printer
-; console is selected.
-; preserves de.
-;
-outlpt:
- push d ; save DE in either case
- call prtflt ; go through printer filter [30]
- ana a ; if A = 0 do nothing,
- jz outlp1 ; if a=0 do nothing
-
-outlp1: pop d ; restore saved register pair
- ret
-
-; delchr - make delete look like a backspace. Unless delete is a printing
-; character, we just need to print a backspace. (we'll output clrspc
-; afterwards)
-delchr:
-
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the character at the current cursor position
-clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the current line
-clrlin: lxi d,eralin
- jmp prtstr
-
-; erase the whole screen, and go home. preserves b (but not c)
-clrtop: lxi d,erascr
- jmp prtstr
-
-
-IF m2215
-sysver: db 'BT Merlin M2215, port TTY1:, settings unchanged.$'
-ENDIF
-
-tstmsg: db 'Test message',cr,lf,'$'
-
-IF lasm
-LINK CPXVDU.ASM ; link to the Terminal definition tables
-ENDIF ;lasm
+IF NOT lasm
+.printx * CPXMRL.ASM *
+ENDIF ; NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; CPXMRL.ASM created 16 July, 1987 from submitted code by William Rose.
+;
+; Kermit system dependent file for Rair Black Box (British Telecom
+; Merlin, ICL PC etc) originally submitted by William Rose, and
+; modified by OBSchou to work with the Kermit-80 V4.08 and later
+; files. Wills original overlay file a stripped down CPXSYS.ASM
+; file.
+;
+; KERSYS.ASM - version 0.6A dated 17 Jun 87.
+;
+; Cutdown CP4SYS.ASM for Telecom Merlin M2215 only. (ICL PC, Rair Black Box)
+;
+; This uses TTY1: only, and cannot alter it's parameters. It resets the
+; interrupt flag to prevent use of the buffer, and is generally a kludge.
+; However it runs at 4800 baud, and tidying the code might get 9600.
+;
+; Revision History (Last entry first)
+;
+; edit 2, 22 July by OBSchou to massage frile to fit with CPXCOM.ASM
+;
+; edit 1, 17 July by OBSchou for Will Rose, to make file suitable for V4.08
+; overlay etc.
+;
+; Keep module name, edit number, and last revision date in memory.
+;
+family: db 'CPXMRL.ASM (2) 22-Jun-87 $' ; Telecom Merlin added
+
+;
+; Assembly time message to let me know I'm building the right version.
+;
+
+IF m2215
+ .printx * Assembling Kermit-80 for Merlin M2215 *
+ENDIF
+
+IF m2215 ;equates removed because interrupts stopped port access
+;iobase equ 14h ; base address of TTY1
+;mnport equ iobase ; rx and tx data ports
+;mnprts equ iobase+1 ; status port
+;mnmode equ iobase+2 ; mode port
+;mncmd equ iobase+3 ; PCI command port
+;txrdy equ 1 ; tx ready bit set if free
+;output equ txrdy
+;rxrdy equ 2 ; RX ready bit
+;input equ rxrdy
+z80 equ false ; For Merlin M2215
+ENDIF
+
+
+sysxin: ; Continue system initialisation fro sysinit
+
+IF FALSE ; unable to penetrate the 8085 interrupts
+ in mncmd ; clear command register counter
+ mvi a,4eh ; 0100$1110 - 1 stop bit, 8 data bits,
+ ; / by 16 counter
+ out mnmode
+ mvi a,30h+7 ; 0011$0000 - select internal rate generator
+ ; use 1200 baud by default
+ out mnmode
+ mvi a,27h ; 0010$0111 - enable tx and rx, RTS and DTR low
+ out mncmd
+ mvi h, 12
+ mvi l, 12
+ shld speed ; to show its been set up
+
+ENDIF
+
+ ret
+
+porbuf: ds 3 ; original port settings
+
+;
+; system-dependent KERMIT termination processing
+; If we've changed anything, this is our last chance to put it back.
+;
+sysexit:
+ ret
+
+;
+; system-dependent processing for start of CONNECT command
+;
+syscon:
+ ret
+
+conmsg: ; Messages printed when entering transparent (CONNECT) mode:
+
+ db '$'
+
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+ ret
+
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing all the
+; system-independent escape sequences.
+;
+sysinh:
+ ; still can't pentrate interrupts
+ ret
+
+; Additional, system-dependent help for transparent mode
+; (two-character escape sequences)
+;
+inhlps:
+
+IF m2215
+ db cr, lf, 'B Transmit a BREAK'
+ENDIF
+
+ db '$' ; string terminator
+
+;
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:
+; non-skip: sequence has been processed
+; skip: seqence was not recognized
+;
+sysint: ani 137O ; convert lower case to upper, for testing...
+
+IF FALSE ; as always
+ cpi 'B' ; send break ?
+ jz sendbr
+ENDIF
+ jmp rskp ; take skip return - command not recognised
+
+; Actual commands
+
+IF FALSE ;as always
+sendbr:
+ in mnprts
+ ani 04h ; make sure shift reg is clear
+ jz sendbr
+
+ mvi a,2fh ; set for a break
+ out mncmd
+ mvi a,100 ; wait a bit
+ call delay
+ mvi a,27h ; restore mode
+ out mncmd
+
+ ret
+ENDIF
+
+ ret
+
+;
+; sysflt - system-dependent filter
+; called with character in E.
+; if this character should not be printed, return with A = zero.
+; preserves bc, de, hl.
+; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
+;
+sysflt:
+ mov a,e ; get character for testing
+ ret
+
+;
+; mdmflt - modem filter
+; called with character to be sent to printer in E
+; with parity set as appropriate.
+; return with accumulator = 0 do do nothing,
+; <> 0 to send char in E.
+mdmflt:
+ mov a,e ; get character to test
+ ret
+
+;
+; prtflt - printer filter
+; called with character to be sent to printer in E
+; returns with a = 0 to do nothing
+; a <> 0 to print it.
+;
+; this routine for those printer that automatically insert
+; a lf on cr, or cr for lf. Should this be shifted to
+; the system indep. stuff, in say 4.06?
+;
+prtflt:
+ mov a,e ; get character to test
+
+IF FALSE ; strip out lf from printer stream
+ ani 7fh ; make sure it is parity less
+ cpi lf ; is it a line feed?
+ rnz ; no, print it
+; xra a ; yes, don't.
+
+ENDIF
+
+ ret
+
+;
+; system-dependent processing for BYE command.
+;
+sysbye:
+ ret
+
+;
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; both
+; bytes of this value are also stored in 'speed'.
+;
+sysspd:
+
+IF FALSE ; as always
+ in mncmd ; clear register counter
+ mvi a,4eh ; set for 1 stop, 8 data bits
+ out mnmode ; save in mode 1 port
+ mvi a,30h ; set bits for rate etc..
+ add e ; add baud rate (bits 0 - 3)
+ out mnmode ; set mode port 2
+ mvi a,27h ; set tx/rx ready, RTS CTS active
+ out mncmd
+ ret
+ENDIF
+ ret ; if routine not supported
+;
+; Speed tables
+; (Note that speed tables MUST be in alphabetical order for later
+; lookup procedures, and must begin with a value showing the total
+; number of entries. The speed help tables are just for us poor
+; humans.
+;
+; db string length, string, divisor (2 bytes or 1 word, ab)
+; the data byte a is return in A and E, and b in D
+; only byte 'a' is the key for the table
+
+IF FALSE ; as always
+spdtbl: db 16 ; sixteen entries for PCI
+ db 3,'110$', 2,2
+ db 4,'1200$', 7,7
+ db 3,'134$', 3,3
+ db 3,'150$', 4,4
+ db 4,'1800$', 8,8
+ db 5,'19200$', 15,15
+ db 4,'2000$', 9,9
+ db 4,'2400$', 10,10
+ db 3,'300$', 5,5
+ db 4,'3600$', 11,11
+ db 4,'4800$', 12,12
+ db 2,'50$', 0,0
+ db 3,'600$', 6,6
+ db 4,'7200$', 13,13
+ db 2,'75$', 1,1
+ db 4,'9600$', 14,14
+
+sphtbl: db ' 50 75 110 134 150 300 600 1200 '
+ db cr,lf,'1800 2000 2400 3600 4800 7200 9600 19200$'
+ENDIF
+
+IF m2215
+spdtbl equ 0 ; routine unsupported
+sphtbl equ 0
+ENDIF
+
+;
+; This is the system-dependent SET PORT command.
+; HL contains the argument from the command table.
+;
+sysprt:
+
+IF m2215
+prttbl equ 0 ; SET PORT is not supported
+prhtbl equ 0 ; Merlin M2215 could, I suppose
+ENDIF
+
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; For iobyt systems, diddle the I/O byte to select console or comm port;
+; For the rest, does nothing.
+; preserves bc, de, hl.
+;
+selmdm:
+ ret
+
+selcon:
+ ret
+
+;
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+ call 0f55dh ;CONST BIOS vector
+ ora a ;set flags
+ rz
+ call 0f56eh ;CONIN BIOS vector
+ ret
+
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+ mov c, e
+ call 0f57fh ;CONOUT BIOS vector
+ ret
+
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+;
+outmdm:
+
+IF m2215
+ push psw
+ push h
+ push d
+ push b
+
+ mov c, e
+ mvi a, 1 ; ie: tty1:
+ mov d, a
+ call 0f6a2h ;PUN BIOS vector
+
+ pop b
+ pop d
+ pop h
+ pop psw
+ENDIF
+
+ ret
+
+;
+; for IOBYT systems, the modem port has already been selected.
+; destroys bc, de, hl.
+;
+inpmdm:
+
+IF m2215
+ ; check status
+ lda 0fa32h ; ie. tty1:
+ ora a
+ rz
+
+ mvi a, 1 ; RDR BIOS vector
+ mov d, a
+ call 0f651h
+; ani 7fh
+
+ push a
+ di
+ mvi a, 0
+ sta 0fa32h ; remove interrupt flag
+ sta 0f2d3h ; zero buffer counter
+ lda 0f2d4h
+ sta 0f2d5h
+ ei
+ nop
+ pop a
+
+ ret
+ENDIF
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+;
+flsmdm:
+
+ call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+
+
+;
+
+;
+; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
+lptstat:
+IF iobyte ;[33]
+ call bprtst ; get status
+ENDIF ;iobyte[33]
+
+IF NOT iobyte ;[33]
+ xra a ; assume it is ok.. this may not be necessary
+ENDIF ;iobyte [33]
+ ret
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+;
+outlpt:
+ push d ; save DE in either case
+ call prtflt ; go through printer filter [30]
+ ana a ; if A = 0 do nothing,
+ jz outlp1 ; if a=0 do nothing
+
+outlp1: pop d ; restore saved register pair
+ ret
+
+; delchr - make delete look like a backspace. Unless delete is a printing
+; character, we just need to print a backspace. (we'll output clrspc
+; afterwards)
+delchr:
+
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the character at the current cursor position
+clrspc: mvi e,' '
+ call outcon
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the current line
+clrlin: lxi d,eralin
+ jmp prtstr
+
+; erase the whole screen, and go home. preserves b (but not c)
+clrtop: lxi d,erascr
+ jmp prtstr
+
+
+IF m2215
+sysver: db 'BT Merlin M2215, port TTY1:, settings unchanged.$'
+ENDIF
+
+tstmsg: db 'Test message',cr,lf,'$'
+
+IF lasm
+LINK CPXVDU.ASM ; link to the Terminal definition tables
+ENDIF ;lasm
diff --git a/cpxnor.asm b/cpxnor.asm
index 2648060..4600bb3 100644
--- a/cpxnor.asm
+++ b/cpxnor.asm
@@ -1,587 +1,587 @@
-IF NOT LASM
-.printx * CPXNOR.ASM *
-ENDIF ;NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the system-dependent code and data for various
-; NorthStar KERMITs. This has the Family name of CPXNOR.ASM.
-;
-; revision history (last edit first)
-;
-;edit 4, 16-Jan-1991 by MF. Fixed a bug in OUTCON wherein the final RET
-; was missing (bug reported by David P. Arnot of Scottish
-; Agricultural College).
-;edit 3, 12-Oct-1990 by MF. Added a semicolon before the comment
-; beginning "Family is the string so we don't get errors
-; edit 2, 23 July, 1987 by OBSchou to massage file to suit CPXCOM.ASM.
-;
-; edit 1: 1 June, 1986 by OBSchou, Loughborogh University, UK.
-; Hived off northstar and Comart system dependent modules from
-; CPXSYS.ASM. This assembles ok, but I cannot test it. Any comments?
-
-
-IF norths
-.printx * Assembling for NorthStar Horizon with HSIO-4 board *
-ENDIF;norths
-
-IF horizon ;[25]
-.printx * Assembling KERMIT-80 for the NorthStar Horizon *
-ENDIF;horizon
-
-IF advant ;[22]
-.printx * Assembling kermit-80 for North Star Advantage *
-ENDIF ;[22]
-
-IF basicns ;[29]
-.printx * Assembling KERMIT-80 for the Northstar Horizon using printer port *
-ENDIF ;basicns [29]
-
-IF comart
-.printx * Assembling KERMIT-80 for Comart Communicator *
-ENDIF ; comart
-
-; the basics...
-IF norths ;The basic Northstar Horizon BIOS does not access ports 2-5
-port0d equ 02h ;Port 0 data (console)
-port0s equ 03h ;Port 0 status
-port1d equ 04h ;Port 1 data (printer)
-port1s equ 05h ;Port 1 status
-
-port2b equ 10h ;Port 2 baud
-port2i equ 11h ;Port 2 interrupt mask
-port2d equ 12h ;Port 2 data
-port2s equ 13h ;Port 2 status
-
-port3b equ 14h ;Port 3 baud
-port3i equ 15h ;Port 3 interrupt mask
-port3d equ 16h ;Port 3 data
-port3s equ 17h ;Port 3 status
-
-port4b equ 18h ;Port 4 baud
-port4i equ 19h ;Port 4 interrupt mask
-port4d equ 1Ah ;Port 4 data
-port4s equ 1Bh ;Port 4 status
-
-port5b equ 1Ch ;Port 5 baud
-port5i equ 1Dh ;Port 5 interrupt mask
-port5d equ 1Eh ;Port 5 data
-port5s equ 1Fh ;Port 5 status
-
-NS19K2 EQU 00H ;19.2 kilobaud
-NS9600 EQU 01H ;9600 baud
-NS4800 EQU 02H ;4800 baud
-NS2400 EQU 03H ;2400 baud
-NS1200 EQU 04H ;1200 baud
-NS0600 EQU 05H ; 600 baud
-NS0300 EQU 06H ; 300 baud
-NS0110 EQU 07H ; 110 baud
-;; Set to use port 5 at 1200 baud
-mnport equ port5d ;Data port
-mnprts equ port5s ;Status port
-baudrt equ port5b ;Baud rate port
-baudini equ ns1200 ;Initial baud rate
-output EQU 1 ;Bit of UART status for transmitter ready
-input EQU 2 ;Bit of UART status for receiver ready
-z80 EQU TRUE ;This one's a Z80.
-ENDIF;norths
-
-IF basicns ;[29]
-mnport equ 04h ;printer port data
-mnprts equ 05h ; printer port status
-output equ 1 ;transmitter ready
-input equ 2 ;receiver ready
-z80 equ FALSE ; not important
-ENDIF ;basicns [29]
-
-IF horizon ;[25]
-mnport EQU 004H ;Modem data port
-mnprts EQU 005H ;Modem status port
-output EQU 01H ;Transmitter empty
-input EQU 02H ;Input data available
-TxEmpty EQU 04h ;Transmitter empty
-;Note: Needs terminal definition (vt100, vt52, tvi925, adm3a or crt above)
-z80 EQU TRUE ;This one's a Z80.
-ENDIF;horizon
-
-IF advant ;[22]
-vtval EQU 1 ; we do emulation of VT52s
-slot EQU 1 ;SIO card slot
-mnport EQU (6-slot)*16 ;Modem data port
-mnprts EQU mnport+1 ;Modem status port
-baudrt EQU mnport+8 ;Baud rate register
-output EQU 01H ;Transmitter buffer empty
-input EQU 02H ;Input data available
-TxEmpty EQU 04h ;Transmitter empty flag
-z80 EQU TRUE
-ENDIF;[22] advant
-
-IF comart ;[25]
-mnport EQU 002H ;Modem data port
-mnprts EQU 003H ;Modem status port
-output EQU 01H ;Transmitter empty
-input EQU 02H ;Input data available
-TxEmpty EQU 04h ;Transmitter empty
-;Note: Needs terminal definition (vt100, vt52, tvi925, adm3a or crt above)
-z80 EQU TRUE ;This one's a Z80.
-ENDIF;comart
-
-
-IF advant
-defesc EQU '\'-100O
-ENDIF;advant
-
-;
-; Family is the string used in VERSION to say which of several
-; smaller overlay files are used. These are (will be) derived from
-; the juge CP4SYS.ASM file, in which case we will never get here.
-; Just a Dollar, but put a sting in for a family of machines.
-;
-family: db 'CPXNOR.ASM (4) 16-Jan-1991$' ; Used for family versions....
-
-
-
-sysxin: ; continuation of system dependent initialisation code
-IF advant ;[22]
- mvi a,40h
- out mnprts ; Reset USART
- lxi h,7070h ; Default to 1200 baud
- shld speed ; store current speed
- xchg
- call sysspd ; set default baud rate
- mvi a,4Eh ; Set UART mode to async 16x clock, 8 data
- out mnprts ; bits, no parity, and 1 stop bit
- mvi a,37h ; Set command to Tx enable, DTR on, Rx enable,
- out mnprts ; break off, error reset, and RTS on
-ENDIF;[22] advant
-
-IF norths
- mvi a,baudini ;Get initial speed
- out baudrt
- sta speed ;save for status display
- sta speed+1
-ENDIF;norths
-
-IF comart OR horizon ;[25]
-; The PD8251/PD8251A is reset by three successive 00 Hex or two
-; successive 80 Hex command instructions followed by a software
-; reset command instruction (40 Hex).
- mvi a,80h ; Send UART reset
- out mnprts
- mvi a,80h
- out mnprts
- mvi a,40h
- out mnprts
- mvi a,4Eh ; Set UART mode to async 16x clock, 8 data
- out mnprts ; bits, no parity, and 1 stop bit
- mvi a,37h ; Set command to Tx enable, DTR on, Rx enable,
- out mnprts ; break off, error reset, and RTS on
-ENDIF;comart OR horizon
-
-
- ret ; return from system-dependent routine
-;
-
-;
-; system-dependent termination processing
-; If we've changed anything, this is our last chance to put it back.
-sysexit:
-
- ret
-
-;
-; system-dependent processing for start of CONNECT command
-;
-syscon:
- ret
-
-conmsg: ; Messages printed when entering transparent (CONNECT) mode:
-;
-
-;
-; syscls - system-dependent close routine
-; called when exiting transparent session.
-;
-syscls:
- ret
-;
-
-;
-; sysinh - help for system-dependent special functions.
-; called in response to <escape>?, after listing all the
-; system-independent escape sequences.
-;
-sysinh:
-IF advant OR comart OR horizon ; some more
- lxi d,inhlps ; we got options...
- call prtstr ; print them.
-ENDIF;[22] advant OR comart OR horizon [29]
-
- ret
-
-
-;additional, system-dependent help for transparent mode
-; (two-character escape sequences)
-inhlps:
-
-; [16] [18] have added super brain and Torch to the list of Breaking machines.
-IF advant OR comart OR horizon ; ... some more
- db cr,lf,'B Transmit a BREAK'
-ENDIF;[22] advant OR comart OR horizon
-
- db '$' ;[hh] table terminator
-
-;
-; sysint - system dependent special functions
-; called when transparent escape character has been typed;
-; the second character of the sequence is in A (and in B).
-; returns:
-; non-skip: sequence has been processed
-; skip: sequence was not recognized
-sysint: ani 137O ; convert lower case to upper, for testing...
-IF advant OR comart OR horizon ; [22] [25] ... some more
- cpi 'B' ; send break?
- jz sendbr ; yes, go do it. return nonskip when through.
-ENDIF;advant OR comart OR horizon [32]
-
- jmp rskp ; take skip return - command not recognized.
-
-
-;
-
-IF advant OR comart OR horizon ;[lmj]
-sendbr:
-;
-; Ensure that the transmitter has finished sending buffered chars
-sndbr1: in mnprts ; get UART status
- ani TxEmpty ; everything sent?
- jz sndbr1 ; no, wait a bit more
-;
-; Begin sending a break by setting bit in UART command register
- mvi a,3Fh ; Set TxEna, DTR, RxEna, SBreak, ErrRst, RTS
- out mnprts
-;
-; Wait for 250 milliseconds (using hundredths second delay routine)
- mvi a,25
- call delay
-;
-; Resume normal operation by clearing the SendBreak command bit
- mvi a,37h ;Set TxEna, DTR, RxEna, ErrRst, RTS
- out mnprts
-;
- ret ;done
-ENDIF;advant OR comart OR horizon
-
-;
-
-;
-; sysflt - system-dependent filter
-; called with character in E.
-; if this character should not be printed, return with A = zero.
-; preserves bc, de, hl.
-; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-sysflt:
- mov a,e ; get character for testing
-IF advant ;[22]
- cpi 'D'-100O ;Control-D's reset video
- rnz ; if not control-D, it's ok.
- xra a ; don't allow control-D out.
-ENDIF;[22] advant
- ret
-
-; mdmflt - modem filter [30]
-; called with character to be sent to printer in E
-; with parity set as appropriate.
-; return with accumulator = 0 do do nothing,
-; <> 0 to send char in E.
-mdmflt:
- mov a,e ;[30] get character to test
- ret
-
-
-
-; prtflt - printer filter [30]
-; called with character to be sent to printer in E
-; returns with a = 0 to do nothing
-; a <> 0 to print it.
-;
-; this routine for those printer that automatically insert
-; a lf on cr, or cr for lf. Should this be shifted to
-; the system indep. stuff, in say 4.06?
-prtflt:
- mov a,e ; [30] get character to test
- ret
-
-
-;
-
-;
-; system-dependent processing for BYE command.
-; for apmmdm, heath, and lobo, hang up the phone.
-sysbye:
- ret
-;
-
-; This is the system-dependent command to change the baud rate.
-; DE contains the two-byte value from the baud rate table; this
-; value is also stored in 'speed'.
-sysspd:
-IF norths OR advant ;
- mov a,e ; get the parsed value
- out baudrt ; Tell the baud rate generator.
- ret
-ENDIF;norths OR advant
-
-IF advant ;[22]
-spdtbl: db 6 ; 6 entries
- db 04,'1200$', 70h,70h
- db 04,'2400$', 78h,78h
- db 03,'300$', 40h,40h
- db 04,'4800$', 7Ch,7Ch
- db 03,'600$', 60h,60h
- db 04,'9600$', 7Eh,7Eh
-
-sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$'
-ENDIF;[22] advant
-
-
-IF norths
-spdtbl: db 8 ; 8 entries
- db 3,'110$', 07H,07H
- db 4,'1200$', 04H,04H
- db 5,'19200$', 00H,00H
- db 4,'2400$', 03H,03H
- db 3,'300$', 06H,06H
- db 4,'4800$', 02H,02H
- db 3,'600$', 05H,05H
- db 4,'9600$', 01H,01H
-
-
-sphtbl: db cr,lf
- db ' 110 300 600 12000 2400 4800 9600 19200$'
-ENDIF;norths
-
-; The following conditionals were once a huge if not statement. There
-; wasn't enough room to add the lobo to the list, so it had to be broken
-; into 2, which you can't do with an if not. I redid it as two ifs and
-; applied them to those that wouldn't set baud. [Hal Hostetler]
-IF NOT (advant OR norths)
-spdtbl EQU 0 ;[hh] SET BAUD not supported.
-sphtbl EQU 0 ;[hh] ran out of room above...
-ENDIF ;NOT (advant OR norths)
-;
-;
-
-; This is the system-dependent SET PORT command.
-; HL contains the argument from the command table.
-sysprt:
- ret
-
-prttbl equ 0 ; SET PORT not supported
-prhtbl equ 0
-;
-
-;
-; selmdm - select modem port
-; selcon - select console port
-; selmdm is called before using inpmdm or outmdm;
-; selcon is called before using inpcon or outcon.
-; For iobyt systems, diddle the I/O byte to select console or comm port;
-; For Decision I, switches Multi I/O board to console or modem serial
-; port. [Toad Hall]
-; For the rest, does nothing.
-; preserves bc, de, hl.
-selmdm:
-selcon:
- ret
-;
-
-; Get character from console, or return zero.
-; result is returned in A. destroys bc, de, hl.
-;
-inpcon:
- mvi c,dconio ;Direct console I/O BDOS call.
- mvi e,0FFH ;Input.
- call BDOS
- ret
-;
-
-;
-; Output character in E to the console.
-; destroys bc, de, hl
-;
-outcon:
- mvi c,dconio ;Console output bdos call.
- call bdos ;Output the char to the console.
- ret ;[MF]per David P. Arnot
-;
-
-;
-; outmdm - output a char from E to the modem.
-; the parity bit has been set as necessary.
-; returns nonskip; bc, de, hl preserved.
-outmdm:
- in mnprts ;Get the output done flag.
- ani output ;Is it set?
- jz outmdm ;If not, loop until it is.
- mov a,e
- out mnport ;Output it.
- ret
-;
-
-;
-; get character from modem; return zero if none available.
-; for IOBYT systems, the modem port has already been selected.
-; destroys bc, de, hl.
-inpmdm:
-;Note: modem port should already be selected for mdI. [Toad Hall]
- in mnprts ;Get the port status into A.
- ani input ;See if the input ready bit is on.
- rz ;If not then return.
- in mnport ;If so, get the char.
- ret ; return with character in A
-
-
-;
-; flsmdm - flush comm line.
-; Modem is selected.
-; Currently, just gets characters until none are available.
-
-flsmdm: call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-;
-
-;
-; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not.
-lptstat:
- xra a ; assume it is ok.. this may not be necessary
- ret
-
-;
-; outlpt - output character in E to printer
-; console is selected.
-; preserves de.
-outlpt:
- push d ; save DE in either case
- call prtflt ; go through printer filter [30]
- ana a ; if A = 0 do nothing,
- jz outlp1 ; [30] if a=0 do nothing
- mvi c,lstout
- call bdos ;Char to printer
-outlp1: pop d ; restore saved register pair
- ret
-IF advant ; all others require terminals
-;
-
-;
-; Screen manipulation routines
-; csrpos - move to row B, column C
-;
-; csrpos for terminals that use a leadin sequence followed
-; by (row + 31.) and (column + 31.)
-;
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,h ; get row
- adi (' '-1) ; space is row one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,l ; get column
- adi (' '-1) ; space is column one
- mov e,a
- jmp outcon ; output it and return
-ENDIF ;advant
-
-;
-; delchr - make delete look like a backspace. Unless delete is a printing
-; character, we just need to print a backspace. (we'll output clrspc
-; afterwards)
-; For Kaypro and Vector General, delete puts a blotch on the screen.
-; For Apple and Osborne 1, delete moves but doesn't print.
-delchr:
-IF advant ;[22]
- ret
-ENDIF;advant
-IF NOT (advant );[22]
- mvi e,bs ;get a backspace
- jmp outcon
-ENDIF;NOT (advant) [22]
-
-; erase the character at the current cursor position
-clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the current line
-clrlin: lxi d,eralin
- jmp prtstr
-
-; erase the whole screen, and go home. preserves b (but not c)
-clrtop: lxi d,erascr
- jmp prtstr
-
-
-IF norths
-sysver: db 'Northstar Horizon$'
-ENDIF;norths
-
-IF basicns ;[29]
-sysver: db 'Northstar using printer port$'
-ENDIF ;basicns [29]
-
-IF comart ;[25]
-sysver: db 'Comart Communicator$'
-ENDIF;comart
-
-IF horizon ;[25]
-sysver: db 'Northstar Horizon$'
-ENDIF;horizon
-
-IF advant ;[22]
-sysver: db 'North Star Advantage$'
-outlin: db 04H,cr,lf,tab,'$'
-erascr: db 04H,'$' ;Clear screen and go home.
-eralin: db cr,0EH,'$' ;Clear line.
-curldn: db esc,'=$' ;cursor leadin
-ttab: ;Table start location.
-ta: db 0BH,'$',0,0 ;Cursor up.
-tb: db 0AH,'$',0,0 ;Cursor down.
-tc: db 0CH,'$',0,0 ;Cursor right.
-td: db bs,'$',0,0 ;Cursor left
-te: db 04H,'$',0,0 ;Clear display
-tf: db 12H,'$',0,0 ;Enter Graphics Mode
-tg: db 13H,'$',0,0 ;Exit Graphics mode
-th: db 1EH,'$',0,0 ;Cursor home.
-ti: db 0BH,'$',0,0 ;Reverse linefeed.
-tj: db 0FH,'$',0,0 ;Clear to end of screen.
-tk: db 0EH,'$',0,0 ;Clear to end of line.
-ENDIF;[22] advant
-IF lasm AND (NOT advant)
-LINK CPXVDU.ASM
-ENDIF ;lasm - m80 will INCLUDE CPXVDU.ASM
-
-IF lasm ; here if not a terminal selected and in LASM
-ovlend equ $
- END
-ENDIF ;lasm
+IF NOT LASM
+.printx * CPXNOR.ASM *
+ENDIF ;NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the system-dependent code and data for various
+; NorthStar KERMITs. This has the Family name of CPXNOR.ASM.
+;
+; revision history (last edit first)
+;
+;edit 4, 16-Jan-1991 by MF. Fixed a bug in OUTCON wherein the final RET
+; was missing (bug reported by David P. Arnot of Scottish
+; Agricultural College).
+;edit 3, 12-Oct-1990 by MF. Added a semicolon before the comment
+; beginning "Family is the string so we don't get errors
+; edit 2, 23 July, 1987 by OBSchou to massage file to suit CPXCOM.ASM.
+;
+; edit 1: 1 June, 1986 by OBSchou, Loughborogh University, UK.
+; Hived off northstar and Comart system dependent modules from
+; CPXSYS.ASM. This assembles ok, but I cannot test it. Any comments?
+
+
+IF norths
+.printx * Assembling for NorthStar Horizon with HSIO-4 board *
+ENDIF;norths
+
+IF horizon ;[25]
+.printx * Assembling KERMIT-80 for the NorthStar Horizon *
+ENDIF;horizon
+
+IF advant ;[22]
+.printx * Assembling kermit-80 for North Star Advantage *
+ENDIF ;[22]
+
+IF basicns ;[29]
+.printx * Assembling KERMIT-80 for the Northstar Horizon using printer port *
+ENDIF ;basicns [29]
+
+IF comart
+.printx * Assembling KERMIT-80 for Comart Communicator *
+ENDIF ; comart
+
+; the basics...
+IF norths ;The basic Northstar Horizon BIOS does not access ports 2-5
+port0d equ 02h ;Port 0 data (console)
+port0s equ 03h ;Port 0 status
+port1d equ 04h ;Port 1 data (printer)
+port1s equ 05h ;Port 1 status
+
+port2b equ 10h ;Port 2 baud
+port2i equ 11h ;Port 2 interrupt mask
+port2d equ 12h ;Port 2 data
+port2s equ 13h ;Port 2 status
+
+port3b equ 14h ;Port 3 baud
+port3i equ 15h ;Port 3 interrupt mask
+port3d equ 16h ;Port 3 data
+port3s equ 17h ;Port 3 status
+
+port4b equ 18h ;Port 4 baud
+port4i equ 19h ;Port 4 interrupt mask
+port4d equ 1Ah ;Port 4 data
+port4s equ 1Bh ;Port 4 status
+
+port5b equ 1Ch ;Port 5 baud
+port5i equ 1Dh ;Port 5 interrupt mask
+port5d equ 1Eh ;Port 5 data
+port5s equ 1Fh ;Port 5 status
+
+NS19K2 EQU 00H ;19.2 kilobaud
+NS9600 EQU 01H ;9600 baud
+NS4800 EQU 02H ;4800 baud
+NS2400 EQU 03H ;2400 baud
+NS1200 EQU 04H ;1200 baud
+NS0600 EQU 05H ; 600 baud
+NS0300 EQU 06H ; 300 baud
+NS0110 EQU 07H ; 110 baud
+;; Set to use port 5 at 1200 baud
+mnport equ port5d ;Data port
+mnprts equ port5s ;Status port
+baudrt equ port5b ;Baud rate port
+baudini equ ns1200 ;Initial baud rate
+output EQU 1 ;Bit of UART status for transmitter ready
+input EQU 2 ;Bit of UART status for receiver ready
+z80 EQU TRUE ;This one's a Z80.
+ENDIF;norths
+
+IF basicns ;[29]
+mnport equ 04h ;printer port data
+mnprts equ 05h ; printer port status
+output equ 1 ;transmitter ready
+input equ 2 ;receiver ready
+z80 equ FALSE ; not important
+ENDIF ;basicns [29]
+
+IF horizon ;[25]
+mnport EQU 004H ;Modem data port
+mnprts EQU 005H ;Modem status port
+output EQU 01H ;Transmitter empty
+input EQU 02H ;Input data available
+TxEmpty EQU 04h ;Transmitter empty
+;Note: Needs terminal definition (vt100, vt52, tvi925, adm3a or crt above)
+z80 EQU TRUE ;This one's a Z80.
+ENDIF;horizon
+
+IF advant ;[22]
+vtval EQU 1 ; we do emulation of VT52s
+slot EQU 1 ;SIO card slot
+mnport EQU (6-slot)*16 ;Modem data port
+mnprts EQU mnport+1 ;Modem status port
+baudrt EQU mnport+8 ;Baud rate register
+output EQU 01H ;Transmitter buffer empty
+input EQU 02H ;Input data available
+TxEmpty EQU 04h ;Transmitter empty flag
+z80 EQU TRUE
+ENDIF;[22] advant
+
+IF comart ;[25]
+mnport EQU 002H ;Modem data port
+mnprts EQU 003H ;Modem status port
+output EQU 01H ;Transmitter empty
+input EQU 02H ;Input data available
+TxEmpty EQU 04h ;Transmitter empty
+;Note: Needs terminal definition (vt100, vt52, tvi925, adm3a or crt above)
+z80 EQU TRUE ;This one's a Z80.
+ENDIF;comart
+
+
+IF advant
+defesc EQU '\'-100O
+ENDIF;advant
+
+;
+; Family is the string used in VERSION to say which of several
+; smaller overlay files are used. These are (will be) derived from
+; the juge CP4SYS.ASM file, in which case we will never get here.
+; Just a Dollar, but put a sting in for a family of machines.
+;
+family: db 'CPXNOR.ASM (4) 16-Jan-1991$' ; Used for family versions....
+
+
+
+sysxin: ; continuation of system dependent initialisation code
+IF advant ;[22]
+ mvi a,40h
+ out mnprts ; Reset USART
+ lxi h,7070h ; Default to 1200 baud
+ shld speed ; store current speed
+ xchg
+ call sysspd ; set default baud rate
+ mvi a,4Eh ; Set UART mode to async 16x clock, 8 data
+ out mnprts ; bits, no parity, and 1 stop bit
+ mvi a,37h ; Set command to Tx enable, DTR on, Rx enable,
+ out mnprts ; break off, error reset, and RTS on
+ENDIF;[22] advant
+
+IF norths
+ mvi a,baudini ;Get initial speed
+ out baudrt
+ sta speed ;save for status display
+ sta speed+1
+ENDIF;norths
+
+IF comart OR horizon ;[25]
+; The PD8251/PD8251A is reset by three successive 00 Hex or two
+; successive 80 Hex command instructions followed by a software
+; reset command instruction (40 Hex).
+ mvi a,80h ; Send UART reset
+ out mnprts
+ mvi a,80h
+ out mnprts
+ mvi a,40h
+ out mnprts
+ mvi a,4Eh ; Set UART mode to async 16x clock, 8 data
+ out mnprts ; bits, no parity, and 1 stop bit
+ mvi a,37h ; Set command to Tx enable, DTR on, Rx enable,
+ out mnprts ; break off, error reset, and RTS on
+ENDIF;comart OR horizon
+
+
+ ret ; return from system-dependent routine
+;
+
+;
+; system-dependent termination processing
+; If we've changed anything, this is our last chance to put it back.
+sysexit:
+
+ ret
+
+;
+; system-dependent processing for start of CONNECT command
+;
+syscon:
+ ret
+
+conmsg: ; Messages printed when entering transparent (CONNECT) mode:
+;
+
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+ ret
+;
+
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing all the
+; system-independent escape sequences.
+;
+sysinh:
+IF advant OR comart OR horizon ; some more
+ lxi d,inhlps ; we got options...
+ call prtstr ; print them.
+ENDIF;[22] advant OR comart OR horizon [29]
+
+ ret
+
+
+;additional, system-dependent help for transparent mode
+; (two-character escape sequences)
+inhlps:
+
+; [16] [18] have added super brain and Torch to the list of Breaking machines.
+IF advant OR comart OR horizon ; ... some more
+ db cr,lf,'B Transmit a BREAK'
+ENDIF;[22] advant OR comart OR horizon
+
+ db '$' ;[hh] table terminator
+
+;
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:
+; non-skip: sequence has been processed
+; skip: sequence was not recognized
+sysint: ani 137O ; convert lower case to upper, for testing...
+IF advant OR comart OR horizon ; [22] [25] ... some more
+ cpi 'B' ; send break?
+ jz sendbr ; yes, go do it. return nonskip when through.
+ENDIF;advant OR comart OR horizon [32]
+
+ jmp rskp ; take skip return - command not recognized.
+
+
+;
+
+IF advant OR comart OR horizon ;[lmj]
+sendbr:
+;
+; Ensure that the transmitter has finished sending buffered chars
+sndbr1: in mnprts ; get UART status
+ ani TxEmpty ; everything sent?
+ jz sndbr1 ; no, wait a bit more
+;
+; Begin sending a break by setting bit in UART command register
+ mvi a,3Fh ; Set TxEna, DTR, RxEna, SBreak, ErrRst, RTS
+ out mnprts
+;
+; Wait for 250 milliseconds (using hundredths second delay routine)
+ mvi a,25
+ call delay
+;
+; Resume normal operation by clearing the SendBreak command bit
+ mvi a,37h ;Set TxEna, DTR, RxEna, ErrRst, RTS
+ out mnprts
+;
+ ret ;done
+ENDIF;advant OR comart OR horizon
+
+;
+
+;
+; sysflt - system-dependent filter
+; called with character in E.
+; if this character should not be printed, return with A = zero.
+; preserves bc, de, hl.
+; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
+sysflt:
+ mov a,e ; get character for testing
+IF advant ;[22]
+ cpi 'D'-100O ;Control-D's reset video
+ rnz ; if not control-D, it's ok.
+ xra a ; don't allow control-D out.
+ENDIF;[22] advant
+ ret
+
+; mdmflt - modem filter [30]
+; called with character to be sent to printer in E
+; with parity set as appropriate.
+; return with accumulator = 0 do do nothing,
+; <> 0 to send char in E.
+mdmflt:
+ mov a,e ;[30] get character to test
+ ret
+
+
+
+; prtflt - printer filter [30]
+; called with character to be sent to printer in E
+; returns with a = 0 to do nothing
+; a <> 0 to print it.
+;
+; this routine for those printer that automatically insert
+; a lf on cr, or cr for lf. Should this be shifted to
+; the system indep. stuff, in say 4.06?
+prtflt:
+ mov a,e ; [30] get character to test
+ ret
+
+
+;
+
+;
+; system-dependent processing for BYE command.
+; for apmmdm, heath, and lobo, hang up the phone.
+sysbye:
+ ret
+;
+
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; this
+; value is also stored in 'speed'.
+sysspd:
+IF norths OR advant ;
+ mov a,e ; get the parsed value
+ out baudrt ; Tell the baud rate generator.
+ ret
+ENDIF;norths OR advant
+
+IF advant ;[22]
+spdtbl: db 6 ; 6 entries
+ db 04,'1200$', 70h,70h
+ db 04,'2400$', 78h,78h
+ db 03,'300$', 40h,40h
+ db 04,'4800$', 7Ch,7Ch
+ db 03,'600$', 60h,60h
+ db 04,'9600$', 7Eh,7Eh
+
+sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$'
+ENDIF;[22] advant
+
+
+IF norths
+spdtbl: db 8 ; 8 entries
+ db 3,'110$', 07H,07H
+ db 4,'1200$', 04H,04H
+ db 5,'19200$', 00H,00H
+ db 4,'2400$', 03H,03H
+ db 3,'300$', 06H,06H
+ db 4,'4800$', 02H,02H
+ db 3,'600$', 05H,05H
+ db 4,'9600$', 01H,01H
+
+
+sphtbl: db cr,lf
+ db ' 110 300 600 12000 2400 4800 9600 19200$'
+ENDIF;norths
+
+; The following conditionals were once a huge if not statement. There
+; wasn't enough room to add the lobo to the list, so it had to be broken
+; into 2, which you can't do with an if not. I redid it as two ifs and
+; applied them to those that wouldn't set baud. [Hal Hostetler]
+IF NOT (advant OR norths)
+spdtbl EQU 0 ;[hh] SET BAUD not supported.
+sphtbl EQU 0 ;[hh] ran out of room above...
+ENDIF ;NOT (advant OR norths)
+;
+;
+
+; This is the system-dependent SET PORT command.
+; HL contains the argument from the command table.
+sysprt:
+ ret
+
+prttbl equ 0 ; SET PORT not supported
+prhtbl equ 0
+;
+
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; For iobyt systems, diddle the I/O byte to select console or comm port;
+; For Decision I, switches Multi I/O board to console or modem serial
+; port. [Toad Hall]
+; For the rest, does nothing.
+; preserves bc, de, hl.
+selmdm:
+selcon:
+ ret
+;
+
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+ mvi c,dconio ;Direct console I/O BDOS call.
+ mvi e,0FFH ;Input.
+ call BDOS
+ ret
+;
+
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+ mvi c,dconio ;Console output bdos call.
+ call bdos ;Output the char to the console.
+ ret ;[MF]per David P. Arnot
+;
+
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+outmdm:
+ in mnprts ;Get the output done flag.
+ ani output ;Is it set?
+ jz outmdm ;If not, loop until it is.
+ mov a,e
+ out mnport ;Output it.
+ ret
+;
+
+;
+; get character from modem; return zero if none available.
+; for IOBYT systems, the modem port has already been selected.
+; destroys bc, de, hl.
+inpmdm:
+;Note: modem port should already be selected for mdI. [Toad Hall]
+ in mnprts ;Get the port status into A.
+ ani input ;See if the input ready bit is on.
+ rz ;If not then return.
+ in mnport ;If so, get the char.
+ ret ; return with character in A
+
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+
+flsmdm: call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+;
+
+;
+; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not.
+lptstat:
+ xra a ; assume it is ok.. this may not be necessary
+ ret
+
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+outlpt:
+ push d ; save DE in either case
+ call prtflt ; go through printer filter [30]
+ ana a ; if A = 0 do nothing,
+ jz outlp1 ; [30] if a=0 do nothing
+ mvi c,lstout
+ call bdos ;Char to printer
+outlp1: pop d ; restore saved register pair
+ ret
+IF advant ; all others require terminals
+;
+
+;
+; Screen manipulation routines
+; csrpos - move to row B, column C
+;
+; csrpos for terminals that use a leadin sequence followed
+; by (row + 31.) and (column + 31.)
+;
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; restore coordinates
+ mov a,h ; get row
+ adi (' '-1) ; space is row one
+ mov e,a
+ push h
+ call outcon ; output row
+ pop h
+ mov a,l ; get column
+ adi (' '-1) ; space is column one
+ mov e,a
+ jmp outcon ; output it and return
+ENDIF ;advant
+
+;
+; delchr - make delete look like a backspace. Unless delete is a printing
+; character, we just need to print a backspace. (we'll output clrspc
+; afterwards)
+; For Kaypro and Vector General, delete puts a blotch on the screen.
+; For Apple and Osborne 1, delete moves but doesn't print.
+delchr:
+IF advant ;[22]
+ ret
+ENDIF;advant
+IF NOT (advant );[22]
+ mvi e,bs ;get a backspace
+ jmp outcon
+ENDIF;NOT (advant) [22]
+
+; erase the character at the current cursor position
+clrspc: mvi e,' '
+ call outcon
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the current line
+clrlin: lxi d,eralin
+ jmp prtstr
+
+; erase the whole screen, and go home. preserves b (but not c)
+clrtop: lxi d,erascr
+ jmp prtstr
+
+
+IF norths
+sysver: db 'Northstar Horizon$'
+ENDIF;norths
+
+IF basicns ;[29]
+sysver: db 'Northstar using printer port$'
+ENDIF ;basicns [29]
+
+IF comart ;[25]
+sysver: db 'Comart Communicator$'
+ENDIF;comart
+
+IF horizon ;[25]
+sysver: db 'Northstar Horizon$'
+ENDIF;horizon
+
+IF advant ;[22]
+sysver: db 'North Star Advantage$'
+outlin: db 04H,cr,lf,tab,'$'
+erascr: db 04H,'$' ;Clear screen and go home.
+eralin: db cr,0EH,'$' ;Clear line.
+curldn: db esc,'=$' ;cursor leadin
+ttab: ;Table start location.
+ta: db 0BH,'$',0,0 ;Cursor up.
+tb: db 0AH,'$',0,0 ;Cursor down.
+tc: db 0CH,'$',0,0 ;Cursor right.
+td: db bs,'$',0,0 ;Cursor left
+te: db 04H,'$',0,0 ;Clear display
+tf: db 12H,'$',0,0 ;Enter Graphics Mode
+tg: db 13H,'$',0,0 ;Exit Graphics mode
+th: db 1EH,'$',0,0 ;Cursor home.
+ti: db 0BH,'$',0,0 ;Reverse linefeed.
+tj: db 0FH,'$',0,0 ;Clear to end of screen.
+tk: db 0EH,'$',0,0 ;Clear to end of line.
+ENDIF;[22] advant
+IF lasm AND (NOT advant)
+LINK CPXVDU.ASM
+ENDIF ;lasm - m80 will INCLUDE CPXVDU.ASM
+
+IF lasm ; here if not a terminal selected and in LASM
+ovlend equ $
+ END
+ENDIF ;lasm
diff --git a/cpxpcw.asm b/cpxpcw.asm
index 554fd61..5bb76c1 100644
--- a/cpxpcw.asm
+++ b/cpxpcw.asm
@@ -1,912 +1,912 @@
-IF NOT lasm
-.printx * CPXPCW.ASM *
-ENDIF ;NOT lasm
-;
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.08
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; This file contains the system-dependent code and data for KERMIT
-; on the Amstrad range of personal computers.
-;
-;
-; Revision history:
-;
-;edit 9, 22-Jan-1991 by MF. Added "sysinit" code at "init04" from Kermit
-; version 4.08 which had been left out of version 4.09 to reserve
-; space for the Amstrad's I/O buffers. Amstrad Kermit now stores
-; files correctly (version 4.09 had garbled files). Again,
-; this fix comes from Mr. D. P. Arnot of the Scottish Agricultural
-; College in the UK.
-;edit 8, 16-Jan-1991 by MF. Added a "bs" left out of "delstr" per
-; instruction from David P. Arnot of Scottish Agricultural
-; College, Auchincruive, Ayr, UK.
-; E-mail: <D.P.Arnot@edinburgh.ac.uk>
-; edit 7, 22 July 1987 by OBSchou to massage code to fit with CPXCOM.ASM
-; Had to rename bcnout to bcnot as the former label clashed with
-; one of the same name in CPXCOM.ASM. Sorry, folks.
-;
-; edit 6, 14th July, 1987 by OBSchou for Phillip Wade, Hull University
-; Computer Centre. Change to delchr routine for PCW machines,
-; as character 127 decimal is a printing character on
-; the Amstrad PCW. The routine has been replaced
-; by a bs,space,bs,bs string. (OBS Comment - why a total of THREE bs?)
-;
-; edit 5 9 May 1987 by C.J.MILES@UK.AC.UMRCC
-; Hangup phone and clear screen options added to
-; terminal mode.
-;
-; edit 4 23 March 1987 by C.J.MILES@UK.AC.UMRCC
-; Use direct input drom SIO for CPC machines instead
-; of using BDOS. Improvement reduces time for file
-; transfer to 65% of time used by BDOS method.
-; Add reverse Prestel baud rate.
-;
-; edit 3 20 March 1987 by Chris Miles (C.J.MILES@UK.AC.UMRCC)
-; (Greater Manchester Archaeological Unit, Manchester Univ.).
-; Added support for Amstrad CPC CP/M Plus machines,
-; Added 31250 baud rate option,
-; Bug fixed in sending BREAK,
-; Bug fixed in 1200/75 baud setup
-; Machine and CP/M version checks added.
-;
-; edit 2 11 Febuary, 1987 by OBSchou for Ian Young.
-; Changes to the send break routine to change two lines of code from
-; ori 018h ; send break, Tx enable
-; and ori 0008h ; Tx enable
-;
-; to ori 01ah ; send break, Tx enable, RTS
-; and ori 00ah ; Tx enable, RTS
-;
-; This is a bug fix to hopefully keep RTS actve during breaks.
-;
-; [Ed. (OBSchou) 21/1/87.
-; This file linked FROM cpxsys.asm, so do NOT rename this
-; file. The diffculty of needing a HUGE CPXSYS.ASM file on your floppy
-; only to act as a switcher remains, but hopefully will be better in
-; the future. If you ARE stuck, then rename this CPXSYS.ASM but add the
-; label SYSEDT: to the FAMILY label. A bit messy.]
-;
-;
-; The "author" of this system-dependent file is:
-;
-; Ian A. Young
-; Lattice Logic Ltd
-; 9 Wemyss Place
-; Edinburgh
-;
-; Some other addresses:
-;
-; ian@latlog.uucp
-; ...seismo!mcvax!ukc!latlog!ian
-; or c/o OBSchou@uk.ac.lut.multics
-;
-; ... although much of the code concerned was written by others.
-;
-
-
-; Keep module name, edit number, and last revision date in memory.
-
-;sysedt: db 'CPXSYS.ASM (36) 20-Mar-87$'
-family: db 'CPXPCW.ASM (9) 22-Jan-1991$'
-
-
-;
-; Assembly-time message announcing which version we are building
-;
-
-IF pcw
-.printx * Assembling Amstrad PCW Kermit-80 *
-ENDIF
-
-IF cpc
-.printx * Assembling Amstrad CPC Kermit-80 *
-ENDIF
-
-;
-; Miscellany of parameter settings
-;
-z80 EQU TRUE ; all Amstrads have a Z80.
-defesc EQU '\'-100O ; The default escape character.
-vtval EQU 0 ; we don't need VT52 emulation
-
-;
-; Amstrad CPC machines use 16 bit I/O address decoding and therefore
-; the Z80 instructions OUT (C),A and IN A,(C) must be defined.
-;
-outc EQU 79edh ; IN A,(C)
-inpc EQU 78edh ; OUT (C),A
-
-;
-; hardware information
-;
-; There is a Z80-DART (Mostek/SGS 8470) at I/O addresses E0..E3 (PCW)
-; and FADC..FADD (CPC), and a 8253 programmable divider running it at
-; E4..E7 (PCW) and FBDC..FBDF (CPC)
-;
-
-input EQU 01h ; input data available
-output EQU 04h ; output buffer ready
-
-IF pcw
-mnport EQU 0E0h ; data register for SIO
-mnprts EQU 0E1h ; control register for SIO
-ctc0 EQU 0E4h ; 8253 load counter 0
-ctc1 EQU 0E5h ; 8253 load counter 1
-ctcmod EQU 0E7h ; 8253 write mode word
-ENDIF
-
-IF cpc
-mnport EQU 0FADCh ; data register for SIO
-mnprts EQU 0FADDh ; control register for SIO
-ctc0 EQU 0FBDCh ; 8253 load counter 0
-ctc1 EQU 0FBDDh ; 8253 load counter 1
-ctcmod EQU 0FBDFh ; 8253 write mode word
-ENDIF
-
-;
-; SIO input buffering
-;
-siosz EQU 4096 ; size of SIO input buffer
-siomsk EQU 4095 ; mask for wrapping buffer round
-
-;
-; Extended BIOS jump-block addresses; reached through USERF
-;
-sainit EQU 00B6h ; initialise SIO
-sabaud EQU 00B9h ; set baud rate
-saparm EQU 00BCh ; fetch SIO parameters
-teask EQU 00BFh ; find out cursor position
-cdvers EQU 00E3h ; get version numbers
-cdinfo EQU 00E6h ; get BIOS system information
-
-;
-; System-dependent initialization
-; Called once at program start.
-sysxin: ; continuation of system initialzation
-;
-; check for correct CP/M version
-;
- mvi c,12 ; get CP/M version BDOS call
- call bdos
- mov a,l ; check if CP/M Plus
- cpi 31h
- jz init08
- lxi d,wrong2 ; point to error message
- call prtstr
- mvi c,0 ; warm boot
- call bdos
-;
-init08: ;[OBS] Moved the Cinfigured for message out as
- ;[OBS] it is in CPXCOM.ASM
-;
-; get addresses of BIOS routines
-;
-; BIOS USERF is used to get to extended BIOS routines
-;
- lhld 1 ; warm boot vector
- lxi d,87 ; offset to USERF vector
- dad d ; DE now has USERF vector address
- shld userf+1 ; ready for jumping to...
-;
-; BIOS routines for fast character I/O
-;
- lhld 1 ; warm boot vector (#1)
- lxi d,3
- dad d ; next is #2, CONST
- shld bcnst+1
- dad d ; next is #3, CONIN
- shld bcnin+1
- dad d ; next is #4, CONOUT
- shld bcnot+1 ;[obs] Was bcnout, but this conflicts
- ;[obs] with a label in CPXCOM.ASM
- dad d ; next is #5, LIST
- shld blist+1
- dad d ; next is #6, AUXOUT
- dad d ; next is #7, AUXIN
- shld baxin+1
- lhld 1 ; warm boot vector again
- lxi d,002Ah ; offset to LISTST (#15)
- dad d
- shld lptstat+1
- lhld 1 ; warm boot vector again
- lxi d,0033h ; offset to AUXIST (#18)
- dad d
- shld baxist+1
-;
-; check if running on correct Amstrad
-;
- call userf
- dw cdvers
-IF pcw
- cpi 0
-ENDIF
-IF cpc
- cpi 1
-ENDIF
- jnz init06
- lxi d,wrong1 ; point to error message
- call prtstr
- mvi c,0
- call bdos
-;
-; verify presence of SIO board by asking the BIOS.
-;
-init06: call userf ; C gets 00 if not fitted
- dw cdinfo
- xra a ; a <- 0
- ora c ; zero => no serial port
- jnz init03 ; non-zero => OK
- lxi d,nosio ; snooty message...
- call prtstr
- mvi c,0 ; warm boot out of here
- call bdos
-init03:
-;
-; find initial baud rate and other information
-;
- call userf ; gives B=rx baud, C=tx baud, D=stop bits,
- ; E=parity, H=rx bits, L=tx bits.
- dw saparm ; get SIO parameters
- push h ; save bit settings
- mov a,b ; if TX and RX speeds same, they are OK
- cmp c
- jz init01
- cpi 8 ; rx=1200?
- jnz init02 ; no, can't be Prestel
- mov a,c
- cpi 2 ; tx=75?
- jnz init02 ; no, can't be Prestel
- lxi b,0 ; otherwise 1200/75 comes out as 0s.
-init01: push b ; assign value to SPEED
- pop h
- shld speed
-init02: ; here if we leave it as is
- pop h ; get bit settings
- mov a,l ; no of TX data bits set
- sui 5 ; make into 00, 01, 10, 11.
- rrc
- rrc
- rrc
- sta txbits ; we may need it later
-;
-; set handshake mode: there are two parts to this, interrupts and
-; hardware handshake. The MODE byte used by the firmware expresses
-; this combination as -(int*2 + hand*1). Thus, both options on would
-; be (-3) or 0FDh.
-;
-; Here, we set the interrupt part of the mode on; it helps the BIOS cope.
-; Unfortunately, >sigh<, according to Soft971, this will only work
-; if you have BIOS V1.4 or higher. I have no idea what would happen
-; if we tried random hanshake mode flags with lower versions, so we
-; just skip over if it would be dangerous...
-;
- call userf ; fetch all parameters
- dw saparm
- sta orgmode ; remember original mode for later
-
- call userf ; get BIOS version to B,C
- dw cdvers
- mov a,b ; BIOS major version number (eg 1)
- ora a ; if zero, too low...
- jz init04
- cpi 1 ; if not 1, definitely OK
- jnz init05
- mov a,c ; otherwise, its 1.X; want >= 4
- cpi 4
- jm init04 ; <4 => too low
-
-init05: call userf ; get the original flags back
- dw saparm
- xri 0FFh ; make mode into bit mask
- inr a
- ori 2 ; set interrupt mode
- xri 0FFh ; turn back into mode value
- inr a
- call userf ; feed change back to BIOS
- dw sainit
-init04: ; come here if not setting mode
-
-; Locate large buffers for multi-sector I/O and SIO input buffering.
-; Space above ovlend is available for buffers; we have pretty well the machine
-; to ourselves in an Amstrad PCW because they all gave 61K TPAs. We don't even
-; bother to perform any checking.
-; We don't want to use more than maxsec for disk buffers because
-; if we use too many, the remote end could time out while we're
-; writing to disk. maxsec is system-dependent, but for now we'll just
-; use 8Kbytes. If you get retransmissions and other protocol errors after
-; transferring the first maxsec sectors, lower maxsec.
-;
-maxsec EQU (8*1024)/bufsiz ; 8K / number of bytes per sector
-
- lxi h,ovlend+siosz ; get start of buffer
- shld bufadr ; store in linkage section
- mvi a,maxsec ; get size of buffer, in sectors
- sta bufsec ; store that, too.
-
-
- ret ; return from system-dependent routine
-
-;
-; message complaining about wrong Amstrad machine
-;
-wrong1: db 'Error - This Kermit will only run on the Amstrad '
-IF pcw
- db 'PCW 8256/8512'
-ENDIF
-IF cpc
- db 'CPC 464/664/6128'
-ENDIF
- db cr,lf,'$'
-;
-; message complaining about version of CP/M being used
-;
-wrong2: db 'Error - Incorrect CP/M version, needs CP/M 3.x'
- db cr,lf,'$'
-;
-; message complaining of no SIO board
-;
-nosio: db 'Error - No SIO option fitted to this machine'
- db cr, lf, '$'
-
-;
-; jumps to BIOS character I/O routines.
-; Addresses filled in by initialisation code above.
-;
-bcnst: jmp $-$ ; console status
-bcnin: jmp $-$ ; console input
-bcnot: jmp $-$ ; console output [obs - was bcnout]
-blist: jmp $-$ ; printer output
-baxin: jmp $-$ ; aux port input
-baxist: jmp $-$ ; aux port status
-lptstat:jmp $-$ ; printer status
-
-;
-; Other BIOS routines
-;
-userf: jmp $-$ ; call extended BIOS function
-
-;
-; saved value of some original parameters
-;
-orgmode:ds 1
-txbits: ds 1
-
-;
-; system-dependent termination processing
-; If we've changed anything, this is our last chance to put it back.
-sysexit:
- call userf ; fetch firmware parameters
- dw saparm
- lda orgmode ; replace with original mode
- call userf ; inform BIOS
- dw sainit
- ret
-
-;
-; system-dependent processing for start of CONNECT command
-;
-syscon:
- lxi d,conmsg ; how to get escape char message
- call prtstr
- ret
-
-conmsg: ; Messages printed when entering transparent (CONNECT) mode:
-IF pcw
- db '(Use boxed minus key next to space bar to generate a Control-\)'
-ENDIF
- db cr,lf,'$'
-
-;
-; syscls - system-dependent close routine
-; called when exiting transparent session.
-;
-syscls:
- ret
-
-;
-; sysinh - help for system-dependent special functions.
-; called in response to <escape>?, after listing all the
-; system-independent escape sequences.
-;
-sysinh:
- lxi d,inhlps ; we got options...
- call prtstr ; print them.
- ret
-
-;
-; additional, system-dependent help for transparent mode
-; (two-character escape sequences)
-;
-inhlps:
- db cr,lf,'B Transmit a BREAK'
- db cr,lf,'H Hangup using DTR'
- db cr,lf,'W Wipe screen clear'
- db '$' ;[hh] table terminator
-
-;
-; sysint - system dependent special functions
-; called when transparent escape character has been typed;
-; the second character of the sequence is in A (and in B).
-; returns:
-; non-skip: sequence has been processed
-; skip : sequence was not recognized
-;
-sysint: ani 137O ; convert lower case to upper, for testing...
- cpi 'B' ; send break ?
- jz sendbr ; yes, go do it. return nonskip when through.
- cpi 'H' ; hang up ?
- jz hangup
- cpi 'W' ; clear screen ?
- jz clrtop
- jmp rskp ; take skip return - command not recognized.
-
-;
-; Hangup (drop DTR) and Break send routine
-;
-
-hangup:
- mvi d,0ah ; set up hangup bit mask
- mvi e,255 ; time for hangup is 2 1/2 secs
- jmp setbit ; skip Tx empty test
-
-sendbr:
- mvi d,9ah ; set up break bit mask
- mvi e,30 ; time for break is 300 ms
-
-sndbr1: mvi a,1 ; select Read Register 1
-
-IF pcw ; allow 8 bit I/O instructions
- out mnprts
- in mnprts ; read the contents
-ENDIF
-
-IF cpc ; use 16 bit I/O instructions
- lxi b,mnprts
- dw outc ; OUT (C),A
- dw inpc ; IN A,(C)
-ENDIF
-
- ani 1 ; test "all done" flag
- jz sndbr1 ; loop until it's nonzero.
-;
-; Next, set the break or hangup bit on the SIO.
-;
-setbit:
- mvi a,5 ; select Write Register 5
-IF pcw
- out mnprts
-ENDIF
-IF cpc
- dw outc ; OUT (C),A
-ENDIF
- lda txbits ; get txbits (already in correct bit positions)
- ora d ; send break, Tx Enable, RTS
-IF pcw
- out mnprts
-ENDIF
-IF cpc
- dw outc ; OUT (C),A
-ENDIF
-
-;
-; Now, delay for duration of hangup or break
-;
- mov a,e ; delay count
- call delay
-;
-; Time's up. Put transmitter back in normal state and return.
-;
- mvi a,5 ; select Write Register 5
-IF pcw
- out mnprts
-ENDIF
-IF cpc
- lxi b,mnprts
- dw outc ; OUT (C),A
-ENDIF
- lda txbits ; get txbits again
- ori 8ah ; Reset break, Tx Enable, RTS
-IF pcw
- out mnprts
-ENDIF
-IF cpc
- dw outc ; OUT (C),A
-ENDIF
- ret ; done.
-
-;
-; sysflt - system-dependent filter
-; called with character in E.
-; if this character should not be printed, return with A = zero.
-; preserves bc, de, hl.
-; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-;
-sysflt:
- mov a,e ; get character for testing
- ret
-;
-; system-dependent processing for BYE command.
-;
-sysbye:
- ret
-
-;
-; This is the system-dependent command to change the baud rate.
-; DE contains the two-byte value from the baud rate table; this
-; value is also stored in 'speed'.
-;
-sysspd:
- push d ; move to HL for firmware
- pop h
- mov a,h ; if h=0 then Prestel rates
- ora a
- jnz spd01 ; if not 1200/75 then skip
- lxi h,0802H ; else set 1200/75 into HL
- jmp spd03 ; jump to normal setup
-
-spd01: cpi 11h ; if h=11h then reverse Prestel
- jnz spd02 ; if not 75/1200 then skip
- lxi h,0208h ; else set 75/1200 into HL
- jmp spd03 ; jump to normal setup
-
-spd02: cpi 10h ; if h=10h then 31250 baud
- jnz spd03 ; if not 31250 then skip to normal setup
- mvi a,36h ; set 8253 for mode 2 binary count
- lxi b,ctcmod ; output to CTC mode register
- dw outc
- lxi b,ctc0 ; select transmit clock
- mov a,4 ; timer value for 31250 (04h)
- dw outc
- mov a,0 ; timer value for 31250 (04h)
- dw outc
- lxi b,ctc0 ; select receive clock
- mov a,4 ; timer value for 31250 (04h)
- dw outc
- mov a,0 ; timer value for 31250 (04h)
- dw outc
- ret
-
-spd03: call userf ; set whatever we have now...
- dw sabaud ; using BIOS routine
- ret
-
-;
-; Speed tables
-; (Note that speed tables MUST be in alphabetical order for later
-; lookup procedures, and must begin with a value showing the total
-; number of entries. The speed help tables are just for us poor
-; humans.
-;
-; db string length,string,divisor (2 identical bytes or 1 word)
-;
-spdtbl: db 12h ;18 entries
- db 03h,'110$', 03h,03h
- db 04h,'1200$', 08h,08h
- db 07h,'1200/75$', 00h,00h ; real values faked up when required
- db 05h,'134.5$', 04h,04h
- db 03h,'150$', 05h,05h
- db 04h,'1800$', 09h,09h
- db 05h,'19200$', 0fh,0fh
- db 04h,'2400$', 0ah,0ah
- db 03h,'300$', 06h,06h
- db 05h,'31250$',10h,10h ; flag to direct setup routine
- db 04h,'3600$', 0bh,0bh
- db 04h,'4800$', 0ch,0ch
- db 02h,'50$', 01h,01h
- db 03h,'600$', 07h,07h
- db 04h,'7200$', 0dh,0dh
- db 02h,'75$', 02h,02h
- db 07h,'75/1200$',11h,11h ; real values faked up when required
- db 04h,'9600$', 0eh,0eh
-
-sphtbl: db cr,lf,lf
- db 'Normal rates: 50 75 110 134.5 150 300 600'
- db cr,lf
- db ' 1200 1800 2400 3600 4800 7200 9600 19200'
- db cr,lf,lf
- db 'High speed : 31250 (only between Amstrads)'
- db cr,lf,lf
- db 'Split rates : 1200/75 (Rx=1200, Tx= 75)'
- db cr,lf
- db ' 75/1200 (Rx= 75, Tx=1200)'
- db cr,lf,'$'
-
-;
-; This is the system-dependent SET PORT command.
-; HL contains the argument from the command table.
-;
-sysprt:
- ret
-
-prttbl equ 0 ; SET PORT is not supported
-prhtbl equ 0
-
-;
-; selmdm - select modem port
-; selcon - select console port
-; selmdm is called before using inpmdm or outmdm;
-; selcon is called before using inpcon or outcon.
-; preserves bc, de, hl.
-;
-selmdm:
-selcon:
- ret
-
-;
-; Get character from console, or return zero.
-; result is returned in A. destroys bc, de, hl.
-;
-inpcon:
- call bcnst ; get console status
- ora a ; anything there?
- rz ; no, forget it
- jmp bcnin ; yes, get the character
-
-;
-; Output character in E to the console.
-; destroys bc, de, hl
-;
-outcon:
- mov a,e ; TAB?
- cpi tab
- jz out001
- mov c,e ; set correct arg register
- jmp bcnot ; output to console via BIOS [obs was bcnout]
-
-;
-; perform tab expansion ourselves
-;
-out001: call userf ; get column in L
- dw teask
- mov a,l ; a <- column 0..n
- ani 7 ; column 0..7
- xri 0FFh ; not(col 0..7)
- adi 9 ; a is 8-(colf7)
-out002: ora a ; any left?
- rz ; return if not
- dcr a ; one less now, anyhow
- push psw ; save over BIOS call (just in case)
- mvi c,' ' ; print one space
- call bcnot ;[obs was bcnout]
- call suck ; in case any stuff coming in
- pop psw ; fetch count back
- jmp out002 ; and go round again
-
-;
-; outmdm - output a char from E to the modem.
-; the parity bit has been set as necessary.
-; returns nonskip; bc, de, hl preserved.
-outmdm:
-IF cpc
- push b ; save BC for CPC 16 bit I/O
-ENDIF
-outmd1:
- call xsuck ; keep checking for incoming characters
-IF pcw
- in mnprts ; get the output done flag.
-ENDIF
-IF cpc
- lxi b,mnprts
- dw inpc ; IN A,(C)
-ENDIF
- ani output ; is it set?
- jz outmd1 ; if not, loop until it is.
- mov a,e
-IF pcw
- out mnport ; output it.
-ENDIF
-IF cpc
- lxi b,mnport
- dw outc ; OUT (C),A
- pop b ; restore BC
-ENDIF
- ret
-
-;
-; get character from modem; return zero if none available.
-; destroys bc, de, hl.
-;
-inpmdm:
- call suck ; get any characters pending
- lhld sioct ; count of chars in buffer
- mov a,h ; or together to get result
- ora l
- rz ; not got any, return now
-
- dcx h ; down count
- shld sioct
-
- lhld siord ; read pointer
- mov c,m ; fetch character ** NB TO C FOR NOW **
-
- lxi d,1-ovlend ; bump pointer, subtract base
- dad d
- mov a,h ; mask high byte of offset
- ani siomsk/256
- mov h,a
- lxi d,ovlend ; add in base again
- dad d
- shld siord
-
- mov a,c ; get to proper register
- ret
-
-;
-; flsmdm - flush comm line.
-; Modem is selected.
-; Currently, just gets characters until none are available.
-
-flsmdm: call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-
-;
-; SIO input buffer handling. The buffer pointers are held as pointers into
-; the buffer. The read pointer
-; is to the next unused character, the write pointer to the next unused space.
-;
-siord: dw ovlend ; next char to read
-siowr: dw ovlend ; next char to write
-sioct: dw 0 ; number in buffer
-
-xsuck: push d ; save regs version of suck
- push b
- push h
- call suck
- pop h
- pop b
- pop d
- ret
-
-;
-; suck
-;
-; this routine is called whenever it would be possible that some
-; characters might be available in the SIO device; they are all
-; transferred (there may be up to 4 pending) to the buffer.
-;
-; all registers are destroyed
-;
-suck:
-IF pcw
- call baxist ; check input status via BDOS
- ora a ; check if zero
-ENDIF
-IF cpc
- lxi b,mnprts ; get input status directly
- dw inpc ; IN A,(C)
- ani input ; mask for Rx ready
-ENDIF
- rz ; return if no
-
-IF pcw
- call baxin ; fetch character via BDOS
-ENDIF
-IF cpc
- lxi b,mnport ; fetch character directly from SIO
- dw inpc ; IN A,(C)
-ENDIF
-
- lhld siowr ; write pointer
- mov m,a ; put character
-
- lxi d,1-ovlend ; take off base, bump pointer
- dad d
- mov a,h ; top byte of offset
- ani siomsk/256 ; masked off
- mov h,a
- lxi d,ovlend ; add on base again
- dad d
- shld siowr ; replace pointer
-
- lhld sioct ; bump count in buffer
- inx h
- shld sioct
-
- jmp suck ; go round in case any more
-
-;
-; outlpt - output character in E to printer
-; console is selected.
-; preserves de.
-outlpt:
- push d ; save DE in either case
- mov c,e ; correct arg register
- call blist
- pop d ; restore saved register pair
- ret
-
-;
-; Screen manipulation routines
-; csrpos - move to row B, column C
-;
-; csrpos for terminals that use a leadin sequence followed
-; by (row + 31.) and (column + 31.)
-; or (row) and (column)
-;
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,h ; get row
- adi (' '-1) ; space is row one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,l ; get column
- adi (' '-1) ; space is column one
- mov e,a
- jmp outcon ; output it and return
-
-;
-; delchr - make delete look like a backspace. Unless delete is a printing
-; character, we just need to print a backspace. (we'll output clrspc
-; afterwards)
-; For Kaypro and Vector General, delete puts a blotch on the screen.
-; For Apple and Osborne 1, delete moves but doesn't print.
-delchr:
-IF pcw ;[6] OBS for Phillip Wade
- lxi d,delstr ;[5] send a string rather than a single character
- call prtstr
-
-delstr: db bs,' ',bs,'$' ;[OBS] Was bs,space,bs,bs
-ENDIF ;pcw
-
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the character at the current cursor position
-clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the current line
-clrlin: lxi d,eralin
- jmp prtstr
-
-; erase the whole screen, and go home. preserves b (but not c)
-clrtop: lxi d,erascr
- jmp prtstr
-
-
-IF pcw
-sysver: db 'Amstrad PCW with SIO option$'
-ENDIF
-IF cpc
-sysver: db 'Amstrad CPC with CP/M Plus$'
-ENDIF
-
-outlin: db esc,'H',esc,'J',cr,lf,' $'
-
-erascr: db esc,'H',esc,'J$' ;Clear screen and go home.
-eralin: db cr,esc,'K$' ;Clear line.
-curldn: db esc,'Y$' ;cursor leadin
-ttab: ;Table start location.
-ta: db esc,'A$',0 ;Cursor up.
-tb: db esc,'B$',0 ;Cursor down.
-tc: db esc,'C$',0 ;Cursor right.
-td: db esc,'D$',0 ;Cursor left
-te: db esc,'E$',0 ;Clear display
-tf: db '$',0,0,0 ;Enter Graphics Mode
-tg: db '$',0,0,0 ;Exit Graphics mode
-th: db esc,'H$',0 ;Cursor home.
-ti: db esc,'I$',0 ;Reverse linefeed.
-tj: db esc,'J$',0 ;Clear to end of screen.
-tk: db esc,'K$',0 ;Clear to end of line.
-
-ovlend equ $ ; End of overlay
-
- END
+IF NOT lasm
+.printx * CPXPCW.ASM *
+ENDIF ;NOT lasm
+;
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.08
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; This file contains the system-dependent code and data for KERMIT
+; on the Amstrad range of personal computers.
+;
+;
+; Revision history:
+;
+;edit 9, 22-Jan-1991 by MF. Added "sysinit" code at "init04" from Kermit
+; version 4.08 which had been left out of version 4.09 to reserve
+; space for the Amstrad's I/O buffers. Amstrad Kermit now stores
+; files correctly (version 4.09 had garbled files). Again,
+; this fix comes from Mr. D. P. Arnot of the Scottish Agricultural
+; College in the UK.
+;edit 8, 16-Jan-1991 by MF. Added a "bs" left out of "delstr" per
+; instruction from David P. Arnot of Scottish Agricultural
+; College, Auchincruive, Ayr, UK.
+; E-mail: <D.P.Arnot@edinburgh.ac.uk>
+; edit 7, 22 July 1987 by OBSchou to massage code to fit with CPXCOM.ASM
+; Had to rename bcnout to bcnot as the former label clashed with
+; one of the same name in CPXCOM.ASM. Sorry, folks.
+;
+; edit 6, 14th July, 1987 by OBSchou for Phillip Wade, Hull University
+; Computer Centre. Change to delchr routine for PCW machines,
+; as character 127 decimal is a printing character on
+; the Amstrad PCW. The routine has been replaced
+; by a bs,space,bs,bs string. (OBS Comment - why a total of THREE bs?)
+;
+; edit 5 9 May 1987 by C.J.MILES@UK.AC.UMRCC
+; Hangup phone and clear screen options added to
+; terminal mode.
+;
+; edit 4 23 March 1987 by C.J.MILES@UK.AC.UMRCC
+; Use direct input drom SIO for CPC machines instead
+; of using BDOS. Improvement reduces time for file
+; transfer to 65% of time used by BDOS method.
+; Add reverse Prestel baud rate.
+;
+; edit 3 20 March 1987 by Chris Miles (C.J.MILES@UK.AC.UMRCC)
+; (Greater Manchester Archaeological Unit, Manchester Univ.).
+; Added support for Amstrad CPC CP/M Plus machines,
+; Added 31250 baud rate option,
+; Bug fixed in sending BREAK,
+; Bug fixed in 1200/75 baud setup
+; Machine and CP/M version checks added.
+;
+; edit 2 11 Febuary, 1987 by OBSchou for Ian Young.
+; Changes to the send break routine to change two lines of code from
+; ori 018h ; send break, Tx enable
+; and ori 0008h ; Tx enable
+;
+; to ori 01ah ; send break, Tx enable, RTS
+; and ori 00ah ; Tx enable, RTS
+;
+; This is a bug fix to hopefully keep RTS actve during breaks.
+;
+; [Ed. (OBSchou) 21/1/87.
+; This file linked FROM cpxsys.asm, so do NOT rename this
+; file. The diffculty of needing a HUGE CPXSYS.ASM file on your floppy
+; only to act as a switcher remains, but hopefully will be better in
+; the future. If you ARE stuck, then rename this CPXSYS.ASM but add the
+; label SYSEDT: to the FAMILY label. A bit messy.]
+;
+;
+; The "author" of this system-dependent file is:
+;
+; Ian A. Young
+; Lattice Logic Ltd
+; 9 Wemyss Place
+; Edinburgh
+;
+; Some other addresses:
+;
+; ian@latlog.uucp
+; ...seismo!mcvax!ukc!latlog!ian
+; or c/o OBSchou@uk.ac.lut.multics
+;
+; ... although much of the code concerned was written by others.
+;
+
+
+; Keep module name, edit number, and last revision date in memory.
+
+;sysedt: db 'CPXSYS.ASM (36) 20-Mar-87$'
+family: db 'CPXPCW.ASM (9) 22-Jan-1991$'
+
+
+;
+; Assembly-time message announcing which version we are building
+;
+
+IF pcw
+.printx * Assembling Amstrad PCW Kermit-80 *
+ENDIF
+
+IF cpc
+.printx * Assembling Amstrad CPC Kermit-80 *
+ENDIF
+
+;
+; Miscellany of parameter settings
+;
+z80 EQU TRUE ; all Amstrads have a Z80.
+defesc EQU '\'-100O ; The default escape character.
+vtval EQU 0 ; we don't need VT52 emulation
+
+;
+; Amstrad CPC machines use 16 bit I/O address decoding and therefore
+; the Z80 instructions OUT (C),A and IN A,(C) must be defined.
+;
+outc EQU 79edh ; IN A,(C)
+inpc EQU 78edh ; OUT (C),A
+
+;
+; hardware information
+;
+; There is a Z80-DART (Mostek/SGS 8470) at I/O addresses E0..E3 (PCW)
+; and FADC..FADD (CPC), and a 8253 programmable divider running it at
+; E4..E7 (PCW) and FBDC..FBDF (CPC)
+;
+
+input EQU 01h ; input data available
+output EQU 04h ; output buffer ready
+
+IF pcw
+mnport EQU 0E0h ; data register for SIO
+mnprts EQU 0E1h ; control register for SIO
+ctc0 EQU 0E4h ; 8253 load counter 0
+ctc1 EQU 0E5h ; 8253 load counter 1
+ctcmod EQU 0E7h ; 8253 write mode word
+ENDIF
+
+IF cpc
+mnport EQU 0FADCh ; data register for SIO
+mnprts EQU 0FADDh ; control register for SIO
+ctc0 EQU 0FBDCh ; 8253 load counter 0
+ctc1 EQU 0FBDDh ; 8253 load counter 1
+ctcmod EQU 0FBDFh ; 8253 write mode word
+ENDIF
+
+;
+; SIO input buffering
+;
+siosz EQU 4096 ; size of SIO input buffer
+siomsk EQU 4095 ; mask for wrapping buffer round
+
+;
+; Extended BIOS jump-block addresses; reached through USERF
+;
+sainit EQU 00B6h ; initialise SIO
+sabaud EQU 00B9h ; set baud rate
+saparm EQU 00BCh ; fetch SIO parameters
+teask EQU 00BFh ; find out cursor position
+cdvers EQU 00E3h ; get version numbers
+cdinfo EQU 00E6h ; get BIOS system information
+
+;
+; System-dependent initialization
+; Called once at program start.
+sysxin: ; continuation of system initialzation
+;
+; check for correct CP/M version
+;
+ mvi c,12 ; get CP/M version BDOS call
+ call bdos
+ mov a,l ; check if CP/M Plus
+ cpi 31h
+ jz init08
+ lxi d,wrong2 ; point to error message
+ call prtstr
+ mvi c,0 ; warm boot
+ call bdos
+;
+init08: ;[OBS] Moved the Cinfigured for message out as
+ ;[OBS] it is in CPXCOM.ASM
+;
+; get addresses of BIOS routines
+;
+; BIOS USERF is used to get to extended BIOS routines
+;
+ lhld 1 ; warm boot vector
+ lxi d,87 ; offset to USERF vector
+ dad d ; DE now has USERF vector address
+ shld userf+1 ; ready for jumping to...
+;
+; BIOS routines for fast character I/O
+;
+ lhld 1 ; warm boot vector (#1)
+ lxi d,3
+ dad d ; next is #2, CONST
+ shld bcnst+1
+ dad d ; next is #3, CONIN
+ shld bcnin+1
+ dad d ; next is #4, CONOUT
+ shld bcnot+1 ;[obs] Was bcnout, but this conflicts
+ ;[obs] with a label in CPXCOM.ASM
+ dad d ; next is #5, LIST
+ shld blist+1
+ dad d ; next is #6, AUXOUT
+ dad d ; next is #7, AUXIN
+ shld baxin+1
+ lhld 1 ; warm boot vector again
+ lxi d,002Ah ; offset to LISTST (#15)
+ dad d
+ shld lptstat+1
+ lhld 1 ; warm boot vector again
+ lxi d,0033h ; offset to AUXIST (#18)
+ dad d
+ shld baxist+1
+;
+; check if running on correct Amstrad
+;
+ call userf
+ dw cdvers
+IF pcw
+ cpi 0
+ENDIF
+IF cpc
+ cpi 1
+ENDIF
+ jnz init06
+ lxi d,wrong1 ; point to error message
+ call prtstr
+ mvi c,0
+ call bdos
+;
+; verify presence of SIO board by asking the BIOS.
+;
+init06: call userf ; C gets 00 if not fitted
+ dw cdinfo
+ xra a ; a <- 0
+ ora c ; zero => no serial port
+ jnz init03 ; non-zero => OK
+ lxi d,nosio ; snooty message...
+ call prtstr
+ mvi c,0 ; warm boot out of here
+ call bdos
+init03:
+;
+; find initial baud rate and other information
+;
+ call userf ; gives B=rx baud, C=tx baud, D=stop bits,
+ ; E=parity, H=rx bits, L=tx bits.
+ dw saparm ; get SIO parameters
+ push h ; save bit settings
+ mov a,b ; if TX and RX speeds same, they are OK
+ cmp c
+ jz init01
+ cpi 8 ; rx=1200?
+ jnz init02 ; no, can't be Prestel
+ mov a,c
+ cpi 2 ; tx=75?
+ jnz init02 ; no, can't be Prestel
+ lxi b,0 ; otherwise 1200/75 comes out as 0s.
+init01: push b ; assign value to SPEED
+ pop h
+ shld speed
+init02: ; here if we leave it as is
+ pop h ; get bit settings
+ mov a,l ; no of TX data bits set
+ sui 5 ; make into 00, 01, 10, 11.
+ rrc
+ rrc
+ rrc
+ sta txbits ; we may need it later
+;
+; set handshake mode: there are two parts to this, interrupts and
+; hardware handshake. The MODE byte used by the firmware expresses
+; this combination as -(int*2 + hand*1). Thus, both options on would
+; be (-3) or 0FDh.
+;
+; Here, we set the interrupt part of the mode on; it helps the BIOS cope.
+; Unfortunately, >sigh<, according to Soft971, this will only work
+; if you have BIOS V1.4 or higher. I have no idea what would happen
+; if we tried random hanshake mode flags with lower versions, so we
+; just skip over if it would be dangerous...
+;
+ call userf ; fetch all parameters
+ dw saparm
+ sta orgmode ; remember original mode for later
+
+ call userf ; get BIOS version to B,C
+ dw cdvers
+ mov a,b ; BIOS major version number (eg 1)
+ ora a ; if zero, too low...
+ jz init04
+ cpi 1 ; if not 1, definitely OK
+ jnz init05
+ mov a,c ; otherwise, its 1.X; want >= 4
+ cpi 4
+ jm init04 ; <4 => too low
+
+init05: call userf ; get the original flags back
+ dw saparm
+ xri 0FFh ; make mode into bit mask
+ inr a
+ ori 2 ; set interrupt mode
+ xri 0FFh ; turn back into mode value
+ inr a
+ call userf ; feed change back to BIOS
+ dw sainit
+init04: ; come here if not setting mode
+
+; Locate large buffers for multi-sector I/O and SIO input buffering.
+; Space above ovlend is available for buffers; we have pretty well the machine
+; to ourselves in an Amstrad PCW because they all gave 61K TPAs. We don't even
+; bother to perform any checking.
+; We don't want to use more than maxsec for disk buffers because
+; if we use too many, the remote end could time out while we're
+; writing to disk. maxsec is system-dependent, but for now we'll just
+; use 8Kbytes. If you get retransmissions and other protocol errors after
+; transferring the first maxsec sectors, lower maxsec.
+;
+maxsec EQU (8*1024)/bufsiz ; 8K / number of bytes per sector
+
+ lxi h,ovlend+siosz ; get start of buffer
+ shld bufadr ; store in linkage section
+ mvi a,maxsec ; get size of buffer, in sectors
+ sta bufsec ; store that, too.
+
+
+ ret ; return from system-dependent routine
+
+;
+; message complaining about wrong Amstrad machine
+;
+wrong1: db 'Error - This Kermit will only run on the Amstrad '
+IF pcw
+ db 'PCW 8256/8512'
+ENDIF
+IF cpc
+ db 'CPC 464/664/6128'
+ENDIF
+ db cr,lf,'$'
+;
+; message complaining about version of CP/M being used
+;
+wrong2: db 'Error - Incorrect CP/M version, needs CP/M 3.x'
+ db cr,lf,'$'
+;
+; message complaining of no SIO board
+;
+nosio: db 'Error - No SIO option fitted to this machine'
+ db cr, lf, '$'
+
+;
+; jumps to BIOS character I/O routines.
+; Addresses filled in by initialisation code above.
+;
+bcnst: jmp $-$ ; console status
+bcnin: jmp $-$ ; console input
+bcnot: jmp $-$ ; console output [obs - was bcnout]
+blist: jmp $-$ ; printer output
+baxin: jmp $-$ ; aux port input
+baxist: jmp $-$ ; aux port status
+lptstat:jmp $-$ ; printer status
+
+;
+; Other BIOS routines
+;
+userf: jmp $-$ ; call extended BIOS function
+
+;
+; saved value of some original parameters
+;
+orgmode:ds 1
+txbits: ds 1
+
+;
+; system-dependent termination processing
+; If we've changed anything, this is our last chance to put it back.
+sysexit:
+ call userf ; fetch firmware parameters
+ dw saparm
+ lda orgmode ; replace with original mode
+ call userf ; inform BIOS
+ dw sainit
+ ret
+
+;
+; system-dependent processing for start of CONNECT command
+;
+syscon:
+ lxi d,conmsg ; how to get escape char message
+ call prtstr
+ ret
+
+conmsg: ; Messages printed when entering transparent (CONNECT) mode:
+IF pcw
+ db '(Use boxed minus key next to space bar to generate a Control-\)'
+ENDIF
+ db cr,lf,'$'
+
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+ ret
+
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing all the
+; system-independent escape sequences.
+;
+sysinh:
+ lxi d,inhlps ; we got options...
+ call prtstr ; print them.
+ ret
+
+;
+; additional, system-dependent help for transparent mode
+; (two-character escape sequences)
+;
+inhlps:
+ db cr,lf,'B Transmit a BREAK'
+ db cr,lf,'H Hangup using DTR'
+ db cr,lf,'W Wipe screen clear'
+ db '$' ;[hh] table terminator
+
+;
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:
+; non-skip: sequence has been processed
+; skip : sequence was not recognized
+;
+sysint: ani 137O ; convert lower case to upper, for testing...
+ cpi 'B' ; send break ?
+ jz sendbr ; yes, go do it. return nonskip when through.
+ cpi 'H' ; hang up ?
+ jz hangup
+ cpi 'W' ; clear screen ?
+ jz clrtop
+ jmp rskp ; take skip return - command not recognized.
+
+;
+; Hangup (drop DTR) and Break send routine
+;
+
+hangup:
+ mvi d,0ah ; set up hangup bit mask
+ mvi e,255 ; time for hangup is 2 1/2 secs
+ jmp setbit ; skip Tx empty test
+
+sendbr:
+ mvi d,9ah ; set up break bit mask
+ mvi e,30 ; time for break is 300 ms
+
+sndbr1: mvi a,1 ; select Read Register 1
+
+IF pcw ; allow 8 bit I/O instructions
+ out mnprts
+ in mnprts ; read the contents
+ENDIF
+
+IF cpc ; use 16 bit I/O instructions
+ lxi b,mnprts
+ dw outc ; OUT (C),A
+ dw inpc ; IN A,(C)
+ENDIF
+
+ ani 1 ; test "all done" flag
+ jz sndbr1 ; loop until it's nonzero.
+;
+; Next, set the break or hangup bit on the SIO.
+;
+setbit:
+ mvi a,5 ; select Write Register 5
+IF pcw
+ out mnprts
+ENDIF
+IF cpc
+ dw outc ; OUT (C),A
+ENDIF
+ lda txbits ; get txbits (already in correct bit positions)
+ ora d ; send break, Tx Enable, RTS
+IF pcw
+ out mnprts
+ENDIF
+IF cpc
+ dw outc ; OUT (C),A
+ENDIF
+
+;
+; Now, delay for duration of hangup or break
+;
+ mov a,e ; delay count
+ call delay
+;
+; Time's up. Put transmitter back in normal state and return.
+;
+ mvi a,5 ; select Write Register 5
+IF pcw
+ out mnprts
+ENDIF
+IF cpc
+ lxi b,mnprts
+ dw outc ; OUT (C),A
+ENDIF
+ lda txbits ; get txbits again
+ ori 8ah ; Reset break, Tx Enable, RTS
+IF pcw
+ out mnprts
+ENDIF
+IF cpc
+ dw outc ; OUT (C),A
+ENDIF
+ ret ; done.
+
+;
+; sysflt - system-dependent filter
+; called with character in E.
+; if this character should not be printed, return with A = zero.
+; preserves bc, de, hl.
+; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
+;
+sysflt:
+ mov a,e ; get character for testing
+ ret
+;
+; system-dependent processing for BYE command.
+;
+sysbye:
+ ret
+
+;
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; this
+; value is also stored in 'speed'.
+;
+sysspd:
+ push d ; move to HL for firmware
+ pop h
+ mov a,h ; if h=0 then Prestel rates
+ ora a
+ jnz spd01 ; if not 1200/75 then skip
+ lxi h,0802H ; else set 1200/75 into HL
+ jmp spd03 ; jump to normal setup
+
+spd01: cpi 11h ; if h=11h then reverse Prestel
+ jnz spd02 ; if not 75/1200 then skip
+ lxi h,0208h ; else set 75/1200 into HL
+ jmp spd03 ; jump to normal setup
+
+spd02: cpi 10h ; if h=10h then 31250 baud
+ jnz spd03 ; if not 31250 then skip to normal setup
+ mvi a,36h ; set 8253 for mode 2 binary count
+ lxi b,ctcmod ; output to CTC mode register
+ dw outc
+ lxi b,ctc0 ; select transmit clock
+ mov a,4 ; timer value for 31250 (04h)
+ dw outc
+ mov a,0 ; timer value for 31250 (04h)
+ dw outc
+ lxi b,ctc0 ; select receive clock
+ mov a,4 ; timer value for 31250 (04h)
+ dw outc
+ mov a,0 ; timer value for 31250 (04h)
+ dw outc
+ ret
+
+spd03: call userf ; set whatever we have now...
+ dw sabaud ; using BIOS routine
+ ret
+
+;
+; Speed tables
+; (Note that speed tables MUST be in alphabetical order for later
+; lookup procedures, and must begin with a value showing the total
+; number of entries. The speed help tables are just for us poor
+; humans.
+;
+; db string length,string,divisor (2 identical bytes or 1 word)
+;
+spdtbl: db 12h ;18 entries
+ db 03h,'110$', 03h,03h
+ db 04h,'1200$', 08h,08h
+ db 07h,'1200/75$', 00h,00h ; real values faked up when required
+ db 05h,'134.5$', 04h,04h
+ db 03h,'150$', 05h,05h
+ db 04h,'1800$', 09h,09h
+ db 05h,'19200$', 0fh,0fh
+ db 04h,'2400$', 0ah,0ah
+ db 03h,'300$', 06h,06h
+ db 05h,'31250$',10h,10h ; flag to direct setup routine
+ db 04h,'3600$', 0bh,0bh
+ db 04h,'4800$', 0ch,0ch
+ db 02h,'50$', 01h,01h
+ db 03h,'600$', 07h,07h
+ db 04h,'7200$', 0dh,0dh
+ db 02h,'75$', 02h,02h
+ db 07h,'75/1200$',11h,11h ; real values faked up when required
+ db 04h,'9600$', 0eh,0eh
+
+sphtbl: db cr,lf,lf
+ db 'Normal rates: 50 75 110 134.5 150 300 600'
+ db cr,lf
+ db ' 1200 1800 2400 3600 4800 7200 9600 19200'
+ db cr,lf,lf
+ db 'High speed : 31250 (only between Amstrads)'
+ db cr,lf,lf
+ db 'Split rates : 1200/75 (Rx=1200, Tx= 75)'
+ db cr,lf
+ db ' 75/1200 (Rx= 75, Tx=1200)'
+ db cr,lf,'$'
+
+;
+; This is the system-dependent SET PORT command.
+; HL contains the argument from the command table.
+;
+sysprt:
+ ret
+
+prttbl equ 0 ; SET PORT is not supported
+prhtbl equ 0
+
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; preserves bc, de, hl.
+;
+selmdm:
+selcon:
+ ret
+
+;
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+ call bcnst ; get console status
+ ora a ; anything there?
+ rz ; no, forget it
+ jmp bcnin ; yes, get the character
+
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+ mov a,e ; TAB?
+ cpi tab
+ jz out001
+ mov c,e ; set correct arg register
+ jmp bcnot ; output to console via BIOS [obs was bcnout]
+
+;
+; perform tab expansion ourselves
+;
+out001: call userf ; get column in L
+ dw teask
+ mov a,l ; a <- column 0..n
+ ani 7 ; column 0..7
+ xri 0FFh ; not(col 0..7)
+ adi 9 ; a is 8-(colf7)
+out002: ora a ; any left?
+ rz ; return if not
+ dcr a ; one less now, anyhow
+ push psw ; save over BIOS call (just in case)
+ mvi c,' ' ; print one space
+ call bcnot ;[obs was bcnout]
+ call suck ; in case any stuff coming in
+ pop psw ; fetch count back
+ jmp out002 ; and go round again
+
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+outmdm:
+IF cpc
+ push b ; save BC for CPC 16 bit I/O
+ENDIF
+outmd1:
+ call xsuck ; keep checking for incoming characters
+IF pcw
+ in mnprts ; get the output done flag.
+ENDIF
+IF cpc
+ lxi b,mnprts
+ dw inpc ; IN A,(C)
+ENDIF
+ ani output ; is it set?
+ jz outmd1 ; if not, loop until it is.
+ mov a,e
+IF pcw
+ out mnport ; output it.
+ENDIF
+IF cpc
+ lxi b,mnport
+ dw outc ; OUT (C),A
+ pop b ; restore BC
+ENDIF
+ ret
+
+;
+; get character from modem; return zero if none available.
+; destroys bc, de, hl.
+;
+inpmdm:
+ call suck ; get any characters pending
+ lhld sioct ; count of chars in buffer
+ mov a,h ; or together to get result
+ ora l
+ rz ; not got any, return now
+
+ dcx h ; down count
+ shld sioct
+
+ lhld siord ; read pointer
+ mov c,m ; fetch character ** NB TO C FOR NOW **
+
+ lxi d,1-ovlend ; bump pointer, subtract base
+ dad d
+ mov a,h ; mask high byte of offset
+ ani siomsk/256
+ mov h,a
+ lxi d,ovlend ; add in base again
+ dad d
+ shld siord
+
+ mov a,c ; get to proper register
+ ret
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+
+flsmdm: call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+
+;
+; SIO input buffer handling. The buffer pointers are held as pointers into
+; the buffer. The read pointer
+; is to the next unused character, the write pointer to the next unused space.
+;
+siord: dw ovlend ; next char to read
+siowr: dw ovlend ; next char to write
+sioct: dw 0 ; number in buffer
+
+xsuck: push d ; save regs version of suck
+ push b
+ push h
+ call suck
+ pop h
+ pop b
+ pop d
+ ret
+
+;
+; suck
+;
+; this routine is called whenever it would be possible that some
+; characters might be available in the SIO device; they are all
+; transferred (there may be up to 4 pending) to the buffer.
+;
+; all registers are destroyed
+;
+suck:
+IF pcw
+ call baxist ; check input status via BDOS
+ ora a ; check if zero
+ENDIF
+IF cpc
+ lxi b,mnprts ; get input status directly
+ dw inpc ; IN A,(C)
+ ani input ; mask for Rx ready
+ENDIF
+ rz ; return if no
+
+IF pcw
+ call baxin ; fetch character via BDOS
+ENDIF
+IF cpc
+ lxi b,mnport ; fetch character directly from SIO
+ dw inpc ; IN A,(C)
+ENDIF
+
+ lhld siowr ; write pointer
+ mov m,a ; put character
+
+ lxi d,1-ovlend ; take off base, bump pointer
+ dad d
+ mov a,h ; top byte of offset
+ ani siomsk/256 ; masked off
+ mov h,a
+ lxi d,ovlend ; add on base again
+ dad d
+ shld siowr ; replace pointer
+
+ lhld sioct ; bump count in buffer
+ inx h
+ shld sioct
+
+ jmp suck ; go round in case any more
+
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+outlpt:
+ push d ; save DE in either case
+ mov c,e ; correct arg register
+ call blist
+ pop d ; restore saved register pair
+ ret
+
+;
+; Screen manipulation routines
+; csrpos - move to row B, column C
+;
+; csrpos for terminals that use a leadin sequence followed
+; by (row + 31.) and (column + 31.)
+; or (row) and (column)
+;
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; restore coordinates
+ mov a,h ; get row
+ adi (' '-1) ; space is row one
+ mov e,a
+ push h
+ call outcon ; output row
+ pop h
+ mov a,l ; get column
+ adi (' '-1) ; space is column one
+ mov e,a
+ jmp outcon ; output it and return
+
+;
+; delchr - make delete look like a backspace. Unless delete is a printing
+; character, we just need to print a backspace. (we'll output clrspc
+; afterwards)
+; For Kaypro and Vector General, delete puts a blotch on the screen.
+; For Apple and Osborne 1, delete moves but doesn't print.
+delchr:
+IF pcw ;[6] OBS for Phillip Wade
+ lxi d,delstr ;[5] send a string rather than a single character
+ call prtstr
+
+delstr: db bs,' ',bs,'$' ;[OBS] Was bs,space,bs,bs
+ENDIF ;pcw
+
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the character at the current cursor position
+clrspc: mvi e,' '
+ call outcon
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the current line
+clrlin: lxi d,eralin
+ jmp prtstr
+
+; erase the whole screen, and go home. preserves b (but not c)
+clrtop: lxi d,erascr
+ jmp prtstr
+
+
+IF pcw
+sysver: db 'Amstrad PCW with SIO option$'
+ENDIF
+IF cpc
+sysver: db 'Amstrad CPC with CP/M Plus$'
+ENDIF
+
+outlin: db esc,'H',esc,'J',cr,lf,' $'
+
+erascr: db esc,'H',esc,'J$' ;Clear screen and go home.
+eralin: db cr,esc,'K$' ;Clear line.
+curldn: db esc,'Y$' ;cursor leadin
+ttab: ;Table start location.
+ta: db esc,'A$',0 ;Cursor up.
+tb: db esc,'B$',0 ;Cursor down.
+tc: db esc,'C$',0 ;Cursor right.
+td: db esc,'D$',0 ;Cursor left
+te: db esc,'E$',0 ;Clear display
+tf: db '$',0,0,0 ;Enter Graphics Mode
+tg: db '$',0,0,0 ;Exit Graphics mode
+th: db esc,'H$',0 ;Cursor home.
+ti: db esc,'I$',0 ;Reverse linefeed.
+tj: db esc,'J$',0 ;Clear to end of screen.
+tk: db esc,'K$',0 ;Clear to end of line.
+
+ovlend equ $ ; End of overlay
+
+ END
diff --git a/cpxpro.asm b/cpxpro.asm
index 9099b04..015ba05 100644
--- a/cpxpro.asm
+++ b/cpxpro.asm
@@ -1,561 +1,561 @@
-IF NOT lasm
-.printx * CPXPRO.ASM *
-ENDIF ;NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; revision history:
-;
-;edit 2, 16-Oct-1990 by MF. Reformatted speed tables according to
-; current usage and reworked sysspd routine accordingly.
-; Also eliminated cursor-positioning routines as we now link to
-; cpxvdu.asm. Reworked version message according to current usage.
-;edit 1, 17 November, 1987, by OBSchou. Extracted Compupro code
-; from CPMPRO.ASM and massaged fort CP/M kermit V4.09
-;
-; Modifications to KERMIT-80 for use with Compupro Interfacer 3/4 "[gv]"
-;
-; Guy Valiquette, M.D.
-; Black Bldg. Rm 322
-; Dept. of Neurology
-; College of Physicians & Surgeons
-; Columbia University
-; 630 W. 168th Street
-; New York, NY 10032
-; (212) 694-3965
-;
-; I/O routines for Interfacer 3/4 board
-; Allow sending break with <ESC> B while CONNECTed
-; Terminal control sequences for Wyse Technology WY-100
-; Add calls to "hangup" subroutine in EXIT and BYE to hang-up phone if
-; using a smart modem by disabling UART (and withdrawing DTR signal)
-;
-;
-; Using KERMIT with Compupro Interfacer 3/4:
-; - Set compro below to TRUE, all other to FALSE
-; - Select the ABSOLUTE USER number you want with the user EQUate
-; - Select the terminal control string set needed (or write your
-; own if not there)
-; - Note that I had to use a kludge to get the signon message right.
-; Code in KERMIT as I found it did not, nor could it, work. Search
-; for the section of code under: IF compro AND wy100 and imitate.
-; - If you have a smart modem, CONNECT puts you in contact with your
-; modem. Use your usual "wake-up" character sequence to dial out.
-; You can CONNECT and return to KERMIT repeateadly without hanging up
-; UNLESS you change the baud rate, execute the BYE command or EXIT.
-; - Baud rate set up in code to use 1200 baud as default. Can easily
-; be changed to 300 (or whatever). The byte defined at label "baudrt"
-; is the mode register 2 used to initialize the UART on first CONNECT.
-; The low order nibble of this byte is the baud rate. Refer to the
-; Compupro manual to set whatever default baud rate desired by changing
-; this low nibble at baudrt db 0011$xxxxb.
-;
-; Note: "Wrapup" work (outlined below) to clean up code not done since
-; new version of KERMIT is due out in a few weeks (says fdc)
-;
-; WRAPUP:
-; - outchri modification done for IF inout ONLY
-; - stchr routine implemented for IF inout ONLY
-; and used by outchr only
-;
-;
-; Keep module name, edit number, and last revision date in memory.
-family: db 'CPXPRO.ASM (2) 16-Oct-1990 $'
-;
-; Assembly time message to let me know I'm building the right version.
-; LASM generates an 'S' error along with the message, which is messy, but
-; better than trying to put everything inside a IF m80 OR mac80 conditional,
-; because LASM doesn't like nested IF's, either.
-
-IF compro
-.printx * Assembling Kermit-80 for Compupro Interfacer 4 (or 3) *
-ENDIF
-
-iobyte EQU 03H ;Location of I/O byte
-
-IF compro
-if4 EQU 10H ;standard base address of Interfacer 4/3 board
-datap EQU if4+0 ;data port (read/write)
-stat EQU if4+1 ;status port (read/write)
-mode EQU if4+2 ;mode registers (read/write)
-command EQU if4+3 ;command register (read/write)
-txint EQU if4+4 ;transmit interrupts status/mask (read/write)
-rxint EQU if4+5 ;receive interrupts status/mask (read/write)
-; if4+6 not used
-usersel EQU if4+7 ;absolute user number select register
-output EQU 1
-input EQU 2
-; Note: tested with CP/M Ver2.2, and Racal-Vadic Auto Dial VA212 modem
-; and USRobotics Password modems. [gv]
-user EQU 7 ;ABSOLUTE user number on IF4 or IF3
-; Also remember to select a terminal!!!
-ENDIF;compro
-;
-
-sysxin: ;system initialisation not covered by sysinit
- ret ; return from system-dependent routine
-
-;
-;
-; system-dependent termination processing
-; If we've changed anything, this is our last chance to put it back.
-sysexit:
- ret
-
-;
-; system-dependent processing for start of CONNECT command
-;
-syscon:
- ret
-
-;
-;
-; syscls - system-dependent close routine
-; called when exiting transparent session.
-;
-syscls:
- ret
-;
-;
-; sysinh - help for system-dependent special functions.
-; called in response to <escape>?, after listing all the
-; system-independent escape sequences.
-;
-sysinh:
- lxi d,inhlps ; we got options...
- call prtstr ; print them.
- ret
-inhlps:
-
- db cr,lf,'D - drop the line'
- db cr,lf,'B - send a break'
- db cr,lf
- db '$' ;[hh] table terminator
-
-;
-; sysint - system dependent special functions
-; called when transparent escape character has been typed;
-; the second character of the sequence is in A (and in B).
-; returns:
-; non-skip: sequence has been processed
-; skip: sequence was not recognized
-sysint:
- ani 137O ; convert lower case to upper, for testing...
-
- cpi 'D' ;Disconnect modem?
- jnz intc00 ;no
-hangup: xra a ;get a null byte
- out command ;disable UART
- sta ckdialf ;pull down flag to reinitialize UART
- ret ;most smart modems will hang up on loosing DTR
-intc00:
- cpi 'B' ; Send a reak?
- jz sendbr
- ret
-
-
-;send a break
-sendbr: mvi a,user ;select our UART
- di ;quiet
- out usersel ;select it
- in command ;get current command byte
- ori 00001000b ;set "send break" bit
- out command ;send to UART
- ei
-
- ;now for 300 msec timing loop (at 4 MHz, 0 wait state)
- mvi a,30 ;[obs] call delay for 300 ms
- call delay
-
- mvi a,user ;now, go back to UART
- di ;quiet
- out usersel
- in command ;get current command
- ani 11110111b ;reset "send break" bit
- ori 00010000b ;and set "reset errors" command bit (in case)
- out command ;send back to UART
- ei
- jmp rskp
-
-
-ckdial:
- lda ckdialf ;check flag that forces reinitialization
- ora a ;test it
- jz ckdial0 ;must redo it
- mvi a,user ;user number
- di
- out usersel ;select it
- in command ;get current command register
- ei
- ani 00000111b ;mask for normal operating mode
- ;(DTR on, RX and TX both enabled)
- cpi 00000111b ;is it?
- jz rskp ;UART is on, start terminal emulation
-; else initialize UART...
-ckdial0:di
- mvi a,user ;select user
- out usersel
- mvi a,0001$0000b ;reset errors command
- out command ;send to command register
- out command
- out command ;...make sure it got it
- in command ;confirm
- lda moderg1 ;get mode register 1
- out mode ;send it
- lda moderg2 ;get mode register 2
- out mode ;send it
- mvi a,0011$0111b ;command register to start things
- out command ;send it
- ei ;turn interrupts back on
- mvi a,0ffh ;get a non-zero byte
- sta ckdialf ;pull down flag
-;
- jmp rskp ;start terminal emulation
-
-
-; sysflt - system-dependent filter.
-; called with the character in E.
-; preserves bc, de, hl.
-; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-sysflt:
- mov a,e ; get character for testing
- ret
-
-; mdmflt - modem filter [30]
-; called with character to be sent to printer in E
-; with parity set as appropriate.
-; return with accumulator = 0 do do nothing,
-; <> 0 to send char in E.
-mdmflt:
- mov a,e ;[30] get character to test
- ret
-
-
-; prtflt - printer filter [30]
-; called with character to be sent to printer in E
-; returns with a = 0 to do nothing
-; a <> 0 to print it.
-;
-; this routine for those printer that automatically insert
-; a lf on cr, or cr for lf. Should this be shifted to
-; the system indep. stuff, in say 4.06?
-prtflt:
- mov a,e ; [30] get character to test
- ret
-
-
-;
-;
-; system-dependent processing for BYE command.
-; for apmmdm, heath, and lobo, hang up the phone.
-sysbye:
-
- call hangup
- ret
-;
-; This is the system-dependent command to change the baud rate.
-; DE contains the two-byte value from the baud rate table; this
-; value is also stored in 'speed'.
-sysspd:
-
-
-IF compro
- lda speed ;[MF]Get requested baud-rate
- mov b,a ;Save the number.
- lxi h,baudrt ;point to current baud rate
- mov a,m ;get it
- ani 0f0h ;keep high nibble
- ora b ;merge back baud rate
- mov m,a ;store back
- xra a ;clear A
- sta ckdialf ;put up flag to force reinitialization
- ret ;...at next connect
-
-ENDIF;compro
-
-
-;
-
-; Speed tables
-; (Note that speed tables MUST be in alphabetical order for later
-; lookup procedures, and must begin with a value showing the total
-; number of entries. The speed help tables are just for us poor
-; humans.
-
-; db string length,string,divisor (2 identical bytes or 1 word)
-; [Toad Hall]
-
-spdtbl: db 8 ;[MF]8 entries in speed table
- db 3,'110$'
- db 02h,02h ;[MF]110 baud
- db 4,'1200$'
- db 07h,07h ;[MF]1200 baud
- db 5,'134.5$'
- db 03h,03h ;[MF]134.5 baud
- db 3,'150$'
- db 04h,04h ;[MF]150 baud
- db 4,'1800$'
- db 08h,08h ;[MF]1800 baud
- db 5,'19200$'
- db 0fh,0fh ;[MF]19200 baud
- db 4,'2000$'
- db 09h,09h ;[MF]2000 baud
- db 4,'2400$'
- db 0ah,0ah ;[MF]2400 baud
- db 3,'300$'
- db 05h,05h ;[MF]300 baud
- db 4,'3600$'
- db 0bh,0bh ;[MF]3600 baud
- db 4,'4800$'
- db 0ch,0ch ;[MF]4800 baud
- db 2,'50$'
- db 00h,00h ;[MF]50 baud
- db 3,'600$'
- db 06h,06h ;[MF]600 baud
- db 4,'7200$'
- db 0dh,0dh ;[MF]7200 baud
- db 2,'75$'
- db 01h,01h ;[MF]75 baud
- db 4,'9600$'
- db 0eh,0eh ;[MF]9600 baud
-
-sphtbl: db cr,lf,'50 75 110 134 150 300 600 1200'
- db cr,lf,'1800 2000 2400 3600 4800 7200 9600 19200$'
-
-ckdialf:db 0 ;force UART initialization on entry
-baudrt: db 0011$0111b ;default baud rate: 1200 baud
-moderg1:db 0100$1110b ;default mode register 1:
- ; -asynch, 8 data bits, 1 stop bit,
- ; -parity odd, disabled
-moderg2 EQU baudrt
-ENDIF;compro
-;
-
-;
-; The following conditionals were once a huge if not statement. There
-; wasn't enough room to add the lobo to the list, so it had to be broken
-; into 2, which you can't do with an if not. I redid it as two ifs and
-; applied them to those that wouldn't set baud. [Hal Hostetler]
-; This is the system-dependent SET PORT command.
-; HL contains the argument from the command table.
-sysprt:
- ret
-;
-;
-; Port table not applicable
-prttbl EQU 0
-prhtbl EQU 0 ;
-
-;
-;
-; selmdm - select modem port
-; selcon - select console port
-; selmdm is called before using inpmdm or outmdm;
-; selcon is called before using inpcon or outcon.
-; For iobyt systems, diddle the I/O byte to select console or comm port;
-; For Decision I, switches Multi I/O board to console or modem serial
-; port. [Toad Hall]
-; For the rest, does nothing.
-; preserves bc, de, hl.
-selmdm:
- ret
-
-selcon:
- ret
-;
-; Get character from console, or return zero.
-; result is returned in A. destroys bc, de, hl.
-;
-inpcon:
- mvi c,dconio ;Direct console I/O BDOS call.
- mvi e,0FFH ;Input.
- call BDOS
- ret
-;
-;
-; Output character in E to the console.
-; destroys bc, de, hl
-;
-outcon:
- mvi c,dconio ;Console output bdos call.
- call bdos ;Output the char to the console.
- ret
-;
-;
-; outmdm - output a char from E to the modem.
-; the parity bit has been set as necessary.
-; returns nonskip; bc, de, hl preserved.
-outmdm:
-;************************System Dependent****************************
-;
-; Addition by [gv], 16/7/84
-; Return the status of the modem port:
-; Z flag set if NO input available
-; C flag set in NOT output ready
-; Destroys A and flags, preserves all other registers
-;
-stchr:
- di
- mvi a,user
- out usersel
- in stat
- ani output
- in stat
- ei
- jz outmdm ;not output ready, try again
-; else...
- di ;no interrupts
- mvi a,user
- out usersel
- mov a,e ;get back character
- out datap
- ei
- ret
-
-;
-
-;
-;
-; get character from modem; return zero if none available.
-; for IOBYT systems, the modem port has already been selected.
-; destroys bc, de, hl.
-inpmdm:
-;
- di
- mvi a,user
- out usersel
- in stat
- ei
- ani input ;test for input status (C flag reset by ANI n)
- rz ; no input available
-;
-;************************System Dependent****************************
-;
-; Addition by [gv], 16/7/84
-; get a character "raw" (i.e. just get it in A)
-;
-; Note: MUST have character ready before call, use stchr
- mvi a,user
- di
- out usersel
- in datap
- ei
- ret
-;
-;
-
-;
-; flsmdm - flush comm line.
-; Modem is selected.
-; Currently, just gets characters until none are available.
-
-flsmdm: call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-
-
-;
-;
-; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
-lptstat:
- xra a ; assume it is ok.. this may not be necessary
- ret
-;
-;
-; outlpt - output character in E to printer
-; console is selected.
-; preserves de.
-outlpt:
- push d ; save DE in either case
- call prtflt ; go through printer filter [30]
- ana a ; if A = 0 do nothing,
- jz outlp1 ; [30] if a=0 do nothing
- mvi c,lstout
- call bdos ;Char to printer
-outlp1: pop d ; restore saved register pair
-
-
-
-IF inout
-prtout:
-ENDIF ;inout
-IF compro AND inout
- di
- mvi a,user
- out usersel
- in stat
- ei
-ENDIF;compro AND inout
-IF (NOT compro) AND inout
- in mnprts ;Get the output ready flag.
-ENDIF;(NOT compro) AND inout
-IF inout
- ani output ;Is it set?
- jz prtout ;If so, loop until it isn't.
-ENDIF ;inout
-IF compro AND inout
- di
- mvi a,user
- out usersel
- mov a,e
- out datap
- ei
-ENDIF;compro AND inout
-IF (NOT compro) AND inout
- mov a,e ;Get the char to output.
-prtou2: out mnport ;Output it.
-ENDIF;(NOT compro) AND inout
- ret
-
-
-;
-
-;
-; Screen manipulation routines
-;
-; delchr - make delete look like a backspace. Unless delete is a printing
-; character, we just need to print a backspace. (we'll output clrspc
-; afterwards)
-; For Kaypro and Vector General, delete puts a blotch on the screen.
-; For Apple and Osborne 1, delete moves but doesn't print.
-delchr:
- mvi e,bs
- call outcon
-
-; erase the character at the current cursor position
-clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the current line
-clrlin: lxi d,eralin
- jmp prtstr
-
-; erase the whole screen, and go home. preserves b (but not c)
-clrtop: lxi d,erascr
- jmp prtstr
-
-
-IF compro; [gv]
-sysver: db '[Compupro IF4-',user+'0',']$'
-ENDIF;compro
-
-IF lasm
-LINK CPXVDU.ASM
-ENDIF ;lasm
+IF NOT lasm
+.printx * CPXPRO.ASM *
+ENDIF ;NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; revision history:
+;
+;edit 2, 16-Oct-1990 by MF. Reformatted speed tables according to
+; current usage and reworked sysspd routine accordingly.
+; Also eliminated cursor-positioning routines as we now link to
+; cpxvdu.asm. Reworked version message according to current usage.
+;edit 1, 17 November, 1987, by OBSchou. Extracted Compupro code
+; from CPMPRO.ASM and massaged fort CP/M kermit V4.09
+;
+; Modifications to KERMIT-80 for use with Compupro Interfacer 3/4 "[gv]"
+;
+; Guy Valiquette, M.D.
+; Black Bldg. Rm 322
+; Dept. of Neurology
+; College of Physicians & Surgeons
+; Columbia University
+; 630 W. 168th Street
+; New York, NY 10032
+; (212) 694-3965
+;
+; I/O routines for Interfacer 3/4 board
+; Allow sending break with <ESC> B while CONNECTed
+; Terminal control sequences for Wyse Technology WY-100
+; Add calls to "hangup" subroutine in EXIT and BYE to hang-up phone if
+; using a smart modem by disabling UART (and withdrawing DTR signal)
+;
+;
+; Using KERMIT with Compupro Interfacer 3/4:
+; - Set compro below to TRUE, all other to FALSE
+; - Select the ABSOLUTE USER number you want with the user EQUate
+; - Select the terminal control string set needed (or write your
+; own if not there)
+; - Note that I had to use a kludge to get the signon message right.
+; Code in KERMIT as I found it did not, nor could it, work. Search
+; for the section of code under: IF compro AND wy100 and imitate.
+; - If you have a smart modem, CONNECT puts you in contact with your
+; modem. Use your usual "wake-up" character sequence to dial out.
+; You can CONNECT and return to KERMIT repeateadly without hanging up
+; UNLESS you change the baud rate, execute the BYE command or EXIT.
+; - Baud rate set up in code to use 1200 baud as default. Can easily
+; be changed to 300 (or whatever). The byte defined at label "baudrt"
+; is the mode register 2 used to initialize the UART on first CONNECT.
+; The low order nibble of this byte is the baud rate. Refer to the
+; Compupro manual to set whatever default baud rate desired by changing
+; this low nibble at baudrt db 0011$xxxxb.
+;
+; Note: "Wrapup" work (outlined below) to clean up code not done since
+; new version of KERMIT is due out in a few weeks (says fdc)
+;
+; WRAPUP:
+; - outchri modification done for IF inout ONLY
+; - stchr routine implemented for IF inout ONLY
+; and used by outchr only
+;
+;
+; Keep module name, edit number, and last revision date in memory.
+family: db 'CPXPRO.ASM (2) 16-Oct-1990 $'
+;
+; Assembly time message to let me know I'm building the right version.
+; LASM generates an 'S' error along with the message, which is messy, but
+; better than trying to put everything inside a IF m80 OR mac80 conditional,
+; because LASM doesn't like nested IF's, either.
+
+IF compro
+.printx * Assembling Kermit-80 for Compupro Interfacer 4 (or 3) *
+ENDIF
+
+iobyte EQU 03H ;Location of I/O byte
+
+IF compro
+if4 EQU 10H ;standard base address of Interfacer 4/3 board
+datap EQU if4+0 ;data port (read/write)
+stat EQU if4+1 ;status port (read/write)
+mode EQU if4+2 ;mode registers (read/write)
+command EQU if4+3 ;command register (read/write)
+txint EQU if4+4 ;transmit interrupts status/mask (read/write)
+rxint EQU if4+5 ;receive interrupts status/mask (read/write)
+; if4+6 not used
+usersel EQU if4+7 ;absolute user number select register
+output EQU 1
+input EQU 2
+; Note: tested with CP/M Ver2.2, and Racal-Vadic Auto Dial VA212 modem
+; and USRobotics Password modems. [gv]
+user EQU 7 ;ABSOLUTE user number on IF4 or IF3
+; Also remember to select a terminal!!!
+ENDIF;compro
+;
+
+sysxin: ;system initialisation not covered by sysinit
+ ret ; return from system-dependent routine
+
+;
+;
+; system-dependent termination processing
+; If we've changed anything, this is our last chance to put it back.
+sysexit:
+ ret
+
+;
+; system-dependent processing for start of CONNECT command
+;
+syscon:
+ ret
+
+;
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+ ret
+;
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing all the
+; system-independent escape sequences.
+;
+sysinh:
+ lxi d,inhlps ; we got options...
+ call prtstr ; print them.
+ ret
+inhlps:
+
+ db cr,lf,'D - drop the line'
+ db cr,lf,'B - send a break'
+ db cr,lf
+ db '$' ;[hh] table terminator
+
+;
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:
+; non-skip: sequence has been processed
+; skip: sequence was not recognized
+sysint:
+ ani 137O ; convert lower case to upper, for testing...
+
+ cpi 'D' ;Disconnect modem?
+ jnz intc00 ;no
+hangup: xra a ;get a null byte
+ out command ;disable UART
+ sta ckdialf ;pull down flag to reinitialize UART
+ ret ;most smart modems will hang up on loosing DTR
+intc00:
+ cpi 'B' ; Send a reak?
+ jz sendbr
+ ret
+
+
+;send a break
+sendbr: mvi a,user ;select our UART
+ di ;quiet
+ out usersel ;select it
+ in command ;get current command byte
+ ori 00001000b ;set "send break" bit
+ out command ;send to UART
+ ei
+
+ ;now for 300 msec timing loop (at 4 MHz, 0 wait state)
+ mvi a,30 ;[obs] call delay for 300 ms
+ call delay
+
+ mvi a,user ;now, go back to UART
+ di ;quiet
+ out usersel
+ in command ;get current command
+ ani 11110111b ;reset "send break" bit
+ ori 00010000b ;and set "reset errors" command bit (in case)
+ out command ;send back to UART
+ ei
+ jmp rskp
+
+
+ckdial:
+ lda ckdialf ;check flag that forces reinitialization
+ ora a ;test it
+ jz ckdial0 ;must redo it
+ mvi a,user ;user number
+ di
+ out usersel ;select it
+ in command ;get current command register
+ ei
+ ani 00000111b ;mask for normal operating mode
+ ;(DTR on, RX and TX both enabled)
+ cpi 00000111b ;is it?
+ jz rskp ;UART is on, start terminal emulation
+; else initialize UART...
+ckdial0:di
+ mvi a,user ;select user
+ out usersel
+ mvi a,0001$0000b ;reset errors command
+ out command ;send to command register
+ out command
+ out command ;...make sure it got it
+ in command ;confirm
+ lda moderg1 ;get mode register 1
+ out mode ;send it
+ lda moderg2 ;get mode register 2
+ out mode ;send it
+ mvi a,0011$0111b ;command register to start things
+ out command ;send it
+ ei ;turn interrupts back on
+ mvi a,0ffh ;get a non-zero byte
+ sta ckdialf ;pull down flag
+;
+ jmp rskp ;start terminal emulation
+
+
+; sysflt - system-dependent filter.
+; called with the character in E.
+; preserves bc, de, hl.
+; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
+sysflt:
+ mov a,e ; get character for testing
+ ret
+
+; mdmflt - modem filter [30]
+; called with character to be sent to printer in E
+; with parity set as appropriate.
+; return with accumulator = 0 do do nothing,
+; <> 0 to send char in E.
+mdmflt:
+ mov a,e ;[30] get character to test
+ ret
+
+
+; prtflt - printer filter [30]
+; called with character to be sent to printer in E
+; returns with a = 0 to do nothing
+; a <> 0 to print it.
+;
+; this routine for those printer that automatically insert
+; a lf on cr, or cr for lf. Should this be shifted to
+; the system indep. stuff, in say 4.06?
+prtflt:
+ mov a,e ; [30] get character to test
+ ret
+
+
+;
+;
+; system-dependent processing for BYE command.
+; for apmmdm, heath, and lobo, hang up the phone.
+sysbye:
+
+ call hangup
+ ret
+;
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; this
+; value is also stored in 'speed'.
+sysspd:
+
+
+IF compro
+ lda speed ;[MF]Get requested baud-rate
+ mov b,a ;Save the number.
+ lxi h,baudrt ;point to current baud rate
+ mov a,m ;get it
+ ani 0f0h ;keep high nibble
+ ora b ;merge back baud rate
+ mov m,a ;store back
+ xra a ;clear A
+ sta ckdialf ;put up flag to force reinitialization
+ ret ;...at next connect
+
+ENDIF;compro
+
+
+;
+
+; Speed tables
+; (Note that speed tables MUST be in alphabetical order for later
+; lookup procedures, and must begin with a value showing the total
+; number of entries. The speed help tables are just for us poor
+; humans.
+
+; db string length,string,divisor (2 identical bytes or 1 word)
+; [Toad Hall]
+
+spdtbl: db 8 ;[MF]8 entries in speed table
+ db 3,'110$'
+ db 02h,02h ;[MF]110 baud
+ db 4,'1200$'
+ db 07h,07h ;[MF]1200 baud
+ db 5,'134.5$'
+ db 03h,03h ;[MF]134.5 baud
+ db 3,'150$'
+ db 04h,04h ;[MF]150 baud
+ db 4,'1800$'
+ db 08h,08h ;[MF]1800 baud
+ db 5,'19200$'
+ db 0fh,0fh ;[MF]19200 baud
+ db 4,'2000$'
+ db 09h,09h ;[MF]2000 baud
+ db 4,'2400$'
+ db 0ah,0ah ;[MF]2400 baud
+ db 3,'300$'
+ db 05h,05h ;[MF]300 baud
+ db 4,'3600$'
+ db 0bh,0bh ;[MF]3600 baud
+ db 4,'4800$'
+ db 0ch,0ch ;[MF]4800 baud
+ db 2,'50$'
+ db 00h,00h ;[MF]50 baud
+ db 3,'600$'
+ db 06h,06h ;[MF]600 baud
+ db 4,'7200$'
+ db 0dh,0dh ;[MF]7200 baud
+ db 2,'75$'
+ db 01h,01h ;[MF]75 baud
+ db 4,'9600$'
+ db 0eh,0eh ;[MF]9600 baud
+
+sphtbl: db cr,lf,'50 75 110 134 150 300 600 1200'
+ db cr,lf,'1800 2000 2400 3600 4800 7200 9600 19200$'
+
+ckdialf:db 0 ;force UART initialization on entry
+baudrt: db 0011$0111b ;default baud rate: 1200 baud
+moderg1:db 0100$1110b ;default mode register 1:
+ ; -asynch, 8 data bits, 1 stop bit,
+ ; -parity odd, disabled
+moderg2 EQU baudrt
+ENDIF;compro
+;
+
+;
+; The following conditionals were once a huge if not statement. There
+; wasn't enough room to add the lobo to the list, so it had to be broken
+; into 2, which you can't do with an if not. I redid it as two ifs and
+; applied them to those that wouldn't set baud. [Hal Hostetler]
+; This is the system-dependent SET PORT command.
+; HL contains the argument from the command table.
+sysprt:
+ ret
+;
+;
+; Port table not applicable
+prttbl EQU 0
+prhtbl EQU 0 ;
+
+;
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; For iobyt systems, diddle the I/O byte to select console or comm port;
+; For Decision I, switches Multi I/O board to console or modem serial
+; port. [Toad Hall]
+; For the rest, does nothing.
+; preserves bc, de, hl.
+selmdm:
+ ret
+
+selcon:
+ ret
+;
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+ mvi c,dconio ;Direct console I/O BDOS call.
+ mvi e,0FFH ;Input.
+ call BDOS
+ ret
+;
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+ mvi c,dconio ;Console output bdos call.
+ call bdos ;Output the char to the console.
+ ret
+;
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+outmdm:
+;************************System Dependent****************************
+;
+; Addition by [gv], 16/7/84
+; Return the status of the modem port:
+; Z flag set if NO input available
+; C flag set in NOT output ready
+; Destroys A and flags, preserves all other registers
+;
+stchr:
+ di
+ mvi a,user
+ out usersel
+ in stat
+ ani output
+ in stat
+ ei
+ jz outmdm ;not output ready, try again
+; else...
+ di ;no interrupts
+ mvi a,user
+ out usersel
+ mov a,e ;get back character
+ out datap
+ ei
+ ret
+
+;
+
+;
+;
+; get character from modem; return zero if none available.
+; for IOBYT systems, the modem port has already been selected.
+; destroys bc, de, hl.
+inpmdm:
+;
+ di
+ mvi a,user
+ out usersel
+ in stat
+ ei
+ ani input ;test for input status (C flag reset by ANI n)
+ rz ; no input available
+;
+;************************System Dependent****************************
+;
+; Addition by [gv], 16/7/84
+; get a character "raw" (i.e. just get it in A)
+;
+; Note: MUST have character ready before call, use stchr
+ mvi a,user
+ di
+ out usersel
+ in datap
+ ei
+ ret
+;
+;
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+
+flsmdm: call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+
+
+;
+;
+; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
+lptstat:
+ xra a ; assume it is ok.. this may not be necessary
+ ret
+;
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+outlpt:
+ push d ; save DE in either case
+ call prtflt ; go through printer filter [30]
+ ana a ; if A = 0 do nothing,
+ jz outlp1 ; [30] if a=0 do nothing
+ mvi c,lstout
+ call bdos ;Char to printer
+outlp1: pop d ; restore saved register pair
+
+
+
+IF inout
+prtout:
+ENDIF ;inout
+IF compro AND inout
+ di
+ mvi a,user
+ out usersel
+ in stat
+ ei
+ENDIF;compro AND inout
+IF (NOT compro) AND inout
+ in mnprts ;Get the output ready flag.
+ENDIF;(NOT compro) AND inout
+IF inout
+ ani output ;Is it set?
+ jz prtout ;If so, loop until it isn't.
+ENDIF ;inout
+IF compro AND inout
+ di
+ mvi a,user
+ out usersel
+ mov a,e
+ out datap
+ ei
+ENDIF;compro AND inout
+IF (NOT compro) AND inout
+ mov a,e ;Get the char to output.
+prtou2: out mnport ;Output it.
+ENDIF;(NOT compro) AND inout
+ ret
+
+
+;
+
+;
+; Screen manipulation routines
+;
+; delchr - make delete look like a backspace. Unless delete is a printing
+; character, we just need to print a backspace. (we'll output clrspc
+; afterwards)
+; For Kaypro and Vector General, delete puts a blotch on the screen.
+; For Apple and Osborne 1, delete moves but doesn't print.
+delchr:
+ mvi e,bs
+ call outcon
+
+; erase the character at the current cursor position
+clrspc: mvi e,' '
+ call outcon
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the current line
+clrlin: lxi d,eralin
+ jmp prtstr
+
+; erase the whole screen, and go home. preserves b (but not c)
+clrtop: lxi d,erascr
+ jmp prtstr
+
+
+IF compro; [gv]
+sysver: db '[Compupro IF4-',user+'0',']$'
+ENDIF;compro
+
+IF lasm
+LINK CPXVDU.ASM
+ENDIF ;lasm
diff --git a/cpxsb.asm b/cpxsb.asm
index 3beefe7..18056d4 100644
--- a/cpxsb.asm
+++ b/cpxsb.asm
@@ -1,696 +1,696 @@
-IF NOT lasm
-.printx * CPXSB.ASM *
-ENDIF ;NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file created 16 July, 1987 by OBSchou from code submitted
-; by William Rose for the Micromint SB180 systems (as featured in
-; BYTE magazine, 1986). This file has been modified to fit in with
-; Kermit-80 V4.08 etc. His file KERSYS.ASM is a stripped down version
-; of CPXSYS.ASM (formerly CP4SYS.ASM).
-;
-; revision history:
-; KERSYS.ASM - version 0.8 dated 13 Jul 87.
-;
-; Cutdown CP4SYS.ASM for SB-180/Ampro 230.
-;
-;
-; While this is a single CPU version (to ease editing) the assembler
-; conditionals have been kept to identify machine specific code.
-;
-; Note that the baud setting routine also sets parity, but this does not
-; change the parity given by Kermit's 'stat' command. I assume that the
-; main body of the program does its own parity check.
-;
-; Revision history (last entry first)
-;
-; edit 2, 22 July by OBSchou to massage file to fit with CPXCOM.ASM.
-;
-; edit 1, 15 July, 1987 by OBSchou for William Rose who submitted
-; the code for Kermit-80 V 4.05. Modified code as appropriate
-; for 4.08 compatability.
-;
-
-delfac EQU 150 ; Delay factor in SB-180 input loop - a fudge
-
-;
-; Keep module name, edit number, and last revision date in memory.
-;
-;sysedt: db 'KERSYS.ASM (03) 12-FEB-87 $' ; last SB-180 revision
-;sysedt: db 'KERSYS.ASM (04) 12-APR-87 $' ; Telecom Merlin added
-;sysedt: db 'KERSYS.ASM (5) 9-May-87 $' ; Minor tidying
-;sysedt: db 'KERSYS.ASM (6A) 17-Jun-87 $' ; BT Merlin M2215 only
-;sysedt: db 'KERSYS.ASM (7) 19-Jun-87 $' ; SB-180 only
-;sysedt: db 'KERSYS.ASM (8) 13-Jul-87 $' ; 6/9 MHz version
-family: db 'CPXSB.ASM (2) 22-Jul-87$' ; First entry for V4.08/9
-
-;
-; Assembly time message to let me know I'm building the right version.
-;
-
-IF sb180
-.printx * Assembling Kermit-80 for Micromint SB-180 *
-ENDIF
-
-
-IF sb180
-mnctrla EQU 000H ;Modem control port - CNTLA0
-mnctrlb EQU 002H ;Modem control port - CNTLB0
-mnstat EQU 004H ;Modem status port - STAT0
-mntxdat EQU 006H ;Modem output port - TDR0
-mnrddat EQU 008H ;Modem input port - RDR0
-output EQU 002H ;Transmit data register empty mask - TDRE
-input EQU 080H ;Receive data register full mask - RDRF
-z80 EQU TRUE ;This one's an HD64180, but Z80 will do
-ENDIF
-
-
-sysxin: ; continuation of system initialisation from sysinit
-
-IF sb180
- lxi h, porbuf ; park the original settings
- db 0EDh, 038h, mnctrla ; HD64180 code IN0 g,(m)
- mov m, a
- inx h
- db 0EDh, 038h, mnctrlb
- mov m, a
- inx h
- db 0EDh, 038h, mnstat
- mov m, a
-ENDIF
- ; re-initialise for KERMIT
-IF sb6
- mvi h, 08h ; 0000$1001 - 9600 baud, (even) parity
- mvi l, 08h ; 'speed' is two bytes
-ENDIF
-
-IF sb9
- mvi h, 21h ; 0010$0001 - 9600 baud, (even) parity
- mvi l, 21h ; 'speed' is two bytes
-ENDIF
-
-IF sb180
- shld speed
- lxi h, parind
- mvi m, 8 ; index for 8 bits, no parity, 2 stop
- call setpor
-ENDIF
-
- ret
-
-porbuf: ds 3 ; original port settings
-
-;
-; system-dependent KERMIT termination processing
-; If we've changed anything, this is our last chance to put it back.
-;
-sysexit:
-
-IF sb180
- lxi h, porbuf
- mov a, m ; output parity
- db 0EDh, 039h, mnctrla ; HD64180 code OUT0 (m),g
- inx h
- mov a, m ; output baud rate
- db 0EDh, 039h, mnctrlb
- inx h
- mov a, m ; output to clear error flags
- db 0EDh, 039h, mnstat
- ; read twice to reset DCD0 ?
- db 0EDh, 038h, mnstat
- db 0EDh, 038h, mnstat
-ENDIF
-
- ret
-
-;
-; system-dependent processing for start of CONNECT command
-;
-syscon:
- ret
-
-conmsg: ; Messages printed when entering transparent (CONNECT) mode:
-
- db '$'
-
-;
-; syscls - system-dependent close routine
-; called when exiting transparent session.
-;
-syscls:
- ret
-
-;
-; sysinh - help for system-dependent special functions.
-; called in response to <escape>?, after listing all the
-; system-independent escape sequences.
-;
-sysinh:
-
-IF sb180
- lxi d, inhlps
- call prtstr
-ENDIF
-
- ret
-
-; Additional, system-dependent help for transparent mode
-; (two-character escape sequences)
-inhlps:
-
-IF sb180
- db cr, lf, 'V Cycle port parameters'
-ENDIF
-
- db '$' ; string terminator
-
-;
-; sysint - system dependent special functions
-; called when transparent escape character has been typed;
-; the second character of the sequence is in A (and in B).
-; returns:
-; non-skip: sequence has been processed
-; skip: seqence was not recognized
-;
-sysint:
-; ani 137O ; convert lower case to upper, for testing...
- ; does this work?
-IF sb180
- cpi 'V' ; cycle port ?
- jz pcycl
- cpi 'v'
- jz pcycl
-ENDIF
-
- jmp rskp ; take skip return - command not recognised
-
-; Actual commands
-
-IF sb180
-pcycl:
- lxi h, parind ; increment parval, modulo 12
- mov a, m
- adi 1
- cpi 13
- jnz pcy1
- mvi a, 1
-pcy1: mov m, a ; update the storage
- ; get index of name in parstr
- ora a ; clear flags
- dcr a
- rlc
- rlc
- mov c, a
- mvi b, 0
- lxi h, parstr
- inx h
- dad b
- push h
- lxi d, cgmsg1
- call prtstr
- pop d
- call prtstr
- lxi d, cgmsg2
- call prtstr
- call setpor ; reset the port
-
- ret
-
-cgmsg1: db '<$'
-cgmsg2: db '>$'
-ENDIF
-
- ret
-
-;
-; Delay routine. Called with time (hundredths of seconds) in A.
-; The inner loop delays 1001 T-states, assuming no wait states are
-; inserted; this is repeated CPUSPD times, for a total delay of just
-; over 0.01 second. (CPUSPD should be set to the system clock rate,
-; in units of 100KHz: for an unmodified Kaypro II, that's 25 for
-; 2.5 MHz. Some enterprising soul could determine whether or not the
-; Kaypro actually inserts a wait state on instruction fetch (a common
-; practice); if so, the magic number at delay2 needs to be decreased.
-; (We also neglect to consider time spent at interrupt level).
-;
-; called by: sendbr
-; destroys BC
-;
-;delay: mvi c,cpuspd ; Number of times to wait 1000 T-states to
-; ; make .01 second delay
-;delay2: mvi b,70 ; Number of times to execute inner loop to
-; ; make 1000 T-state delay
-;delay3: dcr b ; 4 T-states (* 70 * cpuspd)
-; jnz delay3 ; 10 T-states (* 70 * cpuspd)
-; dcr c ; 4 T-states (* cpuspd)
-; jnz delay2 ; 10 T-states (* cpuspd)
-; ; total delay: ((14 * 70) + 14) * cpuspd
-; ; = 1001 * cpuspd
-; dcr a ; 4 T-states
-; jnz delay ; 10 T-states
-;
-; ret ; grand total: ((1001 * cpuspd) + 14) * a
-
-;
-; sysflt - system-dependent filter
-; called with character in E.
-; if this character should not be printed, return with A = zero.
-; preserves bc, de, hl.
-; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-;
-sysflt:
- mov a,e ; get character for testing
- ret
-
-;
-; mdmflt - modem filter
-; called with character to be sent to printer in E
-; with parity set as appropriate.
-; return with accumulator = 0 do do nothing,
-; <> 0 to send char in E.
-mdmflt:
- mov a,e ; get character to test
- ret
-
-;
-; prtflt - printer filter
-; called with character to be sent to printer in E
-; returns with a = 0 to do nothing
-; a <> 0 to print it.
-;
-; this routine for those printer that automatically insert
-; a lf on cr, or cr for lf. Should this be shifted to
-; the system indep. stuff, in say 4.06?
-;
-prtflt:
- mov a,e ; get character to test
-
-IF FALSE ; strip out lf from printer stream
- ani 7fh ; make sure it is parity less
- cpi lf ; is it a line feed?
- rnz ; no, print it
-; xra a ; yes, don't.
-
-ENDIF
-
- ret
-
-;
-; system-dependent processing for BYE command.
-;
-sysbye:
- ret
-
-;
-; This is the system-dependent command to change the baud rate.
-; DE contains the two-byte value from the baud rate table; both
-; bytes of this value are also stored in 'speed'.
-;
-sysspd:
-
-IF sb180
- lxi d, prtmsg ; ask for variables
- call prtstr
-
- lxi d, tbuf ; get suitable string
- mvi c, 10
- call bdos
-
- lxi h, tbuf1
- mov a, m
- ora a
- jz setpor ; leave unchanged if string zero length
-
- cpi 3 ; check given length
- jnz spd1 ; error - wrong length
- inx h
- inx h
- mov a, m
- ani 137O ; convert parity code to upper case
- mov m, a
-
- lxi d, tbuf1 ; get index of given parameter
- lxi h, parstr
- call sposn
- ora a
- jnz spd2 ; or fall through if error
-spd1: lxi d, invmsg ; invalid input - try again
- call prtstr
- jmp sysspd
-
-spd2: adi 3 ; get index to parval table
- rrc ; by dividing by 4
- rrc
- ani 15 ; mask out high bits
- lxi h, parind
- mov m, a ; and store it
- call setpor ; set up port iaw index and speed bytes
-
- ret
-
-prtmsg: db cr,lf,'Enter bit/char, parity, and stop bits required.'
- db cr,lf,'(Bit 7/8 Parity N/O/E Stop 1/2 - CR same) : $'
-invmsg: db cr,lf,'Invalid parameters$'
-
-parind: db 8 ; default <8N2> index
-parstr: db 48,'7N1$7N2$7O1$7O2$7E1$7E2$'
- db '8N1$8N2$8O1$8O2$8E1$8E2$'
-parval: db 0,1,16+2,16+3,2,3
- db 4,5,16+6,16+7,6,7
-tbuf db 6
-tbuf1 db 3,'8N2','$$$$'
-
-;
-; Set up the port using the table index in parind and the speed byte
-;
-setpor:
- lxi h, parind
- mov a, m
- dcr a
- lxi h, parval ; table base
- mvi b, 0
- mov c, a
- dad b ; HL points at parameter value
- mov a, m
- mov b, a ; park parval
-
- ani 16 ; the parity switch bit
- lxi h, speed
- add m ; this is now the baud rate byte
- mov c, a ; park it
-
- mov a, b ; sort out the parameter byte
- ani 7 ; b/p/s only wanted
- adi 96 ; RE, TE enable
- db 0EDh,039h,mnctrla ; output parity etc.
- mov a, c
- db 0EDh,039h,mnctrlb ; output baud rate
- mvi a, 0
- db 0EDh,039h,mnstat ; clear status
- db 0EDh,038h,mnstat ; read twice to reset DCD0
- db 0EDh,038h,mnstat
- ret
-
-;
-; Find substring position - Leventhal page 293, modified
-; enter with subtring in DE and string in HL
-; returns index in A or 0 for failure
-;
-sposn:
- mov a, m ; exit if either string length zero
- ora a
- jz notfnd
- sta slen
- mov b, a
- inx h
- shld string
- xchg
- mov a, m
- ora a
- jz notfnd
- sta sublen
- mov c, a
- inx h
- shld substg
- mov a, b
-
-; no of searches = stringlen - substrlen + 1
-; if substr longer than string quit immediately
-
- sub c
- jc notfnd
- inr a
- mov c, a
- xra a
- sta index
-
-; search until remaining string shorter than substring
-
-slp1: lxi h, index
- inr m
- lda sublen
- mov b, a
- lhld substg
- xchg
- lhld string
-
-; try to match substring starting at index
-
-cmplp: ldax d
- cmp m
- jnz slp2
- dcr b
- jz found
- inx h
- inx d
- jmp cmplp
-
-; arrive here if match fails
-
-slp2: dcr c
- jz notfnd
- lhld string
- inx h
- shld string
- jmp slp1
-
-; found, return index
-
-found: lda index
- ret
-
-; not found, return zero
-
-notfnd: sub a
- ret
-
-string: ds 2
-substg: ds 2
-slen: ds 1
-sublen: ds 1
-index: ds 1
-ENDIF
-
- ret
-
-;
-; Speed tables
-; (Note that speed tables MUST be in alphabetical order for later
-; lookup procedures, and must begin with a value showing the total
-; number of entries. The speed help tables are just for us poor
-; humans.
-;
-; db string length, string, divisor (2 bytes or 1 word, ab)
-; the data byte a is return in A and E, and b in D
-; only byte 'a' is the key for the table
-
-IF sb6
-spdtbl: db 9 ; 9 entries
- db 04h,'1200$', 0Bh,0Bh
- db 03h,'150$', 0Eh,0Eh
- db 05h,'19200$', 01h,01h
- db 04h,'2400$', 0Ah,0Ah
- db 03h,'300$', 0Dh,0Dh
- db 05h,'38400$', 00h,00h
- db 04h,'4800$', 09h,09h
- db 03h,'600$', 0Ch,0Ch
- db 04h,'9600$', 08h,08h
-
-sphtbl: db cr,lf
- db ' 150 300 600 1200 2400 4800 9600 19200 38400$'
-ENDIF
-
-IF sb9
-spdtbl: db 7 ; 7 entries
- db 04h,'1200$', 24h,24h
- db 05h,'19200$', 20h,20h
- db 04h,'2400$', 23h,23h
- db 03h,'300$', 26h,26h
- db 04h,'4800$', 22h,22h
- db 03h,'600$', 25h,25h
- db 04h,'9600$', 21h,21h
-
-sphtbl: db cr,lf
- db ' 300 600 1200 2400 4800 9600 19200$'
-ENDIF
-
-
-;
-; This is the system-dependent SET PORT command.
-; HL contains the argument from the command table.
-;
-sysprt:
- ret
-
-IF sb180
-prttbl EQU 0 ; SET PORT is not supported
-prhtbl EQU 0
-ENDIF
-
-;
-; selmdm - select modem port
-; selcon - select console port
-; selmdm is called before using inpmdm or outmdm;
-; selcon is called before using inpcon or outcon.
-; For iobyt systems, diddle the I/O byte to select console or comm port;
-; For the rest, does nothing.
-; preserves bc, de, hl.
-;
-selmdm:
- ret
-
-selcon:
- ret
-
-;
-; Get character from console, or return zero.
-; result is returned in A. destroys bc, de, hl.
-;
-inpcon:
- mvi c,dconio ;Direct console I/O BDOS call.
- mvi e,0FFH ;Input.
- call BDOS
-
- ret
-
-;
-; Output character in E to the console.
-; destroys bc, de, hl
-;
-outcon:
- mvi c,dconio ;Console output bdos call.
- call bdos ;Output the char to the console.
-
- ret
-
-;
-; outmdm - output a char from E to the modem.
-; the parity bit has been set as necessary.
-; returns nonskip; bc, de, hl preserved.
-;
-outmdm:
-
-IF sb180
- db 0EDh,038h,mnstat
- ani output ; check status
- jz outmdm ; wait until port is available
- mov a, e
- db 0EDh,039h,mntxdat ; transmit
-ENDIF
-
- ret
-
-;
-; get character from modem; return zero if none available.
-; for IOBYT systems, the modem port has already been selected.
-; destroys bc, de, hl.
-;
-inpmdm:
-
-IF sb180
- lxi h, delfac ; loops to give delay
-inpm1: db 0EDh,038h,mnstat
- ani input ; check status
- jz inpm2
- db 0EDh,038h,mnrddat ; get a byte
- ret
-
-inpm2: dcx h ; no data
- mov h, a
- ora l
- jnz inpm1 ; still tries left
- ret ; with zero in A
-ENDIF
-
- ret
-
-;
-; flsmdm - flush comm line.
-; Modem is selected.
-; Currently, just gets characters until none are available.
-;
-flsmdm:
- call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-
-;
-
-;
-; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
-lptstat:
-IF iobyte ;[33]
- call bprtst ; get status
-ENDIF ;iobyte[33]
-IF NOT iobyte ;[33]
- xra a ; assume it is ok.. this may not be necessary
-ENDIF ;iobyte [33]
- ret
-;
-; outlpt - output character in E to printer
-; console is selected.
-; preserves de.
-;
-outlpt:
- push d ; save DE in either case
- call prtflt ; go through printer filter [30]
- ana a ; if A = 0 do nothing,
- jz outlp1 ; if a=0 do nothing
-
-outlp1: pop d ; restore saved register pair
- ret
-
-; delchr - make delete look like a backspace. Unless delete is a printing
-; character, we just need to print a backspace. (we'll output clrspc
-; afterwards)
-delchr:
-
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the character at the current cursor position
-clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the current line
-clrlin: lxi d,eralin
- jmp prtstr
-
-; erase the whole screen, and go home. preserves b (but not c)
-clrtop: lxi d,erascr
- jmp prtstr
-
-IF sb180
-sysver: db 'MicroMint SB 180 '
-ENDIF
-
-IF sb6
- db ' (6 MHz)'
-ENDIF
-
-IF sb9
- db ' (9 MHz)'
-ENDIF
- db '$'
-
-IF lasm
-LINK CPXVDU.ASM ; get terminal defs etc
-ENDIF ;lasm
+IF NOT lasm
+.printx * CPXSB.ASM *
+ENDIF ;NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file created 16 July, 1987 by OBSchou from code submitted
+; by William Rose for the Micromint SB180 systems (as featured in
+; BYTE magazine, 1986). This file has been modified to fit in with
+; Kermit-80 V4.08 etc. His file KERSYS.ASM is a stripped down version
+; of CPXSYS.ASM (formerly CP4SYS.ASM).
+;
+; revision history:
+; KERSYS.ASM - version 0.8 dated 13 Jul 87.
+;
+; Cutdown CP4SYS.ASM for SB-180/Ampro 230.
+;
+;
+; While this is a single CPU version (to ease editing) the assembler
+; conditionals have been kept to identify machine specific code.
+;
+; Note that the baud setting routine also sets parity, but this does not
+; change the parity given by Kermit's 'stat' command. I assume that the
+; main body of the program does its own parity check.
+;
+; Revision history (last entry first)
+;
+; edit 2, 22 July by OBSchou to massage file to fit with CPXCOM.ASM.
+;
+; edit 1, 15 July, 1987 by OBSchou for William Rose who submitted
+; the code for Kermit-80 V 4.05. Modified code as appropriate
+; for 4.08 compatability.
+;
+
+delfac EQU 150 ; Delay factor in SB-180 input loop - a fudge
+
+;
+; Keep module name, edit number, and last revision date in memory.
+;
+;sysedt: db 'KERSYS.ASM (03) 12-FEB-87 $' ; last SB-180 revision
+;sysedt: db 'KERSYS.ASM (04) 12-APR-87 $' ; Telecom Merlin added
+;sysedt: db 'KERSYS.ASM (5) 9-May-87 $' ; Minor tidying
+;sysedt: db 'KERSYS.ASM (6A) 17-Jun-87 $' ; BT Merlin M2215 only
+;sysedt: db 'KERSYS.ASM (7) 19-Jun-87 $' ; SB-180 only
+;sysedt: db 'KERSYS.ASM (8) 13-Jul-87 $' ; 6/9 MHz version
+family: db 'CPXSB.ASM (2) 22-Jul-87$' ; First entry for V4.08/9
+
+;
+; Assembly time message to let me know I'm building the right version.
+;
+
+IF sb180
+.printx * Assembling Kermit-80 for Micromint SB-180 *
+ENDIF
+
+
+IF sb180
+mnctrla EQU 000H ;Modem control port - CNTLA0
+mnctrlb EQU 002H ;Modem control port - CNTLB0
+mnstat EQU 004H ;Modem status port - STAT0
+mntxdat EQU 006H ;Modem output port - TDR0
+mnrddat EQU 008H ;Modem input port - RDR0
+output EQU 002H ;Transmit data register empty mask - TDRE
+input EQU 080H ;Receive data register full mask - RDRF
+z80 EQU TRUE ;This one's an HD64180, but Z80 will do
+ENDIF
+
+
+sysxin: ; continuation of system initialisation from sysinit
+
+IF sb180
+ lxi h, porbuf ; park the original settings
+ db 0EDh, 038h, mnctrla ; HD64180 code IN0 g,(m)
+ mov m, a
+ inx h
+ db 0EDh, 038h, mnctrlb
+ mov m, a
+ inx h
+ db 0EDh, 038h, mnstat
+ mov m, a
+ENDIF
+ ; re-initialise for KERMIT
+IF sb6
+ mvi h, 08h ; 0000$1001 - 9600 baud, (even) parity
+ mvi l, 08h ; 'speed' is two bytes
+ENDIF
+
+IF sb9
+ mvi h, 21h ; 0010$0001 - 9600 baud, (even) parity
+ mvi l, 21h ; 'speed' is two bytes
+ENDIF
+
+IF sb180
+ shld speed
+ lxi h, parind
+ mvi m, 8 ; index for 8 bits, no parity, 2 stop
+ call setpor
+ENDIF
+
+ ret
+
+porbuf: ds 3 ; original port settings
+
+;
+; system-dependent KERMIT termination processing
+; If we've changed anything, this is our last chance to put it back.
+;
+sysexit:
+
+IF sb180
+ lxi h, porbuf
+ mov a, m ; output parity
+ db 0EDh, 039h, mnctrla ; HD64180 code OUT0 (m),g
+ inx h
+ mov a, m ; output baud rate
+ db 0EDh, 039h, mnctrlb
+ inx h
+ mov a, m ; output to clear error flags
+ db 0EDh, 039h, mnstat
+ ; read twice to reset DCD0 ?
+ db 0EDh, 038h, mnstat
+ db 0EDh, 038h, mnstat
+ENDIF
+
+ ret
+
+;
+; system-dependent processing for start of CONNECT command
+;
+syscon:
+ ret
+
+conmsg: ; Messages printed when entering transparent (CONNECT) mode:
+
+ db '$'
+
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+ ret
+
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing all the
+; system-independent escape sequences.
+;
+sysinh:
+
+IF sb180
+ lxi d, inhlps
+ call prtstr
+ENDIF
+
+ ret
+
+; Additional, system-dependent help for transparent mode
+; (two-character escape sequences)
+inhlps:
+
+IF sb180
+ db cr, lf, 'V Cycle port parameters'
+ENDIF
+
+ db '$' ; string terminator
+
+;
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:
+; non-skip: sequence has been processed
+; skip: seqence was not recognized
+;
+sysint:
+; ani 137O ; convert lower case to upper, for testing...
+ ; does this work?
+IF sb180
+ cpi 'V' ; cycle port ?
+ jz pcycl
+ cpi 'v'
+ jz pcycl
+ENDIF
+
+ jmp rskp ; take skip return - command not recognised
+
+; Actual commands
+
+IF sb180
+pcycl:
+ lxi h, parind ; increment parval, modulo 12
+ mov a, m
+ adi 1
+ cpi 13
+ jnz pcy1
+ mvi a, 1
+pcy1: mov m, a ; update the storage
+ ; get index of name in parstr
+ ora a ; clear flags
+ dcr a
+ rlc
+ rlc
+ mov c, a
+ mvi b, 0
+ lxi h, parstr
+ inx h
+ dad b
+ push h
+ lxi d, cgmsg1
+ call prtstr
+ pop d
+ call prtstr
+ lxi d, cgmsg2
+ call prtstr
+ call setpor ; reset the port
+
+ ret
+
+cgmsg1: db '<$'
+cgmsg2: db '>$'
+ENDIF
+
+ ret
+
+;
+; Delay routine. Called with time (hundredths of seconds) in A.
+; The inner loop delays 1001 T-states, assuming no wait states are
+; inserted; this is repeated CPUSPD times, for a total delay of just
+; over 0.01 second. (CPUSPD should be set to the system clock rate,
+; in units of 100KHz: for an unmodified Kaypro II, that's 25 for
+; 2.5 MHz. Some enterprising soul could determine whether or not the
+; Kaypro actually inserts a wait state on instruction fetch (a common
+; practice); if so, the magic number at delay2 needs to be decreased.
+; (We also neglect to consider time spent at interrupt level).
+;
+; called by: sendbr
+; destroys BC
+;
+;delay: mvi c,cpuspd ; Number of times to wait 1000 T-states to
+; ; make .01 second delay
+;delay2: mvi b,70 ; Number of times to execute inner loop to
+; ; make 1000 T-state delay
+;delay3: dcr b ; 4 T-states (* 70 * cpuspd)
+; jnz delay3 ; 10 T-states (* 70 * cpuspd)
+; dcr c ; 4 T-states (* cpuspd)
+; jnz delay2 ; 10 T-states (* cpuspd)
+; ; total delay: ((14 * 70) + 14) * cpuspd
+; ; = 1001 * cpuspd
+; dcr a ; 4 T-states
+; jnz delay ; 10 T-states
+;
+; ret ; grand total: ((1001 * cpuspd) + 14) * a
+
+;
+; sysflt - system-dependent filter
+; called with character in E.
+; if this character should not be printed, return with A = zero.
+; preserves bc, de, hl.
+; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
+;
+sysflt:
+ mov a,e ; get character for testing
+ ret
+
+;
+; mdmflt - modem filter
+; called with character to be sent to printer in E
+; with parity set as appropriate.
+; return with accumulator = 0 do do nothing,
+; <> 0 to send char in E.
+mdmflt:
+ mov a,e ; get character to test
+ ret
+
+;
+; prtflt - printer filter
+; called with character to be sent to printer in E
+; returns with a = 0 to do nothing
+; a <> 0 to print it.
+;
+; this routine for those printer that automatically insert
+; a lf on cr, or cr for lf. Should this be shifted to
+; the system indep. stuff, in say 4.06?
+;
+prtflt:
+ mov a,e ; get character to test
+
+IF FALSE ; strip out lf from printer stream
+ ani 7fh ; make sure it is parity less
+ cpi lf ; is it a line feed?
+ rnz ; no, print it
+; xra a ; yes, don't.
+
+ENDIF
+
+ ret
+
+;
+; system-dependent processing for BYE command.
+;
+sysbye:
+ ret
+
+;
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; both
+; bytes of this value are also stored in 'speed'.
+;
+sysspd:
+
+IF sb180
+ lxi d, prtmsg ; ask for variables
+ call prtstr
+
+ lxi d, tbuf ; get suitable string
+ mvi c, 10
+ call bdos
+
+ lxi h, tbuf1
+ mov a, m
+ ora a
+ jz setpor ; leave unchanged if string zero length
+
+ cpi 3 ; check given length
+ jnz spd1 ; error - wrong length
+ inx h
+ inx h
+ mov a, m
+ ani 137O ; convert parity code to upper case
+ mov m, a
+
+ lxi d, tbuf1 ; get index of given parameter
+ lxi h, parstr
+ call sposn
+ ora a
+ jnz spd2 ; or fall through if error
+spd1: lxi d, invmsg ; invalid input - try again
+ call prtstr
+ jmp sysspd
+
+spd2: adi 3 ; get index to parval table
+ rrc ; by dividing by 4
+ rrc
+ ani 15 ; mask out high bits
+ lxi h, parind
+ mov m, a ; and store it
+ call setpor ; set up port iaw index and speed bytes
+
+ ret
+
+prtmsg: db cr,lf,'Enter bit/char, parity, and stop bits required.'
+ db cr,lf,'(Bit 7/8 Parity N/O/E Stop 1/2 - CR same) : $'
+invmsg: db cr,lf,'Invalid parameters$'
+
+parind: db 8 ; default <8N2> index
+parstr: db 48,'7N1$7N2$7O1$7O2$7E1$7E2$'
+ db '8N1$8N2$8O1$8O2$8E1$8E2$'
+parval: db 0,1,16+2,16+3,2,3
+ db 4,5,16+6,16+7,6,7
+tbuf db 6
+tbuf1 db 3,'8N2','$$$$'
+
+;
+; Set up the port using the table index in parind and the speed byte
+;
+setpor:
+ lxi h, parind
+ mov a, m
+ dcr a
+ lxi h, parval ; table base
+ mvi b, 0
+ mov c, a
+ dad b ; HL points at parameter value
+ mov a, m
+ mov b, a ; park parval
+
+ ani 16 ; the parity switch bit
+ lxi h, speed
+ add m ; this is now the baud rate byte
+ mov c, a ; park it
+
+ mov a, b ; sort out the parameter byte
+ ani 7 ; b/p/s only wanted
+ adi 96 ; RE, TE enable
+ db 0EDh,039h,mnctrla ; output parity etc.
+ mov a, c
+ db 0EDh,039h,mnctrlb ; output baud rate
+ mvi a, 0
+ db 0EDh,039h,mnstat ; clear status
+ db 0EDh,038h,mnstat ; read twice to reset DCD0
+ db 0EDh,038h,mnstat
+ ret
+
+;
+; Find substring position - Leventhal page 293, modified
+; enter with subtring in DE and string in HL
+; returns index in A or 0 for failure
+;
+sposn:
+ mov a, m ; exit if either string length zero
+ ora a
+ jz notfnd
+ sta slen
+ mov b, a
+ inx h
+ shld string
+ xchg
+ mov a, m
+ ora a
+ jz notfnd
+ sta sublen
+ mov c, a
+ inx h
+ shld substg
+ mov a, b
+
+; no of searches = stringlen - substrlen + 1
+; if substr longer than string quit immediately
+
+ sub c
+ jc notfnd
+ inr a
+ mov c, a
+ xra a
+ sta index
+
+; search until remaining string shorter than substring
+
+slp1: lxi h, index
+ inr m
+ lda sublen
+ mov b, a
+ lhld substg
+ xchg
+ lhld string
+
+; try to match substring starting at index
+
+cmplp: ldax d
+ cmp m
+ jnz slp2
+ dcr b
+ jz found
+ inx h
+ inx d
+ jmp cmplp
+
+; arrive here if match fails
+
+slp2: dcr c
+ jz notfnd
+ lhld string
+ inx h
+ shld string
+ jmp slp1
+
+; found, return index
+
+found: lda index
+ ret
+
+; not found, return zero
+
+notfnd: sub a
+ ret
+
+string: ds 2
+substg: ds 2
+slen: ds 1
+sublen: ds 1
+index: ds 1
+ENDIF
+
+ ret
+
+;
+; Speed tables
+; (Note that speed tables MUST be in alphabetical order for later
+; lookup procedures, and must begin with a value showing the total
+; number of entries. The speed help tables are just for us poor
+; humans.
+;
+; db string length, string, divisor (2 bytes or 1 word, ab)
+; the data byte a is return in A and E, and b in D
+; only byte 'a' is the key for the table
+
+IF sb6
+spdtbl: db 9 ; 9 entries
+ db 04h,'1200$', 0Bh,0Bh
+ db 03h,'150$', 0Eh,0Eh
+ db 05h,'19200$', 01h,01h
+ db 04h,'2400$', 0Ah,0Ah
+ db 03h,'300$', 0Dh,0Dh
+ db 05h,'38400$', 00h,00h
+ db 04h,'4800$', 09h,09h
+ db 03h,'600$', 0Ch,0Ch
+ db 04h,'9600$', 08h,08h
+
+sphtbl: db cr,lf
+ db ' 150 300 600 1200 2400 4800 9600 19200 38400$'
+ENDIF
+
+IF sb9
+spdtbl: db 7 ; 7 entries
+ db 04h,'1200$', 24h,24h
+ db 05h,'19200$', 20h,20h
+ db 04h,'2400$', 23h,23h
+ db 03h,'300$', 26h,26h
+ db 04h,'4800$', 22h,22h
+ db 03h,'600$', 25h,25h
+ db 04h,'9600$', 21h,21h
+
+sphtbl: db cr,lf
+ db ' 300 600 1200 2400 4800 9600 19200$'
+ENDIF
+
+
+;
+; This is the system-dependent SET PORT command.
+; HL contains the argument from the command table.
+;
+sysprt:
+ ret
+
+IF sb180
+prttbl EQU 0 ; SET PORT is not supported
+prhtbl EQU 0
+ENDIF
+
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; For iobyt systems, diddle the I/O byte to select console or comm port;
+; For the rest, does nothing.
+; preserves bc, de, hl.
+;
+selmdm:
+ ret
+
+selcon:
+ ret
+
+;
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+ mvi c,dconio ;Direct console I/O BDOS call.
+ mvi e,0FFH ;Input.
+ call BDOS
+
+ ret
+
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+ mvi c,dconio ;Console output bdos call.
+ call bdos ;Output the char to the console.
+
+ ret
+
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+;
+outmdm:
+
+IF sb180
+ db 0EDh,038h,mnstat
+ ani output ; check status
+ jz outmdm ; wait until port is available
+ mov a, e
+ db 0EDh,039h,mntxdat ; transmit
+ENDIF
+
+ ret
+
+;
+; get character from modem; return zero if none available.
+; for IOBYT systems, the modem port has already been selected.
+; destroys bc, de, hl.
+;
+inpmdm:
+
+IF sb180
+ lxi h, delfac ; loops to give delay
+inpm1: db 0EDh,038h,mnstat
+ ani input ; check status
+ jz inpm2
+ db 0EDh,038h,mnrddat ; get a byte
+ ret
+
+inpm2: dcx h ; no data
+ mov h, a
+ ora l
+ jnz inpm1 ; still tries left
+ ret ; with zero in A
+ENDIF
+
+ ret
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+;
+flsmdm:
+ call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+
+;
+
+;
+; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
+lptstat:
+IF iobyte ;[33]
+ call bprtst ; get status
+ENDIF ;iobyte[33]
+IF NOT iobyte ;[33]
+ xra a ; assume it is ok.. this may not be necessary
+ENDIF ;iobyte [33]
+ ret
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+;
+outlpt:
+ push d ; save DE in either case
+ call prtflt ; go through printer filter [30]
+ ana a ; if A = 0 do nothing,
+ jz outlp1 ; if a=0 do nothing
+
+outlp1: pop d ; restore saved register pair
+ ret
+
+; delchr - make delete look like a backspace. Unless delete is a printing
+; character, we just need to print a backspace. (we'll output clrspc
+; afterwards)
+delchr:
+
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the character at the current cursor position
+clrspc: mvi e,' '
+ call outcon
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the current line
+clrlin: lxi d,eralin
+ jmp prtstr
+
+; erase the whole screen, and go home. preserves b (but not c)
+clrtop: lxi d,erascr
+ jmp prtstr
+
+IF sb180
+sysver: db 'MicroMint SB 180 '
+ENDIF
+
+IF sb6
+ db ' (6 MHz)'
+ENDIF
+
+IF sb9
+ db ' (9 MHz)'
+ENDIF
+ db '$'
+
+IF lasm
+LINK CPXVDU.ASM ; get terminal defs etc
+ENDIF ;lasm
diff --git a/cpxswt.asm b/cpxswt.asm
index 32b0d11..1942c41 100644
--- a/cpxswt.asm
+++ b/cpxswt.asm
@@ -1,294 +1,294 @@
-IF NOT lasm
-.printx * CPXSWT.ASM *
-ENDIF ; NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file is a simple family or system file switcher, selecting
-; one of several family files, or selectin CPXSYS.ASM (now modified)
-; if a family file does not exist.
-;
-;
-; revision history:
-;
-;edit 10, 7-Jan-1991 by MF. Added code by Jay S. Rouman to support the
-; Ampro Little Board (see CPXBBI.ASM) and PRINTX for the HP-125.
-; edit 9, 1st September 1990 by Russell Lang, rjl@monu1.cc.monash.edu.au.
-; Added Microbee support.
-; edit 8, 2 December by OBSchou. Added Z80MU "system" to allow kermit-80
-; debugging on a PC!
-;
-; edit 7, 27 October, 1987 by OBSchou. Added bits for Sanyo, Compupro,
-; Genie and TRS-80 M4.
-;
-; edit 6, 16 July, 1987 for Will Rose, who has submitted code for
-; Micromint SB180 (6 and 9 Mhz) and a BT Merlin (alias RAIR)
-;
-; edit 5, 15 July, 1987 by OBSchou for David Moore, who has submitted
-; code for a Teletek SYSTEMASTER and for ADM22 terminals.
-;
-; edit 4, 14 July 1987 by OBSchou for JA Shearwood of Birmingham University,
-; Chris Miles of Manchester University. Added a Cifer family file
-; for John, and added a BigBoard-Kaypro-Xerox family file for Chris
-; Finally, added in new family file for Heath, telcon, z100 and scntpr
-; systems for Martin Carter of Nottingham University.
-;
-; edit 3, 6 April, 1986 by OBSchou.
-; Added in switching for NCR Desision Mate V and Amstrad CPC 664/6128
-; systems.
-;
-; edit 2, March 16, 1987 by OBSchou.
-; added in support for m80 macro assembler.
-;
-; edit 1 28 January, 1987 by OBSchou.
-; Take out the series of printx etx and selection of systems and
-; leave this with only the system dep. code for systems without
-; a family file. Hopefully, this file will go alltogether in time.
-;
-; Keep module name, edit number, and last revision date in memory.
-swtver: db 'CPXSWT.ASM (10) 7-Jan-1991 $'
-;
-; Assembly time message to let me know I'm building the right version.
-; LASM generates an 'S' error along with the message, which is messy, but
-; better than trying to put everything inside a IF m80 OR mac80 conditional,
-; because LASM doesn't like nested IF's, either.
-
-
-IF (torfam AND lasm)
-;Link to the module with the code for Superbrains, Torch, Cifer and pci2651
-LINK CPXTOR.ASM ; also NCR DMV systems
-ENDIF;(torfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
-
-IF (ciffam AND LASM)
-; Link to the Cifer family file. (Cifer code previously on CPXTOR.ASM)
-LINK CPXCIF.ASM ; Cifer family file
-ENDIF ;(ciffam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
-
-IF (appfam AND lasm) ;[33] apple frogs as a separate family..
-; Link to the APPLE family...
-LINK CPXAPP.ASM
-ENDIF ;(appfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
-
-IF (norfam AND lasm); Link to the Northstar family (and Comart)
-; Link to the NorthStar family file
-LINK CPXNOR.ASM
-ENDIF; (norfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
-
-IF (pcwfam AND lasm) ;[35] Amstrad PCW 8256/8512 or CPC systems
-; Link to the Amstrad PCW family
-LINK CPXPCW.ASM
-ENDIF ;(cpwfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
-
-IF (bbifam AND lasm) ;Bigboard, Kaypro and Xerox 820 file
-; Link to the Bigboard family
-.printx * Linking to the BigBoard family *
-LINK CPXBBI.ASM
-ENDIF ;(bbifam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
-
-IF (heafam AND lasm) ; heath, z100, telcon, and scntpr systems
-; Link to the Heath-telcon-screentyper family
-.printx * Linking to the Heath-telcon-screentyper family *
-LINK CPXHEA.ASM
-ENDIF ;(heafam) - m80 use: INCLUDE from CPXTYP.ASM
-
-IF (sbfam AND lasm)
-; Link to the SB180 Family file
-,printx * Linking to the SB180 Family file *
-LINK CPXSB.ASM
-ENDIF ; (sbfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
-
-IF (m2215 AND lasm)
-; Link to the RAIR/ BT Merlin code
-.printx * Linking to the Merlin/Rair code *
-LINK CPXMRL.ASM
-ENDIF ; (m2215 AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
-
-IF (sanfam AND lasm)
-; Link to the Sanyo code
-.printx * linking to the sanyo code *
-LINK CPXSYO.ASM
-ENDIF ; (sanfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
-
-IF (comfam AND lasm)
-; Link to the compupro code
-.printx * linking to the Compupro code *
-LINK CPXPRO.ASM
-ENDIF ; (comfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
-
-IF (genfam AND lasm)
-; Link to the Genie family code
-.printx * linking to the Genie code *
-LINK CPXGNI.ASM
-ENDIF ; (genfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
-
-IF (trsfam AND lasm)
-; Link to the TRS-80 family file
-.printx * linking to the TRS family file*
-LINK CPXTM4.ASM
-ENDIF ; (trsfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
-
-IF (z80fam AND lasm)
-; Link to the Z80MU family file
-.printx * linking to the Z80MU family file*
-LINK CPXZ80.ASM
-ENDIF ; (z80fam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
-
-IF (beefam AND lasm)
-; Link to the Microbee family file
-.printx * linking to the Microbee family file *
-LINK CPXBEE.ASM
-ENDIF ; (beefam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
-
-
-; If we have come here, we are assembling the CPXSYS.ASM file
-
-IF robin
-.printx * Assembling KERMIT-80 for the DEC VT180 *
-ENDIF
-
-IF vector
-.printx * Assembling KERMIT-80 for the Vector Graphics *
-ENDIF
-
-IF osi
-.printx * Assembling KERMIT-80 for the Ohio Scientific *
-ENDIF
-
-IF heath
-.printx * Assembling KERMIT-80 for the Heath/Zenith 89 *
-ENDIF
-
-IF z100
-.printx * Assembling KERMIT-80 for the Heath/Zenith Z100 *
-ENDIF
-
-IF trs80
-.printx * Assembling KERMIT-80 for the TRS-80 II *
-ENDIF
-
-IF osbrn1
-.printx * Assembling KERMIT-80 for the Osborne 1 *
-ENDIF
-
-IF telcon
-.printx * Assembling KERMIT-80 for the Telcon Zorba *
-ENDIF
-
-IF dmII
-.printx * Assembling KERMIT-80 for the DECmate II *
-ENDIF
-
-IF gener
-.printx * Assembling Generic KERMIT-80 *
-ENDIF
-
-IF cpm3
-.printx * Assembling Generic KERMIT-80 for CP/M 3.0 *
-ENDIF
-
-IF hp125
-.printx * Assembling Kermit-80 for the HP-125 Series 100 *
-ENDIF ;hp125
-
-IF kpii
-.printx * Assembling Kaypro II KERMIT-80 *
-ENDIF
-
-IF xer820 ;[pcc001]
-.printx * Assembling Xerox 820 KERMIT-80 *
-ENDIF ;[pcc001]
-
-IF bbII
-.printx * Assembling BigBoard II KERMIT-80 *
-ENDIF
-
-IF ampro
-.printx * Assembling Ampro Little Board KERMIT-80 *
-ENDIF
-
-IF mdI
-.printx * Assembling for Morrow Decision I *
-ENDIF ;mdI [Toad Hall]
-
-IF mmdI
-.printx * Assembling for Morrow Micro Decision I *
-ENDIF ;mmdI
-
-IF mikko
-.printx * Assembling MikroMikko Kermit-80 *
-ENDIF
-
-IF delphi ;[7]
-.printx * Assembling Digicomp Delphi 100 Kermit-80 *
-ENDIF ;[7]
-
-IF cpt85xx
-.printx * Assembling CPT-85xx (under CompuPak CP/M) Kermit-80 *
-ENDIF
-
-IF cmemco ;[25]
-.printx * Assembling KERMIT-80 for the Cromemco (TU-ART) *
-ENDIF;cmemco
-
-IF bbc ;[22]
-.printx * Assembling Kermit-80 for BBC with Z80 co-processor *
-ENDIF ;[22]
-
-IF rm380z ;[22]
-.printx * Assembling Kermit-80 for Research Machines 380Z *
-ENDIF ;[22]
-
-IF px8 ;[29]
-.printx * Assembling Kermit-80 for Epson PX-8 *
-ENDIF ;px8 [29]
-
-IF mmate ;[29]
-.printx * Assembling KERMIT-80 for the PMC MicroMate *
-ENDIF ;mmate [29]
-
-IF disc ;[29]
-.printx * Assembling KERMIT-80 for the A. C. E. Discovery *
-ENDIF ;disc [29]
-
-IF s1008 ;[29]
-.printx * Assembling KERMIT-80 for the MicroSales s1008 *
-ENDIF ;s1008 [29]
-
-IF access ;[29]
-.printx * Assembling Kermit-80 for the ACCESS-MATRIX computer *
-ENDIF ;access [29]
-
-IF lobo ;[hh]
-.printx * Assembling Kermit-80 for the Lobo MAX-80 *
-ENDIF;lobo [hh]
-
-IF teletek
-.printx * Assembling Kermit-80 for the Teletek *
-ENDIF ;teletek
-
-;
-;
-; If here, we have not linked to a family, so link to CPXSYS.ASM
-IF lasm
- LINK CPXSYS.ASM
-ENDIF ;lasm
-;
-; If we are using m80, then the CPXSYS.ASM file will be INCLUDED from CPXTYP
-;
-
-
-
+IF NOT lasm
+.printx * CPXSWT.ASM *
+ENDIF ; NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file is a simple family or system file switcher, selecting
+; one of several family files, or selectin CPXSYS.ASM (now modified)
+; if a family file does not exist.
+;
+;
+; revision history:
+;
+;edit 10, 7-Jan-1991 by MF. Added code by Jay S. Rouman to support the
+; Ampro Little Board (see CPXBBI.ASM) and PRINTX for the HP-125.
+; edit 9, 1st September 1990 by Russell Lang, rjl@monu1.cc.monash.edu.au.
+; Added Microbee support.
+; edit 8, 2 December by OBSchou. Added Z80MU "system" to allow kermit-80
+; debugging on a PC!
+;
+; edit 7, 27 October, 1987 by OBSchou. Added bits for Sanyo, Compupro,
+; Genie and TRS-80 M4.
+;
+; edit 6, 16 July, 1987 for Will Rose, who has submitted code for
+; Micromint SB180 (6 and 9 Mhz) and a BT Merlin (alias RAIR)
+;
+; edit 5, 15 July, 1987 by OBSchou for David Moore, who has submitted
+; code for a Teletek SYSTEMASTER and for ADM22 terminals.
+;
+; edit 4, 14 July 1987 by OBSchou for JA Shearwood of Birmingham University,
+; Chris Miles of Manchester University. Added a Cifer family file
+; for John, and added a BigBoard-Kaypro-Xerox family file for Chris
+; Finally, added in new family file for Heath, telcon, z100 and scntpr
+; systems for Martin Carter of Nottingham University.
+;
+; edit 3, 6 April, 1986 by OBSchou.
+; Added in switching for NCR Desision Mate V and Amstrad CPC 664/6128
+; systems.
+;
+; edit 2, March 16, 1987 by OBSchou.
+; added in support for m80 macro assembler.
+;
+; edit 1 28 January, 1987 by OBSchou.
+; Take out the series of printx etx and selection of systems and
+; leave this with only the system dep. code for systems without
+; a family file. Hopefully, this file will go alltogether in time.
+;
+; Keep module name, edit number, and last revision date in memory.
+swtver: db 'CPXSWT.ASM (10) 7-Jan-1991 $'
+;
+; Assembly time message to let me know I'm building the right version.
+; LASM generates an 'S' error along with the message, which is messy, but
+; better than trying to put everything inside a IF m80 OR mac80 conditional,
+; because LASM doesn't like nested IF's, either.
+
+
+IF (torfam AND lasm)
+;Link to the module with the code for Superbrains, Torch, Cifer and pci2651
+LINK CPXTOR.ASM ; also NCR DMV systems
+ENDIF;(torfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
+
+IF (ciffam AND LASM)
+; Link to the Cifer family file. (Cifer code previously on CPXTOR.ASM)
+LINK CPXCIF.ASM ; Cifer family file
+ENDIF ;(ciffam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
+
+IF (appfam AND lasm) ;[33] apple frogs as a separate family..
+; Link to the APPLE family...
+LINK CPXAPP.ASM
+ENDIF ;(appfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
+
+IF (norfam AND lasm); Link to the Northstar family (and Comart)
+; Link to the NorthStar family file
+LINK CPXNOR.ASM
+ENDIF; (norfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
+
+IF (pcwfam AND lasm) ;[35] Amstrad PCW 8256/8512 or CPC systems
+; Link to the Amstrad PCW family
+LINK CPXPCW.ASM
+ENDIF ;(cpwfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
+
+IF (bbifam AND lasm) ;Bigboard, Kaypro and Xerox 820 file
+; Link to the Bigboard family
+.printx * Linking to the BigBoard family *
+LINK CPXBBI.ASM
+ENDIF ;(bbifam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
+
+IF (heafam AND lasm) ; heath, z100, telcon, and scntpr systems
+; Link to the Heath-telcon-screentyper family
+.printx * Linking to the Heath-telcon-screentyper family *
+LINK CPXHEA.ASM
+ENDIF ;(heafam) - m80 use: INCLUDE from CPXTYP.ASM
+
+IF (sbfam AND lasm)
+; Link to the SB180 Family file
+,printx * Linking to the SB180 Family file *
+LINK CPXSB.ASM
+ENDIF ; (sbfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
+
+IF (m2215 AND lasm)
+; Link to the RAIR/ BT Merlin code
+.printx * Linking to the Merlin/Rair code *
+LINK CPXMRL.ASM
+ENDIF ; (m2215 AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
+
+IF (sanfam AND lasm)
+; Link to the Sanyo code
+.printx * linking to the sanyo code *
+LINK CPXSYO.ASM
+ENDIF ; (sanfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
+
+IF (comfam AND lasm)
+; Link to the compupro code
+.printx * linking to the Compupro code *
+LINK CPXPRO.ASM
+ENDIF ; (comfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
+
+IF (genfam AND lasm)
+; Link to the Genie family code
+.printx * linking to the Genie code *
+LINK CPXGNI.ASM
+ENDIF ; (genfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
+
+IF (trsfam AND lasm)
+; Link to the TRS-80 family file
+.printx * linking to the TRS family file*
+LINK CPXTM4.ASM
+ENDIF ; (trsfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
+
+IF (z80fam AND lasm)
+; Link to the Z80MU family file
+.printx * linking to the Z80MU family file*
+LINK CPXZ80.ASM
+ENDIF ; (z80fam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
+
+IF (beefam AND lasm)
+; Link to the Microbee family file
+.printx * linking to the Microbee family file *
+LINK CPXBEE.ASM
+ENDIF ; (beefam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM
+
+
+; If we have come here, we are assembling the CPXSYS.ASM file
+
+IF robin
+.printx * Assembling KERMIT-80 for the DEC VT180 *
+ENDIF
+
+IF vector
+.printx * Assembling KERMIT-80 for the Vector Graphics *
+ENDIF
+
+IF osi
+.printx * Assembling KERMIT-80 for the Ohio Scientific *
+ENDIF
+
+IF heath
+.printx * Assembling KERMIT-80 for the Heath/Zenith 89 *
+ENDIF
+
+IF z100
+.printx * Assembling KERMIT-80 for the Heath/Zenith Z100 *
+ENDIF
+
+IF trs80
+.printx * Assembling KERMIT-80 for the TRS-80 II *
+ENDIF
+
+IF osbrn1
+.printx * Assembling KERMIT-80 for the Osborne 1 *
+ENDIF
+
+IF telcon
+.printx * Assembling KERMIT-80 for the Telcon Zorba *
+ENDIF
+
+IF dmII
+.printx * Assembling KERMIT-80 for the DECmate II *
+ENDIF
+
+IF gener
+.printx * Assembling Generic KERMIT-80 *
+ENDIF
+
+IF cpm3
+.printx * Assembling Generic KERMIT-80 for CP/M 3.0 *
+ENDIF
+
+IF hp125
+.printx * Assembling Kermit-80 for the HP-125 Series 100 *
+ENDIF ;hp125
+
+IF kpii
+.printx * Assembling Kaypro II KERMIT-80 *
+ENDIF
+
+IF xer820 ;[pcc001]
+.printx * Assembling Xerox 820 KERMIT-80 *
+ENDIF ;[pcc001]
+
+IF bbII
+.printx * Assembling BigBoard II KERMIT-80 *
+ENDIF
+
+IF ampro
+.printx * Assembling Ampro Little Board KERMIT-80 *
+ENDIF
+
+IF mdI
+.printx * Assembling for Morrow Decision I *
+ENDIF ;mdI [Toad Hall]
+
+IF mmdI
+.printx * Assembling for Morrow Micro Decision I *
+ENDIF ;mmdI
+
+IF mikko
+.printx * Assembling MikroMikko Kermit-80 *
+ENDIF
+
+IF delphi ;[7]
+.printx * Assembling Digicomp Delphi 100 Kermit-80 *
+ENDIF ;[7]
+
+IF cpt85xx
+.printx * Assembling CPT-85xx (under CompuPak CP/M) Kermit-80 *
+ENDIF
+
+IF cmemco ;[25]
+.printx * Assembling KERMIT-80 for the Cromemco (TU-ART) *
+ENDIF;cmemco
+
+IF bbc ;[22]
+.printx * Assembling Kermit-80 for BBC with Z80 co-processor *
+ENDIF ;[22]
+
+IF rm380z ;[22]
+.printx * Assembling Kermit-80 for Research Machines 380Z *
+ENDIF ;[22]
+
+IF px8 ;[29]
+.printx * Assembling Kermit-80 for Epson PX-8 *
+ENDIF ;px8 [29]
+
+IF mmate ;[29]
+.printx * Assembling KERMIT-80 for the PMC MicroMate *
+ENDIF ;mmate [29]
+
+IF disc ;[29]
+.printx * Assembling KERMIT-80 for the A. C. E. Discovery *
+ENDIF ;disc [29]
+
+IF s1008 ;[29]
+.printx * Assembling KERMIT-80 for the MicroSales s1008 *
+ENDIF ;s1008 [29]
+
+IF access ;[29]
+.printx * Assembling Kermit-80 for the ACCESS-MATRIX computer *
+ENDIF ;access [29]
+
+IF lobo ;[hh]
+.printx * Assembling Kermit-80 for the Lobo MAX-80 *
+ENDIF;lobo [hh]
+
+IF teletek
+.printx * Assembling Kermit-80 for the Teletek *
+ENDIF ;teletek
+
+;
+;
+; If here, we have not linked to a family, so link to CPXSYS.ASM
+IF lasm
+ LINK CPXSYS.ASM
+ENDIF ;lasm
+;
+; If we are using m80, then the CPXSYS.ASM file will be INCLUDED from CPXTYP
+;
+
+
+
diff --git a/cpxsy2.asm b/cpxsy2.asm
index a420d37..999f084 100644
--- a/cpxsy2.asm
+++ b/cpxsy2.asm
@@ -1,1364 +1,1364 @@
-IF NOT lasm
-.printx * CPXSY2.ASM *
-ENDIF ;NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the system-dependent code and data for KERMIT.
-; It will be probably be broken into independent files to generate
-; overlays for the various systems, one or more overlay possible
-; from each file. For now, we will leave it in one piece.
-;
-; revision history:
-;
-;
-; This is the system-dependent command to change the baud rate.
-; DE contains the two-byte value from the baud rate table; this
-; value is also stored in 'speed'.
-sysspd:
-
-
-IF px8 ; [29]
- push d
- call rsclose ; baud rate can only be set on opening rs232
- pop d
- mov a, e
- sta px8blk+4 ; set param block
- call rsopen ; to set rate
- ret
-ENDIF ; px8 [29]
-
-; Set the speed for the Osborne I
-IF osbrn1
- mvi a,osbin1 ;Reset the ACIA
- call osstst ;Write the control port
-osbs1: inr c ;Waiting loop
- jnz osbs1
- mov a,e ; get the specified speed
- jmp osstst ;Write the control reg.
-ENDIF;osbrn1
-
-;[hh] set the speed for a lobo MAX-80
-IF lobo
- mov a,e ;[hh] get the parsed value
-setbd: sta baudrt ;[hh] and send it to the baud rate port
- ret ;[hh]
-ENDIF;lobo
-
-; Set the speed for bigboard I or the delphi or the CPT-85xx
-; or Cromemco (TU-ART)
-IF delphi OR cpt85xx OR cmemco OR mmate ;[22] [29]
- mov a,e ; get the parsed value
- out baudrt ; Tell the baud rate generator.
- ret
-ENDIF;delphi OR cpt85xx OR cmemco OR mmate [22] [29]
-
-;[22] Set the speed for Acorn BBC
-IF bbc
- mov l,e
- mvi a,7 ;Set receive baud rate
- call osbyte ;*FX7,?e
- mov l,e
- mvi a,8 ;Set transmit baud rate
- call osbyte ;*FX8,?e
- ret
-ENDIF;[22] bbc
-
-;[22] Set speed for RM 380Z
-IF rm380z
- mvi a,4 ;device type (SI/O4) in A
- rst 6 ; EMT
- db 29h ; SETLST
- ret
-ENDIF;[22] rm380z
-
-; Set the speed for MicroMikko. DE is baud rate multiplier
-IF mikko
- di
- lxi h,txclk
- mov m,d ;LSB first (swapped in memory)
- mov m,e ;MSB last
- lxi h,rxclk
- mov m,d
- mov m,e
- mvi b,0 ;"modifier" for 1 stop bit
- mvi a,2 ;Test MSB of speed >2 (110 bps or less)
- cmp e
- jp miksp1
- mvi b,00001000B ;"modifier" for 2 stop bits
-miksp1: mvi a,4 ;Select SIO Reg 4
- lxi h,sioac
- mov m,a
- mvi a,sion4 ;Get values
- ora b ;Add modifier
- mov m,a ;Set value (stop bits)
- ei
- ret
-ENDIF;mikko
-
-
-; Set the speed for the Decision I
-IF mdI
- call selmdm ;Let's be absolutely sure, huh?
- mvi a,dlab+wls1+wls0+stb ;Set data latch access bit
- out lcr ;Out to Line Control Register
- lhld speed ;Load baudrate multiplier
- xchg
- mov a,d ;Get low order byte for baud rate
- out dlm ;Out to the MSB divisor port
- mov a,e ;...and the high order byte
- out dll ;Out to the LSB divisor port
- mvi a,wls1+wls0+stb ;Enable Divisor Access Latch
- out lcr ;Out to ACE Line Control Register
- xra a ;Clear A
- out ier ;Set no interrupts
- out lsr ;Clear status
- in msr ;Clear Modem Status Register
- in lsr ;Clear Line Status Register
- in rbr ;Clear Receiver Buffers
- in rbr
- ret
-ENDIF ;mdI [Toad Hall]
-
-IF teletek
- di
- mov a,e ; first speed byte
- out baudrt
- mov a,d ; second speed byte
- out baudrt
- ei
- ret
-ENDIF ;teletek
-
-IF access ;[29]
- mov a,e ;Get the parsed time constant
-;The following code is derived from the Access initialization code
- sta savspd ;Save the time constant
- mvi a,14h ;Code for 'monitor' to set channel A baudrate
- call monitor
- lda savspd ;Get the time constant
- call monitor ; and send it to the CRT
- ret
-savspd: ds 1
-monitor: ;Routine to do CRT functions
- out 90h ;Output the data to the CRT
- mvi a,1 ;Set DRDY true
- out 23h
-mon1: in 0a0h ;Wait for CACK* true
- rlc
- jc mon1
- in 80h ;Read the input data latch
- push psw ;Save the input data
- xra a ;Set DRDY false
- out 23h
-mon2: in 0a0h ;Wait for CACK* false
- rlc
- jc mon2
- pop psw
- sta 0ee02h ;Save the input data
- ret
-ENDIF;access [29]
-
-
-IF disc ;[29]
-; Assuming that parsing of value from speed table puts low order
-; byte of time constant in the e register and high byte in d.
- mvi a,12 ;Register 12
- out mnprts
- mov a,e ;Low order byte of time constant
- out mnprts
- mvi a,13 ;Register 13
- out mnprts
- mov a,d ;High order byte of time constant
- out mnprts
- mvi a,14 ;Register 14
- out mnprts
- mvi a,3 ;Enable baud rate generator
- out mnprts
- mvi a,11 ;Register 11
- out mnprts
- mvi a,52h ;no Xtal, tclk=rclk=/trxc out=br gen
- out mnprts
- ret
-ENDIF;disc [29]
-; Speed tables
-; (Note that speed tables MUST be in alphabetical order for later
-; lookup procedures, and must begin with a value showing the total
-; number of entries. The speed help tables are just for us poor
-; humans.
-
-; db string length,string,divisor (2 identical bytes or 1 word)
-; [Toad Hall]
-
-IF delphi OR lobo ;[hh]
-spdtbl: db 10h ;16 entries
- db 03h,'110$', 02h,02h
- db 04h,'1200$', 07h,07h
- db 05h,'134.5$', 03h,03h
- db 03h,'150$', 04h,04h
- db 04h,'1800$', 08h,08h
- db 05h,'19200$', 0fh,0fh
- db 04h,'2000$', 09h,09h
- db 04h,'2400$', 0ah,0ah
- db 03h,'300$', 05h,05h
- db 04h,'3600$', 0bh,0bh
- db 04h,'4800$', 0ch,0ch
- db 02h,'50$', 00h,00h
- db 03h,'600$', 06h,06h
- db 04h,'7200$', 0dh,0dh
- db 02h,'75$', 01h,01h
- db 04h,'9600$', 0eh,0eh
-
-sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
- db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'
-ENDIF;delphi OR lobo ;[hh]
-
-IF cpt85xx
-spdtbl: db 15 ; 15 entries
- db 03,'110$', 03h,03h
- db 04,'1200$', 09h,09h
- db 05,'134.5$', 04h,04h
- db 03,'150$', 05h,05h
- db 04,'1800$', 0Ah,0Ah
- db 04,'2400$', 0Bh,0Bh
- db 03,'300$', 06h,06h
- db 04,'3600$', 0Ch,0Ch
- db 04,'4800$', 0Dh,0Dh
- db 02,'50$', 01h,01h
- db 03,'600$', 07h,07h
- db 04,'7200$', 0Eh,0Eh
- db 02,'75$', 02h,02h
- db 03,'900$', 08h,08h
- db 04,'9600$', 0Fh,0Fh
-
-sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 900'
- db cr,lf,' 1200 1800 2400 3600 4800 7200 9600$'
-ENDIF;cpt85xx
-
-IF bbc ;[22]
-spdtbl: db 8 ; 8 entries
- db 04,'1200$', 04h,04h
- db 03,'150$', 02h,02h
- db 05,'19200$', 08h,08h
- db 04,'2400$', 05h,05h
- db 03,'300$', 03h,03h
- db 04,'4800$', 06h,06h
- db 02,'75$', 01h,01h
- db 04,'9600$', 07h,07h
-
-sphtbl: db cr,lf,' 75 150 300 1200 2400 4800 9600 19200$'
-ENDIF;[22] bbc
-
-IF rm380z ;[22]
-spdtbl: db 7 ; 7 entries
- db 03,'110$', 00h,00h
- db 04,'1200$', 03h,03h
- db 04,'2400$', 04h,04h
- db 03,'300$', 01h,01h
- db 04,'4800$', 05h,05h
- db 03,'600$', 02h,02h
- db 04,'9600$', 06h,06h
-
-sphtbl: db cr,lf,' 110 300 600 1200 2400 4800 9600$'
-ENDIF;[22] rm380z
-
-IF px8 ; [29]
-spdtbl: db 9 ; 9 entries
- db 03,'110$', 02h,02h
- db 04,'1200$', 0ah,0ah
- db 03,'150$', 04h,04h
- db 05,'19200$', 0fh,0fh
- db 04,'2400$', 0ch,0ch
- db 03,'300$', 06h,06h
- db 04,'4800$', 0dh,0dh
- db 03,'600$', 08h,08h
- db 04,'9600$', 0eh,0eh
-sphtbl: db cr, lf
- db ' 100 150 300 600 1200 2400 4800 9600 19200$'
-ENDIF ; px8 [29]
-
-IF mikko
-spdtbl: db 9h ;9 entries
- db 03h,'110$'
- dw 0369h
- db 04h,'1200$'
- dw 0050h
- db 03h,'150$'
- dw 0280h
- db 04h,'2400$'
- dw 0028h
- db 03h,'300$'
- dw 0140h
- db 04h,'4800$'
- dw 0014h
- db 03h,'600$'
- dw 00A0H
- db 02h,'75$'
- dw 0500h
- db 04h,'9600$'
- dw 000ah
-
-sphtbl: db cr,lf,' 75 110 150 300 600 1200 2400 4800 9600$'
-ENDIF;mikko
-
-IF osbrn1
-spdtbl: db 02h ;2 entries
- db 04h,'1200$', OSBI12,OSBI12
- db 03h,'300$', OSBI03,OSBI03
-
-sphtbl: db cr,lf,' 300',cr,lf,' 1200$'
-ENDIF;osbrn1
-
-
-IF mdI
-spdtbl: db 0dh ; 13 entries
- db 03h, '110$'
- dw 1047
- db 04h, '1200$'
- dw 96
- db 03h, '150$'
- dw 768
- db 05h,'19200$'
- dw 6
- db 04h, '2400$'
- dw 48
- db 03h, '300$'
- dw 384
- db 05h,'38400$'
- dw 3
- db 03h, '450$'
- dw 288
- db 04h, '4800$'
- dw 24
- db 05h,'56000$'
- dw 2
- db 03h, '600$'
- dw 192
- db 02h, '75$'
- dw 1536
- db 04h, '9600$'
- dw 12
-
-sphtbl: db cr,lf,' 75 110 150 300 450 600 1200'
- db cr,lf,' 2400 4800 9600 19200 38400 56000$'
-
-;(Lord knows what you'll be communicating with at 56000 baud, but the
-;Multi-I/O board literature says it'll do it, so what the heck....
-;might as well throw it in here just to show off...sure hope the
-;port don't melt...)
-
-ENDIF ;mdI [Toad Hall]
-
-IF cmemco ;[25]
-spdtbl: db 7 ; 7 entries
- db 3,'110$', 01H,01H
- db 4,'1200$', 88H,88H
- db 3,'150$', 82H,82H
- db 4,'2400$', 90H,90H
- db 3,'300$', 84H,84H
- db 4,'4800$', 0A0H,0A0H
- db 4,'9600$', 0C0H,0C0H
-
-sphtbl: db cr,lf
- db ' 110 150 300 1200 2400 4800 9600$'
-ENDIF;cmemco
-
-IF access ;Similar to bbI with different values [29]
-spdtbl: db 6h ;6 entries
- db 04h,'1200$', 28h,28h
- db 04h,'2400$', 14h,14h
- db 03h,'300$', 0a0h,0a0h
- db 04h,'4800$', 0ah,0ah
- db 03h,'600$', 50h,50h
- db 04h,'9600$', 5,5
-
-sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$'
-ENDIF;access [29]
-
-IF mmate ;[29]
-spdtbl: db 10h ;16 entries
- db 03h,'110$', 0e2h,0e2h
- db 04h,'1200$', 0e7h,0e7h
- db 05h,'134.5$', 0e3h,0e3h
- db 03h,'150$', 0e4h,0e4h
- db 04h,'1800$', 0e8h,0e8h
- db 05h,'19200$', 0efh,0efh
- db 04h,'2000$', 0e9h,0e9h
- db 04h,'2400$', 0eah,0eah
- db 03h,'300$', 0e5h,0e5h
- db 04h,'3600$', 0ebh,0ebh
- db 04h,'4800$', 0ech,0ech
- db 02h,'50$', 0e0h,0e0h
- db 03h,'600$', 0e6h,0e6h
- db 04h,'7200$', 0edh,0edh
- db 02h,'75$', 0e1h,0e1h
- db 04h,'9600$', 0eeh,0eeh
-
-sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
- db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'
-ENDIF;mmate [29]
-
-IF disc ;[29]
-; Similar to mikko table but with different time constant values
-spdtbl: db 9h ;9 entries
- db 03h,'110$'
- dw 1134
- db 04h,'1200$'
- dw 102h
- db 03h,'150$'
- dw 831
- db 04h,'2400$'
- dw 50
- db 03h,'300$'
- dw 415
- db 04h,'4800$'
- dw 24
- db 03h,'600$'
- dw 206
- db 02h,'75$'
- dw 1665
- db 04h,'9600$'
- dw 11
-
-sphtbl: db cr,lf,' 75 110 150 300 600 1200 2400 4800 9600$'
-ENDIF;disc [29]
-
-IF teletek
-spdtbl: db 7 ; 7 entries
- db 4, '1200$', 47h,40h
- db 5,'19200$', 47h,04h
- db 4, '2400$', 47h,20h
- db 3, '300$', 47h,00h
- db 4, '4800$', 47h,10h
- db 3, '600$', 47h,80h
- db 4, '9600$', 47h,08h
-
-sphtbl: db cr,lf
- db ' 300 600 1200 2400 4800 9600 19200$'
-ENDIF ;teletk
-
-
-; The following conditionals were once a huge if not statement. There
-; wasn't enough room to add the lobo to the list, so it had to be broken
-; into 2, which you can't do with an if not. I redid it as two ifs and
-; applied them to those that wouldn't set baud. [Hal Hostetler]
-IF robin OR gener OR dmII OR vector OR trs80;[32]
-spdtbl equ 0 ; SET BAUD not supported.
-sphtbl equ 0
-ENDIF;robin OR gener OR dmII OR vector OR trs80
-;
-IF mmdI OR osi OR cpm3 OR S1008 ; [29]
-spdtbl EQU 0 ;[hh] SET BAUD not supported.
-sphtbl EQU 0 ;[hh] ran out of room above...
-ENDIF;mmdI OR osi OR cpm3 OR S1008 [29]
-;
-IF hp125 ;[MF]
-spdtbl equ 0 ; SET BAUD not supported.
-sphtbl equ 0
-ENDIF;hp125 [MF]
-;
-; This is the system-dependent SET PORT command.
-; HL contains the argument from the command table.
-sysprt:
-IF lobo ;[hh]
- mov a,l ;[hh] get the data port value and store at
- sta outmd3+1 ;[hh] the two places we use...
- sta inpmd2+1 ;[hh] MNPORT in the overlay
- sta port ;[hh] inform program of the change in ports
- inr a ;[hh] status port = data port + 1 in the Lobo
- sta outmd1+1 ;[hh] store it at the three places...
- sta inpmd1+1 ;[hh] we use MNPRTS...
- sta outctl+1 ;[hh] in the overlay
- mov a,h ;[hh] now get the baud rate port value
- sta getbd+1 ;[hh] store it in the two places we use...
- sta setbd+1 ;[hh] BAUDRT in the overlay
- sta port+1 ;[hh] don't need to, but keeps it consistant
-getbd: lda baudrt ;[hh] get baud rate value from port
- sta speed ;[hh] tell STAT. baud rate for each port
- ;[hh] is independant of the other
-ENDIF ;lobo
-
-IF iobyt
- mov a,m ;Get the I/O byte
- sta prtiob ;Save the desired IO byte for this port
- inx h ;Point at next entry
- mov a,m ;Get the output function
- sta prtfun ;Save it
-ENDIF;iobyt
-
-IF iobyt AND robin
- inx h ;Point at next entry
- mov a,m ;Get the hardware address for the port
- sta prtadr ;Store it
-ENDIF;iobyt AND robin
-;
-IF hp125 ;[MF]
- push psw
- push b
- push d
- push h
- xchg ;Put port connect sequence address in DE
- call prtstr ;Connect proper port
- pop h
- pop d
- pop b
- pop psw
-ENDIF;hp125 [MF]
-;
- ret
-;
-; Port tables for Lobo MAX-80
-IF lobo ;[hh]
-; help text
-prhtbl: db cr,lf,'RS-232 port A or B$'
-;
-; command table
-prttbl: db 02H ;[hh] two entries
- db 01H,'A$',0E4H,0D0H
- db 01H,'B$',0E6H,0D4H
-ENDIF ;lobo
-;
-; Port tables for GENERIC CPM 2.2
-IF gener
-; help text
-prhtbl: db cr,lf,'CRT device'
- db cr,lf,'PTR device'
- db cr,lf,'TTY device'
- db cr,lf,'UC1 device'
- db cr,lf,'UR1 device'
- db cr,lf,'UR2 device$'
-
-; command table
-prttbl: db 06H ;Six devices to choose from
- db 03H,'CRT$'
- dw crtptb
- db 03H,'PTR$'
- dw ptrptb
- db 03H,'TTY$'
- dw ttyptb
- db 03H,'UC1$'
- dw uc1ptb
- db 03H,'UR1$'
- dw ur1ptb
- db 03H,'UR2$'
- dw ur2ptb
-
-; port entry table
-; table entries are:
-; db iobyte-value, BDOS output function, reserved
-crtptb: db crtio,conout,0
-ptrptb: db ptrio,punout,0
-ttyptb: db ttyio,conout,0
-uc1ptb: db uc1io,conout,0
-ur1ptb: db ur1io,punout,0
-ur2ptb: db ur2io,punout,0
-ENDIF;gener
-
-;
-; Port tables for DECmate II or MicroMikko or Acorn BBC
-;
-IF dmII OR mikko OR bbc ;[22]
-; help text
-prhtbl: db cr,lf,'COMMUNICATIONS port$'
-
-; command table
-prttbl: db 01H ;Only one port known at this point
- db 0EH,'COMMUNICATIONS$'
- dw comptb ;address of info
-
-; port entry table
-; table entries are:
-; db iobyte-value, BDOS output function, reserved
-comptb: db batio,punout,0
-
-ENDIF;[22] dmII OR mikko OR bbc
-;
-; Port tables for Robin
-;
-IF robin
-; help text
-prhtbl: db cr,lf,'COMMUNICATIONS port'
- db cr,lf,'GENERAL purpose port'
- db cr,lf,'PRINTER port$'
-
-; command table
-prttbl: db 03H ;Three entries
- db 0EH,'COMMUNICATIONS$'
- dw comptb
- db 07H,'GENERAL$'
- dw gppptb
- db 07H,'PRINTER$'
- dw prnptb
-
-; port entry table
-; table entries are:
-; db iobyte-value, BDOS output function, hardware port address
-; (control/status)
-;
-;At present, the hardware port address is only used for sending a break.
-comptb: db batio,punout,comtst
-gppptb: db gppio,conout,gentst
-prnptb: db lptio,conout,prntst
-
-prtadr: db comtst ;space for current hardware port address
-ENDIF;robin
-
-IF iobyt
-prtfun: db punout ;Function to use for output to comm port
-prtiob: db batio ;I/O byte to use for communicating
-coniob: db defio ;I/O byte to use for console
-ENDIF;iobyt
-;
-IF hp125 ;[MF]
-; Help table
-prhtbl: db cr,lf,'Communications port'
- db cr,lf,'Printer port$'
-; command table
-prttbl: db 02H ;2 entries
- db 0eH,'COMMUNICATIONS$'
- dw mapon1
- db 07H,'PRINTER$'
- dw mapon2
-;Port table entries are the addresses of the escape sequences to connect
-;the ports.
-;
-ENDIF;hp125 [MF]
-
-IF NOT (iobyt OR lobo OR hp125) ;[hh] [MF]
-prttbl equ 0 ; SET PORT is not supported
-prhtbl equ 0
-ENDIF;NOT iobyt OR lobo OR hp125 [MF]
-;
-; selmdm - select modem port
-; selcon - select console port
-; selmdm is called before using inpmdm or outmdm;
-; selcon is called before using inpcon or outcon.
-; For iobyt systems, diddle the I/O byte to select console or comm port;
-; For Decision I, switches Multi I/O board to console or modem serial
-; port. [Toad Hall]
-; For the rest, does nothing.
-; preserves bc, de, hl.
-selmdm:
-IF iobyt
- lda prtiob ;Set up for output to go to the comm port
- sta iobyte ;Switch byte directly
-ENDIF;iobyt
-
-IF mdI
- lda group
- ori mdmgrp ;Mask modem serial port
- out grpsel
-ENDIF;mdI [Toad Hall]
-
- ret
-
-selcon:
-IF iobyt
- lda coniob ;Set up for output to go to the console port
- sta iobyte ;Switch directly
-ENDIF;iobyt
-
-IF mdI
- lda group
- ori congrp ;Mask console serial port (1)
- out grpsel
-ENDIF;mdI [Toad Hall]
-
- ret
-; Get character from console, or return zero.
-; result is returned in A. destroys bc, de, hl.
-;
-inpcon:
-IF NOT iobyt
- mvi c,dconio ;Direct console I/O BDOS call.
- mvi e,0FFH ;Input.
- call BDOS
-ENDIF;NOT iobyt
-
-IF iobyt
- call bconst ;Get the status
- ora a ;Anything there?
- rz ;No, forget it
- call bconin ;Yes, get the character
-ENDIF;iobyt
- ret
-;
-; Output character in E to the console.
-; destroys bc, de, hl
-;
-outcon:
-
-IF rm380z ;[22]
- mov a,e
- cpi cr ;cr produces cr + lf
- jnz outcn1
- mvi e,'N'-100O ;Control-N produces cr only
-outcn1: ;continue
-ENDIF;[22] rm380z
-
-IF NOT iobyt
- mvi c,dconio ;Console output bdos call.
- call bdos ;Output the char to the console.
-ENDIF;NOT iobyt
-
-IF iobyt
- mov c,e ;Character
- call bcnout ;to Console
-ENDIF;iobyt
- ret
-;
-; outmdm - output a char from E to the modem.
-; the parity bit has been set as necessary.
-; returns nonskip; bc, de, hl preserved.
-outmdm:
-IF osi OR lobo ;[hh]
- push h
-outmd1: lxi h,mnprts ;address of the port status register
-outmd2: mov a,m ; get port status in A
- ani output ;Loop till ready.
- jz outmd2
-outmd3: lxi h,mnport ;address of port data register
- mov m,e ; write the character
- pop h
- ret
-ENDIF;osi OR lobo
-
-IF osbrn1
- call osldst ;Read the status port
- ani output ;Loop till ready.
- jz outmdm
- mov a,e
- jmp osstda ;Write to the data port
-ENDIF;osbrn1
-
-IF px8 ; [29]
- push h
- push b
- push d
-outmd1: call rsoutst ; get the output status
- ora a
- jz outmd1 ; check if output enabled
- pop d
- mov c, e ; char in C
- push d
- call rsput
- pop d
- pop b
- pop h
- ret
-ENDIF; px8 [29]
-
-IF inout
- in mnprts ;Get the output done flag.
- ani output ;Is it set?
- jz outmdm ;If not, loop until it is.
- mov a,e
- out mnport ;Output it.
- ret
-ENDIF;inout
-
-IF iobyt
-;**** Note that we enter from outpkt with the I/O byte already set up for
-; output to go to the comm port
- push h
- push b
- lda prtfun ;Get the output function
- mov c,a ;Into C
- call bdos ;And output the character
- pop b
- pop h
- ret
-ENDIF;iobyt
-
-IF cpm3 OR hp125 ;[MF]
- push h
- push b
- mvi c,auxout ;Output to the aux output device
- call bdos
- pop b
- pop h
- ret
-ENDIF;cpm3 OR hp125 [MF]
-
-; org $+100h AND 0FF00h ; get rid of phase error
-
-;
-; get character from modem; return zero if none available.
-; for IOBYT systems, the modem port has already been selected.
-; destroys bc, de, hl.
-inpmdm:
-IF iobyt
- call bconst ;Is Char at COMM-Port?
- ora a ;something there?
- rz ; return if nothing there
- call bconin ; data present. read data.
-ENDIF;iobyt
-
-IF cpm3
- mvi c,auxist
- call bdos ;is char at auxin?
- ora a ;something there?
- rz ;no
- mvi c,auxin
- call bdos ;read char from auxin
-ENDIF;cpm3
-;
-IF hp125 ;[MF]
- lxi b,70ffh ;SEt subfunction to get RDR (auxin) status
- call bdos ;is char at RDR?
- ora a ;something there?
- rz ;no
- mvi c,auxin
- call bdos ;read char from RDR
-ENDIF;hp125 [MF]
-
-IF osi OR lobo ;[hh]
-inpmd1: lda mnprts ;Get the port status into A.
- ani input ;See if the input ready bit is on.
- rz ;If not then return.
-inpmd2: lda mnport ;If so, get the char.
-ENDIF;osi OR lobo
-
-IF osbrn1
- call osldst ;Read the status port
- ani input ;Something there?
- rz ;Nope
- call osldda ;Read the data port
-ENDIF;osbrn1
-
-IF inout
-;Note: modem port should already be selected for mdI. [Toad Hall]
- in mnprts ;Get the port status into A.
- ani input ;See if the input ready bit is on.
- rz ;If not then return.
- in mnport ;If so, get the char.
-ENDIF;inout
-
-IF px8 ; [29]
- call rserst ; check error status
- ani 64h ; this assumes 'not open' cannot occur
- jnz inpmd1 ; error has occurred!
- call rsinst ; any chars outstanding?
- ora a
- rz ; exit if none
- call rsget ; get char in A
- ret
-; return the 'no char outstanding' indication on error
-inpmd1: mvi a, 0
-ENDIF; px8 [29]
-
- ret ; return with character in A
-
-
-;
-; flsmdm - flush comm line.
-; Modem is selected.
-; Currently, just gets characters until none are available.
-
-flsmdm: call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-;
-; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not.
-lptstat:
-IF iobyt ;[33]
- call bprtst ;
-call bprtst ; get status
-ENDIF ;iobyt[33]
-IF NOT iobyt ;[33]
- xra a ; assume it is ok.. this may not be necessary
-ENDIF ;iobyt [33]
- ret
-
-;
-; outlpt - output character in E to printer
-; console is selected.
-; preserves de.
-outlpt:
- push d ; save DE in either case
- call prtflt ; go through printer filter [30]
- ana a ; if A = 0 do nothing,
- jz outlp1 ; [30] if a=0 do nothing
-
-IF NOT iobyt
- mvi c,lstout
- call bdos ;Char to printer
-ENDIF;NOT iobyt
-IF iobyt
- mov c,e
- call blsout
-ENDIF;iobyt
-
-outlp1: pop d ; restore saved register pair
- ret
-;
-; Screen manipulation routines
-; csrpos - move to row B, column C
-;
-; csrpos for terminals that use a leadin sequence followed
-; by (row + 31.) and (column + 31.)
-;
-IF NOT (robin OR dmII OR osi OR vector OR termin OR hp125)
- ;[MF] Terminals code in CPXVDU
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,h ; get row
- adi (' '-1) ; space is row one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,l ; get column
- adi (' '-1) ; space is column one
- mov e,a
- jmp outcon ; output it and return
-ENDIF;NOT (robin OR dmII OR osi OR vector OR termin OR hp125)[MF]
-;
-;
-;
-; csrpos for ANSI terminals
-;
-IF robin OR dmII
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; peek at coordinates
- push h ; then save away again
- mov l,h ; l = row
- mvi h,0 ; hl = row
- call nout ; output in decimal
- mvi e,';' ; follow with semicolon
- call outcon ; print it
- pop h ; restore column
- mvi h,0 ; hl = column
- call nout
- mvi e,'H' ; terminate with 'move cursor' command
- jmp outcon ; output it and return
-ENDIF;robin OR dmII
-;
-; csrpos for the HP-125 [MF]
-;
-IF hp125 ;[MF]
-csrpos: dcr b ;HP-125 uses zero-based addressing
- dcr c ;...
- push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; peek at coordinates
- push h ; then save away again
- mov l,h ; l = row
- mvi h,0 ; hl = row
- call nout ; output in decimal
- mvi e,'R'+20h ;Say it was a row
- call outcon ; print it
- pop h ; restore column
- mvi h,0 ; hl = column
- call nout
- mvi e,'C' ; terminate with 'move cursor' command
- jmp outcon ; output it and return
-ENDIF;hp125 [MF]
-;
-; csrpos for the Vector General. It's weird.
-;
-IF vector
-csrpos: dcr b ; vector uses zero-based addressing?
- dcr c
- push b ; save coordinates
- mvi e,esc ; print an escape
- call outcon
- pop d ; peek at coordinates
- push d
- call outcon ; output column
- pop d
- mov e,d ; get row
- jmp outcon ; output and return
-ENDIF;vector
-
-IF osi ; systems without cursor positioning
-csrpos: ret ; dummy routine referenced by linkage section
-ENDIF;osi
-
-
-;
-; delchr - make delete look like a backspace. Unless delete is a printing
-; character, we just need to print a backspace. (we'll output clrspc
-; afterwards)
-; For Kaypro and Vector General, delete puts a blotch on the screen.
-; For Apple and Osborne 1, delete moves but doesn't print.
-delchr:
-
-IF vector OR osbrn1 OR lobo
- lxi d,delstr
- jmp prtstr
-ENDIF ;vector OR osbrn1 OR lobo
-
-IF bbc OR rm380z ;[22]
- ret
-ENDIF;bbc OR rm380z
-
-IF NOT (vector OR osbrn1 OR bbc OR rm380z);[22]
- mvi e,bs ;get a backspace
- jmp outcon
-ENDIF;NOT (vector OR osbrn1 OR bbc OR rm380z [22]
-
-; erase the character at the current cursor position
-clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the current line
-clrlin: lxi d,eralin
- jmp prtstr
-
-; erase the whole screen, and go home. preserves b (but not c)
-clrtop: lxi d,erascr
- jmp prtstr
-
-
-IF robin
-sysver: db 'VT180 Robin$'
-ENDIF;robin
-
-IF dmII
-sysver: db 'DECmate II CP/M-80$'
-ENDIF;dmII
-
-IF delphi ; [7] new system
-sysver: db 'Digicomp Delphi 100$'
-endif;delphi
-
-IF access
-sysver: db 'Actrix CP/M$'
-endif;
-
-IF teletek
-sysver: db 'Teletek SYSTEMASTER CP/M-80$'
-ENDIF ;teletek
-
-IF cpt85xx
-sysver: db 'CPT-85xx under CompuPak CP/M$'
-ENDIF;cpt85xx
-
-IF mdI
-sysver: db 'Morrow Decision I$'
-ENDIF;mdI [Toad Hall]
-
-IF mmdI
-sysver: db 'MicroDecision I$'
-ENDIF;mmdI
-
-IF osi
-sysver: db 'Ohio Scientific$'
-ENDIF;osi
-
-IF mmate ;[29]
-sysver: db 'PMC Micromate using port I/O$'
-ENDIF;mmate [29]
-
-IF disc ;[29]
-sysver: db 'Discovery using 83U board port B$'
-ENDIF ;disc [29]
-
-IF s1008 ;[29]
-sysver: db 'U. S. MicroSales using printer port$'
-ENDIF ;s1008 [29]
-
-IF cmemco ;[25]
-sysver: db 'Cromemco (TU-ART)$'
-ENDIF;cmemco
-;
-IF robin OR dmII
-; Note that we cannot support Graphics Mode or the H19 erase-screen command
-; (<esc>E), because the sequences are more than three bytes.
-defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
-vtval EQU 0 ; we probably don't want VT52 emulation
-outlin: db esc,3CH,esc,'[H',esc,'[J',cr,lf,tab,tab,'$'
-erascr: db esc,'[H',esc,'[J$' ;Clear screen and go home.
-eralin: db cr,esc,'[K$' ;Clear line.
-curldn: db esc,'[$' ; Cursor leadin
-ttab:
-ta: db esc,'[A$' ; Cursor up.
-tb: db esc,'[B$' ; Cursor down.
-tc: db esc,'[C$' ; Cursor right.
-td: db esc,'[D$' ; Cursor left
-te: db '$',0,0,0 ; (can't) Clear display
-tf: db '$',0,0,0 ; (don't) Enter Graphics Mode
-tg: db '$',0,0,0 ; (don't) Exit Graphics mode
-th: db esc,'[H$' ; Cursor home.
-ti: db esc,'M$',0 ; Reverse linefeed.
-tj: db esc,'[J$' ; Clear to end of screen.
-tk: db esc,'[K$' ; Clear to end of line.
-ENDIF;robin OR dmII
-
-IF mikko
-sysver: db 'MikroMikko$'
-outlin: db subt,cr,lf,tab,'$'
-erascr: db subt,'$' ;Clear screen and go home.
-eralin: db cr,1CH,'$' ;Clear line.
-curldn: db esc,'=$' ;cursor leadin
-ttab: ;Table start location.
-ta: db 0BH,'$',0,0 ;Cursor up.
-tb: db 0AH,'$',0,0 ;Cursor down.
-tc: db 0CH,'$',0,0 ;Cursor right.
-td: db bs,'$',0,0 ;Cursor left
-te: db subt,'$',0,0 ;Clear display
-tf: db '$',0,0,0 ;(can't) Enter Graphics Mode
-tg: db '$',0,0,0 ;(can't) Exit Graphics mode
-th: db 1EH,'$',0,0 ;Cursor home.
-ti: db '$',0,0,0 ;(can't) Reverse linefeed.
-tj: db 1cH,'$',0,0 ;Clear to end of screen.
-tk: db 1cH,'$',0,0 ;Clear to end of line.
-ENDIF;mikko
-;
-IF bbc ;[22]
-sysver: db 'BBC (Z80)$'
-outlin: db 0CH,esc,'=',21H,30H,'$'
-erascr: db 0CH,'$' ;Clear screen and go home.
-eralin: db cr,esc,'@$' ;Clear line.
-curldn: db esc,'=$' ;cursor leadin
-ttab: ;Table start location.
-ta: db 0BH,'$',0,0 ;Cursor up.
-tb: db 0AH,'$',0,0 ;Cursor down.
-tc: db tab,'$',0,0 ;Cursor right.
-td: db bs,'$',0,0 ;Cursor left
-te: db 0CH,'$',0,0 ;Clear display
-tf: db '$',0,0,0 ;(can't) Enter Graphics Mode
-tg: db '$',0,0,0 ;(can't) Exit Graphics mode
-th: db 1EH,'$',0,0 ;Cursor home.
-ti: db '$',0,0,0 ;(can't) Reverse linefeed.
-tj: db esc,'?$',0,0 ;Clear to end of screen.
-tk: db esc,'@$',0,0 ;Clear to end of line.
-ENDIF;[22] bbc
-;
-IF rm380z ;[22]
-sysver: db 'Research Machines 380Z$'
-outlin: db 1FH,cr,tab,'$'
-erascr: db 1FH,'$' ;Clear screen and go home.
-eralin: db 0EH,19H,'$' ;Clear line.
-curldn: db 16H,'$' ;cursor leadin
-ttab: ;Table start location.
-ta: db 0BH,'$',0,0 ;Cursor up.
-tb: db 0AH,'$',0,0 ;Cursor down.
-tc: db 18H,'$',0,0 ;Cursor right.
-td: db bs,'$',0,0 ;Cursor left
-te: db 1FH,'$',0,0 ;Clear display
-tf: db '$',0,0,0 ;(can't) Enter Graphics Mode
-tg: db '$',0,0,0 ;(can't) Exit Graphics mode
-th: db 1DH,'$',0,0 ;Cursor home.
-ti: db '$',0,0,0 ;(can't) Reverse linefeed.
-tj: db 1EH,'$',0,0 ;Clear to end of screen.
-tk: db 19H,'$',0,0 ;Clear to end of line.
-ENDIF;[22] rm380z
-
-IF lobo ;[hh]
-sysver: db 'Lobo MAX-80$'
-outlin: db esc,'*',cr,lf,tab,tab,'$'
-erascr: db esc,'*$' ;[hh] clear screen and home cursor
-eralin: db cr,esc,'R$' ;[hh] clear line
-curldn: db esc,'=$' ;[hh] cursor lead-in string
-delstr: db bs,' ',bs,bs,'$' ;[hh] ??adjust for echoing delete
-ttab: ;[hh] table start location
-ta: db 0BH,'$',0,0 ;[hh] cursor up
-tb: db 0AH,'$',0,0 ;[hh] cursor down
-tc: db 0CH,'$',0,0 ;[hh] cursor right
-td: db 08H,'$',0,0 ;[hh] cursor left
-te: db esc,'*$',0 ;[hh] clear display (homes cursor)
-tf: db '$',0,0,0 ;[hh] (can't) enter graphics mode
-tg: db '$',0,0,0 ;[hh] (can't) exit graphics mode
-th: db 01EH,'$',0,0 ;[hh] home cursor
-ti: db esc,'E$',0 ;[hh] reverse linefeed (insert line)
-tj: db esc,'Y$',0 ;[hh] clear to end of screen
-tk: db esc,'T$',0 ;[hh] clear to end of line
-ENDIF ;lobo
-
-IF px8 ; [29]
-sysver: db 'Epson PX-8$'
-outlin: db esc,'*$'
-erascr: db esc,'*$' ; clear screen and home
-eralin: db cr,esc,'T$' ; clear line
-curldn: db esc,'=$' ; cursor lead in
-ttab: ; table start location
-ta: db 30,'$',0,0 ; cursor up
-tb: db 31,'$',0,0 ; cursor down
-tc: db 28,'$',0,0 ; cursor right
-td: db 29,'$',0,0 ; cursor left
-te: db esc,'*$',0 ; clear display
-tf: db '$',0,0,0 ; can't enter graphics graphics mode
-tg: db '$',0,0,0 ; can't exit graphics mode
-th: db 11,'$',0,0 ; home cursor
-ti: db 30,'$',0,0 ; reverse linefeed
-tj: db esc,'Y$',0 ; erase to end of screen
-tk: db esc,'T$',0 ; erase to end of line
-ENDIF ; px8 [29]
-
-;
-IF osbrn1
-sysver: db 'Osborne 1$'
-outlin: db 1AH,cr,lf,tab,'$' ;(Clear screen, home cursor)
-erascr: db 1AH,'$' ;Clear screen and go home.
-eralin: db cr,esc,'T$' ;Clear line.
-delstr: db bs,bs,'$' ; Adjust for delete
-curldn: db esc,'=$' ;Cursor lead-in
-ttab: ;Table start location.
-ta: db ('K'-100O),'$',0,0 ;Cursor up.
-tb: db 12O,'$',0,0 ;Cursor down.
-tc: db ('L'-100O),'$',0,0 ;Cursor right.
-td: db bs,'$',0,0 ;Cursor left.
-te: db subt,'$',0,0 ;Clear screen.
-tf: db '$',0,0,0 ;(can't) Enter graphics mode
-tg: db '$',0,0,0 ;(can't) Exit graphics mode
-th: db ('^'-100O),'$',0,0 ;Cursor home.
-ti: db ('K'-100O),'$',0,0 ;Reverse linefeed.
-tj: db esc,'T$',0 ;(can't) Clear to end of screen.
-tk: db esc,'T$',0 ;Clear to end of line.
-ENDIF;osbrn1
-;
-IF vector
-sysver: db 'Vector Graphics$'
-outlin: db ('D'-100O),cr,lf,tab,tab,'$'
-erascr: db ('D'-100O),'$' ;Clear screen and go home.
-eralin: db cr,('Q'-100O),'$' ;Clear line.
-delstr: db bs,' ',bs,bs,'$' ; adjust for echoing delete character
-ttab: ;Table start location.
-ta: db ('U'-100O),'$',0,0 ;Cursor up.
-tb: db 12O,'$',0,0 ;Cursor down.
-tc: db ('Z'-100O),'$',0,0 ;Cursor right.
-td: db '$',0,0,0 ;(can't) Cursor left
-te: db '$',0,0,0 ;(can't) Clear display
-tf: db '$',0,0,0 ;(can't) Enter graphics mode
-tg: db '$',0,0,0 ;(can't) Exit graphics mode
-th: db ('B'-100O),'$',0,0 ;Cursor home.
-ti: db ('U'-100O),'$',0,0 ;Reverse linefeed.
-tj: db ('P'-100O),'$',0,0 ;Clear to end of screen.
-tk: db ('Q'-100O),'$',0,0 ;Clear to end of line.
-ENDIF;vector
-
-IF trs80lb
-sysver: db 'TRS-80 II Lifeboat CP/M$'
-outlin: db esc,':',cr,lf,tab,tab,'$'
-erascr: db esc,':$' ;Clear screen and go home.
-eralin: db cr,esc,'T$' ;Clear line.
-curldn: db esc,'=$' ;Cursor lead-in
-ttab: ;Table start location.
-ta: db 0BH,'$',0,0 ;Cursor up.
-tb: db 0AH,'$',0,0 ;Cursor down.
-tc: db 0CH,'$',0,0 ;Cursor right.
-td: db bs,'$',0,0 ;Cursor left
-te: db esc,':$',0 ;Clear display
-tf: db '$',0,0,0 ;(can't) Enter Graphics Mode
-tg: db '$',0,0,0 ;(can't) Exit Graphics mode
-th: db 1EH,'$',0,0 ;Cursor home.
-ti: db 0BH,'$',0,0 ;Reverse linefeed.
-tj: db esc,'Y$',0 ;Clear to end of screen.
-tk: db esc,'T$',0 ;Clear to end of line.
-ENDIF;trs80lb
-;
-IF trs80pt
-sysver: db 'TRS-80 II P+T CP/M$'
-outlin: db 0CH,cr,lf,tab,tab,'$'
-erascr: db 0CH,'$' ;Clear screen and go home.
-eralin: db cr,01H,'$' ;Clear line.
-curldn: db esc,'Y$' ;Cursor lead-in
-ttab: ;Table start location ;Must be 4 bytes each
-ta: db 1EH,'$',0,0 ;Cursor up.
-tb: db 1FH,'$',0,0 ;Cursor down.
-tc: db 1DH,'$',0,0 ;Cursor right.
-td: db 1CH,'$',0,0 ;Cursor left
-te: db 0CH,'$',0,0 ;Clear display
-tf: db 11H,'$',0,0 ;Enter Graphics Mode
-tg: db 14H,'$',0,0 ;Exit Graphics mode
-th: db 06H,'$',0,0 ;Cursor home.
-ti: db 1EH,'$',0,0 ;Reverse linefeed.
-tj: db 02H,'$',0,0 ;Clear to end of screen.
-tk: db 01H,'$',0,0 ;Clear to end of line.
-ENDIF;trs80pt
-
-IF osi
-outlin: db cr,lf,'Starting ...$'
-erascr equ crlf ;"Home & clear" (best we can do).
-eralin: db '^U',cr,lf,'$' ;Clear line.
-prpack: db cr,lf,'RPack: $'
-pspack: db cr,lf,'SPack: $'
-ttab equ 0 ; no VT52 table
-ENDIF;osi
-;
-IF hp125 ;[MF]
-defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
-vtval EQU 0 ; we probably don't want VT52 emulation
-;
-sysver: db 'HP-125 Series 100$'
-;
-outlin: db esc,'H',esc,'J',cr,lf,tab,tab,'$'
-erascr: db esc,'H',esc,'J$' ;Clear screen and go home.
-eralin: db cr,esc,'K$' ;Clear line.
-curldn: db esc,'&a$' ;Cursor leadin
-ttab: ;Table start location.
-ta: db esc,'A$',0 ;Cursor up.
-tb: db esc,'B$',0 ;Cursor down.
-tc: db esc,'C$',0 ;Cursor right.
-td: db esc,'D$',0 ;Cursor left
-te: db esc,'J$',0 ;Clear display
-tf: db '$',0,0,0 ;[hh] (can't) enter graphics mode
-tg: db '$',0,0,0 ;[hh] (can't) exit graphics mode
-th: db esc,'H$',0 ;Cursor home.
-ti: db esc,'M$',0 ;Reverse linefeed.
-tj: db esc,'J$',0 ;Clear to end of screen.
-tk: db esc,'K$',0 ;Clear to end of line.
-;
-;
-; Escape sequences to map CP/M Reader/Punch to Data Comm input/output,
-; respectively and to turn off these mappings
-;
-mapon1: db esc,'&i10s18d9M'
- db esc,'&i2s25d9M'
- db esc,'&i10s16d2M'
- db esc,'&i0s25d2M$';Esc. sequences to turn off DAtacomm2/turn
- ;on Data Comm 1
-mapon2: db esc,'&i10s16d9M'
- db esc,'&i0s25d9M'
- db esc,'&i10s18d2M'
- db esc,'&i2s25d2M$';Esc. sequences to turn off Datacomm1/turn
- ;on Datacomm 2
-mapoff: db esc,'&i0s25d9M'
- db esc,'&i10s16d9M'
- db esc,'&i2s25d9M'
- db esc,'&i10s18d9M$'
-;
-readin: call $-$ ;Read character into b
- mov a,b ;Get 8-bit character
- ret ;and return
-;
-jbuf: db 7 ;bios dispatch table vector argument block
- db 0 ;to read RDR routine address
- db 0c3h ;...
- dw 0 ;...
-;
-ENDIF;hp125 ;[MF]
-
-IF lasm and termin ; if no terminal, no need to link
-LINK CPXVDU.ASM
-ENDIF ; lasm and termin
-
-ovlend EQU $
-
-IF lasm
- END ; If m80 then this ignored
-ENDIF ; lasm
+IF NOT lasm
+.printx * CPXSY2.ASM *
+ENDIF ;NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the system-dependent code and data for KERMIT.
+; It will be probably be broken into independent files to generate
+; overlays for the various systems, one or more overlay possible
+; from each file. For now, we will leave it in one piece.
+;
+; revision history:
+;
+;
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; this
+; value is also stored in 'speed'.
+sysspd:
+
+
+IF px8 ; [29]
+ push d
+ call rsclose ; baud rate can only be set on opening rs232
+ pop d
+ mov a, e
+ sta px8blk+4 ; set param block
+ call rsopen ; to set rate
+ ret
+ENDIF ; px8 [29]
+
+; Set the speed for the Osborne I
+IF osbrn1
+ mvi a,osbin1 ;Reset the ACIA
+ call osstst ;Write the control port
+osbs1: inr c ;Waiting loop
+ jnz osbs1
+ mov a,e ; get the specified speed
+ jmp osstst ;Write the control reg.
+ENDIF;osbrn1
+
+;[hh] set the speed for a lobo MAX-80
+IF lobo
+ mov a,e ;[hh] get the parsed value
+setbd: sta baudrt ;[hh] and send it to the baud rate port
+ ret ;[hh]
+ENDIF;lobo
+
+; Set the speed for bigboard I or the delphi or the CPT-85xx
+; or Cromemco (TU-ART)
+IF delphi OR cpt85xx OR cmemco OR mmate ;[22] [29]
+ mov a,e ; get the parsed value
+ out baudrt ; Tell the baud rate generator.
+ ret
+ENDIF;delphi OR cpt85xx OR cmemco OR mmate [22] [29]
+
+;[22] Set the speed for Acorn BBC
+IF bbc
+ mov l,e
+ mvi a,7 ;Set receive baud rate
+ call osbyte ;*FX7,?e
+ mov l,e
+ mvi a,8 ;Set transmit baud rate
+ call osbyte ;*FX8,?e
+ ret
+ENDIF;[22] bbc
+
+;[22] Set speed for RM 380Z
+IF rm380z
+ mvi a,4 ;device type (SI/O4) in A
+ rst 6 ; EMT
+ db 29h ; SETLST
+ ret
+ENDIF;[22] rm380z
+
+; Set the speed for MicroMikko. DE is baud rate multiplier
+IF mikko
+ di
+ lxi h,txclk
+ mov m,d ;LSB first (swapped in memory)
+ mov m,e ;MSB last
+ lxi h,rxclk
+ mov m,d
+ mov m,e
+ mvi b,0 ;"modifier" for 1 stop bit
+ mvi a,2 ;Test MSB of speed >2 (110 bps or less)
+ cmp e
+ jp miksp1
+ mvi b,00001000B ;"modifier" for 2 stop bits
+miksp1: mvi a,4 ;Select SIO Reg 4
+ lxi h,sioac
+ mov m,a
+ mvi a,sion4 ;Get values
+ ora b ;Add modifier
+ mov m,a ;Set value (stop bits)
+ ei
+ ret
+ENDIF;mikko
+
+
+; Set the speed for the Decision I
+IF mdI
+ call selmdm ;Let's be absolutely sure, huh?
+ mvi a,dlab+wls1+wls0+stb ;Set data latch access bit
+ out lcr ;Out to Line Control Register
+ lhld speed ;Load baudrate multiplier
+ xchg
+ mov a,d ;Get low order byte for baud rate
+ out dlm ;Out to the MSB divisor port
+ mov a,e ;...and the high order byte
+ out dll ;Out to the LSB divisor port
+ mvi a,wls1+wls0+stb ;Enable Divisor Access Latch
+ out lcr ;Out to ACE Line Control Register
+ xra a ;Clear A
+ out ier ;Set no interrupts
+ out lsr ;Clear status
+ in msr ;Clear Modem Status Register
+ in lsr ;Clear Line Status Register
+ in rbr ;Clear Receiver Buffers
+ in rbr
+ ret
+ENDIF ;mdI [Toad Hall]
+
+IF teletek
+ di
+ mov a,e ; first speed byte
+ out baudrt
+ mov a,d ; second speed byte
+ out baudrt
+ ei
+ ret
+ENDIF ;teletek
+
+IF access ;[29]
+ mov a,e ;Get the parsed time constant
+;The following code is derived from the Access initialization code
+ sta savspd ;Save the time constant
+ mvi a,14h ;Code for 'monitor' to set channel A baudrate
+ call monitor
+ lda savspd ;Get the time constant
+ call monitor ; and send it to the CRT
+ ret
+savspd: ds 1
+monitor: ;Routine to do CRT functions
+ out 90h ;Output the data to the CRT
+ mvi a,1 ;Set DRDY true
+ out 23h
+mon1: in 0a0h ;Wait for CACK* true
+ rlc
+ jc mon1
+ in 80h ;Read the input data latch
+ push psw ;Save the input data
+ xra a ;Set DRDY false
+ out 23h
+mon2: in 0a0h ;Wait for CACK* false
+ rlc
+ jc mon2
+ pop psw
+ sta 0ee02h ;Save the input data
+ ret
+ENDIF;access [29]
+
+
+IF disc ;[29]
+; Assuming that parsing of value from speed table puts low order
+; byte of time constant in the e register and high byte in d.
+ mvi a,12 ;Register 12
+ out mnprts
+ mov a,e ;Low order byte of time constant
+ out mnprts
+ mvi a,13 ;Register 13
+ out mnprts
+ mov a,d ;High order byte of time constant
+ out mnprts
+ mvi a,14 ;Register 14
+ out mnprts
+ mvi a,3 ;Enable baud rate generator
+ out mnprts
+ mvi a,11 ;Register 11
+ out mnprts
+ mvi a,52h ;no Xtal, tclk=rclk=/trxc out=br gen
+ out mnprts
+ ret
+ENDIF;disc [29]
+; Speed tables
+; (Note that speed tables MUST be in alphabetical order for later
+; lookup procedures, and must begin with a value showing the total
+; number of entries. The speed help tables are just for us poor
+; humans.
+
+; db string length,string,divisor (2 identical bytes or 1 word)
+; [Toad Hall]
+
+IF delphi OR lobo ;[hh]
+spdtbl: db 10h ;16 entries
+ db 03h,'110$', 02h,02h
+ db 04h,'1200$', 07h,07h
+ db 05h,'134.5$', 03h,03h
+ db 03h,'150$', 04h,04h
+ db 04h,'1800$', 08h,08h
+ db 05h,'19200$', 0fh,0fh
+ db 04h,'2000$', 09h,09h
+ db 04h,'2400$', 0ah,0ah
+ db 03h,'300$', 05h,05h
+ db 04h,'3600$', 0bh,0bh
+ db 04h,'4800$', 0ch,0ch
+ db 02h,'50$', 00h,00h
+ db 03h,'600$', 06h,06h
+ db 04h,'7200$', 0dh,0dh
+ db 02h,'75$', 01h,01h
+ db 04h,'9600$', 0eh,0eh
+
+sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
+ db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'
+ENDIF;delphi OR lobo ;[hh]
+
+IF cpt85xx
+spdtbl: db 15 ; 15 entries
+ db 03,'110$', 03h,03h
+ db 04,'1200$', 09h,09h
+ db 05,'134.5$', 04h,04h
+ db 03,'150$', 05h,05h
+ db 04,'1800$', 0Ah,0Ah
+ db 04,'2400$', 0Bh,0Bh
+ db 03,'300$', 06h,06h
+ db 04,'3600$', 0Ch,0Ch
+ db 04,'4800$', 0Dh,0Dh
+ db 02,'50$', 01h,01h
+ db 03,'600$', 07h,07h
+ db 04,'7200$', 0Eh,0Eh
+ db 02,'75$', 02h,02h
+ db 03,'900$', 08h,08h
+ db 04,'9600$', 0Fh,0Fh
+
+sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 900'
+ db cr,lf,' 1200 1800 2400 3600 4800 7200 9600$'
+ENDIF;cpt85xx
+
+IF bbc ;[22]
+spdtbl: db 8 ; 8 entries
+ db 04,'1200$', 04h,04h
+ db 03,'150$', 02h,02h
+ db 05,'19200$', 08h,08h
+ db 04,'2400$', 05h,05h
+ db 03,'300$', 03h,03h
+ db 04,'4800$', 06h,06h
+ db 02,'75$', 01h,01h
+ db 04,'9600$', 07h,07h
+
+sphtbl: db cr,lf,' 75 150 300 1200 2400 4800 9600 19200$'
+ENDIF;[22] bbc
+
+IF rm380z ;[22]
+spdtbl: db 7 ; 7 entries
+ db 03,'110$', 00h,00h
+ db 04,'1200$', 03h,03h
+ db 04,'2400$', 04h,04h
+ db 03,'300$', 01h,01h
+ db 04,'4800$', 05h,05h
+ db 03,'600$', 02h,02h
+ db 04,'9600$', 06h,06h
+
+sphtbl: db cr,lf,' 110 300 600 1200 2400 4800 9600$'
+ENDIF;[22] rm380z
+
+IF px8 ; [29]
+spdtbl: db 9 ; 9 entries
+ db 03,'110$', 02h,02h
+ db 04,'1200$', 0ah,0ah
+ db 03,'150$', 04h,04h
+ db 05,'19200$', 0fh,0fh
+ db 04,'2400$', 0ch,0ch
+ db 03,'300$', 06h,06h
+ db 04,'4800$', 0dh,0dh
+ db 03,'600$', 08h,08h
+ db 04,'9600$', 0eh,0eh
+sphtbl: db cr, lf
+ db ' 100 150 300 600 1200 2400 4800 9600 19200$'
+ENDIF ; px8 [29]
+
+IF mikko
+spdtbl: db 9h ;9 entries
+ db 03h,'110$'
+ dw 0369h
+ db 04h,'1200$'
+ dw 0050h
+ db 03h,'150$'
+ dw 0280h
+ db 04h,'2400$'
+ dw 0028h
+ db 03h,'300$'
+ dw 0140h
+ db 04h,'4800$'
+ dw 0014h
+ db 03h,'600$'
+ dw 00A0H
+ db 02h,'75$'
+ dw 0500h
+ db 04h,'9600$'
+ dw 000ah
+
+sphtbl: db cr,lf,' 75 110 150 300 600 1200 2400 4800 9600$'
+ENDIF;mikko
+
+IF osbrn1
+spdtbl: db 02h ;2 entries
+ db 04h,'1200$', OSBI12,OSBI12
+ db 03h,'300$', OSBI03,OSBI03
+
+sphtbl: db cr,lf,' 300',cr,lf,' 1200$'
+ENDIF;osbrn1
+
+
+IF mdI
+spdtbl: db 0dh ; 13 entries
+ db 03h, '110$'
+ dw 1047
+ db 04h, '1200$'
+ dw 96
+ db 03h, '150$'
+ dw 768
+ db 05h,'19200$'
+ dw 6
+ db 04h, '2400$'
+ dw 48
+ db 03h, '300$'
+ dw 384
+ db 05h,'38400$'
+ dw 3
+ db 03h, '450$'
+ dw 288
+ db 04h, '4800$'
+ dw 24
+ db 05h,'56000$'
+ dw 2
+ db 03h, '600$'
+ dw 192
+ db 02h, '75$'
+ dw 1536
+ db 04h, '9600$'
+ dw 12
+
+sphtbl: db cr,lf,' 75 110 150 300 450 600 1200'
+ db cr,lf,' 2400 4800 9600 19200 38400 56000$'
+
+;(Lord knows what you'll be communicating with at 56000 baud, but the
+;Multi-I/O board literature says it'll do it, so what the heck....
+;might as well throw it in here just to show off...sure hope the
+;port don't melt...)
+
+ENDIF ;mdI [Toad Hall]
+
+IF cmemco ;[25]
+spdtbl: db 7 ; 7 entries
+ db 3,'110$', 01H,01H
+ db 4,'1200$', 88H,88H
+ db 3,'150$', 82H,82H
+ db 4,'2400$', 90H,90H
+ db 3,'300$', 84H,84H
+ db 4,'4800$', 0A0H,0A0H
+ db 4,'9600$', 0C0H,0C0H
+
+sphtbl: db cr,lf
+ db ' 110 150 300 1200 2400 4800 9600$'
+ENDIF;cmemco
+
+IF access ;Similar to bbI with different values [29]
+spdtbl: db 6h ;6 entries
+ db 04h,'1200$', 28h,28h
+ db 04h,'2400$', 14h,14h
+ db 03h,'300$', 0a0h,0a0h
+ db 04h,'4800$', 0ah,0ah
+ db 03h,'600$', 50h,50h
+ db 04h,'9600$', 5,5
+
+sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$'
+ENDIF;access [29]
+
+IF mmate ;[29]
+spdtbl: db 10h ;16 entries
+ db 03h,'110$', 0e2h,0e2h
+ db 04h,'1200$', 0e7h,0e7h
+ db 05h,'134.5$', 0e3h,0e3h
+ db 03h,'150$', 0e4h,0e4h
+ db 04h,'1800$', 0e8h,0e8h
+ db 05h,'19200$', 0efh,0efh
+ db 04h,'2000$', 0e9h,0e9h
+ db 04h,'2400$', 0eah,0eah
+ db 03h,'300$', 0e5h,0e5h
+ db 04h,'3600$', 0ebh,0ebh
+ db 04h,'4800$', 0ech,0ech
+ db 02h,'50$', 0e0h,0e0h
+ db 03h,'600$', 0e6h,0e6h
+ db 04h,'7200$', 0edh,0edh
+ db 02h,'75$', 0e1h,0e1h
+ db 04h,'9600$', 0eeh,0eeh
+
+sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
+ db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'
+ENDIF;mmate [29]
+
+IF disc ;[29]
+; Similar to mikko table but with different time constant values
+spdtbl: db 9h ;9 entries
+ db 03h,'110$'
+ dw 1134
+ db 04h,'1200$'
+ dw 102h
+ db 03h,'150$'
+ dw 831
+ db 04h,'2400$'
+ dw 50
+ db 03h,'300$'
+ dw 415
+ db 04h,'4800$'
+ dw 24
+ db 03h,'600$'
+ dw 206
+ db 02h,'75$'
+ dw 1665
+ db 04h,'9600$'
+ dw 11
+
+sphtbl: db cr,lf,' 75 110 150 300 600 1200 2400 4800 9600$'
+ENDIF;disc [29]
+
+IF teletek
+spdtbl: db 7 ; 7 entries
+ db 4, '1200$', 47h,40h
+ db 5,'19200$', 47h,04h
+ db 4, '2400$', 47h,20h
+ db 3, '300$', 47h,00h
+ db 4, '4800$', 47h,10h
+ db 3, '600$', 47h,80h
+ db 4, '9600$', 47h,08h
+
+sphtbl: db cr,lf
+ db ' 300 600 1200 2400 4800 9600 19200$'
+ENDIF ;teletk
+
+
+; The following conditionals were once a huge if not statement. There
+; wasn't enough room to add the lobo to the list, so it had to be broken
+; into 2, which you can't do with an if not. I redid it as two ifs and
+; applied them to those that wouldn't set baud. [Hal Hostetler]
+IF robin OR gener OR dmII OR vector OR trs80;[32]
+spdtbl equ 0 ; SET BAUD not supported.
+sphtbl equ 0
+ENDIF;robin OR gener OR dmII OR vector OR trs80
+;
+IF mmdI OR osi OR cpm3 OR S1008 ; [29]
+spdtbl EQU 0 ;[hh] SET BAUD not supported.
+sphtbl EQU 0 ;[hh] ran out of room above...
+ENDIF;mmdI OR osi OR cpm3 OR S1008 [29]
+;
+IF hp125 ;[MF]
+spdtbl equ 0 ; SET BAUD not supported.
+sphtbl equ 0
+ENDIF;hp125 [MF]
+;
+; This is the system-dependent SET PORT command.
+; HL contains the argument from the command table.
+sysprt:
+IF lobo ;[hh]
+ mov a,l ;[hh] get the data port value and store at
+ sta outmd3+1 ;[hh] the two places we use...
+ sta inpmd2+1 ;[hh] MNPORT in the overlay
+ sta port ;[hh] inform program of the change in ports
+ inr a ;[hh] status port = data port + 1 in the Lobo
+ sta outmd1+1 ;[hh] store it at the three places...
+ sta inpmd1+1 ;[hh] we use MNPRTS...
+ sta outctl+1 ;[hh] in the overlay
+ mov a,h ;[hh] now get the baud rate port value
+ sta getbd+1 ;[hh] store it in the two places we use...
+ sta setbd+1 ;[hh] BAUDRT in the overlay
+ sta port+1 ;[hh] don't need to, but keeps it consistant
+getbd: lda baudrt ;[hh] get baud rate value from port
+ sta speed ;[hh] tell STAT. baud rate for each port
+ ;[hh] is independant of the other
+ENDIF ;lobo
+
+IF iobyt
+ mov a,m ;Get the I/O byte
+ sta prtiob ;Save the desired IO byte for this port
+ inx h ;Point at next entry
+ mov a,m ;Get the output function
+ sta prtfun ;Save it
+ENDIF;iobyt
+
+IF iobyt AND robin
+ inx h ;Point at next entry
+ mov a,m ;Get the hardware address for the port
+ sta prtadr ;Store it
+ENDIF;iobyt AND robin
+;
+IF hp125 ;[MF]
+ push psw
+ push b
+ push d
+ push h
+ xchg ;Put port connect sequence address in DE
+ call prtstr ;Connect proper port
+ pop h
+ pop d
+ pop b
+ pop psw
+ENDIF;hp125 [MF]
+;
+ ret
+;
+; Port tables for Lobo MAX-80
+IF lobo ;[hh]
+; help text
+prhtbl: db cr,lf,'RS-232 port A or B$'
+;
+; command table
+prttbl: db 02H ;[hh] two entries
+ db 01H,'A$',0E4H,0D0H
+ db 01H,'B$',0E6H,0D4H
+ENDIF ;lobo
+;
+; Port tables for GENERIC CPM 2.2
+IF gener
+; help text
+prhtbl: db cr,lf,'CRT device'
+ db cr,lf,'PTR device'
+ db cr,lf,'TTY device'
+ db cr,lf,'UC1 device'
+ db cr,lf,'UR1 device'
+ db cr,lf,'UR2 device$'
+
+; command table
+prttbl: db 06H ;Six devices to choose from
+ db 03H,'CRT$'
+ dw crtptb
+ db 03H,'PTR$'
+ dw ptrptb
+ db 03H,'TTY$'
+ dw ttyptb
+ db 03H,'UC1$'
+ dw uc1ptb
+ db 03H,'UR1$'
+ dw ur1ptb
+ db 03H,'UR2$'
+ dw ur2ptb
+
+; port entry table
+; table entries are:
+; db iobyte-value, BDOS output function, reserved
+crtptb: db crtio,conout,0
+ptrptb: db ptrio,punout,0
+ttyptb: db ttyio,conout,0
+uc1ptb: db uc1io,conout,0
+ur1ptb: db ur1io,punout,0
+ur2ptb: db ur2io,punout,0
+ENDIF;gener
+
+;
+; Port tables for DECmate II or MicroMikko or Acorn BBC
+;
+IF dmII OR mikko OR bbc ;[22]
+; help text
+prhtbl: db cr,lf,'COMMUNICATIONS port$'
+
+; command table
+prttbl: db 01H ;Only one port known at this point
+ db 0EH,'COMMUNICATIONS$'
+ dw comptb ;address of info
+
+; port entry table
+; table entries are:
+; db iobyte-value, BDOS output function, reserved
+comptb: db batio,punout,0
+
+ENDIF;[22] dmII OR mikko OR bbc
+;
+; Port tables for Robin
+;
+IF robin
+; help text
+prhtbl: db cr,lf,'COMMUNICATIONS port'
+ db cr,lf,'GENERAL purpose port'
+ db cr,lf,'PRINTER port$'
+
+; command table
+prttbl: db 03H ;Three entries
+ db 0EH,'COMMUNICATIONS$'
+ dw comptb
+ db 07H,'GENERAL$'
+ dw gppptb
+ db 07H,'PRINTER$'
+ dw prnptb
+
+; port entry table
+; table entries are:
+; db iobyte-value, BDOS output function, hardware port address
+; (control/status)
+;
+;At present, the hardware port address is only used for sending a break.
+comptb: db batio,punout,comtst
+gppptb: db gppio,conout,gentst
+prnptb: db lptio,conout,prntst
+
+prtadr: db comtst ;space for current hardware port address
+ENDIF;robin
+
+IF iobyt
+prtfun: db punout ;Function to use for output to comm port
+prtiob: db batio ;I/O byte to use for communicating
+coniob: db defio ;I/O byte to use for console
+ENDIF;iobyt
+;
+IF hp125 ;[MF]
+; Help table
+prhtbl: db cr,lf,'Communications port'
+ db cr,lf,'Printer port$'
+; command table
+prttbl: db 02H ;2 entries
+ db 0eH,'COMMUNICATIONS$'
+ dw mapon1
+ db 07H,'PRINTER$'
+ dw mapon2
+;Port table entries are the addresses of the escape sequences to connect
+;the ports.
+;
+ENDIF;hp125 [MF]
+
+IF NOT (iobyt OR lobo OR hp125) ;[hh] [MF]
+prttbl equ 0 ; SET PORT is not supported
+prhtbl equ 0
+ENDIF;NOT iobyt OR lobo OR hp125 [MF]
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; For iobyt systems, diddle the I/O byte to select console or comm port;
+; For Decision I, switches Multi I/O board to console or modem serial
+; port. [Toad Hall]
+; For the rest, does nothing.
+; preserves bc, de, hl.
+selmdm:
+IF iobyt
+ lda prtiob ;Set up for output to go to the comm port
+ sta iobyte ;Switch byte directly
+ENDIF;iobyt
+
+IF mdI
+ lda group
+ ori mdmgrp ;Mask modem serial port
+ out grpsel
+ENDIF;mdI [Toad Hall]
+
+ ret
+
+selcon:
+IF iobyt
+ lda coniob ;Set up for output to go to the console port
+ sta iobyte ;Switch directly
+ENDIF;iobyt
+
+IF mdI
+ lda group
+ ori congrp ;Mask console serial port (1)
+ out grpsel
+ENDIF;mdI [Toad Hall]
+
+ ret
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+IF NOT iobyt
+ mvi c,dconio ;Direct console I/O BDOS call.
+ mvi e,0FFH ;Input.
+ call BDOS
+ENDIF;NOT iobyt
+
+IF iobyt
+ call bconst ;Get the status
+ ora a ;Anything there?
+ rz ;No, forget it
+ call bconin ;Yes, get the character
+ENDIF;iobyt
+ ret
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+
+IF rm380z ;[22]
+ mov a,e
+ cpi cr ;cr produces cr + lf
+ jnz outcn1
+ mvi e,'N'-100O ;Control-N produces cr only
+outcn1: ;continue
+ENDIF;[22] rm380z
+
+IF NOT iobyt
+ mvi c,dconio ;Console output bdos call.
+ call bdos ;Output the char to the console.
+ENDIF;NOT iobyt
+
+IF iobyt
+ mov c,e ;Character
+ call bcnout ;to Console
+ENDIF;iobyt
+ ret
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+outmdm:
+IF osi OR lobo ;[hh]
+ push h
+outmd1: lxi h,mnprts ;address of the port status register
+outmd2: mov a,m ; get port status in A
+ ani output ;Loop till ready.
+ jz outmd2
+outmd3: lxi h,mnport ;address of port data register
+ mov m,e ; write the character
+ pop h
+ ret
+ENDIF;osi OR lobo
+
+IF osbrn1
+ call osldst ;Read the status port
+ ani output ;Loop till ready.
+ jz outmdm
+ mov a,e
+ jmp osstda ;Write to the data port
+ENDIF;osbrn1
+
+IF px8 ; [29]
+ push h
+ push b
+ push d
+outmd1: call rsoutst ; get the output status
+ ora a
+ jz outmd1 ; check if output enabled
+ pop d
+ mov c, e ; char in C
+ push d
+ call rsput
+ pop d
+ pop b
+ pop h
+ ret
+ENDIF; px8 [29]
+
+IF inout
+ in mnprts ;Get the output done flag.
+ ani output ;Is it set?
+ jz outmdm ;If not, loop until it is.
+ mov a,e
+ out mnport ;Output it.
+ ret
+ENDIF;inout
+
+IF iobyt
+;**** Note that we enter from outpkt with the I/O byte already set up for
+; output to go to the comm port
+ push h
+ push b
+ lda prtfun ;Get the output function
+ mov c,a ;Into C
+ call bdos ;And output the character
+ pop b
+ pop h
+ ret
+ENDIF;iobyt
+
+IF cpm3 OR hp125 ;[MF]
+ push h
+ push b
+ mvi c,auxout ;Output to the aux output device
+ call bdos
+ pop b
+ pop h
+ ret
+ENDIF;cpm3 OR hp125 [MF]
+
+; org $+100h AND 0FF00h ; get rid of phase error
+
+;
+; get character from modem; return zero if none available.
+; for IOBYT systems, the modem port has already been selected.
+; destroys bc, de, hl.
+inpmdm:
+IF iobyt
+ call bconst ;Is Char at COMM-Port?
+ ora a ;something there?
+ rz ; return if nothing there
+ call bconin ; data present. read data.
+ENDIF;iobyt
+
+IF cpm3
+ mvi c,auxist
+ call bdos ;is char at auxin?
+ ora a ;something there?
+ rz ;no
+ mvi c,auxin
+ call bdos ;read char from auxin
+ENDIF;cpm3
+;
+IF hp125 ;[MF]
+ lxi b,70ffh ;SEt subfunction to get RDR (auxin) status
+ call bdos ;is char at RDR?
+ ora a ;something there?
+ rz ;no
+ mvi c,auxin
+ call bdos ;read char from RDR
+ENDIF;hp125 [MF]
+
+IF osi OR lobo ;[hh]
+inpmd1: lda mnprts ;Get the port status into A.
+ ani input ;See if the input ready bit is on.
+ rz ;If not then return.
+inpmd2: lda mnport ;If so, get the char.
+ENDIF;osi OR lobo
+
+IF osbrn1
+ call osldst ;Read the status port
+ ani input ;Something there?
+ rz ;Nope
+ call osldda ;Read the data port
+ENDIF;osbrn1
+
+IF inout
+;Note: modem port should already be selected for mdI. [Toad Hall]
+ in mnprts ;Get the port status into A.
+ ani input ;See if the input ready bit is on.
+ rz ;If not then return.
+ in mnport ;If so, get the char.
+ENDIF;inout
+
+IF px8 ; [29]
+ call rserst ; check error status
+ ani 64h ; this assumes 'not open' cannot occur
+ jnz inpmd1 ; error has occurred!
+ call rsinst ; any chars outstanding?
+ ora a
+ rz ; exit if none
+ call rsget ; get char in A
+ ret
+; return the 'no char outstanding' indication on error
+inpmd1: mvi a, 0
+ENDIF; px8 [29]
+
+ ret ; return with character in A
+
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+
+flsmdm: call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+;
+; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not.
+lptstat:
+IF iobyt ;[33]
+ call bprtst ;
+call bprtst ; get status
+ENDIF ;iobyt[33]
+IF NOT iobyt ;[33]
+ xra a ; assume it is ok.. this may not be necessary
+ENDIF ;iobyt [33]
+ ret
+
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+outlpt:
+ push d ; save DE in either case
+ call prtflt ; go through printer filter [30]
+ ana a ; if A = 0 do nothing,
+ jz outlp1 ; [30] if a=0 do nothing
+
+IF NOT iobyt
+ mvi c,lstout
+ call bdos ;Char to printer
+ENDIF;NOT iobyt
+IF iobyt
+ mov c,e
+ call blsout
+ENDIF;iobyt
+
+outlp1: pop d ; restore saved register pair
+ ret
+;
+; Screen manipulation routines
+; csrpos - move to row B, column C
+;
+; csrpos for terminals that use a leadin sequence followed
+; by (row + 31.) and (column + 31.)
+;
+IF NOT (robin OR dmII OR osi OR vector OR termin OR hp125)
+ ;[MF] Terminals code in CPXVDU
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; restore coordinates
+ mov a,h ; get row
+ adi (' '-1) ; space is row one
+ mov e,a
+ push h
+ call outcon ; output row
+ pop h
+ mov a,l ; get column
+ adi (' '-1) ; space is column one
+ mov e,a
+ jmp outcon ; output it and return
+ENDIF;NOT (robin OR dmII OR osi OR vector OR termin OR hp125)[MF]
+;
+;
+;
+; csrpos for ANSI terminals
+;
+IF robin OR dmII
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; peek at coordinates
+ push h ; then save away again
+ mov l,h ; l = row
+ mvi h,0 ; hl = row
+ call nout ; output in decimal
+ mvi e,';' ; follow with semicolon
+ call outcon ; print it
+ pop h ; restore column
+ mvi h,0 ; hl = column
+ call nout
+ mvi e,'H' ; terminate with 'move cursor' command
+ jmp outcon ; output it and return
+ENDIF;robin OR dmII
+;
+; csrpos for the HP-125 [MF]
+;
+IF hp125 ;[MF]
+csrpos: dcr b ;HP-125 uses zero-based addressing
+ dcr c ;...
+ push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; peek at coordinates
+ push h ; then save away again
+ mov l,h ; l = row
+ mvi h,0 ; hl = row
+ call nout ; output in decimal
+ mvi e,'R'+20h ;Say it was a row
+ call outcon ; print it
+ pop h ; restore column
+ mvi h,0 ; hl = column
+ call nout
+ mvi e,'C' ; terminate with 'move cursor' command
+ jmp outcon ; output it and return
+ENDIF;hp125 [MF]
+;
+; csrpos for the Vector General. It's weird.
+;
+IF vector
+csrpos: dcr b ; vector uses zero-based addressing?
+ dcr c
+ push b ; save coordinates
+ mvi e,esc ; print an escape
+ call outcon
+ pop d ; peek at coordinates
+ push d
+ call outcon ; output column
+ pop d
+ mov e,d ; get row
+ jmp outcon ; output and return
+ENDIF;vector
+
+IF osi ; systems without cursor positioning
+csrpos: ret ; dummy routine referenced by linkage section
+ENDIF;osi
+
+
+;
+; delchr - make delete look like a backspace. Unless delete is a printing
+; character, we just need to print a backspace. (we'll output clrspc
+; afterwards)
+; For Kaypro and Vector General, delete puts a blotch on the screen.
+; For Apple and Osborne 1, delete moves but doesn't print.
+delchr:
+
+IF vector OR osbrn1 OR lobo
+ lxi d,delstr
+ jmp prtstr
+ENDIF ;vector OR osbrn1 OR lobo
+
+IF bbc OR rm380z ;[22]
+ ret
+ENDIF;bbc OR rm380z
+
+IF NOT (vector OR osbrn1 OR bbc OR rm380z);[22]
+ mvi e,bs ;get a backspace
+ jmp outcon
+ENDIF;NOT (vector OR osbrn1 OR bbc OR rm380z [22]
+
+; erase the character at the current cursor position
+clrspc: mvi e,' '
+ call outcon
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the current line
+clrlin: lxi d,eralin
+ jmp prtstr
+
+; erase the whole screen, and go home. preserves b (but not c)
+clrtop: lxi d,erascr
+ jmp prtstr
+
+
+IF robin
+sysver: db 'VT180 Robin$'
+ENDIF;robin
+
+IF dmII
+sysver: db 'DECmate II CP/M-80$'
+ENDIF;dmII
+
+IF delphi ; [7] new system
+sysver: db 'Digicomp Delphi 100$'
+endif;delphi
+
+IF access
+sysver: db 'Actrix CP/M$'
+endif;
+
+IF teletek
+sysver: db 'Teletek SYSTEMASTER CP/M-80$'
+ENDIF ;teletek
+
+IF cpt85xx
+sysver: db 'CPT-85xx under CompuPak CP/M$'
+ENDIF;cpt85xx
+
+IF mdI
+sysver: db 'Morrow Decision I$'
+ENDIF;mdI [Toad Hall]
+
+IF mmdI
+sysver: db 'MicroDecision I$'
+ENDIF;mmdI
+
+IF osi
+sysver: db 'Ohio Scientific$'
+ENDIF;osi
+
+IF mmate ;[29]
+sysver: db 'PMC Micromate using port I/O$'
+ENDIF;mmate [29]
+
+IF disc ;[29]
+sysver: db 'Discovery using 83U board port B$'
+ENDIF ;disc [29]
+
+IF s1008 ;[29]
+sysver: db 'U. S. MicroSales using printer port$'
+ENDIF ;s1008 [29]
+
+IF cmemco ;[25]
+sysver: db 'Cromemco (TU-ART)$'
+ENDIF;cmemco
+;
+IF robin OR dmII
+; Note that we cannot support Graphics Mode or the H19 erase-screen command
+; (<esc>E), because the sequences are more than three bytes.
+defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
+vtval EQU 0 ; we probably don't want VT52 emulation
+outlin: db esc,3CH,esc,'[H',esc,'[J',cr,lf,tab,tab,'$'
+erascr: db esc,'[H',esc,'[J$' ;Clear screen and go home.
+eralin: db cr,esc,'[K$' ;Clear line.
+curldn: db esc,'[$' ; Cursor leadin
+ttab:
+ta: db esc,'[A$' ; Cursor up.
+tb: db esc,'[B$' ; Cursor down.
+tc: db esc,'[C$' ; Cursor right.
+td: db esc,'[D$' ; Cursor left
+te: db '$',0,0,0 ; (can't) Clear display
+tf: db '$',0,0,0 ; (don't) Enter Graphics Mode
+tg: db '$',0,0,0 ; (don't) Exit Graphics mode
+th: db esc,'[H$' ; Cursor home.
+ti: db esc,'M$',0 ; Reverse linefeed.
+tj: db esc,'[J$' ; Clear to end of screen.
+tk: db esc,'[K$' ; Clear to end of line.
+ENDIF;robin OR dmII
+
+IF mikko
+sysver: db 'MikroMikko$'
+outlin: db subt,cr,lf,tab,'$'
+erascr: db subt,'$' ;Clear screen and go home.
+eralin: db cr,1CH,'$' ;Clear line.
+curldn: db esc,'=$' ;cursor leadin
+ttab: ;Table start location.
+ta: db 0BH,'$',0,0 ;Cursor up.
+tb: db 0AH,'$',0,0 ;Cursor down.
+tc: db 0CH,'$',0,0 ;Cursor right.
+td: db bs,'$',0,0 ;Cursor left
+te: db subt,'$',0,0 ;Clear display
+tf: db '$',0,0,0 ;(can't) Enter Graphics Mode
+tg: db '$',0,0,0 ;(can't) Exit Graphics mode
+th: db 1EH,'$',0,0 ;Cursor home.
+ti: db '$',0,0,0 ;(can't) Reverse linefeed.
+tj: db 1cH,'$',0,0 ;Clear to end of screen.
+tk: db 1cH,'$',0,0 ;Clear to end of line.
+ENDIF;mikko
+;
+IF bbc ;[22]
+sysver: db 'BBC (Z80)$'
+outlin: db 0CH,esc,'=',21H,30H,'$'
+erascr: db 0CH,'$' ;Clear screen and go home.
+eralin: db cr,esc,'@$' ;Clear line.
+curldn: db esc,'=$' ;cursor leadin
+ttab: ;Table start location.
+ta: db 0BH,'$',0,0 ;Cursor up.
+tb: db 0AH,'$',0,0 ;Cursor down.
+tc: db tab,'$',0,0 ;Cursor right.
+td: db bs,'$',0,0 ;Cursor left
+te: db 0CH,'$',0,0 ;Clear display
+tf: db '$',0,0,0 ;(can't) Enter Graphics Mode
+tg: db '$',0,0,0 ;(can't) Exit Graphics mode
+th: db 1EH,'$',0,0 ;Cursor home.
+ti: db '$',0,0,0 ;(can't) Reverse linefeed.
+tj: db esc,'?$',0,0 ;Clear to end of screen.
+tk: db esc,'@$',0,0 ;Clear to end of line.
+ENDIF;[22] bbc
+;
+IF rm380z ;[22]
+sysver: db 'Research Machines 380Z$'
+outlin: db 1FH,cr,tab,'$'
+erascr: db 1FH,'$' ;Clear screen and go home.
+eralin: db 0EH,19H,'$' ;Clear line.
+curldn: db 16H,'$' ;cursor leadin
+ttab: ;Table start location.
+ta: db 0BH,'$',0,0 ;Cursor up.
+tb: db 0AH,'$',0,0 ;Cursor down.
+tc: db 18H,'$',0,0 ;Cursor right.
+td: db bs,'$',0,0 ;Cursor left
+te: db 1FH,'$',0,0 ;Clear display
+tf: db '$',0,0,0 ;(can't) Enter Graphics Mode
+tg: db '$',0,0,0 ;(can't) Exit Graphics mode
+th: db 1DH,'$',0,0 ;Cursor home.
+ti: db '$',0,0,0 ;(can't) Reverse linefeed.
+tj: db 1EH,'$',0,0 ;Clear to end of screen.
+tk: db 19H,'$',0,0 ;Clear to end of line.
+ENDIF;[22] rm380z
+
+IF lobo ;[hh]
+sysver: db 'Lobo MAX-80$'
+outlin: db esc,'*',cr,lf,tab,tab,'$'
+erascr: db esc,'*$' ;[hh] clear screen and home cursor
+eralin: db cr,esc,'R$' ;[hh] clear line
+curldn: db esc,'=$' ;[hh] cursor lead-in string
+delstr: db bs,' ',bs,bs,'$' ;[hh] ??adjust for echoing delete
+ttab: ;[hh] table start location
+ta: db 0BH,'$',0,0 ;[hh] cursor up
+tb: db 0AH,'$',0,0 ;[hh] cursor down
+tc: db 0CH,'$',0,0 ;[hh] cursor right
+td: db 08H,'$',0,0 ;[hh] cursor left
+te: db esc,'*$',0 ;[hh] clear display (homes cursor)
+tf: db '$',0,0,0 ;[hh] (can't) enter graphics mode
+tg: db '$',0,0,0 ;[hh] (can't) exit graphics mode
+th: db 01EH,'$',0,0 ;[hh] home cursor
+ti: db esc,'E$',0 ;[hh] reverse linefeed (insert line)
+tj: db esc,'Y$',0 ;[hh] clear to end of screen
+tk: db esc,'T$',0 ;[hh] clear to end of line
+ENDIF ;lobo
+
+IF px8 ; [29]
+sysver: db 'Epson PX-8$'
+outlin: db esc,'*$'
+erascr: db esc,'*$' ; clear screen and home
+eralin: db cr,esc,'T$' ; clear line
+curldn: db esc,'=$' ; cursor lead in
+ttab: ; table start location
+ta: db 30,'$',0,0 ; cursor up
+tb: db 31,'$',0,0 ; cursor down
+tc: db 28,'$',0,0 ; cursor right
+td: db 29,'$',0,0 ; cursor left
+te: db esc,'*$',0 ; clear display
+tf: db '$',0,0,0 ; can't enter graphics graphics mode
+tg: db '$',0,0,0 ; can't exit graphics mode
+th: db 11,'$',0,0 ; home cursor
+ti: db 30,'$',0,0 ; reverse linefeed
+tj: db esc,'Y$',0 ; erase to end of screen
+tk: db esc,'T$',0 ; erase to end of line
+ENDIF ; px8 [29]
+
+;
+IF osbrn1
+sysver: db 'Osborne 1$'
+outlin: db 1AH,cr,lf,tab,'$' ;(Clear screen, home cursor)
+erascr: db 1AH,'$' ;Clear screen and go home.
+eralin: db cr,esc,'T$' ;Clear line.
+delstr: db bs,bs,'$' ; Adjust for delete
+curldn: db esc,'=$' ;Cursor lead-in
+ttab: ;Table start location.
+ta: db ('K'-100O),'$',0,0 ;Cursor up.
+tb: db 12O,'$',0,0 ;Cursor down.
+tc: db ('L'-100O),'$',0,0 ;Cursor right.
+td: db bs,'$',0,0 ;Cursor left.
+te: db subt,'$',0,0 ;Clear screen.
+tf: db '$',0,0,0 ;(can't) Enter graphics mode
+tg: db '$',0,0,0 ;(can't) Exit graphics mode
+th: db ('^'-100O),'$',0,0 ;Cursor home.
+ti: db ('K'-100O),'$',0,0 ;Reverse linefeed.
+tj: db esc,'T$',0 ;(can't) Clear to end of screen.
+tk: db esc,'T$',0 ;Clear to end of line.
+ENDIF;osbrn1
+;
+IF vector
+sysver: db 'Vector Graphics$'
+outlin: db ('D'-100O),cr,lf,tab,tab,'$'
+erascr: db ('D'-100O),'$' ;Clear screen and go home.
+eralin: db cr,('Q'-100O),'$' ;Clear line.
+delstr: db bs,' ',bs,bs,'$' ; adjust for echoing delete character
+ttab: ;Table start location.
+ta: db ('U'-100O),'$',0,0 ;Cursor up.
+tb: db 12O,'$',0,0 ;Cursor down.
+tc: db ('Z'-100O),'$',0,0 ;Cursor right.
+td: db '$',0,0,0 ;(can't) Cursor left
+te: db '$',0,0,0 ;(can't) Clear display
+tf: db '$',0,0,0 ;(can't) Enter graphics mode
+tg: db '$',0,0,0 ;(can't) Exit graphics mode
+th: db ('B'-100O),'$',0,0 ;Cursor home.
+ti: db ('U'-100O),'$',0,0 ;Reverse linefeed.
+tj: db ('P'-100O),'$',0,0 ;Clear to end of screen.
+tk: db ('Q'-100O),'$',0,0 ;Clear to end of line.
+ENDIF;vector
+
+IF trs80lb
+sysver: db 'TRS-80 II Lifeboat CP/M$'
+outlin: db esc,':',cr,lf,tab,tab,'$'
+erascr: db esc,':$' ;Clear screen and go home.
+eralin: db cr,esc,'T$' ;Clear line.
+curldn: db esc,'=$' ;Cursor lead-in
+ttab: ;Table start location.
+ta: db 0BH,'$',0,0 ;Cursor up.
+tb: db 0AH,'$',0,0 ;Cursor down.
+tc: db 0CH,'$',0,0 ;Cursor right.
+td: db bs,'$',0,0 ;Cursor left
+te: db esc,':$',0 ;Clear display
+tf: db '$',0,0,0 ;(can't) Enter Graphics Mode
+tg: db '$',0,0,0 ;(can't) Exit Graphics mode
+th: db 1EH,'$',0,0 ;Cursor home.
+ti: db 0BH,'$',0,0 ;Reverse linefeed.
+tj: db esc,'Y$',0 ;Clear to end of screen.
+tk: db esc,'T$',0 ;Clear to end of line.
+ENDIF;trs80lb
+;
+IF trs80pt
+sysver: db 'TRS-80 II P+T CP/M$'
+outlin: db 0CH,cr,lf,tab,tab,'$'
+erascr: db 0CH,'$' ;Clear screen and go home.
+eralin: db cr,01H,'$' ;Clear line.
+curldn: db esc,'Y$' ;Cursor lead-in
+ttab: ;Table start location ;Must be 4 bytes each
+ta: db 1EH,'$',0,0 ;Cursor up.
+tb: db 1FH,'$',0,0 ;Cursor down.
+tc: db 1DH,'$',0,0 ;Cursor right.
+td: db 1CH,'$',0,0 ;Cursor left
+te: db 0CH,'$',0,0 ;Clear display
+tf: db 11H,'$',0,0 ;Enter Graphics Mode
+tg: db 14H,'$',0,0 ;Exit Graphics mode
+th: db 06H,'$',0,0 ;Cursor home.
+ti: db 1EH,'$',0,0 ;Reverse linefeed.
+tj: db 02H,'$',0,0 ;Clear to end of screen.
+tk: db 01H,'$',0,0 ;Clear to end of line.
+ENDIF;trs80pt
+
+IF osi
+outlin: db cr,lf,'Starting ...$'
+erascr equ crlf ;"Home & clear" (best we can do).
+eralin: db '^U',cr,lf,'$' ;Clear line.
+prpack: db cr,lf,'RPack: $'
+pspack: db cr,lf,'SPack: $'
+ttab equ 0 ; no VT52 table
+ENDIF;osi
+;
+IF hp125 ;[MF]
+defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
+vtval EQU 0 ; we probably don't want VT52 emulation
+;
+sysver: db 'HP-125 Series 100$'
+;
+outlin: db esc,'H',esc,'J',cr,lf,tab,tab,'$'
+erascr: db esc,'H',esc,'J$' ;Clear screen and go home.
+eralin: db cr,esc,'K$' ;Clear line.
+curldn: db esc,'&a$' ;Cursor leadin
+ttab: ;Table start location.
+ta: db esc,'A$',0 ;Cursor up.
+tb: db esc,'B$',0 ;Cursor down.
+tc: db esc,'C$',0 ;Cursor right.
+td: db esc,'D$',0 ;Cursor left
+te: db esc,'J$',0 ;Clear display
+tf: db '$',0,0,0 ;[hh] (can't) enter graphics mode
+tg: db '$',0,0,0 ;[hh] (can't) exit graphics mode
+th: db esc,'H$',0 ;Cursor home.
+ti: db esc,'M$',0 ;Reverse linefeed.
+tj: db esc,'J$',0 ;Clear to end of screen.
+tk: db esc,'K$',0 ;Clear to end of line.
+;
+;
+; Escape sequences to map CP/M Reader/Punch to Data Comm input/output,
+; respectively and to turn off these mappings
+;
+mapon1: db esc,'&i10s18d9M'
+ db esc,'&i2s25d9M'
+ db esc,'&i10s16d2M'
+ db esc,'&i0s25d2M$';Esc. sequences to turn off DAtacomm2/turn
+ ;on Data Comm 1
+mapon2: db esc,'&i10s16d9M'
+ db esc,'&i0s25d9M'
+ db esc,'&i10s18d2M'
+ db esc,'&i2s25d2M$';Esc. sequences to turn off Datacomm1/turn
+ ;on Datacomm 2
+mapoff: db esc,'&i0s25d9M'
+ db esc,'&i10s16d9M'
+ db esc,'&i2s25d9M'
+ db esc,'&i10s18d9M$'
+;
+readin: call $-$ ;Read character into b
+ mov a,b ;Get 8-bit character
+ ret ;and return
+;
+jbuf: db 7 ;bios dispatch table vector argument block
+ db 0 ;to read RDR routine address
+ db 0c3h ;...
+ dw 0 ;...
+;
+ENDIF;hp125 ;[MF]
+
+IF lasm and termin ; if no terminal, no need to link
+LINK CPXVDU.ASM
+ENDIF ; lasm and termin
+
+ovlend EQU $
+
+IF lasm
+ END ; If m80 then this ignored
+ENDIF ; lasm
diff --git a/cpxsyo.asm b/cpxsyo.asm
index 5b1cb0e..aaba2bb 100644
--- a/cpxsyo.asm
+++ b/cpxsyo.asm
@@ -1,389 +1,389 @@
-IF NOT lasm
-.printx * CPXSYO.ASM *
-ENDIF ;NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the system dependent part for Sanyo MBC 1100
-; systems, and has been extracted from the CPMSYO.ASM code (kermit
-; version 3.5)
-;
-; revision history:
-;
-; edit 1, 27 October, 1987, by OBSchou. Extracted Sanyo code from CPMSYO.ASM
-; and massaged fort CP/M kermit V4.09
-;
-; Keep module name, edit number, and last revision date in memory.
-family: db 'CPXSYO.ASM (1) 27-Oct-87 $'
-;
-
-; Assembly time message to let me know I'm building the right version.
-; LASM generates an 'S' error along with the message, which is messy, but
-; better than trying to put everything inside a IF m80 OR mac80 conditional,
-; because LASM doesn't like nested IF's, either.
-
-IF sanyo
-.printx * Assembling Kermit-80 for Sanyo MBC 1100 *
-ENDIF
-
-iobyte EQU 03H ;Location of I/O byte
-
-if sanyo
-baudrt EQU 0DAH ;BAUD RATE MEMORY LOCATION
-MNPORT EQU 0DCH ;COMMUNICATIONS PORT
-MNPRTS EQU 0DDH ;COMMUNICATIONS PORT STATUS
-OUTPUT EQU 01H ;OUTPUT READY BIT
-INPUT EQU 02H ;INPUT READY BIT
-ENDIF;SANYO
-
-defesc EQU '\'-100O ;The default escape character.
-
-; Select initial setting for VT-52 emulation flag.
-vtval EQU 1
-
-
-sysxin: ;system initialisation not covered by sysinit
- ret ; return from system-dependent routine
-
-;
-
-;
-; system-dependent termination processing
-; If we've changed anything, this is our last chance to put it back.
-sysexit:
- ret
-
-;
-; system-dependent processing for start of CONNECT command
-;
-syscon:
- ret
-
-;
-
-;
-; syscls - system-dependent close routine
-; called when exiting transparent session.
-;
-syscls:
- ret
-;
-
-;
-; sysinh - help for system-dependent special functions.
-; called in response to <escape>?, after listing all the
-; system-independent escape sequences.
-;
-sysinh:
- lxi d,inhlps ; we got options...
- call prtstr ; print them.
- ret
-inhlps:
- db '$' ;[hh] table terminator
-
-;
-; sysint - system dependent special functions
-; called when transparent escape character has been typed;
-; the second character of the sequence is in A (and in B).
-; returns:
-; non-skip: sequence has been processed
-; skip: sequence was not recognized
-sysint:
- ani 137O ; convert lower case to upper, for testing...
- ret
-
-; sysflt - system-dependent filter.
-; called with the character in E.
-; preserves bc, de, hl.
-; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-sysflt:
- mov a,e ; get character for testing
- ret
-
-; mdmflt - modem filter [30]
-; called with character to be sent to printer in E
-; with parity set as appropriate.
-; return with accumulator = 0 do do nothing,
-; <> 0 to send char in E.
-mdmflt:
- mov a,e ;[30] get character to test
- ret
-
-
-; prtflt - printer filter [30]
-; called with character to be sent to printer in E
-; returns with a = 0 to do nothing
-; a <> 0 to print it.
-;
-; this routine for those printer that automatically insert
-; a lf on cr, or cr for lf. Should this be shifted to
-; the system indep. stuff, in say 4.06?
-prtflt:
- mov a,e ; [30] get character to test
- ret
-
-
-;
-
-;
-; system-dependent processing for BYE command.
-; for apmmdm, heath, and lobo, hang up the phone.
-sysbye:
- ret
-;
-
-; This is the system-dependent command to change the baud rate.
-; DE contains the two-byte value from the baud rate table; this
-; value is also stored in 'speed'.
-sysspd:
- ret
-
-;
-
-; Speed tables
-; (Note that speed tables MUST be in alphabetical order for later
-; lookup procedures, and must begin with a value showing the total
-; number of entries. The speed help tables are just for us poor
-; humans.
-
-; db string length,string,divisor (2 identical bytes or 1 word)
-; [Toad Hall]
-
-IF sanyo
-spdtbl EQU 0 ; No speed table for the Sanyo
-sphtbl EQU 0 ; ditto help for speed.
-
-; The following conditionals were once a huge if not statement. There
-; wasn't enough room to add the lobo to the list, so it had to be broken
-; into 2, which you can't do with an if not. I redid it as two ifs and
-; applied them to those that wouldn't set baud. [Hal Hostetler]
-;
-
-; This is the system-dependent SET PORT command.
-; HL contains the argument from the command table.
-sysprt:
- ret
-;
-
-;
-; Port table not applicable tot he Sanyo...
-prttbl EQU 0
-prhtbl EQU 0 ;
-
-;
-
-;
-; selmdm - select modem port
-; selcon - select console port
-; selmdm is called before using inpmdm or outmdm;
-; selcon is called before using inpcon or outcon.
-; For iobyt systems, diddle the I/O byte to select console or comm port;
-; For Decision I, switches Multi I/O board to console or modem serial
-; port. [Toad Hall]
-; For the rest, does nothing.
-; preserves bc, de, hl.
-selmdm:
- ret
-
-selcon:
- ret
-;
-
-; Get character from console, or return zero.
-; result is returned in A. destroys bc, de, hl.
-;
-inpcon:
- mvi c,dconio ;Direct console I/O BDOS call.
- mvi e,0FFH ;Input.
- call BDOS
- ret
-;
-
-;
-; Output character in E to the console.
-; destroys bc, de, hl
-;
-outcon:
- mvi c,dconio ;Console output bdos call.
- call bdos ;Output the char to the console.
- ret
-;
-
-;
-; outmdm - output a char from E to the modem.
-; the parity bit has been set as necessary.
-; returns nonskip; bc, de, hl preserved.
-outmdm:
-IF inout
- in mnprts ;Get the output done flag.
- ani output ;Is it set?
- jz outmdm ;If not, loop until it is.
- mov a,e
- out mnport ;Output it.
- ret
-ENDIF;inout
-
-;
-
-;
-; get character from modem; return zero if none available.
-; for IOBYT systems, the modem port has already been selected.
-; destroys bc, de, hl.
-inpmdm:
-IF inout
-;Note: modem port should already be selected for mdI. [Toad Hall]
- in mnprts ;Get the port status into A.
- ani input ;See if the input ready bit is on.
- rz ;If not then return.
- in mnport ;If so, get the char.
-ENDIF;inout
- ret ; return with character in A
-
-
-;
-; flsmdm - flush comm line.
-; Modem is selected.
-; Currently, just gets characters until none are available.
-
-flsmdm: call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-
-
-;
-
-;
-; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
-lptstat:
- xra a ; assume it is ok.. this may not be necessary
- ret
-;
-
-;
-; outlpt - output character in E to printer
-; console is selected.
-; preserves de.
-outlpt:
- push d ; save DE in either case
- call prtflt ; go through printer filter [30]
- ana a ; if A = 0 do nothing,
- jz outlp1 ; [30] if a=0 do nothing
- mvi c,lstout
- call bdos ;Char to printer
-outlp1: pop d ; restore saved register pair
- ret
-;
-
-;
-; Screen manipulation routines
-; csrpos - move to row B, column C
-;
-; csrpos for terminals that use a leadin sequence followed
-; by (row + 31.) and (column + 31.)
-;
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,h ; get row
- adi (' '-1) ; space is row one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,l ; get column
- adi (' '-1) ; space is column one
- mov e,a
- jmp outcon ; output it and return
-ENDIF;NOT (robin OR dmII OR osi OR vector OR termin)
-
- ret ; Can the Sany do cursor opsitioning??
-
-;
-;
-; delchr - make delete look like a backspace. Unless delete is a printing
-; character, we just need to print a backspace. (we'll output clrspc
-; afterwards)
-; For Kaypro and Vector General, delete puts a blotch on the screen.
-; For Apple and Osborne 1, delete moves but doesn't print.
-delchr:
- mvi e,bs
- call outcon
-
-; erase the character at the current cursor position
-clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the current line
-clrlin: lxi d,eralin
- jmp prtstr
-
-; erase the whole screen, and go home. preserves b (but not c)
-clrtop: lxi d,erascr
- jmp prtstr
-
-
-
-IF SANYO
-outlin: DB ESC,'E',ESC,'H',CR,LF,TAB ;WHATEVER
-sysver: DB 'KERMIT-80 V3.9 [SANYO MBC-1100]',CR,LF,'$' ;VERSION HEADING
-DELSTR: DB ESC,'K','$' ;WHATS A STRING?
-eralin: DB ESC,'P','$' ;CLEAR SPACE
-;CLRLIN: DB ESC,'K','$' ;CLEAR LINE
-erascr: DB ESC,'E',ESC,'H','$' ;CLEAR SCREEN AND CURSOR HOME
-curldn: db esc,'=','$',0 ;cursor lead in
-;SCRNP: DB ESC,'=',24H,25H,'$' ;SPOT FOR SCREEN PACKETS
-;SCRNRT: DB ESC,'=',25H,25H,'$' ;SPOT FOR # OF RETRIES
-;SCRFLN: DB ESC,'=',26H,25H,'$' ;SPOT FOR FILE NAME
-;SCRST: DB ESC,'=',28H,25H,'$' ;SPOT FOR STATUS
-;SCREND: DB ESC,'=',2AH,25H,'$' ;SPOT FOR PROMPT
-;SCRERR: DB ESC,'=',2DH,25H,'$' ;SPOT FOR ERRORS
-ttab: ;NO TRANSLATION TABLE
-ta: DB ESC,'A',0,0 ;CURSOR UP
-tb: DB ESC,'B',0,0 ;CURSOR DOWN
-tc: DB ESC,'D',0,0 ;CURSOR RIGHT
-td: DB ESC,'C',0,0 ;CURSOR LEFT
-te: DB ESC,'E',0,0 ;CLEAR SCREEN
-tf: DB 0,0,0,0 ;WHAT???
-tg: DB 0,0,0,0 ;WHAT???
-th: DB ESC,'H',0,0 ;CURSOR HOME
-ti: DB ESC,'A',ESC,'C',0,0 ;REVERSE LINEFEED??
-tj: DB ESC,'J',0,0 ;CLEAR TO END OF SCREEN
-tk: DB ESC,'K',0,0 ;CLEAR TO END OF LINE
-ENDIF;SANYO
-
-ovlend equ $ ; End of overlay
-
- END
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+IF NOT lasm
+.printx * CPXSYO.ASM *
+ENDIF ;NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the system dependent part for Sanyo MBC 1100
+; systems, and has been extracted from the CPMSYO.ASM code (kermit
+; version 3.5)
+;
+; revision history:
+;
+; edit 1, 27 October, 1987, by OBSchou. Extracted Sanyo code from CPMSYO.ASM
+; and massaged fort CP/M kermit V4.09
+;
+; Keep module name, edit number, and last revision date in memory.
+family: db 'CPXSYO.ASM (1) 27-Oct-87 $'
+;
+
+; Assembly time message to let me know I'm building the right version.
+; LASM generates an 'S' error along with the message, which is messy, but
+; better than trying to put everything inside a IF m80 OR mac80 conditional,
+; because LASM doesn't like nested IF's, either.
+
+IF sanyo
+.printx * Assembling Kermit-80 for Sanyo MBC 1100 *
+ENDIF
+
+iobyte EQU 03H ;Location of I/O byte
+
+if sanyo
+baudrt EQU 0DAH ;BAUD RATE MEMORY LOCATION
+MNPORT EQU 0DCH ;COMMUNICATIONS PORT
+MNPRTS EQU 0DDH ;COMMUNICATIONS PORT STATUS
+OUTPUT EQU 01H ;OUTPUT READY BIT
+INPUT EQU 02H ;INPUT READY BIT
+ENDIF;SANYO
+
+defesc EQU '\'-100O ;The default escape character.
+
+; Select initial setting for VT-52 emulation flag.
+vtval EQU 1
+
+
+sysxin: ;system initialisation not covered by sysinit
+ ret ; return from system-dependent routine
+
+;
+
+;
+; system-dependent termination processing
+; If we've changed anything, this is our last chance to put it back.
+sysexit:
+ ret
+
+;
+; system-dependent processing for start of CONNECT command
+;
+syscon:
+ ret
+
+;
+
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+ ret
+;
+
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing all the
+; system-independent escape sequences.
+;
+sysinh:
+ lxi d,inhlps ; we got options...
+ call prtstr ; print them.
+ ret
+inhlps:
+ db '$' ;[hh] table terminator
+
+;
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:
+; non-skip: sequence has been processed
+; skip: sequence was not recognized
+sysint:
+ ani 137O ; convert lower case to upper, for testing...
+ ret
+
+; sysflt - system-dependent filter.
+; called with the character in E.
+; preserves bc, de, hl.
+; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
+sysflt:
+ mov a,e ; get character for testing
+ ret
+
+; mdmflt - modem filter [30]
+; called with character to be sent to printer in E
+; with parity set as appropriate.
+; return with accumulator = 0 do do nothing,
+; <> 0 to send char in E.
+mdmflt:
+ mov a,e ;[30] get character to test
+ ret
+
+
+; prtflt - printer filter [30]
+; called with character to be sent to printer in E
+; returns with a = 0 to do nothing
+; a <> 0 to print it.
+;
+; this routine for those printer that automatically insert
+; a lf on cr, or cr for lf. Should this be shifted to
+; the system indep. stuff, in say 4.06?
+prtflt:
+ mov a,e ; [30] get character to test
+ ret
+
+
+;
+
+;
+; system-dependent processing for BYE command.
+; for apmmdm, heath, and lobo, hang up the phone.
+sysbye:
+ ret
+;
+
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; this
+; value is also stored in 'speed'.
+sysspd:
+ ret
+
+;
+
+; Speed tables
+; (Note that speed tables MUST be in alphabetical order for later
+; lookup procedures, and must begin with a value showing the total
+; number of entries. The speed help tables are just for us poor
+; humans.
+
+; db string length,string,divisor (2 identical bytes or 1 word)
+; [Toad Hall]
+
+IF sanyo
+spdtbl EQU 0 ; No speed table for the Sanyo
+sphtbl EQU 0 ; ditto help for speed.
+
+; The following conditionals were once a huge if not statement. There
+; wasn't enough room to add the lobo to the list, so it had to be broken
+; into 2, which you can't do with an if not. I redid it as two ifs and
+; applied them to those that wouldn't set baud. [Hal Hostetler]
+;
+
+; This is the system-dependent SET PORT command.
+; HL contains the argument from the command table.
+sysprt:
+ ret
+;
+
+;
+; Port table not applicable tot he Sanyo...
+prttbl EQU 0
+prhtbl EQU 0 ;
+
+;
+
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; For iobyt systems, diddle the I/O byte to select console or comm port;
+; For Decision I, switches Multi I/O board to console or modem serial
+; port. [Toad Hall]
+; For the rest, does nothing.
+; preserves bc, de, hl.
+selmdm:
+ ret
+
+selcon:
+ ret
+;
+
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+ mvi c,dconio ;Direct console I/O BDOS call.
+ mvi e,0FFH ;Input.
+ call BDOS
+ ret
+;
+
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+ mvi c,dconio ;Console output bdos call.
+ call bdos ;Output the char to the console.
+ ret
+;
+
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+outmdm:
+IF inout
+ in mnprts ;Get the output done flag.
+ ani output ;Is it set?
+ jz outmdm ;If not, loop until it is.
+ mov a,e
+ out mnport ;Output it.
+ ret
+ENDIF;inout
+
+;
+
+;
+; get character from modem; return zero if none available.
+; for IOBYT systems, the modem port has already been selected.
+; destroys bc, de, hl.
+inpmdm:
+IF inout
+;Note: modem port should already be selected for mdI. [Toad Hall]
+ in mnprts ;Get the port status into A.
+ ani input ;See if the input ready bit is on.
+ rz ;If not then return.
+ in mnport ;If so, get the char.
+ENDIF;inout
+ ret ; return with character in A
+
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+
+flsmdm: call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+
+
+;
+
+;
+; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
+lptstat:
+ xra a ; assume it is ok.. this may not be necessary
+ ret
+;
+
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+outlpt:
+ push d ; save DE in either case
+ call prtflt ; go through printer filter [30]
+ ana a ; if A = 0 do nothing,
+ jz outlp1 ; [30] if a=0 do nothing
+ mvi c,lstout
+ call bdos ;Char to printer
+outlp1: pop d ; restore saved register pair
+ ret
+;
+
+;
+; Screen manipulation routines
+; csrpos - move to row B, column C
+;
+; csrpos for terminals that use a leadin sequence followed
+; by (row + 31.) and (column + 31.)
+;
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; restore coordinates
+ mov a,h ; get row
+ adi (' '-1) ; space is row one
+ mov e,a
+ push h
+ call outcon ; output row
+ pop h
+ mov a,l ; get column
+ adi (' '-1) ; space is column one
+ mov e,a
+ jmp outcon ; output it and return
+ENDIF;NOT (robin OR dmII OR osi OR vector OR termin)
+
+ ret ; Can the Sany do cursor opsitioning??
+
+;
+;
+; delchr - make delete look like a backspace. Unless delete is a printing
+; character, we just need to print a backspace. (we'll output clrspc
+; afterwards)
+; For Kaypro and Vector General, delete puts a blotch on the screen.
+; For Apple and Osborne 1, delete moves but doesn't print.
+delchr:
+ mvi e,bs
+ call outcon
+
+; erase the character at the current cursor position
+clrspc: mvi e,' '
+ call outcon
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the current line
+clrlin: lxi d,eralin
+ jmp prtstr
+
+; erase the whole screen, and go home. preserves b (but not c)
+clrtop: lxi d,erascr
+ jmp prtstr
+
+
+
+IF SANYO
+outlin: DB ESC,'E',ESC,'H',CR,LF,TAB ;WHATEVER
+sysver: DB 'KERMIT-80 V3.9 [SANYO MBC-1100]',CR,LF,'$' ;VERSION HEADING
+DELSTR: DB ESC,'K','$' ;WHATS A STRING?
+eralin: DB ESC,'P','$' ;CLEAR SPACE
+;CLRLIN: DB ESC,'K','$' ;CLEAR LINE
+erascr: DB ESC,'E',ESC,'H','$' ;CLEAR SCREEN AND CURSOR HOME
+curldn: db esc,'=','$',0 ;cursor lead in
+;SCRNP: DB ESC,'=',24H,25H,'$' ;SPOT FOR SCREEN PACKETS
+;SCRNRT: DB ESC,'=',25H,25H,'$' ;SPOT FOR # OF RETRIES
+;SCRFLN: DB ESC,'=',26H,25H,'$' ;SPOT FOR FILE NAME
+;SCRST: DB ESC,'=',28H,25H,'$' ;SPOT FOR STATUS
+;SCREND: DB ESC,'=',2AH,25H,'$' ;SPOT FOR PROMPT
+;SCRERR: DB ESC,'=',2DH,25H,'$' ;SPOT FOR ERRORS
+ttab: ;NO TRANSLATION TABLE
+ta: DB ESC,'A',0,0 ;CURSOR UP
+tb: DB ESC,'B',0,0 ;CURSOR DOWN
+tc: DB ESC,'D',0,0 ;CURSOR RIGHT
+td: DB ESC,'C',0,0 ;CURSOR LEFT
+te: DB ESC,'E',0,0 ;CLEAR SCREEN
+tf: DB 0,0,0,0 ;WHAT???
+tg: DB 0,0,0,0 ;WHAT???
+th: DB ESC,'H',0,0 ;CURSOR HOME
+ti: DB ESC,'A',ESC,'C',0,0 ;REVERSE LINEFEED??
+tj: DB ESC,'J',0,0 ;CLEAR TO END OF SCREEN
+tk: DB ESC,'K',0,0 ;CLEAR TO END OF LINE
+ENDIF;SANYO
+
+ovlend equ $ ; End of overlay
+
+ END
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cpxsys.asm b/cpxsys.asm
index 0b179b9..93b5c1f 100644
--- a/cpxsys.asm
+++ b/cpxsys.asm
@@ -1,1386 +1,1386 @@
-IF NOT lasm
-.printx * CPXSYS.ASM *
-ENDIF ;NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the system-dependent code and data for KERMIT.
-; It will be probably be broken into independent files to generate
-; overlays for the various systems, one or more overlay possible
-; from each file. For now, we will leave it in one piece.
-;
-; revision history:
-;
-;
-; Edit 40, 28-Aug-89 by Mike Freeman of Bonneville Power Administration,
-; P.O. Box 491, Vancouver WA 98666 USA, Telephone (206)690-2307:
-; Home address: 301 N.E. 107th Street; Vancouver, WA 98685 USA
-; Home telephone: (206)574-8221
-; added support for Hewlett-Packard HP-125 Business Assistant computer
-; running a HP-modified CP/M Version 2.2; communications on
-; DAta Comm 1 or Data Comm 2 (8th-bit quoting must be used on
-; Data Comm 2 to transfer binary files as Data Comm 2 only supports
-; a 7-bit data path); printer cannot be used with communications on
-; Data Comm 2 (the printer port).
-; edit 39, 4 August, 1987b by OBSchou for Charles Lasner re. DECMATE II
-; fixes to set xon/off control off for the duration of Kermit-80.
-;
-; His header reads:
-;
-; IBM mode restore program
-;
-; This routine must be run after using CP4DMF (and KERMIT-80) to restore
-; the normal handling of XON/XOFF; the user may also elect to cold-boot
-; the DECMATE instead.
-;
-; acknowledgments and limitations.
-;
-; This program is based on DECMATE specific implementation details
-; provided by Walt Lamia of DEC. It is of course, specific to DECMATE
-; implementations of CP/M-80 for DECMATE II, III, III-plus, etc.
-;
-; usage consists of merely:
-;
-; CP4DMF run xon/xoff disable program
-; KERMIT80 then run kermit
-; <KERMIT-80 commands used normally here, including SET IBM ON>
-; CP4DMU run this program to restore normal XON
-;
-; unless CP4DMU is run following KERMIT-80, the normal handling of
-; XON/XOFF provided by KERMIT-80 will not work (cold boot is another
-; alternative).
-;
-; [Note - These edits now included in the init/de-init code]
-;
-; edit 38, 23 July, 1987 by OBSchou. Moved out commonly used code
-; to CPXCOM.ASM, and adjusted this (ond other family) files accordingly.
-; Also filtered out code now in other family files.
-;
-; edit 37 , 15 July 1987 by OBSchou for David Moore, who has submitted
-; code for Teletek SYSTEMASTER (teletek) and for an ADM 22 terminal.
-;
-; edit 36 28 Jan 87 by OBSchou.
-; Removed the printx etc and should only have this file if a system
-; does not have a family file.
-;
-; edit 35 1st Dec 1986 by OBSchou. Added test for Amstrad PCW range (PCW)
-; Links to CPXPCW.ASM, which was submitted by Ian Young, Lattice
-; Logic Systems.
-;
-; edit 34 20 August by OBSchou for Brian Robertson, Aberdeen University:
-; I have discovered a bug in my code for the BBC/Z80 version of Kermit.
-; At startup the transmitter baud rate is read from the serial ULA.
-; The TX and RX baud rates are then reset to this value and the
-; value is stored in location 'baud:' for the STATUS (or SHOW)
-; command. That is how it is supposed to work ! Unfortunately
-; my code at present "misreads" the initial TX baud rate - there
-; is some bit manipulation that needs to be done to extract the
-; correct value.
-;
-; edit 33 30-May-86 OBSchou. Added two new enties to the overly. One for
-; printer status and the other for the address of the family of
-; computer using the overlay. If it is still in CPXSYS.ASM then it
-; is a dollar only.
-;
-;edit 32, 27 May, 1986 by OBSchou Loughborough University for
-; B Robertson, Aberdeen Univ. Computing Centre. Any mistakes my fault.
-; Add support for APPLE II with serial cards based on the 6850 ACIA.
-; Mod 380Z support to allow both MDS (5 1/4" discs) and FDS (8" discs)
-; configurations.
-;
-; edit 31, 22 April, 1986, OBSchou.
-; Kermit version 4.06 starts here. All previous edits have been
-; put aside (leave in a BWR file?). Hived off some definitions
-; to the CPSDEF.ASM file as that is where they belong.
-; Start on splitting off individual
-; systems from this huge file. It is done using the LINK facility
-; LASM. We link to a collection of systems under CPXxxx.ASM.
-; I have started with the systems I know, the Torch, Cifer and
-; pci2651. These will all be held under CPXTOR.ASM
-;
-;
-; Keep module name, edit number, and last revision date in memory.
-family: db 'CPXSYS.ASM (40) 28-Aug-89 $' ; now a family...
-;
-
-
-; Processor speed in units of 100KHz
-; for cpt85xx, advance, apple,bbc,px8 & rm380z timing loop [12]
-IF rm380z
-cpuspd SET 40 ; 4.0 MHz CPU
-ENDIF; rm380z
-
-IF disc OR mmate OR s1008 OR access
-cpuspd SET 40 ; 4.0 MHz CPU
-ENDIF ;disc OR mmate OR s1008 OR access
-
-IF bbc ;[9]
-cpuspd SET 60 ; BBC with 6Mhz Z80
-ENDIF;bbc
-
-
-; the basics...
-
-IF gener
-batio EQU 056H ;I/O byte CON=BAT,LIST=CRT,READER=RDR,PUNCH=PTP
-defio EQU 095H ;I/O byte CON=CRT,LIST=LPT,READER=RDR,PUNCH=PTP
-crtio equ 01010101B ; use CRT: device
-ptrio equ 01010110B ; use PTR: device
-ttyio equ 00000000B ; use TTY: device
-uc1io equ 01010111B ; use UC1: device
-ur1io equ 01101010B ; use UR1: device
-ur2io equ 01111110B ; use UR2: device
-ENDIF;gener
-
-IF robin
-batio EQU 056H ;I/O byte CON=BAT,LIST=CRT,READER=RDR,PUNCH=PTP
-defio EQU 095H ;I/O byte CON=CRT,LIST=LPT,READER=RDR,PUNCH=PTP
-lptio EQU 054H ;I/O byte CON=TTY,LIST=CRT,READER=PTR,PUNCH=PTP
-gppio EQU 057H ;I/O byte CON=UC1,LIST=CRT,READER=RDR,PUNCH=PTP
-ENDIF;robin
-
-
-IF dmII OR bbc ;[22]
-batio EQU 042H ;I/O byte CON=BAT,LIST=CRT,READER=RDR
-defio EQU 081H ;I/O byte CON=CRT,LIST=LPT,READER=RDR
-ENDIF;dmII
-
-IF mikko
-batio EQU 10110010B ; I/O byte console => serial line
-defio EQU 10000001B ; I/O byte console => CRT and Keyboard
-ENDIF;mikko
-;
-IF lobo ;[hh]
-mnport EQU 0F7E4H ;Modem data port A
-mnprts EQU 0F7E5H ;Modem status/conrtol port A
-baudrt EQU 0F7D0H ;Baud rate port A
-output EQU 04H ;Transmit buffer empty
-input EQU 01H ;Receive data available
-z80 SET TRUE ;a good z80, here
-ENDIF;lobo
-
-IF osi
-mnport EQU 0CF01H ;Modem data port
-mnprts EQU 0CF00H ;Modem status port
-output EQU 02H ;Transmitter empty
-input EQU 01H ;Input data available
-z80 SET FALSE ;I don't know...
-ENDIF;osi
-
-IF vector
-mnport EQU 04H ;Modem data port
-mnprts EQU 05H ;Modem status port
-output EQU 01H ;Transmitter empty
-input EQU 02H ;Input data available
-z80 SET FALSE ;I don't know...
-ENDIF;vector
-
-IF delphi ;[7]
-mnport EQU 22H ;[7] Modem data port
-mnprts EQU 23H ;[7] Modem status port
-output EQU 01H ;[7] Transmitter empty
-input EQU 02H ;[7] Input data available
-baudrt equ 29h ;[7] Baud rate port for channel 2 (default)
-z80 SET true ;[7] We're using the z80 side of the dual processor
-ENDIF;[7] delphi
-
-IF trs80
-;NEEDS display definition (e.g. trs80lb or trs80pt)
-mnport EQU 0F4H ;Modem data port (0F5H for port B)
-mnprts EQU 0F6H ;Modem status port (0F7H for port B)
-output EQU 04H ;Transmitter empty
-input EQU 01H ;Input data available
-z80 SET TRUE ;[hh] All TRS-80's but the CoCo
-ENDIF;trs80
-
-IF teletek
-mnport EQU 00H ;Modem data port (02 for port B (console))
-mnprts EQU 01H ;Modem status port (03 for port B (console))
-baudrt EQU 08H ;ctc0 control port (09 for port B (console))
-output EQU 04H ;Transmitter empty
-input EQU 01H ;Input data available
-z80 SET TRUE ;All Teleteks
-ENDIF;teletek
-
-IF osbrn1
-;Osborne 1 uses 6850 ACIA, but memory mapped. Derived from Apple.
-BAUDRT EQU 0EFC1H ;Memory location where baud rates are stored.
-OSTOP EQU 4000H ;Where we move OSMOVE to at startup
-OSPORT EQU 2A01H ;Communications Port.
-OSPRTS EQU 2A00H ;Communications Port Status.
-OUTPUT EQU 02H ;Output Buffer Empty.
-INPUT EQU 01H ;Input Register Full.
-OSBIN1 EQU 57H ;First Init Character for 6850 ACIA (Reset)
-;(I would have thought 03, but prom code writes 57 there)
-OSBI12 EQU 55H ;Second Init Character for ACIA (8-bits, 1200)
-OSBI03 EQU 56H ;Second init char. for ACIA (8 bits, 300)
-;(don't ask.. I don't know why SETUP writes 55 and 56 either)
-z80 SET TRUE ;[hh] a z80 here, also
-ENDIF;osbrn1
-
-IF robin
-;Those definitions below that are commented out are just for information
-;***** NOT generally found in distributed documentation ****
-
-;pbausl EQU 90H ;The Baud-Rate register.
-prntst EQU 49H ;Printer
-;prndat EQU 48H
-contst EQU 41H ;Console
-;condat EQU 40H
-gentst EQU 51H ;General port.
-;gendat EQU 50H
-comtst EQU 59H ;COMM-Port
-;comdat EQU 58H
-;output EQU 01H ;Output ready bit.
-;input EQU 02H ;Input ready bit.
-z80 SET TRUE ; This one's a Z80.
-ENDIF;robin
-
-IF s1008 ;[29]
-mnport equ 00 ;printer port data
-mnprts equ 01 ;printer port status
-output equ 4 ;transmitter ready
-input equ 2 ;receiver ready
-z80 equ FALSE ;not important
-ENDIF;s1008 [29]
-
-IF mmate ;[29]
-mnport EQU 89H ;MODEM data port
-mnprts EQU 8BH ;MODEM status/control port
-output EQU 04H ;Transmit buffer empty, ready to send
-input EQU 01H ;Receive data available
-baudrt EQU 93H ;MODEM baud rate port
- ;NOTE - also used for console
-z80 SET TRUE
-ENDIF;mmate [29]
-
-IF disc ;[29]
-mnport EQU 05 ;Discovery 83U port B data
-mnprts EQU 04 ;Discovery 83U port B status/command
-output EQU 04 ;Transmit buffer empty
-input EQU 01 ;Receiver ready
-z80 SET TRUE
-ENDIF;disc [29]
-
-IF cmemco ;[25]
-tuart EQU 020H ;TU-ART address
-mnport EQU tuart+1 ;Modem data port
-mnprts EQU tuart ;Modem status port
-output EQU 080H ;Transmitter empty
-input EQU 040H ;Input data available
-baudrt EQU tuart ;Baud rate port
-;Note: Needs terminal definition
-z80 SET TRUE ;This one's a Z80.
-ENDIF;cmemco
-
-IF cpt85xx
-baudrt EQU 4Ch ; Baud rate generater (National MM5307)
-mnport EQU 4Bh ; Comm port data register (Intel 8251)
-mnprts EQU 4Ah ; Comm port command/status register
-output EQU 01h ; Transmitter buffer empty flag
-input EQU 02h ; Reciver buffer full flag
-TxEmpty EQU 04h ; Transmitter empty flag
-z80 SET FALSE ; It's really an 8080 [or 8085 ... same thing]
-ENDIF;cpt85xx
-
-IF mmdI ;Morrow MicroDecision - the single-board one
-mnport EQU 0FEH ;Morrow Printer UART data port
-mnprts EQU 0FFH ;Morrow Printer UART command/status
-output EQU 01H ;Output ready bit.
-input EQU 02H ;Input ready bit.
-;Note: Needs terminal definition
-z80 SET FALSE ;I don't know...
-ENDIF;mmdI
-
-IF bbc ;[22]
-osbyte EQU 0FFF4H ; OS entry point
-osword EQU 0FFF1H ; " " "
-term EQU 0FFC8H ;Terminal mode OS entry
-z80 SET TRUE
-ENDIF;[22] bbc
-
-;Two types of 380Z system
-IF rm380zm ;[27] MDS - 5 1/4" discs
-mnport EQU 0C8H ;Modem data port
-mnprts EQU 0C9H ;Modem status port
-ENDIF;[32] rm380zm
-
-IF rm380zf ;[32] FDS - 8" discs
-mnport EQU 0E8H ;Modem data port
-mnprts EQU 0E9H ;Modem status port
-ENDIF;[32] rm380zf
-
-IF rm380z ;[32] Common to both systems
-output EQU 01H ;Transmitter buffer empty
-input EQU 02H ;Input data available
-TxEmpty EQU 04h ;Transmitter empty flag
-z80 SET TRUE
-ENDIF;[22] rm380z
-
-IF px8 ; [29]
-z80 SET TRUE
-mnprts EQU 0dh ; used in sending a break
-ENDIF ;px8 [29]
-
-IF mdI ;Morrow Decision I - the big sucker
-mnport equ 48H ; Modem data port.
-mnprts equ 4DH ; Modem status port.
-output equ 20H ; Transmitter empty.
-input equ 1 ; Input data available.
-mbase equ 48H ; Base address of Multi I/O port
- ; selector area.
-grpsel equ 4FH ; Group select port.
-rbr equ 48H ; Read Data Buffer.
-group equ 1 ; Multi I/O Group byte for serial ports.
-congrp equ 1 ; Serial Port 1 for console
-mdmgrp equ 3 ; Serial Port 3 for modem.
-
-; Following are needed for baud rate changes...[Toad Hall]
-
-dlm equ 49H ; Baud Rate Divisor (Most Sig Bit)
-dll equ 48H ; Baud Rate Divisor (Least Sig Bit)
-ier equ 49H ; Interrupt Enable Register
-lcr equ 4BH ; Line Control Register
-lsr equ 4DH ; Line Status Register
-msr equ 4EH ; Modem Status Register
-dlab equ 80H ; Divisor Latch Access Bit
-wls0 equ 1 ; Word Length Select Bit 0
-wls1 equ 2 ; Word Length Select Bit 1 for 8 bit word
-stb equ 4 ; Stop bit count - 2 stop bits
-imask equ 0 ; Interrupt mask (all disabled)
-z80 SET TRUE ; This one's a Z80.
-ENDIF ;mdI NOTE: needs terminal definition. [Toad Hall]
-
-IF mikko
-sioac EQU 0FF12H ;SIO channel A register(s) address
-sioo3 EQU 01000001B ;SIO Write Reg. 3 original setup (?)
- ;RX 7 bits,synch mode bits 0,RX enable
-sion3 EQU 11001111B ;SIO Write Reg. 3 KERMIT setup
- ;RX 8 bits,synch mode bits 0,RX enable
-sioo4 EQU 01001111B ;SIO Write Reg. 4 original setup (?)
- ;X16 clock,8 bit synch(ignored),
- ;2stop bits,par even(on)
-sion4 EQU 01000100B ;SIO Write Reg. 4 KERMIT setup
- ;X16 clock,8 bit synch(ignored),
- ;1stop bit,par off
-sioo5 EQU 10101010B ;SIO Write Reg. 5 original setup (?)
- ;DTR,TX 7 bits,TX enable,RTS
-sion5 EQU 11101010B ;SIO Write Reg. 5 KERMIT setup
- ;DTR,TX 8 bits,TX enable,RTS
-txclk EQU 0FF30H ;Baud rate generator (CTC) for transmitter
-rxclk EQU 0FF31H ;Baud rate generator (CTC) for receiver
-chmask EQU 0F1F2H ;Mask byte address for SIO ch. A reception
-z80 SET TRUE ;It's got a SIO and a CTC, it must be a Z80
-ENDIF;mikko
-
-
-IF access ;[29]
-mnport EQU 40H ;Modem data port A
-mnprts EQU 42H ;Modem status/conrtol port A
-output EQU 04H ;Transmit buffer empty
-input EQU 01H ;Receive data available
-z80 SET TRUE ;a good z80, here
-ENDIF;access [29]
-
-
-IF robin OR dmII
-z80 SET TRUE ; This one's a Z80
-ENDIF;robin OR dmII
-
-IF hp125 ;[MF]
-z80 SET TRUE ;HP-125 uses a Z80
-ENDIF;hp125 [MF]
-
-IF gener OR cpm3 ; To be truly generic, we must assume 8080.
-z80 SET FALSE
-ENDIF;gener OR cpm3
-;
-IF osi
-defesc EQU ']'-100O ;The default escape character.
-ENDIF; osi
-
-IF vector
-defesc EQU '~' ;Vector can't type ']'.
-ENDIF;vector
-
-IF mikko OR osbrn1 OR lobo
-defesc EQU '\'-100O ;The default is Control \ -- it's easier B.E.
-ENDIF;mikko OR osbrn1 OR lobo
-
-IF cpt85xx
-defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
-ENDIF;cpt85xx
-
-IF bbc OR rm380z OR px8 OR access OR S1008 ;[22] [29]
-defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
-ENDIF ;bbc OR rm380z OR px8 OR access OR s1008[29]
-
-IF trs80
-defesc EQU '_'-100O ;CTRL-_ (Down-arrow on TRS-80 keyboard)
-ENDIF;trs80
-
-; Select initial setting for VT-52 emulation flag.
-
-IF vt52 ; If console looks like (or is) VT52
-vtval EQU 0 ; we don't need VT52 emulation
-ENDIF;vt52
-
-; If none of the above, default to VT52-EMULATION ON.
-IF NOT (crt OR vt52 OR robin OR dmII OR vt100 OR hp125);[MF]
-vtval EQU 1
-ENDIF;NOT (crt OR vt52 OR robin OR dmII OR vt100 OR hp125)[MF]
-
-
-; sysxin - system dependent initialisation code, called from SYSINIT
-;
-sysxin:
-
-IF dmII
-; edit added by OBSchou for C. Lasner. If this dont work, tell me whats
-; wrong, as I have no DMII or IBM to play with
-;
-; IBM mode fixup program
-;
-; This routine must be run before attempting to use KERMIT-80 with half
-; duplex KERMIT implementations such as CMS-KERMIT, as the 6120 processor
-; will otherwise "swallow" the XON character.
-;
-; acknowledgments and limitations.
-;
-; This program is based on DECMATE specific implementation details
-; provided by Walt Lamia of DEC. It is of course, specific to DECMATE
-; implementations of CP/M-80 for DECMATE II, III, III-plus, etc.
-;
-; usage consists of merely:
-;
-; CP4DMF run this program
-; KERMIT80 then run kermit
-; <KERMIT-80 commands used normally here, including SET IBM ON>
-; CP4DMU run companion program to restore normal XON
-;
-; unless CP4DMU is run following KERMIT-80, the normal handling of
-; XON/XOFF provided by KERMIT-80 will not work (cold boot is another
-; alternative).
-;
-; CP4DMF.ASM
-;
-; last edit: 12-jun-87 20:00:00 Charles J. Lasner (CJL)
-
-;oboff equ 3fh ; offset of outbyt routine for 6120
-;prtctl equ 02h ; port control
-nocoxon equ 001h ; turn off comm. output XON
-
- lxi b,(nocoxon * 100h) + prtctl ; c/prtctl, b/no out. xon
- call outbyt
- ret ; and return
-
-;outbyt has been catered for (in break routine)
-ENDIF ;dmII
-
-IF osbrn1 ;(Note now no longer needs code > 4000h as it is already there
-; lxi d,ostop ;where we're moving it to
-; lxi h,osmove ;what we're moving
-; mvi b,osmct ;How many bytes we're moving
-; call mover
- lda baudrt ; Find out what speed is current
- ani 1
- mvi a,osbi03 ; assume 300 baud
- jz osstr1
- mvi a,osbi12 ; nope, it's 1200.
-osstr1: sta speed ; save initial speed
- sta speed+1 ; as 16 bits, to match speed table entries
- mov d,a
- mov e,a ; get initial speed in DE
- call sysspd ;set up parity etc.
-ENDIF;osbrn1
-
-IF cpt85xx
- mvi a,80h ; Send UART reset [force idle] by setting
- out baudrt ; bit 7 of baud rate I/O port
- lxi H,0f0fh ; Clear reset and default to 9600 baud [23]
- shld speed ; store current speed
- xchg
- call sysspd ; set default baud rate
- mvi a,4Eh ; Set UART mode to async 16x clock, 8 data
- out mnprts ; bits, no parity, and 1 stop bit
- mvi a,37h ; Set command to Tx enable, DTR on, Rx enable,
- out mnprts ; break off, error reset, and RTS on
-ENDIF ; cpt85x
-
-IF bbc ;[22]
- lxi d,modstr ; Set MODE 3
- call prtstr
- mvi a,1 ; Set terminal mode on
- call term
- mvi a,0F2H ; Read current transmit speed
- lxi h,0FF00H ; .. 3 lsb of ULA register
- call osbyte ; FX242,0,255
- mov a,l
- ani 7 ; Mask of 3 lsb
-;
-; Edit of July 22, 1986 by B Robertson, Aberdeen Univ. Computing Centre.
-; Correct bug in sysinit for BBC - reads the initial baud rate at
-; start up incorrectly.
-;
-;
- rar ; Reverse order of 3 lsb
- rar ; Bit2 now in bit0
- jnc binit1 ;
- ori 2 ; Restore bit1
-binit1: ana a ; Set sign bit as appropriate
- jp binit2 ;
- ori 4 ; Bit0 now in bit2
-binit2: ani 7 ; Mask off unwanted bits
-; End of Edit
-
- xri 7 ; Stored as 2's complement
- inr a
- sta speed ; Store 16 bit value
- sta speed+1
- mov e,a ; Ensure RX and TX speeds are the same
- call sysspd
-ENDIF;[22] bbc
-
-IF rm380z ;[22]
- mvi e,11h ;Output ctrl-Q to clear autopaging
- call outcon
-ENDIF;[22] rm380z
-
-
-IF lobo ;[hh]
- lxi d,siotbl ;[hh] address of status table
- mvi c,siolen ;[hh] length of the table
-siolup: ;[hh] loop here for each command byte
- ldax d ;[hh] load first byte into A
- inx d ;[hh] index pointer to next bute
- sta mnprts ;[hh] send it to status port A
- sta mnprts+2 ;[hh] and to status port B
- dcr c ;[hh] decrement the counter
- jnz siolup ;[hh] loop back for more commands
- mvi a,05H ;[hh] value for 300 baud
- sta baudrt ;[hh] starting default for port A
- sta baudrt+4 ;[hh] and for port B
- sta speed ;[hh] tell program they're set
- mvi a,0E4H ;[hh] value for port A
- sta port ;[hh] tell program we've set this, too
- mvi a,0D0H ;[hh] port A baud rate value
- sta port+1 ;[hh] save this as well, for consistancy
-ENDIF ;lobo
-
-IF mikko
- lxi d,mintbl ;Address of KERMIT Reg values (what)
- mvi c,minlen ;Length of table (how many)
- lxi h,sioac ;Send data to ch. A SIO registers (to where)
- call movmik
- mvi a,0FFH ;Set ch. A mask to use all bits
- sta chmask
-ENDIF;mikko
-
-IF mdI
- lxi h,96 ;Default 1200 baud modem port speed
- shld speed ;Store as modem port speed
- call sysspd ;Initialize the port
-ENDIF;mdI [Toad Hall]
-
-IF cmemco ;[25]
- mvi a,01h ; Reset TU-ART
- out tuart+2
- mvi a,90h ; Set default baud rate (2400), and 1 stop bit
- out tuart
- sta speed ; save for status display
- sta speed+1
-ENDIF;cmemco
-
-IF delphi ;[7]
-;
-; shove the default baud rate (1200) in to the Delphi port address
-; for the baud rate generator on port 2, the default port; save this
-; value so we can tell what speed is selected.
-;
- mvi a,07h ;[7] get value for 1200 baud
- out baudrt ;[7] set it for port 2
- sta speed ;[7] save for status display
- sta speed+1
-ENDIF;[7] delphi
-
-IF px8 ; [29]
- lda 0f6a9h ; get baud rate value set by CONFIG
- sta px8blk+4 ; put into parameter block
- mov h, a ; initialise global speed indicator
- mov l, a
- shld speed
- lhld 6 ; base of CP/M
-; buffer starts at ovlend+8192, immediately after sector buffer
-; We must also allow (800h) for the CCP as Kermit exits with a RET
- lxi d, ovlend+8192+800h ; calc buffer length
- ora a ; clear carry
- db 0edh, 52h ; sbc hl, de
- shld px8blk+2
- call rsopen
-ENDIF ; px8 [29]
-
-IF disc ;[29]
-;Initialization sequence for Discovery 83U port B
-;Sets port to 9600 baud, 8 data bits, 1 stop bit, no parity
- mvi a,12 ;Register 12
- out mnprts
- mvi a,11 ;Low byte of time constant for 9600
- out mnprts
- mvi a,13 ;Register 13
- out mnprts
- mvi a,0 ;High byte of time constant for 9600
- out mnprts
- mvi a,14 ;Register 14
- out mnprts
- mvi a,3 ;Enable baud rate generator
- out mnprts
- mvi a,11 ;Register 11
- out mnprts
- mvi a,52h ;No Xtal, tclk=rclk=/trxc out=br gen
- out mnprts
- mvi a,4 ;Register 4
- out mnprts
- mvi a,44h ;16x clock, 1 stop, no parity
- out mnprts
- mvi a,3 ;Register 3
- out mnprts
- mvi a,71h ;rx 8 bit/ch, autoenable, rx enable
- out mnprts
- mvi a,5 ;Register 5
- out mnprts
- mvi a,0eah ;tx 8 bit/ch, tx enable, rts
- out mnprts
-ENDIF;disc [29]
-;
-;
-IF mikko ;currently for MIKROMIKKO only
-; copy command block into memory-mapped SIO.
-movmik: di ;disable interrupts
-movmk1: ldax d ;Get a register value
- mov m,a ;Output it
- inx d ;Next value
- dcr c ;Decrement counter
- jnz movmk1 ;Repeat until done
- ei
- ret
-ENDIF;mikko
-
-;
-IF osbrn1
-osmove:
-osflag equ 0EF08H ;Osborne 1 Bank-2 flag
-;
-; return modem status in A
-;
-OSLDST:
- DI
- OUT 0
- LDA osprts ;Read the status port
- OUT 1
- EI
- ret
-;
-; set modem status from A
-;
-OSSTST:
- DI
- OUT 0
- STA osprts ;Write the control port
- jmp osstex
-;
-; read character from modem into A
-;
-OSLDDA:
- DI
- OUT 0
- LDA osport
- OUT 1
- EI
- ret
-;
-; output character in A to modem
-;
-OSSTDA:
- DI
- OUT 0
- STA osport
-osstex:
- OUT 1
- mvi a,1
- sta osflag
- EI
- ret
-ENDIF;osbrn1
-
-IF lobo
-; List of commands to set up SIO channel A for asynchronous operation.
-siotbl: DB 18H ; Channel reset
- DB 18H ; another, in case register 0 wasn't selected
- DB 04H ; Select register 4
- DB 44H ; 1 stop bit, clock*16
- DB 01H ; Select register 1
- DB 00H ; No interrupts enabled
- DB 03H ; Select register 3
- DB 0C1H ; Rx enable, 8 bit Rx character
- DB 05H ; Select register 5
- DB 0EAH ; Tx enable, 8 bit Tx character,
- ; raise DTR and RTS
-siolen equ $-siotbl ; length of command list
-ENDIF;lobo
-
-IF mikko
-; command list to set SIO chip back to normal state
-miotbl: db 3 ;reg. 3
- db sioo3
- db 5 ;reg. 5
- db sioo5
- db 4 ;reg. 4
- db sioo4
- db 0 ;reselect reg. 0
-miolen equ $-miotbl ;MikroMikko SIO table length (original values)
-
-; command list to set up SIO chip for operation with Kermit
-mintbl: db 3 ;reg. 3
- db sion3
- db 5 ;reg. 5
- db sion5
- db 4 ;reg. 4
- db sion4
- db 0 ;reselect reg. 0
-minlen equ $-mintbl ;MikroMikko SIO table length (KERMIT values)
-ENDIF;mikko
-
-
-IF bbc ;[22]
-modstr: db 16h,03h,'$' ; String to put screen into MODE 3
-ENDIF
-
-IF px8 ; [29]
-rsget: mvi b, 50h
- jmp rsiox
-rsinst: mvi b, 30h
- jmp rsiox
-rsput: mvi b, 60h
- jmp rsiox
-rsoutst:mvi b, 40h
- jmp rsiox
-rserst: mvi b, 90h
- jmp rsiox
-rsopen: lxi h, px8blk ; copy px8blk to px8prm
- lxi d, px8prm
- lxi b, 9
- call mover
- mvi b, 10h ; open code
- jmp rsiox
-rsclose:mvi b, 20h ; close code
-rsiox: lxi h, px8prm
- lxi d, 51h ; offset into BIOS jump table
- push h
- lhld 1 ; start of BIOS
- dad d
- xthl ; entry point on stack, px8prm addr in hl
- ret ; jump indirect
-
-px8prm: dw 0, 0
- db 0, 0, 0, 0, 0 ; the param area is overwritten in rsopen
-px8blk: dw ovlend+8192 ; buffer address
- dw 0 ; buffer size - overwritten
- db 0 ; baud rate - overwritten
- db 3 ; 8 bits/char
- db 0 ; no parity, it is done internally
- db 1 ; 1 stop bit
- db 0cfh ; special bits - activate xon/xoff
-; The documentation suggests that the xon/xoff bit is bit 4, i.e the pattern
-; should be 0efh, but the top bit is omitted from the diagram. I will try
-; clearing both bit 4 and bit 5.
-ENDIF ; px8 [29]
-
-IF hp125 ;[MF]
- lxi b,73ffh ;Prepare Data Comm 1 to
- call bdos ;Transfer eight-bit data
- lxi d,jbuf ;Point to bios jump-table vector
- lxi b,7effh ;Set up special subfunction code to
- call bdos ;Get rdr routine address
- lhld jbuf+3 ;Remember this address
- shld readin+1 ;for our eight-bit rdr routine
- mvi a,1 ;We want to write into the bios jump table
- sta jbuf+1 ;...
- lxi h,readin ;Point to our rdr routine (all 8 bits)
- shld jbuf+3 ;as new RDR routine
- lxi d,jbuf ;Point to jump vector argument block
- lxi b,7effh ;Set subfunction code to
- call bdos ;Substitute our rdr routine in dispatch table
- lxi h,mapon1 ;Make Data Comm 1 the default port
- shld port ;at program-start
- xchg ;Put in DE
- call prtstr ;Print escape sequences to connect
- ;DAta Comm 1 to rdr/punch
-ENDIF ;hp125 [MF]
-
- ret ; end of sysxin
-
-;
-; system-dependent termination processing
-; If we've changed anything, this is our last chance to put it back.
-sysexit:
-
-IF dmII
-; Edited by OBSchou for Charles Lasner. His bug fix now in Kermit-80:
-;
-; IBM mode restore program
-;
-; This routine must be run after using CP4DMF (and KERMIT-80) to restore
-; the normal handling of XON/XOFF; the user may also elect to cold-boot
-; the DECMATE instead.
-;
-; acknowledgments and limitations.
-;
-; This program is based on DECMATE specific implementation details
-; provided by Walt Lamia of DEC. It is of course, specific to DECMATE
-; implementations of CP/M-80 for DECMATE II, III, III-plus, etc.
-;
-; usage consists of merely:
-;
-; CP4DMF run xon/xoff disable program
-; KERMIT80 then run kermit
-; <KERMIT-80 commands used normally here, including SET IBM ON>
-; CP4DMU run this program to restore normal XON
-;
-; unless CP4DMU is run following KERMIT-80, the normal handling of
-; XON/XOFF provided by KERMIT-80 will not work (cold boot is another
-; alternative).
-;
-; CP4DMF.ASM
-;
-; last edit: 12-jun-87 20:00:00 Charles J. Lasner (CJL)
-;
-coxon equ 000h ; enable comm. output XON
-;oboff equ 3fh ; offset of outbyt routine for 6120
-;prtctl equ 02h ; port control
-
-
- lxi b,(coxon * 100h) + prtctl ; c/prtctl, b/with out. xon
- call outbyt ;[OBS] declared elswhere
- ret ; and return
-
-ENDIF ;dmII
-
-IF mikko
- lxi d,miotbl ;Load the adress of original reg values
- mvi c,miolen ;Length of table
- lxi h,sioac ;Send data to ch A SIO registers
- call movmik
- mvi a,07FH ;Set ch A mask to use just 7 bits
- sta chmask
-ENDIF;mikko
-
-IF teletek
-;Note - This code was handwritten onto the lising I was sent, with the
-; comment that David had just thought of the code, so it was
-; not on the listing. If you have problems I suggest you
-; comment out these few lines.
-;Bertil Schou.
-;
- di
- mvi a,47h ; reset baud rate to 9600
- out baudrt
- mvi a,08h
- out baudrt
- ei
-ENDIF ;teletek
-
-IF cpt85xx
- mvi a,80h ; Reset (force idle) the 8251 UART via bit 7
- out baudrt ; of the baud rate generater port
- mvi a,00h ; and turn off the baud rate generater
- out baudrt
-ENDIF;cpt85xx
-
-IF bbc ;[22]
- mvi a,0 ; Turn off terminal mode
- call term
-ENDIF;[22] bbc
-
-IF px8 ;[29]
- call rsclose
-ENDIF ;px8 [29]
-
-IF hp125 ;[MF]
- lxi b,74ffh ;Set subfunction code to
- call bdos ;Reset Data Comm 1 for 7-bit data
- lhld readin+1 ;Get original rdr routine address
- shld jbuf+3 ;and store in jump vector
- lxi d,jbuf ;Point to jump vector
- lxi b,7effh ;Set subfunction code to
- call bdos ;Put original rdr routine back in bios
- ;dispatch table
- lxi d,mapoff ;Point to escape sequences to
- call prtstr ;Turn off Data Comm 1/2 mappings
-ENDIF ;hp125 [MF]
-
- ret
-
-;
-; system-dependent processing for start of CONNECT command
-;
-syscon:
-IF robin OR trs80 OR cpt85xx ;For Robin/TRS80/CPT-85xx, add some more info
- lxi d,conmsg ; about obscure key combinations
- call prtstr
-ENDIF;robin OR trs80 OR cpt85xx
-
-IF osbrn1 ;*** This is Software dependent ***
- lhld 1 ;Modify back-arrow code to DELETE
- mvi l,0 ;Get BIOS-start address
- lxi d,85H ;Adress for key-code = XX85H
- dad d
- mov e,m ;Get it in DE
- inx h
- mov d,m
- xchg ;Memory pointer to HL
- mvi m,del ;modify the code
-ENDIF;osbrn1
- ret
-
-conmsg: ; Messages printed when entering transparent (CONNECT) mode:
-IF robin ; for Robin, control-S key is hidden
- db ' (Type Left Arrow to send CTRL-S)',cr,lf,'$'
-ENDIF;robin
-IF trs80 ; for TRS-80, the preferred escape key is hidden
- db ' (Control-_ is the Down-Arrow key on the TRS-80 keyboard)'
- db cr,lf,'$'
-ENDIF;trs80
-IF cpt85xx ; for CPT-85xx, some graphics map "funny" to keyboard in CP/M
- db ' (Use CODE + SHIFT + 1/2 key to generate a Control-\)'
- db cr,lf,'$'
-ENDIF;cpt85xx
-;
-; syscls - system-dependent close routine
-; called when exiting transparent session.
-;
-syscls:
-IF osbrn1
- lhld 1 ;Modify back-arrow code to BACKSPACE
- mvi l,0 ;Get BIOS address
- lxi d,85H ;Address for key-code =XX85H
- dad d
- mov e,m ;Get it in DE
- inx h
- mov d,m
- xchg ;Address to HL
- mvi m,bs ;Modify code
-ENDIF;osbrn1
- ret
-;
-; sysinh - help for system-dependent special functions.
-; called in response to <escape>?, after listing all the
-; system-independent escape sequences.
-;
-sysinh:
-IF robin OR dmII OR cpt85xx OR lobo
- lxi d,inhlps ; we got options...
- call prtstr ; print them.
-ENDIF;robin OR dmII OR cpt85xx OR lobo
-
-IF bbc OR rm380z ; some more
- lxi d,inhlps ; we got options...
- call prtstr ; print them.
-ENDIF;[22] bbc OR rm380z
-
-IF px8 OR access OR mmate OR disc ;and more...
- lxi d,inhlps ; we got options...
- call prtstr ; print them.
-ENDIF ;px8 OR access OR mmate OR disc
-
- ret
-
-
-;additional, system-dependent help for transparent mode
-; (two-character escape sequences)
-inhlps:
-
-IF robin OR dmII OR cpt85xx OR lobo
- db cr,lf,'B Transmit a BREAK'
-ENDIF;robin OR dmII OR cpt85xx OR lobo
-
-IF bbc OR rm380z
- db cr,lf,'B Transmit a BREAK'
-ENDIF;bbc OR rm380z
-
-IF px8 OR access OR mmate
- db cr,lf,'B Transmit a BREAK'
-ENDIF ;px8 OR access OR mmate
-
-IF disc ;[29] [32]
- db cr,lf,'B Transmit a 300ms BREAK'
- db cr,lf,'L Transmit a 5 second BREAK'
-ENDIF;disc [29]
-
-IF lobo
- db cr,lf,'D Drop the line'
-ENDIF;lobo
-
- db '$' ;[hh] table terminator
-
-;
-; sysint - system dependent special functions
-; called when transparent escape character has been typed;
-; the second character of the sequence is in A (and in B).
-; returns:
-; non-skip: sequence has been processed
-; skip: sequence was not recognized
-
-sysint: ani 137O ; convert lower case to upper, for testing...
-
-IF robin OR dmII OR cpt85xx OR lobo
- cpi 'B' ; send break?
- jz sendbr ; yes, go do it. return nonskip when through.
-ENDIF;robin OR dmII OR cpt85xx OR lobo
-
-IF bbc OR rm380z ; [22] [25] ... some more
- cpi 'B' ; send break?
- jz sendbr ; yes, go do it. return nonskip when through.
-ENDIF; bbc OR rm380z
-
-IF px8 OR access OR mmate ;[28] [29] and anothers
- cpi 'B' ; send break?
- jz sendbr ; yes, go do it. return nonskip when through.
-ENDIF ; px8 OR access OR mmate [28] [29]
-
-IF lobo ;[hh]
- cpi 'D' ;[hh] disconnect?
- jz discon ;[hh] yes, go do it. nonskip return when done.
-ENDIF ;lobo
-
-IF disc ;[29]
- cpi 'B' ;Send short break?
- jz sendbr
- cpi 'L' ;Send long break?
- jz sendlbr
-ENDIF;disc [29]
-
- jmp rskp ; take skip return - command not recognized.
-
-
-;
-IF robin ;Definitions & code to send a BREAK (ungenerically, no other way).
-
-comctl equ 59h ;VT180 communications port
-crtctl equ 41h ;VT180 crt port
-
-;VT180 serial port command bits
-
-txe equ 1 ;transmit enable
-dtr equ 2 ;dtr on
-rxe equ 4 ;rx enable
-sndbrk equ 8
-rerr equ 10h ;reset error
-rts equ 20h ;RTS on
-reset equ 40h ;port reset
-
-;Send a break to the communications port.
-;
-
-sendbr: lxi h,38500 ;250 ms(?)
- lda prtadr ;Get address of selected port
- mov c,a ;Into C
- mvi a,sndbrk+dtr
-; OUT C,A ;Want to send to port addressed by C
- db 0EDH,079H ;Op code for above instruction
-sndbr1: dcx h ;timing loop...
- mov a,l
- ora h
- jnz sndbr1 ;...until over
- lda prtadr ;Get the address for the port
- mov c,a ;Into C
- mvi a,txe+dtr+rxe+rerr+rts ;enable tr/rc, dtr, reset error
-; out c,a ;Z-80 only instruction
- db 0EDH,079H ;Op code for above instruction
- out contst ;reset ports
- ret
-ENDIF;robin
-;
-IF dmII ;[jd] this added to send break on DECmate
-
-; DECmate command codes for 6120 I/O processor
-oboff equ 3fh ; offset of outbyt routine for 6120
-prtctl equ 02h ; port control
-brdat equ 06h ; data to tell 6120 to send a break
-brdur equ 30 ; duration, 30 = 300 ms.
-
-sendbr: lxi b,(brdat * 100h) + prtctl ; c/prtctl, b/brdat
- call outbyt
- lxi b,brdur*100h ; b/duration, c/0
-; fall through into outbyt
-
-outbyt: lhld 1 ; get warm boot address
- lxi d,oboff ; offset of outbyt routine
- dad d ; compute address
- pchl ; branch there (a callret)
-
-ENDIF;dmII
-;
-IF access OR mmate ;[cjc] send break on Kaypro [29]
-; Officially, a "break" is 300 milliseconds of "space" (idle line is
-; "mark"). (or maybe 200 milliseconds; I forget.) The timing isn't
-; usually that critical, but we'll make an attempt, at least. Sending
-; too long a break can cause some modems to hang up.
-
-sendbr:
-; First, make sure the transmitter is really empty. (The SIO sets
-; "transmitter buffer empty" when it can accept another character;
-; the previous character is still being shifted onto the line.
-; Another status bit, "all done", is set to indicate that the
-; transmitter is really idle.
-sndbr1: mvi a,1 ; select Read Register 1
- out mnprts
- in mnprts ; read the contents
- ani 1 ; test "all done" flag
- jz sndbr1 ; loop until it's nonzero.
-;
-; Next, set the "send break" bit to start the transmitter spacing.
- mvi a,5 ; select Write Register 5
- out mnprts
- mvi a,0FAH ; Tx enable, 8 bit Tx character, Send Break,
- out mnprts ; DTR and RTS on.
-;
-; Now, delay for 30 hundredths of a second
- mvi a,30 ; delay count
- call delay
-;
-; Time's up. Put transmitter back in normal state (data byte is the
-; same as the one in siotbl: for Write Register 5) and return.
- mvi a,5 ; select Write Register 5
- out mnprts
- mvi a,0EAH ; Tx enable, 8 bit Tx character,
- out mnprts ; DTR and RTS on.
- ret ; done.
-ENDIF;access OR mmate [29]
-
-IF lobo ;[hh] This routine sends a break tone or disconnects a modem
-; (those that respond to it) by setting the DTR line low
-; for 300 ms.
-;
-sendbr: mvi a,05H ;[hh] write register 5
- call outctl ;[hh] send it to control port
- mvi a,0FAH ;[hh] value to send break tone
- jmp sndbr1 ;[hh]
-;
-discon: mvi a,05H ;[hh] write register 5
- call outctl ;[hh] send it to the control port
- mvi a,06AH ;[hh] DTR off and break tone on
-sndbr1: call outctl ;[hh] send to control port
- mvi a,30 ;[hh] delay count for 300 ms.
- call delay ;[hh] wait a while...
- mvi a,05H ;[hh] write register 5
- call outctl ;[hh] get it's attention
- mvi a,0EAH ;[hh] normal 8 bits, DTR on, RTS on, etc.
- call outctl ;[hh] restore SIO
- ret
-;
-outctl: sta mnprts ;[hh]
- ret
-ENDIF ;lobo
-;
-IF cpt85xx OR rm380z ;[lmj] [22] [25]
-sendbr:
-;
-; Ensure that the transmitter has finished sending buffered chars
-sndbr1: in mnprts ; get UART status
- ani TxEmpty ; everything sent?
- jz sndbr1 ; no, wait a bit more
-;
-; Begin sending a break by setting bit in UART command register
- mvi a,3Fh ; Set TxEna, DTR, RxEna, SBreak, ErrRst, RTS
- out mnprts
-;
-; Wait for 250 milliseconds (using hundredths second delay routine)
- mvi a,25
- call delay
-;
-; Resume normal operation by clearing the SendBreak command bit
- mvi a,37h ;Set TxEna, DTR, RxEna, ErrRst, RTS
- out mnprts
-;
- ret ;done
-ENDIF;cpt85xx OR rm380z
-
-IF px8 ; [29]
-sendbr: mvi a, 3fh ; set break bit
- out mnprts
- mvi a, 25
- call delay ; wait 250 msec
- mvi a, 37h ; clear break bit
- out mnprts
- ret
-ENDIF ; px8 [29]
-
-;
-IF bbc ;[22]
-sendbr:
-;
-; Ensure that the transmitter has finished sending buffered chars
-sndbr1: mvi a,96h ; get ACIA status
- mvi l,8
- call osbyte ; *FX150,8
- mov a,h
- ani 2 ; everything sent?
- jz sndbr1 ; no, wait a bit more
-;
-; Disable centisecond clock (system VIA) which interferes with break
- lxi h,0FE4Eh ; system VIA interrupt enable register
- mvi a,40H ; disable timer 1
- call wrtiom ; write to I/O processor memory
-;
-; Begin sending a break by setting bit in ACIA control register
- mvi a,9Ch
- lxi h,9F60h ; Set Rxint, Txint, Break, RTS
- call osbyte ; *FX 156,96,159
-;
-; Wait for 250 milliseconds (using hundredths second delay routine)
- mvi a,25
- call delay
-;
-; Resume normal operation by returning old control byte
- mvi a,9Ch
- mvi h,0 ;Set TxEna, DTR, RxEna, ErrRst, RTS
- call osbyte ; *FX 156,oldvalue,0
-;
-; Enable centisecond clock (system VIA)
- lxi h,0FE4Eh ; system VIA interrupt enable register
- mvi a,0C0H ; enable timer 1
- call wrtiom ; write to I/O processor memory
-;
- ret ;done
-;
-; Routine to write byte in A to I/O processor memory address
-; given by HL
-wrtiom:
- shld parblk ; store address to parameter block
- sta parblk+4 ; store data
- lxi h,parblk ; load hl with address of param block
- mvi a,6 ; write I/O processor memory
- call osword ; go do it
- ret
-;
-parblk: DS 5 ; reserve space for parameter block
-ENDIF;bbc [22]
-;
-IF disc ;[29]
-; This is almost an exact copy of the bbI sendbr routine.
-; Modifications to include a long break have been made.
-;
-; Officially, a "break" is 300 milliseconds of "space" (idle line is
-; "mark"). (or maybe 200 milliseconds; I forget.) The timing isn't
-; usually that critical, but we'll make an attempt, at least. Sending
-; too long a break can cause some modems to hang up.
-
-sendlbr:
- push d ;save d, this may not be necessary, but safe
- mvi d,17 ;do short break 17 times (approx. 5 sec.)
- jmp sndbr1
-sendbr:
- push d
- mvi d,1 ;On short break, do only once
-; First, make sure the transmitter is really empty. (The SIO sets
-; "transmitter buffer empty" when it can accept another character;
-; the previous character is still being shifted onto the line.
-; Another status bit, "all done", is set to indicate that the
-; transmitter is really idle.
-sndbr1: mvi a,1 ; select Read Register 1
- out mnprts
- in mnprts ; read the contents
- ani 1 ; test "all done" flag
- jz sndbr1 ; loop until it's nonzero.
-;
-; Next, set the "send break" bit to start the transmitter spacing.
- mvi a,5 ; select Write Register 5
- out mnprts
- mvi a,0FAH ; Tx enable, 8 bit Tx character, Send Break,
- out mnprts ; DTR and RTS on.
-;
-; Now, delay for 30*d hundredths of a second
-sendbr2:
- mvi a,30 ; delay count
- call delay
-; The following has been added to allow doing .03 delay d times
- dcr d ; decrement # of times to do loop
- jnz sendbr2 ; if not done, do again
- pop d ; reload d
-;
-; Time's up. Put transmitter back in normal state (data byte is the
-; same as the one in siotbl: for Write Register 5) and return.
- mvi a,5 ; select Write Register 5
- out mnprts
- mvi a,0EAH ; Tx enable, 8 bit Tx character,
- out mnprts ; DTR and RTS on.
- ret ; done.
-ENDIF ;disc [29]
-
-
-;
-; sysflt - system-dependent filter
-; called with character in E.
-; if this character should not be printed, return with A = zero.
-; preserves bc, de, hl.
-; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-sysflt:
- mov a,e ; get character for testing
-IF mikko
- cpi 'O'-100O ;Control-O's lock keyboard
- rnz ; if not control-O, it's ok.
- xra a ; don't allow control-O out.
-ENDIF;mikko
-
- ret
-
-; mdmflt - modem filter [30]
-; called with character to be sent to printer in E
-; with parity set as appropriate.
-; return with accumulator = 0 do do nothing,
-; <> 0 to send char in E.
-mdmflt:
- mov a,e ;[30] get character to test
- ret
-
-
-
-; prtflt - printer filter [30]
-; called with character to be sent to printer in E
-; returns with a = 0 to do nothing
-; a <> 0 to print it.
-;
-; this routine for those printer that automatically insert
-; a lf on cr, or cr for lf. Should this be shifted to
-; the system indep. stuff, in say 4.06?
-prtflt:
- mov a,e ; [30] get character to test
- ret
-
-
-;
-; system-dependent processing for BYE command.
-; for lobo, hang up the phone.
-sysbye:
-IF lobo ;[hh]
- call discon ;[hh] force modem to hang up
-ENDIF;lobo
- ret
-
-IF lasm
- LINK CPXSY2.ASM ; If m80 then this ignored
-ENDIF ; lasm
+IF NOT lasm
+.printx * CPXSYS.ASM *
+ENDIF ;NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the system-dependent code and data for KERMIT.
+; It will be probably be broken into independent files to generate
+; overlays for the various systems, one or more overlay possible
+; from each file. For now, we will leave it in one piece.
+;
+; revision history:
+;
+;
+; Edit 40, 28-Aug-89 by Mike Freeman of Bonneville Power Administration,
+; P.O. Box 491, Vancouver WA 98666 USA, Telephone (206)690-2307:
+; Home address: 301 N.E. 107th Street; Vancouver, WA 98685 USA
+; Home telephone: (206)574-8221
+; added support for Hewlett-Packard HP-125 Business Assistant computer
+; running a HP-modified CP/M Version 2.2; communications on
+; DAta Comm 1 or Data Comm 2 (8th-bit quoting must be used on
+; Data Comm 2 to transfer binary files as Data Comm 2 only supports
+; a 7-bit data path); printer cannot be used with communications on
+; Data Comm 2 (the printer port).
+; edit 39, 4 August, 1987b by OBSchou for Charles Lasner re. DECMATE II
+; fixes to set xon/off control off for the duration of Kermit-80.
+;
+; His header reads:
+;
+; IBM mode restore program
+;
+; This routine must be run after using CP4DMF (and KERMIT-80) to restore
+; the normal handling of XON/XOFF; the user may also elect to cold-boot
+; the DECMATE instead.
+;
+; acknowledgments and limitations.
+;
+; This program is based on DECMATE specific implementation details
+; provided by Walt Lamia of DEC. It is of course, specific to DECMATE
+; implementations of CP/M-80 for DECMATE II, III, III-plus, etc.
+;
+; usage consists of merely:
+;
+; CP4DMF run xon/xoff disable program
+; KERMIT80 then run kermit
+; <KERMIT-80 commands used normally here, including SET IBM ON>
+; CP4DMU run this program to restore normal XON
+;
+; unless CP4DMU is run following KERMIT-80, the normal handling of
+; XON/XOFF provided by KERMIT-80 will not work (cold boot is another
+; alternative).
+;
+; [Note - These edits now included in the init/de-init code]
+;
+; edit 38, 23 July, 1987 by OBSchou. Moved out commonly used code
+; to CPXCOM.ASM, and adjusted this (ond other family) files accordingly.
+; Also filtered out code now in other family files.
+;
+; edit 37 , 15 July 1987 by OBSchou for David Moore, who has submitted
+; code for Teletek SYSTEMASTER (teletek) and for an ADM 22 terminal.
+;
+; edit 36 28 Jan 87 by OBSchou.
+; Removed the printx etc and should only have this file if a system
+; does not have a family file.
+;
+; edit 35 1st Dec 1986 by OBSchou. Added test for Amstrad PCW range (PCW)
+; Links to CPXPCW.ASM, which was submitted by Ian Young, Lattice
+; Logic Systems.
+;
+; edit 34 20 August by OBSchou for Brian Robertson, Aberdeen University:
+; I have discovered a bug in my code for the BBC/Z80 version of Kermit.
+; At startup the transmitter baud rate is read from the serial ULA.
+; The TX and RX baud rates are then reset to this value and the
+; value is stored in location 'baud:' for the STATUS (or SHOW)
+; command. That is how it is supposed to work ! Unfortunately
+; my code at present "misreads" the initial TX baud rate - there
+; is some bit manipulation that needs to be done to extract the
+; correct value.
+;
+; edit 33 30-May-86 OBSchou. Added two new enties to the overly. One for
+; printer status and the other for the address of the family of
+; computer using the overlay. If it is still in CPXSYS.ASM then it
+; is a dollar only.
+;
+;edit 32, 27 May, 1986 by OBSchou Loughborough University for
+; B Robertson, Aberdeen Univ. Computing Centre. Any mistakes my fault.
+; Add support for APPLE II with serial cards based on the 6850 ACIA.
+; Mod 380Z support to allow both MDS (5 1/4" discs) and FDS (8" discs)
+; configurations.
+;
+; edit 31, 22 April, 1986, OBSchou.
+; Kermit version 4.06 starts here. All previous edits have been
+; put aside (leave in a BWR file?). Hived off some definitions
+; to the CPSDEF.ASM file as that is where they belong.
+; Start on splitting off individual
+; systems from this huge file. It is done using the LINK facility
+; LASM. We link to a collection of systems under CPXxxx.ASM.
+; I have started with the systems I know, the Torch, Cifer and
+; pci2651. These will all be held under CPXTOR.ASM
+;
+;
+; Keep module name, edit number, and last revision date in memory.
+family: db 'CPXSYS.ASM (40) 28-Aug-89 $' ; now a family...
+;
+
+
+; Processor speed in units of 100KHz
+; for cpt85xx, advance, apple,bbc,px8 & rm380z timing loop [12]
+IF rm380z
+cpuspd SET 40 ; 4.0 MHz CPU
+ENDIF; rm380z
+
+IF disc OR mmate OR s1008 OR access
+cpuspd SET 40 ; 4.0 MHz CPU
+ENDIF ;disc OR mmate OR s1008 OR access
+
+IF bbc ;[9]
+cpuspd SET 60 ; BBC with 6Mhz Z80
+ENDIF;bbc
+
+
+; the basics...
+
+IF gener
+batio EQU 056H ;I/O byte CON=BAT,LIST=CRT,READER=RDR,PUNCH=PTP
+defio EQU 095H ;I/O byte CON=CRT,LIST=LPT,READER=RDR,PUNCH=PTP
+crtio equ 01010101B ; use CRT: device
+ptrio equ 01010110B ; use PTR: device
+ttyio equ 00000000B ; use TTY: device
+uc1io equ 01010111B ; use UC1: device
+ur1io equ 01101010B ; use UR1: device
+ur2io equ 01111110B ; use UR2: device
+ENDIF;gener
+
+IF robin
+batio EQU 056H ;I/O byte CON=BAT,LIST=CRT,READER=RDR,PUNCH=PTP
+defio EQU 095H ;I/O byte CON=CRT,LIST=LPT,READER=RDR,PUNCH=PTP
+lptio EQU 054H ;I/O byte CON=TTY,LIST=CRT,READER=PTR,PUNCH=PTP
+gppio EQU 057H ;I/O byte CON=UC1,LIST=CRT,READER=RDR,PUNCH=PTP
+ENDIF;robin
+
+
+IF dmII OR bbc ;[22]
+batio EQU 042H ;I/O byte CON=BAT,LIST=CRT,READER=RDR
+defio EQU 081H ;I/O byte CON=CRT,LIST=LPT,READER=RDR
+ENDIF;dmII
+
+IF mikko
+batio EQU 10110010B ; I/O byte console => serial line
+defio EQU 10000001B ; I/O byte console => CRT and Keyboard
+ENDIF;mikko
+;
+IF lobo ;[hh]
+mnport EQU 0F7E4H ;Modem data port A
+mnprts EQU 0F7E5H ;Modem status/conrtol port A
+baudrt EQU 0F7D0H ;Baud rate port A
+output EQU 04H ;Transmit buffer empty
+input EQU 01H ;Receive data available
+z80 SET TRUE ;a good z80, here
+ENDIF;lobo
+
+IF osi
+mnport EQU 0CF01H ;Modem data port
+mnprts EQU 0CF00H ;Modem status port
+output EQU 02H ;Transmitter empty
+input EQU 01H ;Input data available
+z80 SET FALSE ;I don't know...
+ENDIF;osi
+
+IF vector
+mnport EQU 04H ;Modem data port
+mnprts EQU 05H ;Modem status port
+output EQU 01H ;Transmitter empty
+input EQU 02H ;Input data available
+z80 SET FALSE ;I don't know...
+ENDIF;vector
+
+IF delphi ;[7]
+mnport EQU 22H ;[7] Modem data port
+mnprts EQU 23H ;[7] Modem status port
+output EQU 01H ;[7] Transmitter empty
+input EQU 02H ;[7] Input data available
+baudrt equ 29h ;[7] Baud rate port for channel 2 (default)
+z80 SET true ;[7] We're using the z80 side of the dual processor
+ENDIF;[7] delphi
+
+IF trs80
+;NEEDS display definition (e.g. trs80lb or trs80pt)
+mnport EQU 0F4H ;Modem data port (0F5H for port B)
+mnprts EQU 0F6H ;Modem status port (0F7H for port B)
+output EQU 04H ;Transmitter empty
+input EQU 01H ;Input data available
+z80 SET TRUE ;[hh] All TRS-80's but the CoCo
+ENDIF;trs80
+
+IF teletek
+mnport EQU 00H ;Modem data port (02 for port B (console))
+mnprts EQU 01H ;Modem status port (03 for port B (console))
+baudrt EQU 08H ;ctc0 control port (09 for port B (console))
+output EQU 04H ;Transmitter empty
+input EQU 01H ;Input data available
+z80 SET TRUE ;All Teleteks
+ENDIF;teletek
+
+IF osbrn1
+;Osborne 1 uses 6850 ACIA, but memory mapped. Derived from Apple.
+BAUDRT EQU 0EFC1H ;Memory location where baud rates are stored.
+OSTOP EQU 4000H ;Where we move OSMOVE to at startup
+OSPORT EQU 2A01H ;Communications Port.
+OSPRTS EQU 2A00H ;Communications Port Status.
+OUTPUT EQU 02H ;Output Buffer Empty.
+INPUT EQU 01H ;Input Register Full.
+OSBIN1 EQU 57H ;First Init Character for 6850 ACIA (Reset)
+;(I would have thought 03, but prom code writes 57 there)
+OSBI12 EQU 55H ;Second Init Character for ACIA (8-bits, 1200)
+OSBI03 EQU 56H ;Second init char. for ACIA (8 bits, 300)
+;(don't ask.. I don't know why SETUP writes 55 and 56 either)
+z80 SET TRUE ;[hh] a z80 here, also
+ENDIF;osbrn1
+
+IF robin
+;Those definitions below that are commented out are just for information
+;***** NOT generally found in distributed documentation ****
+
+;pbausl EQU 90H ;The Baud-Rate register.
+prntst EQU 49H ;Printer
+;prndat EQU 48H
+contst EQU 41H ;Console
+;condat EQU 40H
+gentst EQU 51H ;General port.
+;gendat EQU 50H
+comtst EQU 59H ;COMM-Port
+;comdat EQU 58H
+;output EQU 01H ;Output ready bit.
+;input EQU 02H ;Input ready bit.
+z80 SET TRUE ; This one's a Z80.
+ENDIF;robin
+
+IF s1008 ;[29]
+mnport equ 00 ;printer port data
+mnprts equ 01 ;printer port status
+output equ 4 ;transmitter ready
+input equ 2 ;receiver ready
+z80 equ FALSE ;not important
+ENDIF;s1008 [29]
+
+IF mmate ;[29]
+mnport EQU 89H ;MODEM data port
+mnprts EQU 8BH ;MODEM status/control port
+output EQU 04H ;Transmit buffer empty, ready to send
+input EQU 01H ;Receive data available
+baudrt EQU 93H ;MODEM baud rate port
+ ;NOTE - also used for console
+z80 SET TRUE
+ENDIF;mmate [29]
+
+IF disc ;[29]
+mnport EQU 05 ;Discovery 83U port B data
+mnprts EQU 04 ;Discovery 83U port B status/command
+output EQU 04 ;Transmit buffer empty
+input EQU 01 ;Receiver ready
+z80 SET TRUE
+ENDIF;disc [29]
+
+IF cmemco ;[25]
+tuart EQU 020H ;TU-ART address
+mnport EQU tuart+1 ;Modem data port
+mnprts EQU tuart ;Modem status port
+output EQU 080H ;Transmitter empty
+input EQU 040H ;Input data available
+baudrt EQU tuart ;Baud rate port
+;Note: Needs terminal definition
+z80 SET TRUE ;This one's a Z80.
+ENDIF;cmemco
+
+IF cpt85xx
+baudrt EQU 4Ch ; Baud rate generater (National MM5307)
+mnport EQU 4Bh ; Comm port data register (Intel 8251)
+mnprts EQU 4Ah ; Comm port command/status register
+output EQU 01h ; Transmitter buffer empty flag
+input EQU 02h ; Reciver buffer full flag
+TxEmpty EQU 04h ; Transmitter empty flag
+z80 SET FALSE ; It's really an 8080 [or 8085 ... same thing]
+ENDIF;cpt85xx
+
+IF mmdI ;Morrow MicroDecision - the single-board one
+mnport EQU 0FEH ;Morrow Printer UART data port
+mnprts EQU 0FFH ;Morrow Printer UART command/status
+output EQU 01H ;Output ready bit.
+input EQU 02H ;Input ready bit.
+;Note: Needs terminal definition
+z80 SET FALSE ;I don't know...
+ENDIF;mmdI
+
+IF bbc ;[22]
+osbyte EQU 0FFF4H ; OS entry point
+osword EQU 0FFF1H ; " " "
+term EQU 0FFC8H ;Terminal mode OS entry
+z80 SET TRUE
+ENDIF;[22] bbc
+
+;Two types of 380Z system
+IF rm380zm ;[27] MDS - 5 1/4" discs
+mnport EQU 0C8H ;Modem data port
+mnprts EQU 0C9H ;Modem status port
+ENDIF;[32] rm380zm
+
+IF rm380zf ;[32] FDS - 8" discs
+mnport EQU 0E8H ;Modem data port
+mnprts EQU 0E9H ;Modem status port
+ENDIF;[32] rm380zf
+
+IF rm380z ;[32] Common to both systems
+output EQU 01H ;Transmitter buffer empty
+input EQU 02H ;Input data available
+TxEmpty EQU 04h ;Transmitter empty flag
+z80 SET TRUE
+ENDIF;[22] rm380z
+
+IF px8 ; [29]
+z80 SET TRUE
+mnprts EQU 0dh ; used in sending a break
+ENDIF ;px8 [29]
+
+IF mdI ;Morrow Decision I - the big sucker
+mnport equ 48H ; Modem data port.
+mnprts equ 4DH ; Modem status port.
+output equ 20H ; Transmitter empty.
+input equ 1 ; Input data available.
+mbase equ 48H ; Base address of Multi I/O port
+ ; selector area.
+grpsel equ 4FH ; Group select port.
+rbr equ 48H ; Read Data Buffer.
+group equ 1 ; Multi I/O Group byte for serial ports.
+congrp equ 1 ; Serial Port 1 for console
+mdmgrp equ 3 ; Serial Port 3 for modem.
+
+; Following are needed for baud rate changes...[Toad Hall]
+
+dlm equ 49H ; Baud Rate Divisor (Most Sig Bit)
+dll equ 48H ; Baud Rate Divisor (Least Sig Bit)
+ier equ 49H ; Interrupt Enable Register
+lcr equ 4BH ; Line Control Register
+lsr equ 4DH ; Line Status Register
+msr equ 4EH ; Modem Status Register
+dlab equ 80H ; Divisor Latch Access Bit
+wls0 equ 1 ; Word Length Select Bit 0
+wls1 equ 2 ; Word Length Select Bit 1 for 8 bit word
+stb equ 4 ; Stop bit count - 2 stop bits
+imask equ 0 ; Interrupt mask (all disabled)
+z80 SET TRUE ; This one's a Z80.
+ENDIF ;mdI NOTE: needs terminal definition. [Toad Hall]
+
+IF mikko
+sioac EQU 0FF12H ;SIO channel A register(s) address
+sioo3 EQU 01000001B ;SIO Write Reg. 3 original setup (?)
+ ;RX 7 bits,synch mode bits 0,RX enable
+sion3 EQU 11001111B ;SIO Write Reg. 3 KERMIT setup
+ ;RX 8 bits,synch mode bits 0,RX enable
+sioo4 EQU 01001111B ;SIO Write Reg. 4 original setup (?)
+ ;X16 clock,8 bit synch(ignored),
+ ;2stop bits,par even(on)
+sion4 EQU 01000100B ;SIO Write Reg. 4 KERMIT setup
+ ;X16 clock,8 bit synch(ignored),
+ ;1stop bit,par off
+sioo5 EQU 10101010B ;SIO Write Reg. 5 original setup (?)
+ ;DTR,TX 7 bits,TX enable,RTS
+sion5 EQU 11101010B ;SIO Write Reg. 5 KERMIT setup
+ ;DTR,TX 8 bits,TX enable,RTS
+txclk EQU 0FF30H ;Baud rate generator (CTC) for transmitter
+rxclk EQU 0FF31H ;Baud rate generator (CTC) for receiver
+chmask EQU 0F1F2H ;Mask byte address for SIO ch. A reception
+z80 SET TRUE ;It's got a SIO and a CTC, it must be a Z80
+ENDIF;mikko
+
+
+IF access ;[29]
+mnport EQU 40H ;Modem data port A
+mnprts EQU 42H ;Modem status/conrtol port A
+output EQU 04H ;Transmit buffer empty
+input EQU 01H ;Receive data available
+z80 SET TRUE ;a good z80, here
+ENDIF;access [29]
+
+
+IF robin OR dmII
+z80 SET TRUE ; This one's a Z80
+ENDIF;robin OR dmII
+
+IF hp125 ;[MF]
+z80 SET TRUE ;HP-125 uses a Z80
+ENDIF;hp125 [MF]
+
+IF gener OR cpm3 ; To be truly generic, we must assume 8080.
+z80 SET FALSE
+ENDIF;gener OR cpm3
+;
+IF osi
+defesc EQU ']'-100O ;The default escape character.
+ENDIF; osi
+
+IF vector
+defesc EQU '~' ;Vector can't type ']'.
+ENDIF;vector
+
+IF mikko OR osbrn1 OR lobo
+defesc EQU '\'-100O ;The default is Control \ -- it's easier B.E.
+ENDIF;mikko OR osbrn1 OR lobo
+
+IF cpt85xx
+defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
+ENDIF;cpt85xx
+
+IF bbc OR rm380z OR px8 OR access OR S1008 ;[22] [29]
+defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
+ENDIF ;bbc OR rm380z OR px8 OR access OR s1008[29]
+
+IF trs80
+defesc EQU '_'-100O ;CTRL-_ (Down-arrow on TRS-80 keyboard)
+ENDIF;trs80
+
+; Select initial setting for VT-52 emulation flag.
+
+IF vt52 ; If console looks like (or is) VT52
+vtval EQU 0 ; we don't need VT52 emulation
+ENDIF;vt52
+
+; If none of the above, default to VT52-EMULATION ON.
+IF NOT (crt OR vt52 OR robin OR dmII OR vt100 OR hp125);[MF]
+vtval EQU 1
+ENDIF;NOT (crt OR vt52 OR robin OR dmII OR vt100 OR hp125)[MF]
+
+
+; sysxin - system dependent initialisation code, called from SYSINIT
+;
+sysxin:
+
+IF dmII
+; edit added by OBSchou for C. Lasner. If this dont work, tell me whats
+; wrong, as I have no DMII or IBM to play with
+;
+; IBM mode fixup program
+;
+; This routine must be run before attempting to use KERMIT-80 with half
+; duplex KERMIT implementations such as CMS-KERMIT, as the 6120 processor
+; will otherwise "swallow" the XON character.
+;
+; acknowledgments and limitations.
+;
+; This program is based on DECMATE specific implementation details
+; provided by Walt Lamia of DEC. It is of course, specific to DECMATE
+; implementations of CP/M-80 for DECMATE II, III, III-plus, etc.
+;
+; usage consists of merely:
+;
+; CP4DMF run this program
+; KERMIT80 then run kermit
+; <KERMIT-80 commands used normally here, including SET IBM ON>
+; CP4DMU run companion program to restore normal XON
+;
+; unless CP4DMU is run following KERMIT-80, the normal handling of
+; XON/XOFF provided by KERMIT-80 will not work (cold boot is another
+; alternative).
+;
+; CP4DMF.ASM
+;
+; last edit: 12-jun-87 20:00:00 Charles J. Lasner (CJL)
+
+;oboff equ 3fh ; offset of outbyt routine for 6120
+;prtctl equ 02h ; port control
+nocoxon equ 001h ; turn off comm. output XON
+
+ lxi b,(nocoxon * 100h) + prtctl ; c/prtctl, b/no out. xon
+ call outbyt
+ ret ; and return
+
+;outbyt has been catered for (in break routine)
+ENDIF ;dmII
+
+IF osbrn1 ;(Note now no longer needs code > 4000h as it is already there
+; lxi d,ostop ;where we're moving it to
+; lxi h,osmove ;what we're moving
+; mvi b,osmct ;How many bytes we're moving
+; call mover
+ lda baudrt ; Find out what speed is current
+ ani 1
+ mvi a,osbi03 ; assume 300 baud
+ jz osstr1
+ mvi a,osbi12 ; nope, it's 1200.
+osstr1: sta speed ; save initial speed
+ sta speed+1 ; as 16 bits, to match speed table entries
+ mov d,a
+ mov e,a ; get initial speed in DE
+ call sysspd ;set up parity etc.
+ENDIF;osbrn1
+
+IF cpt85xx
+ mvi a,80h ; Send UART reset [force idle] by setting
+ out baudrt ; bit 7 of baud rate I/O port
+ lxi H,0f0fh ; Clear reset and default to 9600 baud [23]
+ shld speed ; store current speed
+ xchg
+ call sysspd ; set default baud rate
+ mvi a,4Eh ; Set UART mode to async 16x clock, 8 data
+ out mnprts ; bits, no parity, and 1 stop bit
+ mvi a,37h ; Set command to Tx enable, DTR on, Rx enable,
+ out mnprts ; break off, error reset, and RTS on
+ENDIF ; cpt85x
+
+IF bbc ;[22]
+ lxi d,modstr ; Set MODE 3
+ call prtstr
+ mvi a,1 ; Set terminal mode on
+ call term
+ mvi a,0F2H ; Read current transmit speed
+ lxi h,0FF00H ; .. 3 lsb of ULA register
+ call osbyte ; FX242,0,255
+ mov a,l
+ ani 7 ; Mask of 3 lsb
+;
+; Edit of July 22, 1986 by B Robertson, Aberdeen Univ. Computing Centre.
+; Correct bug in sysinit for BBC - reads the initial baud rate at
+; start up incorrectly.
+;
+;
+ rar ; Reverse order of 3 lsb
+ rar ; Bit2 now in bit0
+ jnc binit1 ;
+ ori 2 ; Restore bit1
+binit1: ana a ; Set sign bit as appropriate
+ jp binit2 ;
+ ori 4 ; Bit0 now in bit2
+binit2: ani 7 ; Mask off unwanted bits
+; End of Edit
+
+ xri 7 ; Stored as 2's complement
+ inr a
+ sta speed ; Store 16 bit value
+ sta speed+1
+ mov e,a ; Ensure RX and TX speeds are the same
+ call sysspd
+ENDIF;[22] bbc
+
+IF rm380z ;[22]
+ mvi e,11h ;Output ctrl-Q to clear autopaging
+ call outcon
+ENDIF;[22] rm380z
+
+
+IF lobo ;[hh]
+ lxi d,siotbl ;[hh] address of status table
+ mvi c,siolen ;[hh] length of the table
+siolup: ;[hh] loop here for each command byte
+ ldax d ;[hh] load first byte into A
+ inx d ;[hh] index pointer to next bute
+ sta mnprts ;[hh] send it to status port A
+ sta mnprts+2 ;[hh] and to status port B
+ dcr c ;[hh] decrement the counter
+ jnz siolup ;[hh] loop back for more commands
+ mvi a,05H ;[hh] value for 300 baud
+ sta baudrt ;[hh] starting default for port A
+ sta baudrt+4 ;[hh] and for port B
+ sta speed ;[hh] tell program they're set
+ mvi a,0E4H ;[hh] value for port A
+ sta port ;[hh] tell program we've set this, too
+ mvi a,0D0H ;[hh] port A baud rate value
+ sta port+1 ;[hh] save this as well, for consistancy
+ENDIF ;lobo
+
+IF mikko
+ lxi d,mintbl ;Address of KERMIT Reg values (what)
+ mvi c,minlen ;Length of table (how many)
+ lxi h,sioac ;Send data to ch. A SIO registers (to where)
+ call movmik
+ mvi a,0FFH ;Set ch. A mask to use all bits
+ sta chmask
+ENDIF;mikko
+
+IF mdI
+ lxi h,96 ;Default 1200 baud modem port speed
+ shld speed ;Store as modem port speed
+ call sysspd ;Initialize the port
+ENDIF;mdI [Toad Hall]
+
+IF cmemco ;[25]
+ mvi a,01h ; Reset TU-ART
+ out tuart+2
+ mvi a,90h ; Set default baud rate (2400), and 1 stop bit
+ out tuart
+ sta speed ; save for status display
+ sta speed+1
+ENDIF;cmemco
+
+IF delphi ;[7]
+;
+; shove the default baud rate (1200) in to the Delphi port address
+; for the baud rate generator on port 2, the default port; save this
+; value so we can tell what speed is selected.
+;
+ mvi a,07h ;[7] get value for 1200 baud
+ out baudrt ;[7] set it for port 2
+ sta speed ;[7] save for status display
+ sta speed+1
+ENDIF;[7] delphi
+
+IF px8 ; [29]
+ lda 0f6a9h ; get baud rate value set by CONFIG
+ sta px8blk+4 ; put into parameter block
+ mov h, a ; initialise global speed indicator
+ mov l, a
+ shld speed
+ lhld 6 ; base of CP/M
+; buffer starts at ovlend+8192, immediately after sector buffer
+; We must also allow (800h) for the CCP as Kermit exits with a RET
+ lxi d, ovlend+8192+800h ; calc buffer length
+ ora a ; clear carry
+ db 0edh, 52h ; sbc hl, de
+ shld px8blk+2
+ call rsopen
+ENDIF ; px8 [29]
+
+IF disc ;[29]
+;Initialization sequence for Discovery 83U port B
+;Sets port to 9600 baud, 8 data bits, 1 stop bit, no parity
+ mvi a,12 ;Register 12
+ out mnprts
+ mvi a,11 ;Low byte of time constant for 9600
+ out mnprts
+ mvi a,13 ;Register 13
+ out mnprts
+ mvi a,0 ;High byte of time constant for 9600
+ out mnprts
+ mvi a,14 ;Register 14
+ out mnprts
+ mvi a,3 ;Enable baud rate generator
+ out mnprts
+ mvi a,11 ;Register 11
+ out mnprts
+ mvi a,52h ;No Xtal, tclk=rclk=/trxc out=br gen
+ out mnprts
+ mvi a,4 ;Register 4
+ out mnprts
+ mvi a,44h ;16x clock, 1 stop, no parity
+ out mnprts
+ mvi a,3 ;Register 3
+ out mnprts
+ mvi a,71h ;rx 8 bit/ch, autoenable, rx enable
+ out mnprts
+ mvi a,5 ;Register 5
+ out mnprts
+ mvi a,0eah ;tx 8 bit/ch, tx enable, rts
+ out mnprts
+ENDIF;disc [29]
+;
+;
+IF mikko ;currently for MIKROMIKKO only
+; copy command block into memory-mapped SIO.
+movmik: di ;disable interrupts
+movmk1: ldax d ;Get a register value
+ mov m,a ;Output it
+ inx d ;Next value
+ dcr c ;Decrement counter
+ jnz movmk1 ;Repeat until done
+ ei
+ ret
+ENDIF;mikko
+
+;
+IF osbrn1
+osmove:
+osflag equ 0EF08H ;Osborne 1 Bank-2 flag
+;
+; return modem status in A
+;
+OSLDST:
+ DI
+ OUT 0
+ LDA osprts ;Read the status port
+ OUT 1
+ EI
+ ret
+;
+; set modem status from A
+;
+OSSTST:
+ DI
+ OUT 0
+ STA osprts ;Write the control port
+ jmp osstex
+;
+; read character from modem into A
+;
+OSLDDA:
+ DI
+ OUT 0
+ LDA osport
+ OUT 1
+ EI
+ ret
+;
+; output character in A to modem
+;
+OSSTDA:
+ DI
+ OUT 0
+ STA osport
+osstex:
+ OUT 1
+ mvi a,1
+ sta osflag
+ EI
+ ret
+ENDIF;osbrn1
+
+IF lobo
+; List of commands to set up SIO channel A for asynchronous operation.
+siotbl: DB 18H ; Channel reset
+ DB 18H ; another, in case register 0 wasn't selected
+ DB 04H ; Select register 4
+ DB 44H ; 1 stop bit, clock*16
+ DB 01H ; Select register 1
+ DB 00H ; No interrupts enabled
+ DB 03H ; Select register 3
+ DB 0C1H ; Rx enable, 8 bit Rx character
+ DB 05H ; Select register 5
+ DB 0EAH ; Tx enable, 8 bit Tx character,
+ ; raise DTR and RTS
+siolen equ $-siotbl ; length of command list
+ENDIF;lobo
+
+IF mikko
+; command list to set SIO chip back to normal state
+miotbl: db 3 ;reg. 3
+ db sioo3
+ db 5 ;reg. 5
+ db sioo5
+ db 4 ;reg. 4
+ db sioo4
+ db 0 ;reselect reg. 0
+miolen equ $-miotbl ;MikroMikko SIO table length (original values)
+
+; command list to set up SIO chip for operation with Kermit
+mintbl: db 3 ;reg. 3
+ db sion3
+ db 5 ;reg. 5
+ db sion5
+ db 4 ;reg. 4
+ db sion4
+ db 0 ;reselect reg. 0
+minlen equ $-mintbl ;MikroMikko SIO table length (KERMIT values)
+ENDIF;mikko
+
+
+IF bbc ;[22]
+modstr: db 16h,03h,'$' ; String to put screen into MODE 3
+ENDIF
+
+IF px8 ; [29]
+rsget: mvi b, 50h
+ jmp rsiox
+rsinst: mvi b, 30h
+ jmp rsiox
+rsput: mvi b, 60h
+ jmp rsiox
+rsoutst:mvi b, 40h
+ jmp rsiox
+rserst: mvi b, 90h
+ jmp rsiox
+rsopen: lxi h, px8blk ; copy px8blk to px8prm
+ lxi d, px8prm
+ lxi b, 9
+ call mover
+ mvi b, 10h ; open code
+ jmp rsiox
+rsclose:mvi b, 20h ; close code
+rsiox: lxi h, px8prm
+ lxi d, 51h ; offset into BIOS jump table
+ push h
+ lhld 1 ; start of BIOS
+ dad d
+ xthl ; entry point on stack, px8prm addr in hl
+ ret ; jump indirect
+
+px8prm: dw 0, 0
+ db 0, 0, 0, 0, 0 ; the param area is overwritten in rsopen
+px8blk: dw ovlend+8192 ; buffer address
+ dw 0 ; buffer size - overwritten
+ db 0 ; baud rate - overwritten
+ db 3 ; 8 bits/char
+ db 0 ; no parity, it is done internally
+ db 1 ; 1 stop bit
+ db 0cfh ; special bits - activate xon/xoff
+; The documentation suggests that the xon/xoff bit is bit 4, i.e the pattern
+; should be 0efh, but the top bit is omitted from the diagram. I will try
+; clearing both bit 4 and bit 5.
+ENDIF ; px8 [29]
+
+IF hp125 ;[MF]
+ lxi b,73ffh ;Prepare Data Comm 1 to
+ call bdos ;Transfer eight-bit data
+ lxi d,jbuf ;Point to bios jump-table vector
+ lxi b,7effh ;Set up special subfunction code to
+ call bdos ;Get rdr routine address
+ lhld jbuf+3 ;Remember this address
+ shld readin+1 ;for our eight-bit rdr routine
+ mvi a,1 ;We want to write into the bios jump table
+ sta jbuf+1 ;...
+ lxi h,readin ;Point to our rdr routine (all 8 bits)
+ shld jbuf+3 ;as new RDR routine
+ lxi d,jbuf ;Point to jump vector argument block
+ lxi b,7effh ;Set subfunction code to
+ call bdos ;Substitute our rdr routine in dispatch table
+ lxi h,mapon1 ;Make Data Comm 1 the default port
+ shld port ;at program-start
+ xchg ;Put in DE
+ call prtstr ;Print escape sequences to connect
+ ;DAta Comm 1 to rdr/punch
+ENDIF ;hp125 [MF]
+
+ ret ; end of sysxin
+
+;
+; system-dependent termination processing
+; If we've changed anything, this is our last chance to put it back.
+sysexit:
+
+IF dmII
+; Edited by OBSchou for Charles Lasner. His bug fix now in Kermit-80:
+;
+; IBM mode restore program
+;
+; This routine must be run after using CP4DMF (and KERMIT-80) to restore
+; the normal handling of XON/XOFF; the user may also elect to cold-boot
+; the DECMATE instead.
+;
+; acknowledgments and limitations.
+;
+; This program is based on DECMATE specific implementation details
+; provided by Walt Lamia of DEC. It is of course, specific to DECMATE
+; implementations of CP/M-80 for DECMATE II, III, III-plus, etc.
+;
+; usage consists of merely:
+;
+; CP4DMF run xon/xoff disable program
+; KERMIT80 then run kermit
+; <KERMIT-80 commands used normally here, including SET IBM ON>
+; CP4DMU run this program to restore normal XON
+;
+; unless CP4DMU is run following KERMIT-80, the normal handling of
+; XON/XOFF provided by KERMIT-80 will not work (cold boot is another
+; alternative).
+;
+; CP4DMF.ASM
+;
+; last edit: 12-jun-87 20:00:00 Charles J. Lasner (CJL)
+;
+coxon equ 000h ; enable comm. output XON
+;oboff equ 3fh ; offset of outbyt routine for 6120
+;prtctl equ 02h ; port control
+
+
+ lxi b,(coxon * 100h) + prtctl ; c/prtctl, b/with out. xon
+ call outbyt ;[OBS] declared elswhere
+ ret ; and return
+
+ENDIF ;dmII
+
+IF mikko
+ lxi d,miotbl ;Load the adress of original reg values
+ mvi c,miolen ;Length of table
+ lxi h,sioac ;Send data to ch A SIO registers
+ call movmik
+ mvi a,07FH ;Set ch A mask to use just 7 bits
+ sta chmask
+ENDIF;mikko
+
+IF teletek
+;Note - This code was handwritten onto the lising I was sent, with the
+; comment that David had just thought of the code, so it was
+; not on the listing. If you have problems I suggest you
+; comment out these few lines.
+;Bertil Schou.
+;
+ di
+ mvi a,47h ; reset baud rate to 9600
+ out baudrt
+ mvi a,08h
+ out baudrt
+ ei
+ENDIF ;teletek
+
+IF cpt85xx
+ mvi a,80h ; Reset (force idle) the 8251 UART via bit 7
+ out baudrt ; of the baud rate generater port
+ mvi a,00h ; and turn off the baud rate generater
+ out baudrt
+ENDIF;cpt85xx
+
+IF bbc ;[22]
+ mvi a,0 ; Turn off terminal mode
+ call term
+ENDIF;[22] bbc
+
+IF px8 ;[29]
+ call rsclose
+ENDIF ;px8 [29]
+
+IF hp125 ;[MF]
+ lxi b,74ffh ;Set subfunction code to
+ call bdos ;Reset Data Comm 1 for 7-bit data
+ lhld readin+1 ;Get original rdr routine address
+ shld jbuf+3 ;and store in jump vector
+ lxi d,jbuf ;Point to jump vector
+ lxi b,7effh ;Set subfunction code to
+ call bdos ;Put original rdr routine back in bios
+ ;dispatch table
+ lxi d,mapoff ;Point to escape sequences to
+ call prtstr ;Turn off Data Comm 1/2 mappings
+ENDIF ;hp125 [MF]
+
+ ret
+
+;
+; system-dependent processing for start of CONNECT command
+;
+syscon:
+IF robin OR trs80 OR cpt85xx ;For Robin/TRS80/CPT-85xx, add some more info
+ lxi d,conmsg ; about obscure key combinations
+ call prtstr
+ENDIF;robin OR trs80 OR cpt85xx
+
+IF osbrn1 ;*** This is Software dependent ***
+ lhld 1 ;Modify back-arrow code to DELETE
+ mvi l,0 ;Get BIOS-start address
+ lxi d,85H ;Adress for key-code = XX85H
+ dad d
+ mov e,m ;Get it in DE
+ inx h
+ mov d,m
+ xchg ;Memory pointer to HL
+ mvi m,del ;modify the code
+ENDIF;osbrn1
+ ret
+
+conmsg: ; Messages printed when entering transparent (CONNECT) mode:
+IF robin ; for Robin, control-S key is hidden
+ db ' (Type Left Arrow to send CTRL-S)',cr,lf,'$'
+ENDIF;robin
+IF trs80 ; for TRS-80, the preferred escape key is hidden
+ db ' (Control-_ is the Down-Arrow key on the TRS-80 keyboard)'
+ db cr,lf,'$'
+ENDIF;trs80
+IF cpt85xx ; for CPT-85xx, some graphics map "funny" to keyboard in CP/M
+ db ' (Use CODE + SHIFT + 1/2 key to generate a Control-\)'
+ db cr,lf,'$'
+ENDIF;cpt85xx
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+IF osbrn1
+ lhld 1 ;Modify back-arrow code to BACKSPACE
+ mvi l,0 ;Get BIOS address
+ lxi d,85H ;Address for key-code =XX85H
+ dad d
+ mov e,m ;Get it in DE
+ inx h
+ mov d,m
+ xchg ;Address to HL
+ mvi m,bs ;Modify code
+ENDIF;osbrn1
+ ret
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing all the
+; system-independent escape sequences.
+;
+sysinh:
+IF robin OR dmII OR cpt85xx OR lobo
+ lxi d,inhlps ; we got options...
+ call prtstr ; print them.
+ENDIF;robin OR dmII OR cpt85xx OR lobo
+
+IF bbc OR rm380z ; some more
+ lxi d,inhlps ; we got options...
+ call prtstr ; print them.
+ENDIF;[22] bbc OR rm380z
+
+IF px8 OR access OR mmate OR disc ;and more...
+ lxi d,inhlps ; we got options...
+ call prtstr ; print them.
+ENDIF ;px8 OR access OR mmate OR disc
+
+ ret
+
+
+;additional, system-dependent help for transparent mode
+; (two-character escape sequences)
+inhlps:
+
+IF robin OR dmII OR cpt85xx OR lobo
+ db cr,lf,'B Transmit a BREAK'
+ENDIF;robin OR dmII OR cpt85xx OR lobo
+
+IF bbc OR rm380z
+ db cr,lf,'B Transmit a BREAK'
+ENDIF;bbc OR rm380z
+
+IF px8 OR access OR mmate
+ db cr,lf,'B Transmit a BREAK'
+ENDIF ;px8 OR access OR mmate
+
+IF disc ;[29] [32]
+ db cr,lf,'B Transmit a 300ms BREAK'
+ db cr,lf,'L Transmit a 5 second BREAK'
+ENDIF;disc [29]
+
+IF lobo
+ db cr,lf,'D Drop the line'
+ENDIF;lobo
+
+ db '$' ;[hh] table terminator
+
+;
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:
+; non-skip: sequence has been processed
+; skip: sequence was not recognized
+
+sysint: ani 137O ; convert lower case to upper, for testing...
+
+IF robin OR dmII OR cpt85xx OR lobo
+ cpi 'B' ; send break?
+ jz sendbr ; yes, go do it. return nonskip when through.
+ENDIF;robin OR dmII OR cpt85xx OR lobo
+
+IF bbc OR rm380z ; [22] [25] ... some more
+ cpi 'B' ; send break?
+ jz sendbr ; yes, go do it. return nonskip when through.
+ENDIF; bbc OR rm380z
+
+IF px8 OR access OR mmate ;[28] [29] and anothers
+ cpi 'B' ; send break?
+ jz sendbr ; yes, go do it. return nonskip when through.
+ENDIF ; px8 OR access OR mmate [28] [29]
+
+IF lobo ;[hh]
+ cpi 'D' ;[hh] disconnect?
+ jz discon ;[hh] yes, go do it. nonskip return when done.
+ENDIF ;lobo
+
+IF disc ;[29]
+ cpi 'B' ;Send short break?
+ jz sendbr
+ cpi 'L' ;Send long break?
+ jz sendlbr
+ENDIF;disc [29]
+
+ jmp rskp ; take skip return - command not recognized.
+
+
+;
+IF robin ;Definitions & code to send a BREAK (ungenerically, no other way).
+
+comctl equ 59h ;VT180 communications port
+crtctl equ 41h ;VT180 crt port
+
+;VT180 serial port command bits
+
+txe equ 1 ;transmit enable
+dtr equ 2 ;dtr on
+rxe equ 4 ;rx enable
+sndbrk equ 8
+rerr equ 10h ;reset error
+rts equ 20h ;RTS on
+reset equ 40h ;port reset
+
+;Send a break to the communications port.
+;
+
+sendbr: lxi h,38500 ;250 ms(?)
+ lda prtadr ;Get address of selected port
+ mov c,a ;Into C
+ mvi a,sndbrk+dtr
+; OUT C,A ;Want to send to port addressed by C
+ db 0EDH,079H ;Op code for above instruction
+sndbr1: dcx h ;timing loop...
+ mov a,l
+ ora h
+ jnz sndbr1 ;...until over
+ lda prtadr ;Get the address for the port
+ mov c,a ;Into C
+ mvi a,txe+dtr+rxe+rerr+rts ;enable tr/rc, dtr, reset error
+; out c,a ;Z-80 only instruction
+ db 0EDH,079H ;Op code for above instruction
+ out contst ;reset ports
+ ret
+ENDIF;robin
+;
+IF dmII ;[jd] this added to send break on DECmate
+
+; DECmate command codes for 6120 I/O processor
+oboff equ 3fh ; offset of outbyt routine for 6120
+prtctl equ 02h ; port control
+brdat equ 06h ; data to tell 6120 to send a break
+brdur equ 30 ; duration, 30 = 300 ms.
+
+sendbr: lxi b,(brdat * 100h) + prtctl ; c/prtctl, b/brdat
+ call outbyt
+ lxi b,brdur*100h ; b/duration, c/0
+; fall through into outbyt
+
+outbyt: lhld 1 ; get warm boot address
+ lxi d,oboff ; offset of outbyt routine
+ dad d ; compute address
+ pchl ; branch there (a callret)
+
+ENDIF;dmII
+;
+IF access OR mmate ;[cjc] send break on Kaypro [29]
+; Officially, a "break" is 300 milliseconds of "space" (idle line is
+; "mark"). (or maybe 200 milliseconds; I forget.) The timing isn't
+; usually that critical, but we'll make an attempt, at least. Sending
+; too long a break can cause some modems to hang up.
+
+sendbr:
+; First, make sure the transmitter is really empty. (The SIO sets
+; "transmitter buffer empty" when it can accept another character;
+; the previous character is still being shifted onto the line.
+; Another status bit, "all done", is set to indicate that the
+; transmitter is really idle.
+sndbr1: mvi a,1 ; select Read Register 1
+ out mnprts
+ in mnprts ; read the contents
+ ani 1 ; test "all done" flag
+ jz sndbr1 ; loop until it's nonzero.
+;
+; Next, set the "send break" bit to start the transmitter spacing.
+ mvi a,5 ; select Write Register 5
+ out mnprts
+ mvi a,0FAH ; Tx enable, 8 bit Tx character, Send Break,
+ out mnprts ; DTR and RTS on.
+;
+; Now, delay for 30 hundredths of a second
+ mvi a,30 ; delay count
+ call delay
+;
+; Time's up. Put transmitter back in normal state (data byte is the
+; same as the one in siotbl: for Write Register 5) and return.
+ mvi a,5 ; select Write Register 5
+ out mnprts
+ mvi a,0EAH ; Tx enable, 8 bit Tx character,
+ out mnprts ; DTR and RTS on.
+ ret ; done.
+ENDIF;access OR mmate [29]
+
+IF lobo ;[hh] This routine sends a break tone or disconnects a modem
+; (those that respond to it) by setting the DTR line low
+; for 300 ms.
+;
+sendbr: mvi a,05H ;[hh] write register 5
+ call outctl ;[hh] send it to control port
+ mvi a,0FAH ;[hh] value to send break tone
+ jmp sndbr1 ;[hh]
+;
+discon: mvi a,05H ;[hh] write register 5
+ call outctl ;[hh] send it to the control port
+ mvi a,06AH ;[hh] DTR off and break tone on
+sndbr1: call outctl ;[hh] send to control port
+ mvi a,30 ;[hh] delay count for 300 ms.
+ call delay ;[hh] wait a while...
+ mvi a,05H ;[hh] write register 5
+ call outctl ;[hh] get it's attention
+ mvi a,0EAH ;[hh] normal 8 bits, DTR on, RTS on, etc.
+ call outctl ;[hh] restore SIO
+ ret
+;
+outctl: sta mnprts ;[hh]
+ ret
+ENDIF ;lobo
+;
+IF cpt85xx OR rm380z ;[lmj] [22] [25]
+sendbr:
+;
+; Ensure that the transmitter has finished sending buffered chars
+sndbr1: in mnprts ; get UART status
+ ani TxEmpty ; everything sent?
+ jz sndbr1 ; no, wait a bit more
+;
+; Begin sending a break by setting bit in UART command register
+ mvi a,3Fh ; Set TxEna, DTR, RxEna, SBreak, ErrRst, RTS
+ out mnprts
+;
+; Wait for 250 milliseconds (using hundredths second delay routine)
+ mvi a,25
+ call delay
+;
+; Resume normal operation by clearing the SendBreak command bit
+ mvi a,37h ;Set TxEna, DTR, RxEna, ErrRst, RTS
+ out mnprts
+;
+ ret ;done
+ENDIF;cpt85xx OR rm380z
+
+IF px8 ; [29]
+sendbr: mvi a, 3fh ; set break bit
+ out mnprts
+ mvi a, 25
+ call delay ; wait 250 msec
+ mvi a, 37h ; clear break bit
+ out mnprts
+ ret
+ENDIF ; px8 [29]
+
+;
+IF bbc ;[22]
+sendbr:
+;
+; Ensure that the transmitter has finished sending buffered chars
+sndbr1: mvi a,96h ; get ACIA status
+ mvi l,8
+ call osbyte ; *FX150,8
+ mov a,h
+ ani 2 ; everything sent?
+ jz sndbr1 ; no, wait a bit more
+;
+; Disable centisecond clock (system VIA) which interferes with break
+ lxi h,0FE4Eh ; system VIA interrupt enable register
+ mvi a,40H ; disable timer 1
+ call wrtiom ; write to I/O processor memory
+;
+; Begin sending a break by setting bit in ACIA control register
+ mvi a,9Ch
+ lxi h,9F60h ; Set Rxint, Txint, Break, RTS
+ call osbyte ; *FX 156,96,159
+;
+; Wait for 250 milliseconds (using hundredths second delay routine)
+ mvi a,25
+ call delay
+;
+; Resume normal operation by returning old control byte
+ mvi a,9Ch
+ mvi h,0 ;Set TxEna, DTR, RxEna, ErrRst, RTS
+ call osbyte ; *FX 156,oldvalue,0
+;
+; Enable centisecond clock (system VIA)
+ lxi h,0FE4Eh ; system VIA interrupt enable register
+ mvi a,0C0H ; enable timer 1
+ call wrtiom ; write to I/O processor memory
+;
+ ret ;done
+;
+; Routine to write byte in A to I/O processor memory address
+; given by HL
+wrtiom:
+ shld parblk ; store address to parameter block
+ sta parblk+4 ; store data
+ lxi h,parblk ; load hl with address of param block
+ mvi a,6 ; write I/O processor memory
+ call osword ; go do it
+ ret
+;
+parblk: DS 5 ; reserve space for parameter block
+ENDIF;bbc [22]
+;
+IF disc ;[29]
+; This is almost an exact copy of the bbI sendbr routine.
+; Modifications to include a long break have been made.
+;
+; Officially, a "break" is 300 milliseconds of "space" (idle line is
+; "mark"). (or maybe 200 milliseconds; I forget.) The timing isn't
+; usually that critical, but we'll make an attempt, at least. Sending
+; too long a break can cause some modems to hang up.
+
+sendlbr:
+ push d ;save d, this may not be necessary, but safe
+ mvi d,17 ;do short break 17 times (approx. 5 sec.)
+ jmp sndbr1
+sendbr:
+ push d
+ mvi d,1 ;On short break, do only once
+; First, make sure the transmitter is really empty. (The SIO sets
+; "transmitter buffer empty" when it can accept another character;
+; the previous character is still being shifted onto the line.
+; Another status bit, "all done", is set to indicate that the
+; transmitter is really idle.
+sndbr1: mvi a,1 ; select Read Register 1
+ out mnprts
+ in mnprts ; read the contents
+ ani 1 ; test "all done" flag
+ jz sndbr1 ; loop until it's nonzero.
+;
+; Next, set the "send break" bit to start the transmitter spacing.
+ mvi a,5 ; select Write Register 5
+ out mnprts
+ mvi a,0FAH ; Tx enable, 8 bit Tx character, Send Break,
+ out mnprts ; DTR and RTS on.
+;
+; Now, delay for 30*d hundredths of a second
+sendbr2:
+ mvi a,30 ; delay count
+ call delay
+; The following has been added to allow doing .03 delay d times
+ dcr d ; decrement # of times to do loop
+ jnz sendbr2 ; if not done, do again
+ pop d ; reload d
+;
+; Time's up. Put transmitter back in normal state (data byte is the
+; same as the one in siotbl: for Write Register 5) and return.
+ mvi a,5 ; select Write Register 5
+ out mnprts
+ mvi a,0EAH ; Tx enable, 8 bit Tx character,
+ out mnprts ; DTR and RTS on.
+ ret ; done.
+ENDIF ;disc [29]
+
+
+;
+; sysflt - system-dependent filter
+; called with character in E.
+; if this character should not be printed, return with A = zero.
+; preserves bc, de, hl.
+; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
+sysflt:
+ mov a,e ; get character for testing
+IF mikko
+ cpi 'O'-100O ;Control-O's lock keyboard
+ rnz ; if not control-O, it's ok.
+ xra a ; don't allow control-O out.
+ENDIF;mikko
+
+ ret
+
+; mdmflt - modem filter [30]
+; called with character to be sent to printer in E
+; with parity set as appropriate.
+; return with accumulator = 0 do do nothing,
+; <> 0 to send char in E.
+mdmflt:
+ mov a,e ;[30] get character to test
+ ret
+
+
+
+; prtflt - printer filter [30]
+; called with character to be sent to printer in E
+; returns with a = 0 to do nothing
+; a <> 0 to print it.
+;
+; this routine for those printer that automatically insert
+; a lf on cr, or cr for lf. Should this be shifted to
+; the system indep. stuff, in say 4.06?
+prtflt:
+ mov a,e ; [30] get character to test
+ ret
+
+
+;
+; system-dependent processing for BYE command.
+; for lobo, hang up the phone.
+sysbye:
+IF lobo ;[hh]
+ call discon ;[hh] force modem to hang up
+ENDIF;lobo
+ ret
+
+IF lasm
+ LINK CPXSY2.ASM ; If m80 then this ignored
+ENDIF ; lasm
diff --git a/cpxtm4.asm b/cpxtm4.asm
index bb933ee..b2faa7f 100644
--- a/cpxtm4.asm
+++ b/cpxtm4.asm
@@ -1,490 +1,490 @@
-;CPXTM4.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the system-dependent code and data for various
-; Tandy Model 4 running under Montezuma Micro CPM
-;
-; This has the Family name of CPXTM4.ASM.
-;
-; revision history (last edit first)
-;
-; edit 5, 8-Feb-1991 by Lance Tagliapietra of the University of Wisconsin-
-; Platteville. Corrected error in the VT52 translation table for
-; clearing from the cursor to the end of the line.
-;
-; edit 4, 27 October, 1987 by OBSchou. Massaged into format suitable
-; for overlay version 4.09
-;
-; Edit 3: Sept 5 1987 GDS Transformed code from Genie III to Tandy Model 4
-;
-; Edit 2: Aug 27 1987 GDS Put in code for BREAK and fillited out
-; a lot of unnecessary IF's
-;
-;Edit 1: Nov. 28, 1986 Geof Smith Clinical Research centre Harrow UK.
-
-
-.printx * Assembling for Tandy Model 4*
-;
-drtime EQU 05H ;Default receive time out interval.
-;
-; the basics...
-;
-mnport EQU 0EBH
-mnprts EQU 0EAH
-output EQU 40H
-input EQU 80H
-lctrl EQU 0E8H
-baudpt EQU 0E9H
-z80 EQU TRUE
-brkval EQU 0H
-inout EQU TRUE
-
-defesc EQU 'X'-100O ;The default escape character.
-
-
-;Select initial setting for VT-52 emulation flag.
-
-; default to VT52-EMULATION ON.
-;
-vtval EQU 1
-;
-;
-
-
-
-
-
-
-
-
-
-; Family is the string used in VERSION to say which of several
-; smaller overlay files are used. These are (will be) derived from
-; the huge CP4SYS.ASM file, in which case we will never get here.
-; Just a Dollar, but put a sting in for a family of machines.
-;
-family: db 'CPXTM4.ASM (5) 8-Feb-91$' ; Used for family versions....
-
-
-;
-; System-dependent initialization
-; Called once at program start.
-sysxin:
-;
- ;Set up 9600 bd, 8bit words, no parity 1stop bit
-
- mvi a,0EEH ;Get byte for desired baud (9600 = CC) and
- out baudpt ;and put it out of baud port
- out lctrl ;latch control port with anything
- lda pstore ;get parity etc and put it out of
- out mnprts ;port
- ret ; return from system-dependent routine
-
-;
-
-
-
-
-
-
-
-
-
-;
-; system-dependent termination processing
-; If we've changed anything, this is our last chance to put it back.
-sysexit:
- ret
-;
-; system-dependent processing for start of CONNECT command
-;
-syscon:
- ret
-
-conmsg: ; Messages printed when entering transparent (CONNECT) mode:
-;-------------------------------------------------------------------------------
-; --
-;
-; syscls - system-dependent close routine
-; called when exiting transparent session.
-;
-syscls:
- ret
-;-------------------------------------------------------------------------------
-; ---
-;
-; sysinh - help for system-dependent special functions.
-; called in response to <escape>?, after listing all the
-; system-independent escape sequences.
-;
-sysinh:
- lxi d,inhlps ; we got options...
- call prtstr ; print them.
- ret
-
-
-;additional, system-dependent help for transparent mode
-; (two-character escape sequences)
-inhlps:
-
- db cr,lf,'B Transmit a BREAK'
-
- db '$' ;[hh] table terminator
-
-;
-; sysint - system dependent special functions
-; called when transparent escape character has been typed;
-; the second character of the sequence is in A (and in B).
-; returns:
-; non-skip: sequence has been processed
-; skip: sequence was not recognized
-sysint: ani 137O ; convert lower case to upper, for testing...
- cpi 'B' ; send break?
- jz sendbr ; yes, go do it. return nonskip when through.
-
- jmp rskp ; take skip return - command not recognized.
-
-
-;-------------------------------------------------------------------------------
-sendbr:
-;
-; Ensure that the transmitter has finished sending buffered chars
-sndbr1: in mnprts ; get UART status
- ani output ; everything sent?
- jz sndbr1 ; no, wait a bit more
-;
-; Begin sending a break by setting bit in UART command register
- mvi a,brkval ; SBreak,
- out lctrl
- out mnprts
-;
-
-; Wait for 250 milliseconds (using hundredths second delay routine)
- mvi a,25
- call delay
-;
-; Resume normal operation by clearing the SendBreak command bit
- lda pstore ;get parity etc value
- out lctrl ;latch control port
- out mnprts ;and set values
-;
- ret ;done
-
-;
-;
-
-
-
-
-
-
-
-
-
-;
-; sysflt - system-dependent filter
-; called with character in E.
-; if this character should not be printed, return with A = zero.
-; preserves bc, de, hl.
-; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-sysflt:
- mov a,e ; get character for testing
- ret
-
-; mdmflt - modem filter [30]
-; called with character to be sent to modem in E
-; with parity set as appropriate.
-; return with accumulator = 0 do do nothing,
-; <> 0 to send char in E.
-mdmflt: mov a,e
- ret
-
-
-
-; prtflt - printer filter [30]
-; called with character to be sent to printer in E
-; returns with a = 0 to do nothing
-; a <> 0 to print it.
-;
-; this routine for those printer that automatically insert
-; a lf on cr, or cr for lf. Should this be shifted to
-; the system indep. stuff, in say 4.06?
-prtflt:
- mov a,e ; [30] get character to test
- ret
-
-
-;
-
-
-
-
-
-
-
-
-
-
-;
-; system-dependent processing for BYE command.
-; for apmmdm, heath, and lobo, hang up the phone.
-sysbye:
- ret
-;
-
-
-
-
-
-
-
-
-
-
-; This is the system-dependent command to change the baud rate.
-; DE contains the two-byte value from the baud rate table; this
-; value is also stored in 'speed'.
-sysspd:
- ;Set up baud rate 8bit words, no parity 1stop bit
-
- mov a,e ;get get speed into a
- out baudpt ;output it as well
- lda pstore ;get parity etc
- out lctrl ;do it resetting DLAB at same time
- out mnprts
- ret
-
-pstore: db 6CH ;Default value for parity word length and stop bits
-
-spdtbl: db 10h ;17 entries
- db 03h,'110$', 22H,22H
- db 04h,'1200$', 77H,77H
- db 05h,'134.5$', 33H,33H
- db 03h,'150$', 44H,44H
- db 04h,'1800$', 88H,88H
- db 05h,'19200$', 0FFH,0FFH
- db 04h,'2000$', 99H,99H
- db 04h,'2400$', 0AAH,0AAH
- db 03h,'300$', 55H,55H
- db 04h,'3600$', 0BBH,0BBH
- db 04h,'4800$', 0CCH,0CCH
- db 02h,'50$', 00H,00H
- db 03h,'600$', 66H,66H
- db 04h,'7200$', 0DDH,0DDH
- db 02h,'75$', 11H,11H
- db 04h,'9600$', 0EEH,0EEH
-
-sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
- db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200 $'
-
-; This is the system-dependent SET PORT command.
-; HL contains the argument from the command table.
-sysprt:
- ret
-;
-prttbl equ 0 ; SET PORT not supported
-prhtbl equ 0
-
-;
-
-
-
-
-
-
-
-
-
-;
-; selmdm - select modem port
-; selcon - select console port
-; selmdm is called before using inpmdm or outmdm;
-; selcon is called before using inpcon or outcon.
-; For iobyt systems, diddle the I/O byte to select console or comm port;
-; For Decision I, switches Multi I/O board to console or modem serial
-; port. [Toad Hall]
-; For the rest, does nothing.
-; preserves bc, de, hl.
-selmdm:
- ret
-
-selcon:
- ret
-;
-
-
-
-
-
-
-
-
-
-; Get character from console, or return zero.
-; result is returned in A. destroys bc, de, hl.
-;
-inpcon:
- mvi c,dconio ;Direct console I/O BDOS call.
- mvi e,0FFH ;Input.
- call BDOS
-
- ret
-;
-; Output character in E to the console.
-; destroys bc, de, hl
-;
-outcon:
-
- mvi c,dconio ;Console output bdos call.
- call bdos ;Output the char to the console.
-
- ret
-;
-;
-; outmdm - output a char from E to the modem.
-; the parity bit has been set as necessary.
-; returns nonskip; bc, de, hl preserved.
-outmdm:
-
- in mnprts ;Get the output done flag.
- ani output ;Is it set?
- jz outmdm ;If not, loop until it is.
- mov a,e
- out mnport ;Output it.
- ret
-
-;--------------------------------------------------------------------------
-;
-; get character from modem; return zero if none available.
-; for IOBYT systems, the modem port has already been selected.
-; destroys bc, de, hl.
-inpmdm:
-;Note: modem port should already be selected for mdI. [Toad Hall]
- in mnprts ;Get the port status into A.
- ani input ;See if the input ready bit is on.
- rz ;If not then return.
- in mnport ;If so, get the char.
- ret ; return with character in A
-
-
-;
-; flsmdm - flush comm line.
-; Modem is selected.
-; Currently, just gets characters until none are available.
-
-flsmdm: call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-;-----------------------------------------------------------------------------
-;
-; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
-lptstat:
- xra a ; assume it is ok.. this may not be necessary
- ret
-
-;
-; outlpt - output character in E to printer
-; console is selected.
-; preserves de.
-outlpt:
- push d ; save DE in either case
- call prtflt ; go through printer filter [30]
- ana a ; if A = 0 do nothing,
- jz outlp1 ; [30] if a=0 do nothing
-
- mvi c,lstout
- call bdos ;Char to printer
-outlp1: pop d ; restore saved register pair
- ret
-;------------------------------------------------------------------------------
-;
-; Screen manipulation routines
-; csrpos - move to row B, column C
-;
-; csrpos for terminals that use a leadin sequence followed
-; by (row + 31.) and (column + 31.)
-;
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,h ; get row
- adi (' '-1) ; space is row one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,l ; get column
- adi (' '-1) ; space is column one
- mov e,a
- jmp outcon ; output it and return
-
-;
-; delchr - make delete look like a backspace. Unless delete is a printing
-; character, we just need to print a backspace. (we'll output clrspc
-; afterwards)
-; For Kaypro and Vector General, delete puts a blotch on the screen.
-; For Apple and Osborne 1, delete moves but doesn't print.
-delchr:
-
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the character at the current cursor position
-clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the current line
-clrlin: lxi d,eralin
- jmp prtstr
-
-; erase the whole screen, and go home. preserves b (but not c)
-clrtop: lxi d,erascr
- jmp prtstr
-
-;[2] I see no real saving in having all screens in separate file and
-;therefore have included screen definition here and commented out
-;the link to VDU file
-;
-;
-;Specific definitions for the Model IV screen
-;
-sysver: db 'Tandy Model IV$'
-outlin: db 1aH,cr,lf,' $'
-erascr: db 1AH,'$'
-eralin: db cr,15H,'$'
-curldn: db esc,'=$'
-ttab:
-ta: db 0BH,'$',0,0 ;Cursor up
-tb: db 0AH,'$',0,0 ;Cursor down
-tc: db 0CH,'$',0,0 ;Cursor right
-td: db 08H,'$',0,0 ;Cursor left
-te: db 1AH,'$',0,0 ;Clear display
-tf: db 0FH,'$',0,0 ;Reverse on
-tg: db 0EH,'$',0,0 ;Reverse off
-th: db 1EH,'$',0,0 ;Cursor home
-ti: db 0BH,'$',0,0 ;Reverse linefeed
-tj: db 19H,'$',0,0 ;Clear to end of screen
-tk: db 15H,'$',0,0 ;Clear to end of line
-
-ovlend equ $ ;End of overlay
-
- END
+;CPXTM4.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the system-dependent code and data for various
+; Tandy Model 4 running under Montezuma Micro CPM
+;
+; This has the Family name of CPXTM4.ASM.
+;
+; revision history (last edit first)
+;
+; edit 5, 8-Feb-1991 by Lance Tagliapietra of the University of Wisconsin-
+; Platteville. Corrected error in the VT52 translation table for
+; clearing from the cursor to the end of the line.
+;
+; edit 4, 27 October, 1987 by OBSchou. Massaged into format suitable
+; for overlay version 4.09
+;
+; Edit 3: Sept 5 1987 GDS Transformed code from Genie III to Tandy Model 4
+;
+; Edit 2: Aug 27 1987 GDS Put in code for BREAK and fillited out
+; a lot of unnecessary IF's
+;
+;Edit 1: Nov. 28, 1986 Geof Smith Clinical Research centre Harrow UK.
+
+
+.printx * Assembling for Tandy Model 4*
+;
+drtime EQU 05H ;Default receive time out interval.
+;
+; the basics...
+;
+mnport EQU 0EBH
+mnprts EQU 0EAH
+output EQU 40H
+input EQU 80H
+lctrl EQU 0E8H
+baudpt EQU 0E9H
+z80 EQU TRUE
+brkval EQU 0H
+inout EQU TRUE
+
+defesc EQU 'X'-100O ;The default escape character.
+
+
+;Select initial setting for VT-52 emulation flag.
+
+; default to VT52-EMULATION ON.
+;
+vtval EQU 1
+;
+;
+
+
+
+
+
+
+
+
+
+; Family is the string used in VERSION to say which of several
+; smaller overlay files are used. These are (will be) derived from
+; the huge CP4SYS.ASM file, in which case we will never get here.
+; Just a Dollar, but put a sting in for a family of machines.
+;
+family: db 'CPXTM4.ASM (5) 8-Feb-91$' ; Used for family versions....
+
+
+;
+; System-dependent initialization
+; Called once at program start.
+sysxin:
+;
+ ;Set up 9600 bd, 8bit words, no parity 1stop bit
+
+ mvi a,0EEH ;Get byte for desired baud (9600 = CC) and
+ out baudpt ;and put it out of baud port
+ out lctrl ;latch control port with anything
+ lda pstore ;get parity etc and put it out of
+ out mnprts ;port
+ ret ; return from system-dependent routine
+
+;
+
+
+
+
+
+
+
+
+
+;
+; system-dependent termination processing
+; If we've changed anything, this is our last chance to put it back.
+sysexit:
+ ret
+;
+; system-dependent processing for start of CONNECT command
+;
+syscon:
+ ret
+
+conmsg: ; Messages printed when entering transparent (CONNECT) mode:
+;-------------------------------------------------------------------------------
+; --
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+ ret
+;-------------------------------------------------------------------------------
+; ---
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing all the
+; system-independent escape sequences.
+;
+sysinh:
+ lxi d,inhlps ; we got options...
+ call prtstr ; print them.
+ ret
+
+
+;additional, system-dependent help for transparent mode
+; (two-character escape sequences)
+inhlps:
+
+ db cr,lf,'B Transmit a BREAK'
+
+ db '$' ;[hh] table terminator
+
+;
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:
+; non-skip: sequence has been processed
+; skip: sequence was not recognized
+sysint: ani 137O ; convert lower case to upper, for testing...
+ cpi 'B' ; send break?
+ jz sendbr ; yes, go do it. return nonskip when through.
+
+ jmp rskp ; take skip return - command not recognized.
+
+
+;-------------------------------------------------------------------------------
+sendbr:
+;
+; Ensure that the transmitter has finished sending buffered chars
+sndbr1: in mnprts ; get UART status
+ ani output ; everything sent?
+ jz sndbr1 ; no, wait a bit more
+;
+; Begin sending a break by setting bit in UART command register
+ mvi a,brkval ; SBreak,
+ out lctrl
+ out mnprts
+;
+
+; Wait for 250 milliseconds (using hundredths second delay routine)
+ mvi a,25
+ call delay
+;
+; Resume normal operation by clearing the SendBreak command bit
+ lda pstore ;get parity etc value
+ out lctrl ;latch control port
+ out mnprts ;and set values
+;
+ ret ;done
+
+;
+;
+
+
+
+
+
+
+
+
+
+;
+; sysflt - system-dependent filter
+; called with character in E.
+; if this character should not be printed, return with A = zero.
+; preserves bc, de, hl.
+; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
+sysflt:
+ mov a,e ; get character for testing
+ ret
+
+; mdmflt - modem filter [30]
+; called with character to be sent to modem in E
+; with parity set as appropriate.
+; return with accumulator = 0 do do nothing,
+; <> 0 to send char in E.
+mdmflt: mov a,e
+ ret
+
+
+
+; prtflt - printer filter [30]
+; called with character to be sent to printer in E
+; returns with a = 0 to do nothing
+; a <> 0 to print it.
+;
+; this routine for those printer that automatically insert
+; a lf on cr, or cr for lf. Should this be shifted to
+; the system indep. stuff, in say 4.06?
+prtflt:
+ mov a,e ; [30] get character to test
+ ret
+
+
+;
+
+
+
+
+
+
+
+
+
+
+;
+; system-dependent processing for BYE command.
+; for apmmdm, heath, and lobo, hang up the phone.
+sysbye:
+ ret
+;
+
+
+
+
+
+
+
+
+
+
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; this
+; value is also stored in 'speed'.
+sysspd:
+ ;Set up baud rate 8bit words, no parity 1stop bit
+
+ mov a,e ;get get speed into a
+ out baudpt ;output it as well
+ lda pstore ;get parity etc
+ out lctrl ;do it resetting DLAB at same time
+ out mnprts
+ ret
+
+pstore: db 6CH ;Default value for parity word length and stop bits
+
+spdtbl: db 10h ;17 entries
+ db 03h,'110$', 22H,22H
+ db 04h,'1200$', 77H,77H
+ db 05h,'134.5$', 33H,33H
+ db 03h,'150$', 44H,44H
+ db 04h,'1800$', 88H,88H
+ db 05h,'19200$', 0FFH,0FFH
+ db 04h,'2000$', 99H,99H
+ db 04h,'2400$', 0AAH,0AAH
+ db 03h,'300$', 55H,55H
+ db 04h,'3600$', 0BBH,0BBH
+ db 04h,'4800$', 0CCH,0CCH
+ db 02h,'50$', 00H,00H
+ db 03h,'600$', 66H,66H
+ db 04h,'7200$', 0DDH,0DDH
+ db 02h,'75$', 11H,11H
+ db 04h,'9600$', 0EEH,0EEH
+
+sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
+ db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200 $'
+
+; This is the system-dependent SET PORT command.
+; HL contains the argument from the command table.
+sysprt:
+ ret
+;
+prttbl equ 0 ; SET PORT not supported
+prhtbl equ 0
+
+;
+
+
+
+
+
+
+
+
+
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; For iobyt systems, diddle the I/O byte to select console or comm port;
+; For Decision I, switches Multi I/O board to console or modem serial
+; port. [Toad Hall]
+; For the rest, does nothing.
+; preserves bc, de, hl.
+selmdm:
+ ret
+
+selcon:
+ ret
+;
+
+
+
+
+
+
+
+
+
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+ mvi c,dconio ;Direct console I/O BDOS call.
+ mvi e,0FFH ;Input.
+ call BDOS
+
+ ret
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+
+ mvi c,dconio ;Console output bdos call.
+ call bdos ;Output the char to the console.
+
+ ret
+;
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+outmdm:
+
+ in mnprts ;Get the output done flag.
+ ani output ;Is it set?
+ jz outmdm ;If not, loop until it is.
+ mov a,e
+ out mnport ;Output it.
+ ret
+
+;--------------------------------------------------------------------------
+;
+; get character from modem; return zero if none available.
+; for IOBYT systems, the modem port has already been selected.
+; destroys bc, de, hl.
+inpmdm:
+;Note: modem port should already be selected for mdI. [Toad Hall]
+ in mnprts ;Get the port status into A.
+ ani input ;See if the input ready bit is on.
+ rz ;If not then return.
+ in mnport ;If so, get the char.
+ ret ; return with character in A
+
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+
+flsmdm: call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+;-----------------------------------------------------------------------------
+;
+; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
+lptstat:
+ xra a ; assume it is ok.. this may not be necessary
+ ret
+
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+outlpt:
+ push d ; save DE in either case
+ call prtflt ; go through printer filter [30]
+ ana a ; if A = 0 do nothing,
+ jz outlp1 ; [30] if a=0 do nothing
+
+ mvi c,lstout
+ call bdos ;Char to printer
+outlp1: pop d ; restore saved register pair
+ ret
+;------------------------------------------------------------------------------
+;
+; Screen manipulation routines
+; csrpos - move to row B, column C
+;
+; csrpos for terminals that use a leadin sequence followed
+; by (row + 31.) and (column + 31.)
+;
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; restore coordinates
+ mov a,h ; get row
+ adi (' '-1) ; space is row one
+ mov e,a
+ push h
+ call outcon ; output row
+ pop h
+ mov a,l ; get column
+ adi (' '-1) ; space is column one
+ mov e,a
+ jmp outcon ; output it and return
+
+;
+; delchr - make delete look like a backspace. Unless delete is a printing
+; character, we just need to print a backspace. (we'll output clrspc
+; afterwards)
+; For Kaypro and Vector General, delete puts a blotch on the screen.
+; For Apple and Osborne 1, delete moves but doesn't print.
+delchr:
+
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the character at the current cursor position
+clrspc: mvi e,' '
+ call outcon
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the current line
+clrlin: lxi d,eralin
+ jmp prtstr
+
+; erase the whole screen, and go home. preserves b (but not c)
+clrtop: lxi d,erascr
+ jmp prtstr
+
+;[2] I see no real saving in having all screens in separate file and
+;therefore have included screen definition here and commented out
+;the link to VDU file
+;
+;
+;Specific definitions for the Model IV screen
+;
+sysver: db 'Tandy Model IV$'
+outlin: db 1aH,cr,lf,' $'
+erascr: db 1AH,'$'
+eralin: db cr,15H,'$'
+curldn: db esc,'=$'
+ttab:
+ta: db 0BH,'$',0,0 ;Cursor up
+tb: db 0AH,'$',0,0 ;Cursor down
+tc: db 0CH,'$',0,0 ;Cursor right
+td: db 08H,'$',0,0 ;Cursor left
+te: db 1AH,'$',0,0 ;Clear display
+tf: db 0FH,'$',0,0 ;Reverse on
+tg: db 0EH,'$',0,0 ;Reverse off
+th: db 1EH,'$',0,0 ;Cursor home
+ti: db 0BH,'$',0,0 ;Reverse linefeed
+tj: db 19H,'$',0,0 ;Clear to end of screen
+tk: db 15H,'$',0,0 ;Clear to end of line
+
+ovlend equ $ ;End of overlay
+
+ END
diff --git a/cpxtor.asm b/cpxtor.asm
index 51b653a..9f574ad 100644
--- a/cpxtor.asm
+++ b/cpxtor.asm
@@ -1,1229 +1,1229 @@
-IF NOT lasm
-.printx * CPXTOR.ASM *
-ENDIF ;NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the system dependent part for Torch, Superbrains,
-; PCI2651 (Loughborough 8" Standard CP/M system) and Cifer computers.
-;
-; This is the first attempt to break the huge CPXSYS.ASM file
-; into smaller system dependent files. To start with I will bunch
-; several micros to one class.
-;
-; Please name system dependent files in the form CPXxxx.ASM where
-; xxx is a three letter abbrev. for the system you are adding.
-;
-; revision history:
-;
-;edit 5, 10-Jan-1991 by MF. Removed references to assembly switch ker09.
-; edit 4, 21 July, 1987 by OBSchou. Removed routines no in CPXCOM.ASM
-;
-; edit 3, 8 April, 1987 by OBSchou. Moved the VDU declarations for the
-; Torch, superbrain and Cifer from CPXVDU.ASM. Also added code to
-; see if the MCP/CCCP ROM versions on the Torch is less or grater than
-; 1. Less than 1 => poor screen control. Finally adjusted the
-; positioning of the filename to cope with a user number and drive
-; in the filename field
-;
-;
-; edit 2, 20 March, 1987 by C.J.MILES@UK.AC.UMRCC. Added support for
-; NCR Decision Mate V (2651 USART)
-;
-; edit 1, 22 April, 1986, OBSchou. Start on splitting off individual
-; systems from this huge file. It is done using the LINK facility
-; LASM. We link to a collection of systems under CPXxxx.ASM.
-; I have started with the systems I know, the Torch, Cifer and
-; pci2651. These will all be held under CPXTOR.ASM
-;
-;
-; Keep module name, edit number, and last revision date in memory.
-family: db 'CPXTOR.ASM (5) 10-Jan-1991 $'
-;
-; Assembly time message to let me know I'm building the right version.
-; LASM generates an 'S' error along with the message, which is messy, but
-; better than trying to put everything inside a IF m80 OR mac80 conditional,
-; because LASM doesn't like nested IF's, either.
-
-IF ncrdmv
-.printx * Assembling KERMIT-80 for the N.C.R. Decision Mate V *
-ENDIF
-
-IF brain
-.printx * Assembling KERMIT-80 for the Intertec Superbrain *
-ENDIF
-
-IF brainm
-.printx * With main port selected
-ENDIF
-IF braina
-.printx * With Aux port
-ENDIF
-
-IF pci2651 ;
-.printx * assembling Kermit-80 for 2651 PCI as comms device *
-ENDIF
-
-IF torch
-.printx * Assembling Kermit-80 for Torch Unicorn 5 *
-ENDIF
-; *******This should be in the original CPXSYS.ASM file
-;
-;=========================================================================
-; I/O Byte assignments (2-bit fields for 4 devices at loc 3)
-;
-;bits 6+7 LIST field
-; 0 LIST is Teletype device (TTY:)
-; 1 LIST is CRT device (CRT:)
-; 2 LIST is Lineprinter (LPT:)
-; 3 LIST is user defined (UL1:)
-;
-;bits 4+5 PUNCH field
-; 0 PUNCH is Teletype device (TTY:)
-; 1 PUNCH is high speed punch (PUN:)
-; 2 PUNCH is user defined #1 (UP1:)
-; 3 PUNCH is user defined #2 (UP2:)
-;
-;bits 2+3 READER field
-; 0 READER is Teletype device (TTY:)
-; 1 READER is high speed reader (RDR:)
-; 2 READER is user defined #1 (UR1:)
-; 3 READER is user defined #2 (UR2:)
-;
-;bits 0+1 CONSOLE field
-; 0 CONSOLE is console printer (TTY:)
-; 1 CONSOLE is CRT device (CRT:)
-; 2 CONSOLE is in Batch-mode (BAT:);READER = Input,
-; LIST = Output
-; 3 CONSOLE is user defined (UC1:)
-;
-;=========================================================================
-
-iobyte EQU 03H ;Location of I/O byte
-
-
-; [13] modifed to use either main or aux port. Should really
-; be selected by set port, but this is urgent, so no frills
-IF brain
-baudst EQU 60H ;
-baudrt EQU 0EF00H ;Memory location where baud rates are stored.
-output EQU 01H ;Transmitter ready
-input EQU 02H ;Input data available
-TxEmpty EQU 04h ;Transmitter empty
-z80 SET TRUE ;I don't know...
-ENDIF;brain
-IF brainm ; Superbrain and main ports
-mnport EQU 58H ;Modem data port
-mnprts EQU 59H ;Modem status port
-ENDIF ;brainm
-IF braina ; Superbrain and aux port
-mnport EQU 40H ;Modem data port
-mnprts EQU 41H ;Modem status port
-ENDIF ;braina [13]
-
-IF ncrdmv
-iobase equ 70h ; base address of PCI device
-modrx equ 70h ; Rx data port
-mnprts equ 71h ; status port
-mnmodr equ 72h ; mode register read
-mncmdr equ 73h ; command register read
-modtx equ 74h ; Tx data port
-mnmodw equ 76h ; mode register write
-mncmdw equ 77h ; command register write
-txrdy equ 1
-output equ txrdy
-rxrdy equ 2
-input equ rxrdy
-baudini equ 0ah ; initial baud to 2400
-z80 SET true
-cpuspd SET 40
-ENDIF
-
-IF pci2651 ;[28]
-iobase equ 04h ; base address of PCI device
-mnport equ iobase ; rx and tx data ports
-mnprts equ iobase+1 ; status port
-mnmode equ iobase+2 ; mode port
-mncmd equ iobase+3 ; PCI command port
-
-txrdy equ 1 ; tx ready bit set if free
-output equ txrdy
-rxrdy equ 2 ; RX ready bit
-input equ rxrdy
-baudini equ 7 ; 7 => 1200 baud by default
-z80 SET true ; For Ithica intersystems it is
-cpuspd SET 40 ; and running at four megs
-ENDIF ;[28]
-
-IF torch ;[13]
-z80 SET TRUE
-; [32] baudini removed as now read current baud rate
-; settings from base processor.
-
-;baudini equ 707h ; Initial Baud rate = 1200 baud
- ; Entry to be of form x0xh where x is
- ; the value x in the FX 7,x and FX 8,x
- ; funtion calls. 4= 1200 baud, 7 = 9600
- ; 2 = 300 baud.
-ENDIF
-
-IF brain OR torch
-defesc EQU ']'-100O ;The default escape character.
-ENDIF;brain OR torch
-
-; If none of the above, default to VT52-EMULATION ON.
-IF NOT crt
-vtval EQU 1
-ENDIF;NOT crt
-
-
-sysxin:
-
-IF brainm ;[25]
- lda baudrt ; fetch current baud rate
- ani 0F0H ; extract left nibble
- rrc ; shift right 4 places
- rrc
- rrc
- rrc
- sta speed ; store as comm port speed
- sta speed+1 ; (16 bits, to match speed table entries)
-ENDIF;brainm
-
-IF braina ;[25]
- lda baudrt ; fetch current baud rate
- ani 00FH ; extract right nibble
- sta speed ; store as comm port speed
- sta speed+1 ; (16 bits, to match speed table entries)
-ENDIF;braina
-
-IF torch ; [13] [32]
- push h
- mvi a,0f2h ; nick code from BBC initialisation
- lxi h,0ff00h
- call osbyte ; Read current speed setting
- mov a,l
- ani 7
- xri 7 ; Store as two's complement
- inr a
- sta speed
- sta speed+1
- mov e,a
- call sysspd ; Make sure they are both the same!
- mvi a,15 ; Flush all internal buffers [32]
- mvi l,0
-; call osbyte
- mvi a,3
- lxi h,0100h ; *FX 3,0,1 Enable RS423
- call osbyte
- mvi a,2 ; Select keyboard, Enable RS423 input
- mvi l,2
- call osbyte
- mvi a,5 ; Select serial printer [32]
- mvi l,2
- call osbyte ; [30]
- mvi a,6 ; Must be able to send LF [30]
- mvi l,0
- call osbyte ; [30]
- mvi a,202 ; FX 202,255 set lower case on
- mvi l,255
- call osbyte
- pop h
-
-; Now see what version of MCP CCP roms. Assume >1, else copy a few of the
-; older Torch VDU declares over the new ones.
-;
-; lda 0ffffh ; Address 0ffffh has single byte Version no.
-; push psw ; save for a rainy day
-; ani 0F0h ; get ms digit of MCP version
-; rra ; move right 4 places
-; rra
-; rra
-; rra
-; ani 0fh
-; adi 30h ; make it a number
-; sta mcpver
-; pop psw ; its raining...
-; push psw ; ... its pouring...
-; ani 0fh ; get ls digit
-; adi 30h ; make it ascii number
-; sta mcpver+2
-; pop psw ; restore psw
-; cpi 10h ; Version 1.00 or less?
-; jp init2 ; yes, so skip next bit
-; lxi h,ooutli ; from old string table
-; lxi d,ttab ; to new ttab
-; lxi b,60 ; 60 bytes to move
-; call mover
-init2:
-
-IF ncrdmv
- mvi a,00 ; clear out command register
- out mncmdw
- mvi a,4eh ; 1 stop bit, 8 data bits, / by 16 counter
- out mnmodw
- mvi a,70h+baudini ; baud rate and select internal rate gen.
- out mnmodw
- mvi a,27h ; enable tx and rx, RTS and DTR low
- out mncmdw
-ENDIF ; ncrdmv
-
-IF pci2651 ;[28]
- in mncmd ; clearw command reg counter
- mvi a,4eh ; 1 stop bit, 8 data bits, / by 16 counter
- out mnmode
- mvi a,30h+baudini ; baud rate and select internal rate gen.
- out mnmode
- mvi a,27h ; enable tx and rx, RTS and DTR low
- out mncmd
-ENDIF ; pci2651 [28]
-
- ret ; return from system-dependent routine
-
-;
-;
-; system-dependent termination processing
-; If we've changed anything, this is our last chance to put it back.
-sysexit:
- ret
-
-;
-; system-dependent processing for start of CONNECT command
-;
-syscon:
- ret
-
-conmsg: ; Messages printed when entering transparent (CONNECT) mode:
-;
-;
-; syscls - system-dependent close routine
-; called when exiting transparent session.
-;
-syscls:
- ret
-;
-;
-; sysinh - help for system-dependent special functions.
-; called in response to <escape>?, after listing all the
-; system-independent escape sequences.
-;
-sysinh:
-IF torch OR brain OR pci2651 OR ncrdmv
- lxi d,inhlps ; we got options...
- call prtstr ; print them.
-ENDIF;torch OR brain OR pci2651 OR ncrdmv
-
- ret
-
-
-;additional, system-dependent help for transparent mode
-; (two-character escape sequences)
-inhlps:
-
-; [16] [18] have added super brain and Torch to the list of Breaking machines.
-
-IF pci2651 OR brain OR torch OR ncrdmv
- db cr,lf,'B Transmit a BREAK'
-ENDIF ;pci2651 OR brain OR torch OR ncrdmv
-
-IF torch ; added this simply to debug the escape cokebottle D for the apple
- db cr,lf,'D Disconnect the modem (Test purposes only)'
-ENDIF;Torch
-
- db '$' ;[hh] table terminator
-
-;
-; sysint - system dependent special functions
-; called when transparent escape character has been typed;
-; the second character of the sequence is in A (and in B).
-; returns:
-; non-skip: sequence has been processed
-; skip: sequence was not recognized
-sysint: ani 137O ; convert lower case to upper, for testing...
-
-; [19] have added superbrain and torch to the list
-
-IF brain OR pci2651 OR torch OR ncrdmv
- cpi 'B' ; send break?
- jz sendbr ; yes, go do it. return nonskip when through.
-ENDIF ;brain OR pci2651 OR torch OR ncrdmv
-
-IF Torch; added bit for doing a D...
- cpi 'D' ;drop the line...
- jz dropln
-ENDIF ;torch
-
- jmp rskp ; take skip return - command not recognized.
-
-
-IF torch
-dropln: lxi d,dropm ; tell user line is dropped..
- call prtstr
- xra a ; destroy A
- ret
-dropm: db bell,cr,lf,'Testing line dropped ',cr,lf,bell
- db '$'
-ENDIF ;torch and dropping them there lines..
-
-;
-
-IF brain
-sendbr:
-;
-; Ensure that the transmitter has finished sending buffered chars
-sndbr1: in mnprts ; get UART status
- ani TxEmpty ; everything sent?
- jz sndbr1 ; no, wait a bit more
-;
-; Begin sending a break by setting bit in UART command register
- mvi a,3Fh ; Set TxEna, DTR, RxEna, SBreak, ErrRst, RTS
- out mnprts
-;
-; Wait for 250 milliseconds (using hundredths second delay routine)
- mvi a,25
- call delay
-;
-; Resume normal operation by clearing the SendBreak command bit
- mvi a,37h ;Set TxEna, DTR, RxEna, ErrRst, RTS
- out mnprts
-;
- ret ;done
-ENDIF;brain
-
-IF torch ; [18] [27] [30] [32]
-; Send a break.
-;
-; [30] Dumping of 6502 code not yet used, but may be for later versions of
-; the Torch CCCP Rom in the BBC. This works, so I leave it for now.
-
-sendbr:
- push h ;save for a monsoon
- mvi a,0e8h
- lxi h,0 ; turn interrupts off
- call osbyte
- push h
-;
- mvi a,9ch ; OSBYTE call 9c is read/write 6850 cntl prt
- lxi h,0077h ; H = 6502 Y reg, L = 6502 X reg
- call osbyte ; returned new val. = (old value AND Y)XOR X
- push h ; save it for return
-;
- mvi a,30
- call delay ; do a delay
-;
-; now clear rx register
-;
- mvi a,96h ; do a read sheila address 08h
- mvi l,8
- mvi h,0
- call osbyte ; read sheila 08h = 6850 rx reg
-;
-; restore 6850 regs...
-;
- pop h ; restore previous cntl reg
- ; old x reg in l, so leave it there
-; mov l,h
- mvi h,0
- mvi a,9ch ; write previous value to 6850
- call osbyte
-;
-; and Beebs interrupt mask
-;
- pop h ; get interrupt mask
- ; Once again, old X in L so leave it alone
-; mov l,h
- mvi h,0
- mvi a,0e8h
- call osbyte ; restore interrupts mask
-;
- pop h
- ret ; its raining again, so exit
-ENDIF ; torch [18] [32]
-
-IF ncrdmv
-sendbr: in mnprts ; get status
- ani 04h ; make sure shift register is empty
- jz sendbr
-
- mvi a,2fh ; force a break
- out mncmdw
- mvi a,100 ; set delay period
- call delay
- mvi a,27h ; restore command register
- out mncmdw
- ret
-ENDIF ; ncrdmv
-
-IF pci2651 ;[28]
-sendbr: in mnprts
- ani 04h ; make sure shift reg is clear
- jz sendbr
-
- mvi a,2fh ; set foe a break
- out mncmd
- mvi a,100 ; wait a bit
- call delay
- mvi a,27h ; restore mode
- out mncmd
- ret
-ENDIF ;pci2651 [28]
-
-;
-; sysflt - system-dependent filter
-; called with character in E.
-; if this character should not be printed, return with A = zero.
-; preserves bc, de, hl.
-; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-sysflt:
- mov a,e ; get character for testing
- ret
-
-; mdmflt - modem filter [30]
-; called with character to be sent to printer in E
-; with parity set as appropriate.
-; return with accumulator = 0 do do nothing,
-; <> 0 to send char in E.
-mdmflt:
- mov a,e ;[30] get character to test
-IF torch ;[30] map del to bs,space,bs
- ani 7fh ; strip parity
- cpi 7fh ; is it the delete character
- rnz ; no, then a <> 0 so print it
- mvi e,bs ; else load a backspace
- call outmdm ; little recursion...
- mvi e,' ' ; then a space
- call outmdm ; backspace, space, now another...
- mvi e,bs ; backspace
- call outmdm ;
- xra a ; clear a => on return do nowt.
-ENDIF ;torch [30]
- ret
-
-
-
-; prtflt - printer filter [30]
-; called with character to be sent to printer in E
-; returns with a = 0 to do nothing
-; a <> 0 to print it.
-;
-; this routine for those printer that automatically insert
-; a lf on cr, or cr for lf. Should this be shifted to
-; the system indep. stuff, in say 4.06?
-prtflt:
- mov a,e ; [30] get character to test
-IF torch ; strip out lf from printer stream
- ani 7fh ; make sure it is parity less
- cpi lf ; is it a line feed?
- rnz ; no, print it
-; xra a ; yes, don't.
-
-ENDIF ;torch [30]
- ret
-
-
-;
-;
-; system-dependent processing for BYE command.
-; for apmmdm, heath, and lobo, hang up the phone.
-sysbye:
- ret
-;
-; This is the system-dependent command to change the baud rate.
-; DE contains the two-byte value from the baud rate table; this
-; value is also stored in 'speed'.
-sysspd:
-
-; Set the speed for the Brain (Main Port)
-IF brainm ;[25]
- lda baudrt ;Get the present baud rates.
- ani 0fH ;turn off the left
- mov d,a ;Set it aside.
- mov a,e ;Get the new baud rate.
- rlc ;Shift left 4 places.
- rlc
- rlc
- rlc
- ora d ; combine with the old baud rate
- sta baudrt ;Store the new baud rates.
- out baudst ;Set the baud rates.
- ret
-ENDIF;brainm
-
-; Set the speed for the Brain (Aux Port)
-IF braina ;[25]
- lda baudrt ;Get the present baud rates.
- ani 0f0H ;turn off the right
- ora e ; combine with the new baud rate
- sta baudrt ;Store the new baud rates.
- out baudst ;Set the baud rates.
- ret
-ENDIF;braina
-
-If torch ; Set speed for Torch [14] [32]
- mvi a,7 ; Osbyte call to set rx rate
- mov l,e
- call osbyte ;
- mvi a,8 ; set up for tx rate to be set
- mov l,e
- call osbyte
- ret ; and now, all rates should be different
-
-ENDIF ;torch [14] [32]
-
-IF ncrdmv ; Set baud rate for NCR Decision Mate V
- mvi a,00 ; clear command register
- out mncmdw
- mvi a,4eh ; set for 1 stop, 8 data bits
- out mnmodw ; save in mode 1 port
- mvi a,70h ; set bits for rate etc..
- add e ; add baud rate (bits 0 - 3)
- out mnmodw ; set mode port 2
- mvi a,27h ; set tx/rx ready, RTS CTS active
- out mncmdw
- ret
-ENDIF ; ncrdmv
-
-
-IF pci2651 ; Set baud for PCI [28]
- in mncmd ; Clear register counter
- mvi a,4eh ; set for 1 stop, 8 data bits
- out mnmode ; save in mode 1 port
- mvi a,30h ; set bits for rate etc..
- add e ; add baud rate (bits 0 - 3)
- out mnmode ; set mode port 2
- mvi a,27h ; set tx/rx ready, RTS CTS active
- out mncmd
- ret
-ENDIF ;pci2651 [28]
-
-;
-; Speed tables
-; (Note that speed tables MUST be in alphabetical order for later
-; lookup procedures, and must begin with a value showing the total
-; number of entries. The speed help tables are just for us poor
-; humans.
-
-; db string length,string,divisor (2 identical bytes or 1 word)
-; [Toad Hall]
-
-IF brain OR pci2651 OR ncrdmv
-spdtbl: db 10h ;16 entries
- db 03h,'110$', 02h,02h
- db 04h,'1200$', 07h,07h
- db 05h,'134.5$', 03h,03h
- db 03h,'150$', 04h,04h
- db 04h,'1800$', 08h,08h
- db 05h,'19200$', 0fh,0fh
- db 04h,'2000$', 09h,09h
- db 04h,'2400$', 0ah,0ah
- db 03h,'300$', 05h,05h
- db 04h,'3600$', 0bh,0bh
- db 04h,'4800$', 0ch,0ch
- db 02h,'50$', 00h,00h
- db 03h,'600$', 06h,06h
- db 04h,'7200$', 0dh,0dh
- db 02h,'75$', 01h,01h
- db 04h,'9600$', 0eh,0eh
-
-sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
- db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'
-ENDIF;brain OR pci2651 OR ncrdmv
-
-IF torch ;[17]
-spdtbl: db 8 ; 8 entries
- db 4,'1200$', 4,4
- db 3,'150$', 2,2
- db 5,'19200$', 8,8
- db 4,'2400$', 5,5
- db 3,'300$', 3,3
- db 4,'4800$', 6,6
- db 2,'75$', 1,1
- db 4,'9600$', 7,7
-
-sphtbl: db cr,lf,' 75 150 300 1200 2400 4800 9600 19200$'
-ENDIF;torch [17]
-
-
-; The following conditionals were once a huge if not statement. There
-; wasn't enough room to add the lobo to the list, so it had to be broken
-; into 2, which you can't do with an if not. I redid it as two ifs and
-; applied them to those that wouldn't set baud. [Hal Hostetler]
-;
-; This is the system-dependent SET PORT command.
-; HL contains the argument from the command table.
-sysprt:
-IF iobyt
- mov a,m ;Get the I/O byte
- sta prtiob ;Save the desired IO byte for this port
- inx h ;Point at next entry
- mov a,m ;Get the output function
- sta prtfun ;Save it
-ENDIF;iobyt
-
- ret
-;
-;
-;
-; Port tables for GENERIC CPM 2.2
-IF gener
-; help text
-prhtbl: db cr,lf,'CRT device'
- db cr,lf,'PTR device'
- db cr,lf,'TTY device'
- db cr,lf,'UC1 device'
- db cr,lf,'UR1 device'
- db cr,lf,'UR2 device$'
-
-; command table
-prttbl: db 06H ;Six devices to choose from
- db 03H,'CRT$'
- dw crtptb
- db 03H,'PTR$'
- dw ptrptb
- db 03H,'TTY$'
- dw ttyptb
- db 03H,'UC1$'
- dw uc1ptb
- db 03H,'UR1$'
- dw ur1ptb
- db 03H,'UR2$'
- dw ur2ptb
-
-; port entry table
-; table entries are:
-; db iobyte-value, BDOS output function, reserved
-crtptb: db crtio,conout,0
-ptrptb: db ptrio,punout,0
-ttyptb: db ttyio,conout,0
-uc1ptb: db uc1io,conout,0
-ur1ptb: db ur1io,punout,0
-ur2ptb: db ur2io,punout,0
-ENDIF;gener
-
-;
-;
-IF iobyt
-prtfun: db punout ;Function to use for output to comm port
-prtiob: db batio ;I/O byte to use for communicating
-coniob: db defio ;I/O byte to use for console
-ENDIF;iobyt
-
-IF NOT iobyt
-prttbl equ 0 ; SET PORT is not supported
-prhtbl equ 0
-ENDIF;NOT iobyt
-;
-;
-; selmdm - select modem port
-; selcon - select console port
-; selmdm is called before using inpmdm or outmdm;
-; selcon is called before using inpcon or outcon.
-; For iobyt systems, diddle the I/O byte to select console or comm port;
-; For Decision I, switches Multi I/O board to console or modem serial
-; port. [Toad Hall]
-; For the rest, does nothing.
-; preserves bc, de, hl.
-selmdm:
-IF iobyt
- lda prtiob ;Set up for output to go to the comm port
- sta iobyte ;Switch byte directly
-ENDIF;iobyt
- ret
-
-selcon:
-IF iobyt
- lda coniob ;Set up for output to go to the console port
- sta iobyte ;Switch directly
-ENDIF;iobyt
-
- ret
-;
-; Get character from console, or return zero.
-; result is returned in A. destroys bc, de, hl.
-;
-inpcon:
-IF NOT iobyt
- mvi c,dconio ;Direct console I/O BDOS call.
- mvi e,0FFH ;Input.
- call BDOS
-ENDIF;NOT iobyt
-
-IF iobyt
- call bconst ;Get the status
- ora a ;Anything there?
- rz ;No, forget it
- call bconin ;Yes, get the character
-ENDIF;iobyt
- ret
-;
-;
-; Output character in E to the console.
-; destroys bc, de, hl
-;
-outcon:
-
-IF NOT iobyt
- mvi c,dconio ;Console output bdos call.
- call bdos ;Output the char to the console.
-ENDIF;NOT iobyt
-
-IF iobyt
- mov c,e ;Character
- call bcnout ;to Console
-ENDIF;iobyt
- ret
-;
-;
-; outmdm - output a char from E to the modem.
-; the parity bit has been set as necessary.
-; returns nonskip; bc, de, hl preserved.
-outmdm:
-IF inout AND NOT ncrdmv
- in mnprts ;Get the output done flag.
- ani output ;Is it set?
- jz outmdm ;If not, loop until it is.
- mov a,e
- out mnport ;Output it.
- ret
-ENDIF;inout AND NOT ncrdmv
-
-IF inout AND ncrdmv
- in mnprts ;Get the output done flag
- ani output ;Set ?
- jz outmdm ;Loop until it is
- mov a,e
- out modtx ;output char
- ret
-ENDIF;inout AND ncrdmv
-
-IF iobyt
-;**** Note that we enter from outpkt with the I/O byte already set up for
-; output to go to the comm port
- push h
- push b
- lda prtfun ;Get the output function
- mov c,a ;Into C
- call bdos ;And output the character
- pop b
- pop h
- ret
-ENDIF;iobyt
-
-
-IF torch ; [32] [13] Torch stuff. Requires some bit bashing
- ; via the BBC host computer (io computer)
- ; see also decription of osbyte later on
-outdat:
- lda prinuse ; get the printer in use flag
- ana a ; if set, then must use traditional osbyte,
- jnz outda2 ; else...
- push b
- push h ; Preserve registers [32]
- call tx
- db 1 ; MCP send to printer command
- mov c,e ; Byte to send is in E [32]
- call txbyte
- pop h
- pop b
- ret
-
-outda2: ; Preserve registers [32]
- push h
- mvi a,138 ; Osbyte insert byte into buffer
- mvi l,2
- mov h,e ; get the byte to be sent s-l-o-w-l-y
- call osbyte
- pop h ; Restore registers and exit
- ret
-
-ENDIF ;[13]
-
-;
-;
-; get character from modem; return zero if none available.
-; for IOBYT systems, the modem port has already been selected.
-; destroys bc, de, hl.
-inpmdm:
-IF iobyt
- call bconst ;Is Char at COMM-Port?
- ora a ;something there?
- rz ; return if nothing there
- call bconin ; data present. read data.
-ENDIF;iobyt
-
-IF inout AND NOT ncrdmv
-;Note: modem port should already be selected for mdI. [Toad Hall]
- in mnprts ;Get the port status into A.
- ani input ;See if the input ready bit is on.
- rz ;If not then return.
- in mnport ;If so, get the char.
-ENDIF;inout AND NOT ncrdmv
-
-IF inout AND ncrdmv
- in mnprts ;Get input port status
- ani input ;Mask input RDY bit
- rz ;return if no char
- in modrx ;get the char
-ENDIF;inout AND ncrdmv
-IF torch ; [32] [13] torch input
-indat:
- push h
- mvi a,128
- lxi h,0fffeh ; Read buffer status
- call osbyte
- mov a,h ; HL has number of characters
- ora l ; in the buffer
- jz indatq ; None, so skip fetch
- mvi a,145 ; Get character from input buffer [32]
- lxi h,1
- call osbyte ; Result returned in 'Y', rather H
- mov a,h
-indatq:
- pop h
- ani 7fh
- ret ; rx data in A
-ENDIF ;torch [13] [32]
-
-ret ; return with character in A
-
-
-;
-; flsmdm - flush comm line.
-; Modem is selected.
-; Currently, just gets characters until none are available.
-
-flsmdm: call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-
-
-;
-;
-; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
-lptstat:
-IF torch
- mvi a,80h ; read chars remaining in printer buffer
- mvi l,252 ; do osbyte 80H, X=252 (printer buffer)
- mvi h,0ffh
- call osbyte
- mov a,h
- cpi 10 ; 10 characters left?
- mvi a,0 ; if pos, yes r better
- rp
- mvi a,0ffh
- ret
-ENDIF ;torch
-
-IF torch
- mvi a,5 ; got to select the real printer (par. port)
- mvi l,1 ; ie FX 5,1
- call osbyte
-ENDIF ;torch
-
-IF iobyte ;[33]
- call bprtst ; get status
-ENDIF ;iobyte[33]
-
-IF torch
- push psw
- mvi a,5 ; restore serial line = printer
- mvi l,2 ; ie FX 5,2
- call osbyte
- pop psw ; return with code in a
-ENDIF ;torch
-
-
-IF NOT iobyte ;[33]
- xra a ; assume it is ok.. this may not be necessary
-ENDIF ;iobyte [33]
- ret
-;
-;
-; outlpt - output character in E to printer
-; console is selected.
-; preserves de.
-outlpt:
- push d ; save DE in either case
- call prtflt ; go through printer filter [30]
- ana a ; if A = 0 do nothing,
- jz outlp1 ; [30] if a=0 do nothing
-
-IF torch ;[30] Must set printer routed to par port
- mvi a,5 ; fx 5,1 (parallel port selected for printer)
- mvi l,1 ; Modified for new osbyte form [32]
- call osbyte
-ENDIF ;torch [30]
-
-IF NOT iobyt
- mvi c,lstout
- call bdos ;Char to printer
-ENDIF;NOT iobyt
-IF iobyt
- mov c,e
- call blsout
-ENDIF;iobyt
-IF torch ; re-route printer to serial port => faster tx bytes to line [30]
- mvi a,5 ; Modified for new Osbyte form [32]
- mvi l,2 ;fx 5,2
- call osbyte
- mvi a,6
- mvi l,0 ;fx 6,0
- call osbyte
-ENDIF ;torch [30]
-
-outlp1: pop d ; restore saved register pair
- ret
-;
-;
-; Screen manipulation routines
-; csrpos - move to row B, column C
-;
-; csrpos for terminals that use a leadin sequence followed
-; by (row + 31.) and (column + 31.)
-;
-IF brain
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,h ; get row
- adi (' '-1) ; space is row one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,l ; get column
- adi (' '-1) ; space is column one
- mov e,a
- jmp outcon ; output it and return
-ENDIF;brain
-;
-;
-IF torch
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,l ; [obs] get column
- adi 0ffh ; NULL is column one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,h ; [obs] get row
- adi 0ffh ; NULL (ie decrement) is row one
- mov e,a
- jmp outcon ; output it and return
-ENDIF;torch
-;
-;
-; delchr - make delete look like a backspace. Unless delete is a printing
-; character, we just need to print a backspace. (we'll output clrspc
-; afterwards)
-; For Kaypro and Vector General, delete puts a blotch on the screen.
-; For Apple and Osborne 1, delete moves but doesn't print.
-delchr:
-
-
-IF NOT torch ;[22]
- mvi e,bs ;get a backspace
- jmp outcon
-ENDIF;NOT torch
-
-; erase the character at the current cursor position
-clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the current line
-clrlin: lxi d,eralin
- jmp prtstr
-
-; erase the whole screen, and go home. preserves b (but not c)
-clrtop: lxi d,erascr
- jmp prtstr
-
-
-IF torch ;[13]
-;
-; OSBYTE call from Torch to BBC Base Processor.
-;
-; A register has osbyte type
-; H register has equivalent Y register of 6502
-; L register has equivalent X register of 6502
-;
-; Results (X and Y) are returned in HL respectively
-;
-;
-
-usrimm equ 0ffc0h ; MCP user function [32]
-tx equ 0ffc3h ; tx routine to talk to base board proc.
-rx equ 0ffc6h ; rx ditto
-txbyte equ 0ffc9h ; send C to base processor [32]
-
-osbyte: ; Osbyte rewritten [32]
- push b ; Keep these
- mov b,a ; Local copy - use in a moment
- call usrimm ; MCP osbyte function
- db 15
- mov c,b ; Osbyte function
- call txbyte
- mov c,l ; 6502 X register
- call txbyte
- mov c,h ; 6502 Y register
- call txbyte
- call rx ; fetch results
- mov l,a ; X returned
- sta xx ; save just in case...
- call rx
- mov h,a ; Y returned
- sta yy
- mov a,b ; return A as called
- pop b
- ret
-
-xx: db 0
-yy: db 0 ; temporary space
-
-prinuse:db 0 ; 0=> fast tx, <>0 => slow tx to serial pt. [30]
-
-ENDIF ;torch [13]
-
-IF pci2651 ; whatever version
-sysver: db 'Ithaca Intersystems S100$'
-ENDIF ;pci2651
-
-IF ncrdmv ; whatever version
-sysver: db 'NCR DecisionMate V$'
-ENDIF ;ncrdmv
-
-IF torch ; whatever version
-ttytyp:
-sysver: db 'Torch Unicorn 5 '
- db '$' ; stop here for now, otherwise say..
- db ' MCP version '
- db '1.00 $' ; or whatever...
-ENDIF ;torch
-
-; Assume MCP - CCCP ROMS greater than 1
-;mcpver: db 'x.x $'
-;outlin: db esc,'*',cr,lf,tab,'$'
-;eralin: db cr,esc,'&$' ;Clear to end of line.
-;erascr: db esc,'*$' ;Clear screen and go home.
-;curldn: db esc,'=$' ;Cursor lead-in
-;ttab: ;Table start location.
-;ta:
- db esc,'!$',0 ;Cursor up.
-;tb: db 0ah,'$',0,0 ;Cursor down.
-;tc: db esc,'+$',0 ;Cursor right.
-;td: db 08h,'$',0,0 ;Cursor left.
-;te: db esc,'*$',0 ;Clear screen and home cursor
-;tf: db '$',0,0,0 ;(can't) Enter Graphics mode
-;tg: db '$',0,0,0 ;(can't) Exit Graphics mode
-;th: db esc,'>$',0 ;Cursor home.
-;ti: db '$',0,0,0 ;(Can't) reverse linefeed
-;tj: db esc,'%$',0 ; Clear to end of screen
-;tk: db esc,'&$',0 ; Clear to end of line.
-
-
-;Older message for MCP - CCCP verstion less than 1
-;ooutli: db 0ch,cr,lf,tab,tab,'$';
-;oerali: db '$',0,0,0 ;Clear to end of line.
-;oerasc: db 0ch,'$',0 ;Clear screen and go home.
-;ocurld: db 1fh,'$',0 ;Cursor lead-in
-;ottab: ;Table start location.
-; db 0bh,'$',0,0 ;Cursor up.
-; db 0ah,'$',0,0 ;Cursor down.
-; db 09h,'$',0,0 ;Cursor right.
-; db 08h,'$',0,0 ;Cursor left.
-; db 0ch,'$',0,0 ;Clear screen and home cursor
-; db '$',0,0,0 ;(can't) Enter Graphics mode
-; db '$',0,0,0 ;(can't) Exit Graphics mode
-; db 1eh,'$',0,0 ;Cursor home.
-; db 0bh,'$',0,0 ;reverse linfeed
-; db '$',0,0,0 ;(Can't) Clear to end of screen
-; db '$',0,0,0 ;(Can't) Clear to end of line.
-;
-;Specials
-;spac15: db ' '
-; db bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,'$';
-;spac80: db cr
-; db ' '
-; db ' '
-; db bs,cr,'$' ;80 spaces, bs and then back to line start
-;
-
-IF torch ; Should be IF ker08 AND torch...
- db '$' ; to terminate the ID string
-outlin: db 0ch,cr,lf,tab,tab,'$'
-eralin: db '$',0,0,0 ;Clear to end of line.
-erascr: db 0ch,'$',0 ;Clear screen and go home.
-curldn: db 1fh,'$',0 ;Cursor lead-in
-ttab: ;Table start location.
-ta: db 0bh,'$',0,0 ;Cursor up.
-tb: db 0ah,'$',0,0 ;Cursor down.
-tc: db 09h,'$',0,0 ;Cursor right.
-td: db 08h,'$',0,0 ;Cursor left.
-te: db 0ch,'$',0,0 ;Clear screen and home cursor
-tf: db '$',0,0,0 ;(can't) Enter Graphics mode
-tg: db '$',0,0,0 ;(can't) Exit Graphics mode
-th: db 1eh,'$',0,0 ;Cursor home.
-ti: db 0bh,'$',0,0 ;reverse linfeed
-tj: db '$',0,0,0 ;(Can't) Clear to end of screen
-tk: db '$',0,0,0 ;(Can't) Clear to end of line.
-
-;Specials
-spac15: db ' '
- db bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,'$';
-spac80: db cr
- db ' '
- db ' '
- db bs,cr,'$' ;80 spaces, bs and then back to line start
-
-ENDIF;ker08 AND torch [13]
-
-IF brain
-sysver: db 'Intertec SuperBrain$'
-outlin: db ('A'-100O),esc,'~k',cr,lf,tab,tab,'$'
-erascr: db ('A'-100O),esc,'~k$' ;Clear screen and go home.
-eralin: db cr,esc,'~K$' ;Clear line.
-curldn: db esc,'Y$' ; leadin for cursor positioning
-ttab: ;Table start location.
-ta: db ('K'-100O),'$',0,0 ;Cursor up.
-tb: db 12O,'$',0,0 ;Cursor down.
-tc: db ('F'-100O),'$',0,0 ;Cursor right.
-td: db '$',0,0,0 ;(can't) Cursor left
-te: db '$',0,0,0 ;(can't) Clear display
-tf: db '$',0,0,0 ;(can't) Enter graphics mode
-tg: db '$',0,0,0 ;(can't) Exit graphics mode
-th: db ('A'-100O),'$',0,0 ;Cursor home.
-ti: db ('K'-100O),'$',0,0 ;Reverse linefeed.
-tj: db esc,'~k$',0 ;Clear to end of screen.
-tk: db esc,'~K$',0 ;Clear to end of line.
-ENDIF;brain
-
-IF lasm and not termin ; we dont want CPXVDU
-ovlend equ $ ;Overlay end - start buffer
- end
-ENDIF ;lasm and not termin
-
-IF lasm; we want a terminal
-LINK CPXVDU.ASM
-ENDIF ;lasm
-
+IF NOT lasm
+.printx * CPXTOR.ASM *
+ENDIF ;NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the system dependent part for Torch, Superbrains,
+; PCI2651 (Loughborough 8" Standard CP/M system) and Cifer computers.
+;
+; This is the first attempt to break the huge CPXSYS.ASM file
+; into smaller system dependent files. To start with I will bunch
+; several micros to one class.
+;
+; Please name system dependent files in the form CPXxxx.ASM where
+; xxx is a three letter abbrev. for the system you are adding.
+;
+; revision history:
+;
+;edit 5, 10-Jan-1991 by MF. Removed references to assembly switch ker09.
+; edit 4, 21 July, 1987 by OBSchou. Removed routines no in CPXCOM.ASM
+;
+; edit 3, 8 April, 1987 by OBSchou. Moved the VDU declarations for the
+; Torch, superbrain and Cifer from CPXVDU.ASM. Also added code to
+; see if the MCP/CCCP ROM versions on the Torch is less or grater than
+; 1. Less than 1 => poor screen control. Finally adjusted the
+; positioning of the filename to cope with a user number and drive
+; in the filename field
+;
+;
+; edit 2, 20 March, 1987 by C.J.MILES@UK.AC.UMRCC. Added support for
+; NCR Decision Mate V (2651 USART)
+;
+; edit 1, 22 April, 1986, OBSchou. Start on splitting off individual
+; systems from this huge file. It is done using the LINK facility
+; LASM. We link to a collection of systems under CPXxxx.ASM.
+; I have started with the systems I know, the Torch, Cifer and
+; pci2651. These will all be held under CPXTOR.ASM
+;
+;
+; Keep module name, edit number, and last revision date in memory.
+family: db 'CPXTOR.ASM (5) 10-Jan-1991 $'
+;
+; Assembly time message to let me know I'm building the right version.
+; LASM generates an 'S' error along with the message, which is messy, but
+; better than trying to put everything inside a IF m80 OR mac80 conditional,
+; because LASM doesn't like nested IF's, either.
+
+IF ncrdmv
+.printx * Assembling KERMIT-80 for the N.C.R. Decision Mate V *
+ENDIF
+
+IF brain
+.printx * Assembling KERMIT-80 for the Intertec Superbrain *
+ENDIF
+
+IF brainm
+.printx * With main port selected
+ENDIF
+IF braina
+.printx * With Aux port
+ENDIF
+
+IF pci2651 ;
+.printx * assembling Kermit-80 for 2651 PCI as comms device *
+ENDIF
+
+IF torch
+.printx * Assembling Kermit-80 for Torch Unicorn 5 *
+ENDIF
+; *******This should be in the original CPXSYS.ASM file
+;
+;=========================================================================
+; I/O Byte assignments (2-bit fields for 4 devices at loc 3)
+;
+;bits 6+7 LIST field
+; 0 LIST is Teletype device (TTY:)
+; 1 LIST is CRT device (CRT:)
+; 2 LIST is Lineprinter (LPT:)
+; 3 LIST is user defined (UL1:)
+;
+;bits 4+5 PUNCH field
+; 0 PUNCH is Teletype device (TTY:)
+; 1 PUNCH is high speed punch (PUN:)
+; 2 PUNCH is user defined #1 (UP1:)
+; 3 PUNCH is user defined #2 (UP2:)
+;
+;bits 2+3 READER field
+; 0 READER is Teletype device (TTY:)
+; 1 READER is high speed reader (RDR:)
+; 2 READER is user defined #1 (UR1:)
+; 3 READER is user defined #2 (UR2:)
+;
+;bits 0+1 CONSOLE field
+; 0 CONSOLE is console printer (TTY:)
+; 1 CONSOLE is CRT device (CRT:)
+; 2 CONSOLE is in Batch-mode (BAT:);READER = Input,
+; LIST = Output
+; 3 CONSOLE is user defined (UC1:)
+;
+;=========================================================================
+
+iobyte EQU 03H ;Location of I/O byte
+
+
+; [13] modifed to use either main or aux port. Should really
+; be selected by set port, but this is urgent, so no frills
+IF brain
+baudst EQU 60H ;
+baudrt EQU 0EF00H ;Memory location where baud rates are stored.
+output EQU 01H ;Transmitter ready
+input EQU 02H ;Input data available
+TxEmpty EQU 04h ;Transmitter empty
+z80 SET TRUE ;I don't know...
+ENDIF;brain
+IF brainm ; Superbrain and main ports
+mnport EQU 58H ;Modem data port
+mnprts EQU 59H ;Modem status port
+ENDIF ;brainm
+IF braina ; Superbrain and aux port
+mnport EQU 40H ;Modem data port
+mnprts EQU 41H ;Modem status port
+ENDIF ;braina [13]
+
+IF ncrdmv
+iobase equ 70h ; base address of PCI device
+modrx equ 70h ; Rx data port
+mnprts equ 71h ; status port
+mnmodr equ 72h ; mode register read
+mncmdr equ 73h ; command register read
+modtx equ 74h ; Tx data port
+mnmodw equ 76h ; mode register write
+mncmdw equ 77h ; command register write
+txrdy equ 1
+output equ txrdy
+rxrdy equ 2
+input equ rxrdy
+baudini equ 0ah ; initial baud to 2400
+z80 SET true
+cpuspd SET 40
+ENDIF
+
+IF pci2651 ;[28]
+iobase equ 04h ; base address of PCI device
+mnport equ iobase ; rx and tx data ports
+mnprts equ iobase+1 ; status port
+mnmode equ iobase+2 ; mode port
+mncmd equ iobase+3 ; PCI command port
+
+txrdy equ 1 ; tx ready bit set if free
+output equ txrdy
+rxrdy equ 2 ; RX ready bit
+input equ rxrdy
+baudini equ 7 ; 7 => 1200 baud by default
+z80 SET true ; For Ithica intersystems it is
+cpuspd SET 40 ; and running at four megs
+ENDIF ;[28]
+
+IF torch ;[13]
+z80 SET TRUE
+; [32] baudini removed as now read current baud rate
+; settings from base processor.
+
+;baudini equ 707h ; Initial Baud rate = 1200 baud
+ ; Entry to be of form x0xh where x is
+ ; the value x in the FX 7,x and FX 8,x
+ ; funtion calls. 4= 1200 baud, 7 = 9600
+ ; 2 = 300 baud.
+ENDIF
+
+IF brain OR torch
+defesc EQU ']'-100O ;The default escape character.
+ENDIF;brain OR torch
+
+; If none of the above, default to VT52-EMULATION ON.
+IF NOT crt
+vtval EQU 1
+ENDIF;NOT crt
+
+
+sysxin:
+
+IF brainm ;[25]
+ lda baudrt ; fetch current baud rate
+ ani 0F0H ; extract left nibble
+ rrc ; shift right 4 places
+ rrc
+ rrc
+ rrc
+ sta speed ; store as comm port speed
+ sta speed+1 ; (16 bits, to match speed table entries)
+ENDIF;brainm
+
+IF braina ;[25]
+ lda baudrt ; fetch current baud rate
+ ani 00FH ; extract right nibble
+ sta speed ; store as comm port speed
+ sta speed+1 ; (16 bits, to match speed table entries)
+ENDIF;braina
+
+IF torch ; [13] [32]
+ push h
+ mvi a,0f2h ; nick code from BBC initialisation
+ lxi h,0ff00h
+ call osbyte ; Read current speed setting
+ mov a,l
+ ani 7
+ xri 7 ; Store as two's complement
+ inr a
+ sta speed
+ sta speed+1
+ mov e,a
+ call sysspd ; Make sure they are both the same!
+ mvi a,15 ; Flush all internal buffers [32]
+ mvi l,0
+; call osbyte
+ mvi a,3
+ lxi h,0100h ; *FX 3,0,1 Enable RS423
+ call osbyte
+ mvi a,2 ; Select keyboard, Enable RS423 input
+ mvi l,2
+ call osbyte
+ mvi a,5 ; Select serial printer [32]
+ mvi l,2
+ call osbyte ; [30]
+ mvi a,6 ; Must be able to send LF [30]
+ mvi l,0
+ call osbyte ; [30]
+ mvi a,202 ; FX 202,255 set lower case on
+ mvi l,255
+ call osbyte
+ pop h
+
+; Now see what version of MCP CCP roms. Assume >1, else copy a few of the
+; older Torch VDU declares over the new ones.
+;
+; lda 0ffffh ; Address 0ffffh has single byte Version no.
+; push psw ; save for a rainy day
+; ani 0F0h ; get ms digit of MCP version
+; rra ; move right 4 places
+; rra
+; rra
+; rra
+; ani 0fh
+; adi 30h ; make it a number
+; sta mcpver
+; pop psw ; its raining...
+; push psw ; ... its pouring...
+; ani 0fh ; get ls digit
+; adi 30h ; make it ascii number
+; sta mcpver+2
+; pop psw ; restore psw
+; cpi 10h ; Version 1.00 or less?
+; jp init2 ; yes, so skip next bit
+; lxi h,ooutli ; from old string table
+; lxi d,ttab ; to new ttab
+; lxi b,60 ; 60 bytes to move
+; call mover
+init2:
+
+IF ncrdmv
+ mvi a,00 ; clear out command register
+ out mncmdw
+ mvi a,4eh ; 1 stop bit, 8 data bits, / by 16 counter
+ out mnmodw
+ mvi a,70h+baudini ; baud rate and select internal rate gen.
+ out mnmodw
+ mvi a,27h ; enable tx and rx, RTS and DTR low
+ out mncmdw
+ENDIF ; ncrdmv
+
+IF pci2651 ;[28]
+ in mncmd ; clearw command reg counter
+ mvi a,4eh ; 1 stop bit, 8 data bits, / by 16 counter
+ out mnmode
+ mvi a,30h+baudini ; baud rate and select internal rate gen.
+ out mnmode
+ mvi a,27h ; enable tx and rx, RTS and DTR low
+ out mncmd
+ENDIF ; pci2651 [28]
+
+ ret ; return from system-dependent routine
+
+;
+;
+; system-dependent termination processing
+; If we've changed anything, this is our last chance to put it back.
+sysexit:
+ ret
+
+;
+; system-dependent processing for start of CONNECT command
+;
+syscon:
+ ret
+
+conmsg: ; Messages printed when entering transparent (CONNECT) mode:
+;
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+ ret
+;
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing all the
+; system-independent escape sequences.
+;
+sysinh:
+IF torch OR brain OR pci2651 OR ncrdmv
+ lxi d,inhlps ; we got options...
+ call prtstr ; print them.
+ENDIF;torch OR brain OR pci2651 OR ncrdmv
+
+ ret
+
+
+;additional, system-dependent help for transparent mode
+; (two-character escape sequences)
+inhlps:
+
+; [16] [18] have added super brain and Torch to the list of Breaking machines.
+
+IF pci2651 OR brain OR torch OR ncrdmv
+ db cr,lf,'B Transmit a BREAK'
+ENDIF ;pci2651 OR brain OR torch OR ncrdmv
+
+IF torch ; added this simply to debug the escape cokebottle D for the apple
+ db cr,lf,'D Disconnect the modem (Test purposes only)'
+ENDIF;Torch
+
+ db '$' ;[hh] table terminator
+
+;
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:
+; non-skip: sequence has been processed
+; skip: sequence was not recognized
+sysint: ani 137O ; convert lower case to upper, for testing...
+
+; [19] have added superbrain and torch to the list
+
+IF brain OR pci2651 OR torch OR ncrdmv
+ cpi 'B' ; send break?
+ jz sendbr ; yes, go do it. return nonskip when through.
+ENDIF ;brain OR pci2651 OR torch OR ncrdmv
+
+IF Torch; added bit for doing a D...
+ cpi 'D' ;drop the line...
+ jz dropln
+ENDIF ;torch
+
+ jmp rskp ; take skip return - command not recognized.
+
+
+IF torch
+dropln: lxi d,dropm ; tell user line is dropped..
+ call prtstr
+ xra a ; destroy A
+ ret
+dropm: db bell,cr,lf,'Testing line dropped ',cr,lf,bell
+ db '$'
+ENDIF ;torch and dropping them there lines..
+
+;
+
+IF brain
+sendbr:
+;
+; Ensure that the transmitter has finished sending buffered chars
+sndbr1: in mnprts ; get UART status
+ ani TxEmpty ; everything sent?
+ jz sndbr1 ; no, wait a bit more
+;
+; Begin sending a break by setting bit in UART command register
+ mvi a,3Fh ; Set TxEna, DTR, RxEna, SBreak, ErrRst, RTS
+ out mnprts
+;
+; Wait for 250 milliseconds (using hundredths second delay routine)
+ mvi a,25
+ call delay
+;
+; Resume normal operation by clearing the SendBreak command bit
+ mvi a,37h ;Set TxEna, DTR, RxEna, ErrRst, RTS
+ out mnprts
+;
+ ret ;done
+ENDIF;brain
+
+IF torch ; [18] [27] [30] [32]
+; Send a break.
+;
+; [30] Dumping of 6502 code not yet used, but may be for later versions of
+; the Torch CCCP Rom in the BBC. This works, so I leave it for now.
+
+sendbr:
+ push h ;save for a monsoon
+ mvi a,0e8h
+ lxi h,0 ; turn interrupts off
+ call osbyte
+ push h
+;
+ mvi a,9ch ; OSBYTE call 9c is read/write 6850 cntl prt
+ lxi h,0077h ; H = 6502 Y reg, L = 6502 X reg
+ call osbyte ; returned new val. = (old value AND Y)XOR X
+ push h ; save it for return
+;
+ mvi a,30
+ call delay ; do a delay
+;
+; now clear rx register
+;
+ mvi a,96h ; do a read sheila address 08h
+ mvi l,8
+ mvi h,0
+ call osbyte ; read sheila 08h = 6850 rx reg
+;
+; restore 6850 regs...
+;
+ pop h ; restore previous cntl reg
+ ; old x reg in l, so leave it there
+; mov l,h
+ mvi h,0
+ mvi a,9ch ; write previous value to 6850
+ call osbyte
+;
+; and Beebs interrupt mask
+;
+ pop h ; get interrupt mask
+ ; Once again, old X in L so leave it alone
+; mov l,h
+ mvi h,0
+ mvi a,0e8h
+ call osbyte ; restore interrupts mask
+;
+ pop h
+ ret ; its raining again, so exit
+ENDIF ; torch [18] [32]
+
+IF ncrdmv
+sendbr: in mnprts ; get status
+ ani 04h ; make sure shift register is empty
+ jz sendbr
+
+ mvi a,2fh ; force a break
+ out mncmdw
+ mvi a,100 ; set delay period
+ call delay
+ mvi a,27h ; restore command register
+ out mncmdw
+ ret
+ENDIF ; ncrdmv
+
+IF pci2651 ;[28]
+sendbr: in mnprts
+ ani 04h ; make sure shift reg is clear
+ jz sendbr
+
+ mvi a,2fh ; set foe a break
+ out mncmd
+ mvi a,100 ; wait a bit
+ call delay
+ mvi a,27h ; restore mode
+ out mncmd
+ ret
+ENDIF ;pci2651 [28]
+
+;
+; sysflt - system-dependent filter
+; called with character in E.
+; if this character should not be printed, return with A = zero.
+; preserves bc, de, hl.
+; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
+sysflt:
+ mov a,e ; get character for testing
+ ret
+
+; mdmflt - modem filter [30]
+; called with character to be sent to printer in E
+; with parity set as appropriate.
+; return with accumulator = 0 do do nothing,
+; <> 0 to send char in E.
+mdmflt:
+ mov a,e ;[30] get character to test
+IF torch ;[30] map del to bs,space,bs
+ ani 7fh ; strip parity
+ cpi 7fh ; is it the delete character
+ rnz ; no, then a <> 0 so print it
+ mvi e,bs ; else load a backspace
+ call outmdm ; little recursion...
+ mvi e,' ' ; then a space
+ call outmdm ; backspace, space, now another...
+ mvi e,bs ; backspace
+ call outmdm ;
+ xra a ; clear a => on return do nowt.
+ENDIF ;torch [30]
+ ret
+
+
+
+; prtflt - printer filter [30]
+; called with character to be sent to printer in E
+; returns with a = 0 to do nothing
+; a <> 0 to print it.
+;
+; this routine for those printer that automatically insert
+; a lf on cr, or cr for lf. Should this be shifted to
+; the system indep. stuff, in say 4.06?
+prtflt:
+ mov a,e ; [30] get character to test
+IF torch ; strip out lf from printer stream
+ ani 7fh ; make sure it is parity less
+ cpi lf ; is it a line feed?
+ rnz ; no, print it
+; xra a ; yes, don't.
+
+ENDIF ;torch [30]
+ ret
+
+
+;
+;
+; system-dependent processing for BYE command.
+; for apmmdm, heath, and lobo, hang up the phone.
+sysbye:
+ ret
+;
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; this
+; value is also stored in 'speed'.
+sysspd:
+
+; Set the speed for the Brain (Main Port)
+IF brainm ;[25]
+ lda baudrt ;Get the present baud rates.
+ ani 0fH ;turn off the left
+ mov d,a ;Set it aside.
+ mov a,e ;Get the new baud rate.
+ rlc ;Shift left 4 places.
+ rlc
+ rlc
+ rlc
+ ora d ; combine with the old baud rate
+ sta baudrt ;Store the new baud rates.
+ out baudst ;Set the baud rates.
+ ret
+ENDIF;brainm
+
+; Set the speed for the Brain (Aux Port)
+IF braina ;[25]
+ lda baudrt ;Get the present baud rates.
+ ani 0f0H ;turn off the right
+ ora e ; combine with the new baud rate
+ sta baudrt ;Store the new baud rates.
+ out baudst ;Set the baud rates.
+ ret
+ENDIF;braina
+
+If torch ; Set speed for Torch [14] [32]
+ mvi a,7 ; Osbyte call to set rx rate
+ mov l,e
+ call osbyte ;
+ mvi a,8 ; set up for tx rate to be set
+ mov l,e
+ call osbyte
+ ret ; and now, all rates should be different
+
+ENDIF ;torch [14] [32]
+
+IF ncrdmv ; Set baud rate for NCR Decision Mate V
+ mvi a,00 ; clear command register
+ out mncmdw
+ mvi a,4eh ; set for 1 stop, 8 data bits
+ out mnmodw ; save in mode 1 port
+ mvi a,70h ; set bits for rate etc..
+ add e ; add baud rate (bits 0 - 3)
+ out mnmodw ; set mode port 2
+ mvi a,27h ; set tx/rx ready, RTS CTS active
+ out mncmdw
+ ret
+ENDIF ; ncrdmv
+
+
+IF pci2651 ; Set baud for PCI [28]
+ in mncmd ; Clear register counter
+ mvi a,4eh ; set for 1 stop, 8 data bits
+ out mnmode ; save in mode 1 port
+ mvi a,30h ; set bits for rate etc..
+ add e ; add baud rate (bits 0 - 3)
+ out mnmode ; set mode port 2
+ mvi a,27h ; set tx/rx ready, RTS CTS active
+ out mncmd
+ ret
+ENDIF ;pci2651 [28]
+
+;
+; Speed tables
+; (Note that speed tables MUST be in alphabetical order for later
+; lookup procedures, and must begin with a value showing the total
+; number of entries. The speed help tables are just for us poor
+; humans.
+
+; db string length,string,divisor (2 identical bytes or 1 word)
+; [Toad Hall]
+
+IF brain OR pci2651 OR ncrdmv
+spdtbl: db 10h ;16 entries
+ db 03h,'110$', 02h,02h
+ db 04h,'1200$', 07h,07h
+ db 05h,'134.5$', 03h,03h
+ db 03h,'150$', 04h,04h
+ db 04h,'1800$', 08h,08h
+ db 05h,'19200$', 0fh,0fh
+ db 04h,'2000$', 09h,09h
+ db 04h,'2400$', 0ah,0ah
+ db 03h,'300$', 05h,05h
+ db 04h,'3600$', 0bh,0bh
+ db 04h,'4800$', 0ch,0ch
+ db 02h,'50$', 00h,00h
+ db 03h,'600$', 06h,06h
+ db 04h,'7200$', 0dh,0dh
+ db 02h,'75$', 01h,01h
+ db 04h,'9600$', 0eh,0eh
+
+sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200'
+ db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$'
+ENDIF;brain OR pci2651 OR ncrdmv
+
+IF torch ;[17]
+spdtbl: db 8 ; 8 entries
+ db 4,'1200$', 4,4
+ db 3,'150$', 2,2
+ db 5,'19200$', 8,8
+ db 4,'2400$', 5,5
+ db 3,'300$', 3,3
+ db 4,'4800$', 6,6
+ db 2,'75$', 1,1
+ db 4,'9600$', 7,7
+
+sphtbl: db cr,lf,' 75 150 300 1200 2400 4800 9600 19200$'
+ENDIF;torch [17]
+
+
+; The following conditionals were once a huge if not statement. There
+; wasn't enough room to add the lobo to the list, so it had to be broken
+; into 2, which you can't do with an if not. I redid it as two ifs and
+; applied them to those that wouldn't set baud. [Hal Hostetler]
+;
+; This is the system-dependent SET PORT command.
+; HL contains the argument from the command table.
+sysprt:
+IF iobyt
+ mov a,m ;Get the I/O byte
+ sta prtiob ;Save the desired IO byte for this port
+ inx h ;Point at next entry
+ mov a,m ;Get the output function
+ sta prtfun ;Save it
+ENDIF;iobyt
+
+ ret
+;
+;
+;
+; Port tables for GENERIC CPM 2.2
+IF gener
+; help text
+prhtbl: db cr,lf,'CRT device'
+ db cr,lf,'PTR device'
+ db cr,lf,'TTY device'
+ db cr,lf,'UC1 device'
+ db cr,lf,'UR1 device'
+ db cr,lf,'UR2 device$'
+
+; command table
+prttbl: db 06H ;Six devices to choose from
+ db 03H,'CRT$'
+ dw crtptb
+ db 03H,'PTR$'
+ dw ptrptb
+ db 03H,'TTY$'
+ dw ttyptb
+ db 03H,'UC1$'
+ dw uc1ptb
+ db 03H,'UR1$'
+ dw ur1ptb
+ db 03H,'UR2$'
+ dw ur2ptb
+
+; port entry table
+; table entries are:
+; db iobyte-value, BDOS output function, reserved
+crtptb: db crtio,conout,0
+ptrptb: db ptrio,punout,0
+ttyptb: db ttyio,conout,0
+uc1ptb: db uc1io,conout,0
+ur1ptb: db ur1io,punout,0
+ur2ptb: db ur2io,punout,0
+ENDIF;gener
+
+;
+;
+IF iobyt
+prtfun: db punout ;Function to use for output to comm port
+prtiob: db batio ;I/O byte to use for communicating
+coniob: db defio ;I/O byte to use for console
+ENDIF;iobyt
+
+IF NOT iobyt
+prttbl equ 0 ; SET PORT is not supported
+prhtbl equ 0
+ENDIF;NOT iobyt
+;
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; For iobyt systems, diddle the I/O byte to select console or comm port;
+; For Decision I, switches Multi I/O board to console or modem serial
+; port. [Toad Hall]
+; For the rest, does nothing.
+; preserves bc, de, hl.
+selmdm:
+IF iobyt
+ lda prtiob ;Set up for output to go to the comm port
+ sta iobyte ;Switch byte directly
+ENDIF;iobyt
+ ret
+
+selcon:
+IF iobyt
+ lda coniob ;Set up for output to go to the console port
+ sta iobyte ;Switch directly
+ENDIF;iobyt
+
+ ret
+;
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+IF NOT iobyt
+ mvi c,dconio ;Direct console I/O BDOS call.
+ mvi e,0FFH ;Input.
+ call BDOS
+ENDIF;NOT iobyt
+
+IF iobyt
+ call bconst ;Get the status
+ ora a ;Anything there?
+ rz ;No, forget it
+ call bconin ;Yes, get the character
+ENDIF;iobyt
+ ret
+;
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+
+IF NOT iobyt
+ mvi c,dconio ;Console output bdos call.
+ call bdos ;Output the char to the console.
+ENDIF;NOT iobyt
+
+IF iobyt
+ mov c,e ;Character
+ call bcnout ;to Console
+ENDIF;iobyt
+ ret
+;
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+outmdm:
+IF inout AND NOT ncrdmv
+ in mnprts ;Get the output done flag.
+ ani output ;Is it set?
+ jz outmdm ;If not, loop until it is.
+ mov a,e
+ out mnport ;Output it.
+ ret
+ENDIF;inout AND NOT ncrdmv
+
+IF inout AND ncrdmv
+ in mnprts ;Get the output done flag
+ ani output ;Set ?
+ jz outmdm ;Loop until it is
+ mov a,e
+ out modtx ;output char
+ ret
+ENDIF;inout AND ncrdmv
+
+IF iobyt
+;**** Note that we enter from outpkt with the I/O byte already set up for
+; output to go to the comm port
+ push h
+ push b
+ lda prtfun ;Get the output function
+ mov c,a ;Into C
+ call bdos ;And output the character
+ pop b
+ pop h
+ ret
+ENDIF;iobyt
+
+
+IF torch ; [32] [13] Torch stuff. Requires some bit bashing
+ ; via the BBC host computer (io computer)
+ ; see also decription of osbyte later on
+outdat:
+ lda prinuse ; get the printer in use flag
+ ana a ; if set, then must use traditional osbyte,
+ jnz outda2 ; else...
+ push b
+ push h ; Preserve registers [32]
+ call tx
+ db 1 ; MCP send to printer command
+ mov c,e ; Byte to send is in E [32]
+ call txbyte
+ pop h
+ pop b
+ ret
+
+outda2: ; Preserve registers [32]
+ push h
+ mvi a,138 ; Osbyte insert byte into buffer
+ mvi l,2
+ mov h,e ; get the byte to be sent s-l-o-w-l-y
+ call osbyte
+ pop h ; Restore registers and exit
+ ret
+
+ENDIF ;[13]
+
+;
+;
+; get character from modem; return zero if none available.
+; for IOBYT systems, the modem port has already been selected.
+; destroys bc, de, hl.
+inpmdm:
+IF iobyt
+ call bconst ;Is Char at COMM-Port?
+ ora a ;something there?
+ rz ; return if nothing there
+ call bconin ; data present. read data.
+ENDIF;iobyt
+
+IF inout AND NOT ncrdmv
+;Note: modem port should already be selected for mdI. [Toad Hall]
+ in mnprts ;Get the port status into A.
+ ani input ;See if the input ready bit is on.
+ rz ;If not then return.
+ in mnport ;If so, get the char.
+ENDIF;inout AND NOT ncrdmv
+
+IF inout AND ncrdmv
+ in mnprts ;Get input port status
+ ani input ;Mask input RDY bit
+ rz ;return if no char
+ in modrx ;get the char
+ENDIF;inout AND ncrdmv
+IF torch ; [32] [13] torch input
+indat:
+ push h
+ mvi a,128
+ lxi h,0fffeh ; Read buffer status
+ call osbyte
+ mov a,h ; HL has number of characters
+ ora l ; in the buffer
+ jz indatq ; None, so skip fetch
+ mvi a,145 ; Get character from input buffer [32]
+ lxi h,1
+ call osbyte ; Result returned in 'Y', rather H
+ mov a,h
+indatq:
+ pop h
+ ani 7fh
+ ret ; rx data in A
+ENDIF ;torch [13] [32]
+
+ret ; return with character in A
+
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+
+flsmdm: call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+
+
+;
+;
+; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not.
+lptstat:
+IF torch
+ mvi a,80h ; read chars remaining in printer buffer
+ mvi l,252 ; do osbyte 80H, X=252 (printer buffer)
+ mvi h,0ffh
+ call osbyte
+ mov a,h
+ cpi 10 ; 10 characters left?
+ mvi a,0 ; if pos, yes r better
+ rp
+ mvi a,0ffh
+ ret
+ENDIF ;torch
+
+IF torch
+ mvi a,5 ; got to select the real printer (par. port)
+ mvi l,1 ; ie FX 5,1
+ call osbyte
+ENDIF ;torch
+
+IF iobyte ;[33]
+ call bprtst ; get status
+ENDIF ;iobyte[33]
+
+IF torch
+ push psw
+ mvi a,5 ; restore serial line = printer
+ mvi l,2 ; ie FX 5,2
+ call osbyte
+ pop psw ; return with code in a
+ENDIF ;torch
+
+
+IF NOT iobyte ;[33]
+ xra a ; assume it is ok.. this may not be necessary
+ENDIF ;iobyte [33]
+ ret
+;
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+outlpt:
+ push d ; save DE in either case
+ call prtflt ; go through printer filter [30]
+ ana a ; if A = 0 do nothing,
+ jz outlp1 ; [30] if a=0 do nothing
+
+IF torch ;[30] Must set printer routed to par port
+ mvi a,5 ; fx 5,1 (parallel port selected for printer)
+ mvi l,1 ; Modified for new osbyte form [32]
+ call osbyte
+ENDIF ;torch [30]
+
+IF NOT iobyt
+ mvi c,lstout
+ call bdos ;Char to printer
+ENDIF;NOT iobyt
+IF iobyt
+ mov c,e
+ call blsout
+ENDIF;iobyt
+IF torch ; re-route printer to serial port => faster tx bytes to line [30]
+ mvi a,5 ; Modified for new Osbyte form [32]
+ mvi l,2 ;fx 5,2
+ call osbyte
+ mvi a,6
+ mvi l,0 ;fx 6,0
+ call osbyte
+ENDIF ;torch [30]
+
+outlp1: pop d ; restore saved register pair
+ ret
+;
+;
+; Screen manipulation routines
+; csrpos - move to row B, column C
+;
+; csrpos for terminals that use a leadin sequence followed
+; by (row + 31.) and (column + 31.)
+;
+IF brain
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; restore coordinates
+ mov a,h ; get row
+ adi (' '-1) ; space is row one
+ mov e,a
+ push h
+ call outcon ; output row
+ pop h
+ mov a,l ; get column
+ adi (' '-1) ; space is column one
+ mov e,a
+ jmp outcon ; output it and return
+ENDIF;brain
+;
+;
+IF torch
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; restore coordinates
+ mov a,l ; [obs] get column
+ adi 0ffh ; NULL is column one
+ mov e,a
+ push h
+ call outcon ; output row
+ pop h
+ mov a,h ; [obs] get row
+ adi 0ffh ; NULL (ie decrement) is row one
+ mov e,a
+ jmp outcon ; output it and return
+ENDIF;torch
+;
+;
+; delchr - make delete look like a backspace. Unless delete is a printing
+; character, we just need to print a backspace. (we'll output clrspc
+; afterwards)
+; For Kaypro and Vector General, delete puts a blotch on the screen.
+; For Apple and Osborne 1, delete moves but doesn't print.
+delchr:
+
+
+IF NOT torch ;[22]
+ mvi e,bs ;get a backspace
+ jmp outcon
+ENDIF;NOT torch
+
+; erase the character at the current cursor position
+clrspc: mvi e,' '
+ call outcon
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the current line
+clrlin: lxi d,eralin
+ jmp prtstr
+
+; erase the whole screen, and go home. preserves b (but not c)
+clrtop: lxi d,erascr
+ jmp prtstr
+
+
+IF torch ;[13]
+;
+; OSBYTE call from Torch to BBC Base Processor.
+;
+; A register has osbyte type
+; H register has equivalent Y register of 6502
+; L register has equivalent X register of 6502
+;
+; Results (X and Y) are returned in HL respectively
+;
+;
+
+usrimm equ 0ffc0h ; MCP user function [32]
+tx equ 0ffc3h ; tx routine to talk to base board proc.
+rx equ 0ffc6h ; rx ditto
+txbyte equ 0ffc9h ; send C to base processor [32]
+
+osbyte: ; Osbyte rewritten [32]
+ push b ; Keep these
+ mov b,a ; Local copy - use in a moment
+ call usrimm ; MCP osbyte function
+ db 15
+ mov c,b ; Osbyte function
+ call txbyte
+ mov c,l ; 6502 X register
+ call txbyte
+ mov c,h ; 6502 Y register
+ call txbyte
+ call rx ; fetch results
+ mov l,a ; X returned
+ sta xx ; save just in case...
+ call rx
+ mov h,a ; Y returned
+ sta yy
+ mov a,b ; return A as called
+ pop b
+ ret
+
+xx: db 0
+yy: db 0 ; temporary space
+
+prinuse:db 0 ; 0=> fast tx, <>0 => slow tx to serial pt. [30]
+
+ENDIF ;torch [13]
+
+IF pci2651 ; whatever version
+sysver: db 'Ithaca Intersystems S100$'
+ENDIF ;pci2651
+
+IF ncrdmv ; whatever version
+sysver: db 'NCR DecisionMate V$'
+ENDIF ;ncrdmv
+
+IF torch ; whatever version
+ttytyp:
+sysver: db 'Torch Unicorn 5 '
+ db '$' ; stop here for now, otherwise say..
+ db ' MCP version '
+ db '1.00 $' ; or whatever...
+ENDIF ;torch
+
+; Assume MCP - CCCP ROMS greater than 1
+;mcpver: db 'x.x $'
+;outlin: db esc,'*',cr,lf,tab,'$'
+;eralin: db cr,esc,'&$' ;Clear to end of line.
+;erascr: db esc,'*$' ;Clear screen and go home.
+;curldn: db esc,'=$' ;Cursor lead-in
+;ttab: ;Table start location.
+;ta:
+ db esc,'!$',0 ;Cursor up.
+;tb: db 0ah,'$',0,0 ;Cursor down.
+;tc: db esc,'+$',0 ;Cursor right.
+;td: db 08h,'$',0,0 ;Cursor left.
+;te: db esc,'*$',0 ;Clear screen and home cursor
+;tf: db '$',0,0,0 ;(can't) Enter Graphics mode
+;tg: db '$',0,0,0 ;(can't) Exit Graphics mode
+;th: db esc,'>$',0 ;Cursor home.
+;ti: db '$',0,0,0 ;(Can't) reverse linefeed
+;tj: db esc,'%$',0 ; Clear to end of screen
+;tk: db esc,'&$',0 ; Clear to end of line.
+
+
+;Older message for MCP - CCCP verstion less than 1
+;ooutli: db 0ch,cr,lf,tab,tab,'$';
+;oerali: db '$',0,0,0 ;Clear to end of line.
+;oerasc: db 0ch,'$',0 ;Clear screen and go home.
+;ocurld: db 1fh,'$',0 ;Cursor lead-in
+;ottab: ;Table start location.
+; db 0bh,'$',0,0 ;Cursor up.
+; db 0ah,'$',0,0 ;Cursor down.
+; db 09h,'$',0,0 ;Cursor right.
+; db 08h,'$',0,0 ;Cursor left.
+; db 0ch,'$',0,0 ;Clear screen and home cursor
+; db '$',0,0,0 ;(can't) Enter Graphics mode
+; db '$',0,0,0 ;(can't) Exit Graphics mode
+; db 1eh,'$',0,0 ;Cursor home.
+; db 0bh,'$',0,0 ;reverse linfeed
+; db '$',0,0,0 ;(Can't) Clear to end of screen
+; db '$',0,0,0 ;(Can't) Clear to end of line.
+;
+;Specials
+;spac15: db ' '
+; db bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,'$';
+;spac80: db cr
+; db ' '
+; db ' '
+; db bs,cr,'$' ;80 spaces, bs and then back to line start
+;
+
+IF torch ; Should be IF ker08 AND torch...
+ db '$' ; to terminate the ID string
+outlin: db 0ch,cr,lf,tab,tab,'$'
+eralin: db '$',0,0,0 ;Clear to end of line.
+erascr: db 0ch,'$',0 ;Clear screen and go home.
+curldn: db 1fh,'$',0 ;Cursor lead-in
+ttab: ;Table start location.
+ta: db 0bh,'$',0,0 ;Cursor up.
+tb: db 0ah,'$',0,0 ;Cursor down.
+tc: db 09h,'$',0,0 ;Cursor right.
+td: db 08h,'$',0,0 ;Cursor left.
+te: db 0ch,'$',0,0 ;Clear screen and home cursor
+tf: db '$',0,0,0 ;(can't) Enter Graphics mode
+tg: db '$',0,0,0 ;(can't) Exit Graphics mode
+th: db 1eh,'$',0,0 ;Cursor home.
+ti: db 0bh,'$',0,0 ;reverse linfeed
+tj: db '$',0,0,0 ;(Can't) Clear to end of screen
+tk: db '$',0,0,0 ;(Can't) Clear to end of line.
+
+;Specials
+spac15: db ' '
+ db bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,'$';
+spac80: db cr
+ db ' '
+ db ' '
+ db bs,cr,'$' ;80 spaces, bs and then back to line start
+
+ENDIF;ker08 AND torch [13]
+
+IF brain
+sysver: db 'Intertec SuperBrain$'
+outlin: db ('A'-100O),esc,'~k',cr,lf,tab,tab,'$'
+erascr: db ('A'-100O),esc,'~k$' ;Clear screen and go home.
+eralin: db cr,esc,'~K$' ;Clear line.
+curldn: db esc,'Y$' ; leadin for cursor positioning
+ttab: ;Table start location.
+ta: db ('K'-100O),'$',0,0 ;Cursor up.
+tb: db 12O,'$',0,0 ;Cursor down.
+tc: db ('F'-100O),'$',0,0 ;Cursor right.
+td: db '$',0,0,0 ;(can't) Cursor left
+te: db '$',0,0,0 ;(can't) Clear display
+tf: db '$',0,0,0 ;(can't) Enter graphics mode
+tg: db '$',0,0,0 ;(can't) Exit graphics mode
+th: db ('A'-100O),'$',0,0 ;Cursor home.
+ti: db ('K'-100O),'$',0,0 ;Reverse linefeed.
+tj: db esc,'~k$',0 ;Clear to end of screen.
+tk: db esc,'~K$',0 ;Clear to end of line.
+ENDIF;brain
+
+IF lasm and not termin ; we dont want CPXVDU
+ovlend equ $ ;Overlay end - start buffer
+ end
+ENDIF ;lasm and not termin
+
+IF lasm; we want a terminal
+LINK CPXVDU.ASM
+ENDIF ;lasm
+
diff --git a/cpxtyp.asm b/cpxtyp.asm
index 28b65b3..83528a9 100644
--- a/cpxtyp.asm
+++ b/cpxtyp.asm
@@ -1,722 +1,722 @@
-; CPXTYP.ASM
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This is the header file for building the system-dependent overlay
-; for KERMIT. It contains the definitions used to select the target
-; system, and collects (via INCLUDE or LINK directives) the remaining
-; code. If the target system is one of the supported systems
-; described below, then this is the only file that needs to be
-; edited.
-;
-; revision history:
-;
-;edit 34, 10-Jan-1991 by MF. Put in "terminal required" notation for
-; more machines that need terminals.
-;edit 33, 9-Jan-1991 by MF. Put in "terminal required" notation for Access
-; Matrix and eliminated an extra "sysfam set FALSE" when torfam set TRUE
-;edit 32, 7-Jan-1991 by MF. Added code by Jay. S. Rouman to support the
-; Ampro Little Board (see CPXBBI.ASM).
-; Also put in a couple of missing .printx's
-;edit 31, 2-Nov-1990 by MF. Moved overlay address to 7000H.
-;edit 30, 14-Sep-1990 by MF. Added INCOMPLETE-FILE flag for SET
-; INCOMPLETE-FILE
-;edit 29, 11-Sep-1990 by MF. Moved overlay address for version 4.10.
-; to 6C00H.
-; edit 28, 1st September 1990 by Russell Lang, rjl@monu1.cc.monash.edu.au
-; Added support for MicroBee (CPXBEE.ASM).
-;
-; edit 27, 28-Aug-89 by Mike Freeman, Bonneville Power Administration,
-; P.O. Box 491, Vancouver WA 98666 USA: add support for Hewlett-
-; Packard HP-125 "Business Assistant" computer using a HP-modified
- ;CP/M Version 2.2.
-;
-; edit 26, 2 December, by OBSchou. Added code for CP/M-80 Kermit to
-; run on an IBM-PC under Z80MU. Perverse?? No, its to allow testing
-; of independent code on a PC running CP/M kermit.
-;
-; edit 25, 27 October, 1987 by OBSchou. Merged in Sanyo, CompuPro, Genie
-; and TRS Model 4 code, and added four new families.
-; CPXSYO.ASM for the Sanyo, CPXPRO.ASM for the Compupro,
-; CPXTRS.ASM for the TRS-80 Model 4, CPXGNI.ASM for the Genie.
-; Many thanks to G. Smith for these latter two systems. Also
-; added the WYSE 100 Terminal type to the VDU table.
-;
-; edit 24, 17 July, 1987 by OBSchou. Added (hopefully) code from
-; CP/M Kermit 3.5 (WOW) for the Heath 8. (h8quad) The actual code
-; has been put into the CPXHEA.ASM family file, but I do not actually
-; *KNOW* if this new version works. Anyone willing to test it out??
-;
-; edit 23 16 July, 1987 for for Will Rose:
-; edit of 15 Jan 1987 by C W Rose
-; Added code for Micromint SB180 and Ampro 230 terminal.
-;
-; edit of 10 Apr 87 by C W Rose
-; Amended code for pci2651 to handle Telecom Merlin M2215.
-; (8085 at 5 MHz, 2651 USART, port TTY1:, Ampro 230 terminal equivalent).
-;
-; edit of 13 Jul 1987 by C W Rose
-; Added Micromint SB180 with 6/9 MHz. option.
-;
-; edit 22, 15th July, 1987 by OBSchou for David Moore.
-; David submitted a paper copy of Kermit 4.05 overlay for a Teletek
-; system: I have (hopefully) correctly appended his code. He also
-; send in the code for ADM 22 terminals.
-;
-; edit 21, 14 July, 1986 by OBSchou for John Shearwood of Birmingham
-; University. His edits:
-; edit of Apr 7th, 1987 by JA Shearwood. Added entry for Cifer Aux port
-; edit of Mar 24 1987 by JA Shearwood, Birmingham. Added code for Cifer
-; 1886 with CP/M Plus
-;
-; Also added in code from Chris Miles:
-; edit of 19 May 26, 1987 by C.J.MILES@UMRCC.
-; Kaypro II, Xerox 820 and Big Board II code seperated
-; from CPXSYS.ASM and put in a new family file called
-; CPXBBI.ASM.
-;
-; Finally added code from MJ Carter of Nottingham University:
-; edit 16a of 5th Mar 1987 by M J Carter, Nottingham Uni [majoc], to add
-; entry for OEM ScreenTyper (scntpr). See also CPXFRK.ASM ("fork"),
-; the tail end of CPXLNK.ASM, and the Heath-Zenith family file
-; CPXHEA.ASM (heath, z100, telcon, and scntpr).
-;
-; [Note: Martins CPXFRK is another version of CPXSWT.ASM]
-;
-;
-; edit 20, 21 May 1987 by OBSchou for Colin Burns of the Institute
-; of Neurological Sciences, Glasgow. Added flag for Hazeltine 1500
-; VDU (h1500)
-;
-; edit 19, 6th April, 1987 by OBSchou.
-; Added in EQUs for Amstrad 664 and 6128 machines (CPC) and NCR
-; Decsision mate V, bot sets of code submitted by Chris Miles of
-; Manchester University. NCR code is similar to the PCI2651 code, so
-; NCRDMV chains to CPXTOR.ASM. CPC cahins to the modified CPXPCW file
-; as submitted by Chris. *** NOTE *** All Amstrad versions require
-; CP/M 3, so the 664 version must both have the system upgraded to
-; CP/M 3 and have an aditional RAM pack. All Amstrad systems require
-; a serial interface.
-;
-; edit 18, 30 March, 1986. OBSchou.
-; * * * Here Begineth kermit-80 Version 4.09 * * *
-;
-; Biggest change is the overlay address has been moved (again) to 6000h
-; and the files have all been diced into families. M80 (almost) back
-; in, though I have found some bugs. Will worry about those later.
-; CPXSYS.ASM (CP4SYS.ASM in V4.05) now is a family file as well.
-;
-; Comments and all that would be much appreciated.
-;
-; Bertil Schou,
-; The Computer Centre,
-; Loughborough University of Technology,
-; Loughborough
-; Leicestershire, LE11 3TU
-; Great Britain
-;
-; tel (0509) 222313
-; E-Mail (Janet) OBSchou at LOUGHBOROUGH.MULTICS
-;
-;
-; edit 17, March 15, by OBSchou to add in support for M80 Macro Assembler.
-; Now its a little messy using the M80 Assembler,asn we have family files
-; and how are we gonna tell M80 what files to use?
-; Sort of Simple: we generate a set of EQUs that only INCLUDE the family
-; file being assembled. I hope.
-;
-; edit 16 Dec 1st, 1986 by OBSchou. Added entry for Amstrad PCW range (PCW)
-; Code in Family file CPXPCW.ASM, submitted by Ian Young of Lattice
-; Logic Systems.
-;
-; Edit 15 June 20 1986. Had to chand org address to 5000h to give room for
-; multi-fcb space for DIR command and other additions in the system
-; indepentent part. This starts Kermit-80 version 4.08...
-;
-; Edit 14: March 20, 1986 by OBSchou Loughborough University for
-; B Robertson, Aberdeen Univ. Computing Centre.
-; Add support for APPLE II with serial cards based on the 6850 ACIA.
-; Mod 380Z support to allow both MDS (5 1/4" discs) and FDS (8" discs)
-; configurations. Any mistakes on this merge all my fault (OBSchou)
-;
-; edit 13 22 April, 1986 by OBSchou Loughborough University
-; Changed org address to 4000h to allow for mods to the system
-; independent part for kermit version 4.06
-;
-; edit 12 5 Febuary, 1986 by OBSchou
-; merged in conditionals for Epson PX8 (px8). Code from Tony Addyman
-; Salford University, England.
-; Added code from other contibutors for Basic Northstar (basicns),
-; Access-Matrix (access), US Micro Sales s1008 (s1008),
-; Micro Mate (mmate), A.C.E. Discovery (disc).
-; These I cannot test: please send comments back if these are buggy.
-;
-; edit 11 29 January 1985 by OBSchou @ multics.lut.ac.uk
-; added in code for 2651 USART for use with CP/M and a VDU
-;
-; edit 10: 21 November, 1985 by ajcole @ leeds.ai
-; Merged in support for the following:
-; North Star Horizon without SIO-4 (horizon)
-; Comart Communicator (comart)
-; Cromemco TU-ART interface (cmemco)
-; TVI912/920 VDUs (tvi912)
-;
-; edit 9 24 October by OBSchou. Merged code from B Robertson from
-; Aberdeen University. He writes:
-; September 20, 1985 by B Robertson, Aberdeen Univ. Computing Centre.
-; Add support for Research Machines 380Z, North Star Advantage, Acorn
-; BBC with Z80 co-processor and APPLE II with Mountain Computers CPS
-; Multifunction card.
-;
-; edit 8: 11 October, 1985 by OBSchou
-; tidied up code around Superbrain main/aux port business
-;
-; edit 7: 11 June, 1985 by O B Schou, Loughborough University of Tech.
-; Loughborough, Leics, England.
-; Added code for Torch (Second processor to BBC-B) and Cifer 1886
-; Hopefully this code will work with Torchpacks, and Cifer 26xx
-; and 28xx series computers. Edits marked by OBS
-;
-; edit 6: 9-Feb-85 by CJC
-; Merge Northstar Horizon, Lobo MAX, and Xerox 820 changes:
-; 13-Dec-84 Add Northstar Horizon with SIO-4 board, port 5 at 1200 [CSM]
-; 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
-;
-;pcc001 27-Dec-84 vjc modules: cp4sys,cp4typ
-; Add conditional for Xerox 820. I thought at first I could
-; live with the kaypro conditional, but it's enough of a pain
-; that I added it back in. The clear-to-end-of-screen char
-; is different, breaking many programs in VT52 mode, and the
-; default escape char control-\, is not at all obvious how
-; to type on the 820 keyboard. If you muddle through the
-; key translation table, it turns out to be control-comma.
-; Rather than OR xer820 all the occurances of kpII conditionals
-; I added a bbI conditional for all common code for the big
-; board I based machines that is automatically turned on by
-; either kpII or xer820. This will also make it easier in
-; the future if another flavor of bigboard is added.
-;
-;pcc010 2-Jan-85 vjc modules:cp4pkt,cp4typ
-; Control-C during send or recieve clobbers some of the screen
-; and doesn't look nice. Position the cursor to end of screen
-; before returning to main loop.
-;
-;pcc013 8-Jan-85 vjc modules:cp4mit,cp4utl,cp4typ
-; Replace CLOSE command to cancel session logging to SET
-; LOGGING ON/OFF. This seems to fit in with the command
-; structure better. Default the log file to KERMIT.LOG
-; incase no previous LOG command. Logging is also enabled
-; by LOG command, as before.
-;
-; edit 5: October 13, 1984 by L M Jones, JCC, for New York Botanical Garden
-; Add support for CPT-85xx series of word processors when running CP/M.
-;
-; edit 4: August 29, 1984 by Bdale Garbee @ CMU
-; Add support for Digicomp Delphi 100 and Netronics Smartvid terminal.
-;
-; edit 3: July 27, 1984 (CJC)
-; Shuffle files around for easier assembly by both M80 and LASM.
-;
-; edit 2: June 4, 1984 [Toad Hall]
-; Added Morrow Decision I (the big S100 bus sucker, not the
-; little single motherboard one); added Toad Hall TACTrap to deal
-; with those working through a TAC and its intercept character.
-;
-; edit 1: May, 1984 (CJC)
-; extracted from CPMBASE.M80 version 3.9; modifications are described
-; in the accompanying .UPD file.
-;
-
-FALSE EQU 0
-TRUE EQU NOT FALSE
-
-;
-; Assembler type. Define the appropriate one TRUE, the rest FALSE. (We can't
-; use ASM, because it cannot handle multiple input files)
-mac80 EQU FALSE ; For assembly via MAC80 cross-assembler.
-m80 EQU FALSE ; For assembly via Microsoft's M80.
-lasm EQU TRUE ; For assembly via LASM, a public-domain
- ; assembler.
-;
-; Address at which the overlay should be loaded. This will not
-; change often (no more than once per version of KERMIT); it should
-; be updated when a new version of KERMIT is released.
-;
-
-ovladr EQU 7000H ; [18] address = 6c00h for Kermit v4.10
- ;[MF]...
-
-cpsker EQU FALSE ; building the system-dependent part...
-
-; SET some options to FALSE, then SET them TRUE if needed
-iobyt SET FALSE ;assume we dont want IOBYTE..
-inout SET FALSE ;... or IN/OUT code
-termin SET FALSE ; we are not using a terminal
-; Also set the CPU speed to a default 2.0 Mhz
-cpuspd SET 20 ; default to 2 Mhz, in case we dont know
-; Assume kit is Z80 based, and set z80 false for non z80 systems.
-;z80 SET TRUE
-
-;Which CP/M system hardware are we building KERMIT-80 for?
-;One of the following should be TRUE, the rest FALSE:
-;
-;We have basically three "classes" of systems:
-
-;Systems supporting the IO-redirection via I/O-Byte
-
-bbc EQU FALSE ;[9] Acorn BBC model B
-;added code by JAS
-cifer2 EQU FALSE ; Cifer 1886 using io byte flipping [OBS]
-cifer3 EQU FALSE ; Cifer 1886 with CP/M Plus [JAS]
- ; (Not IOBYTE but easier to keep together)
-cifaux EQU FALSE ; One of above Cifers using AUX port else VL port
-dmII EQU FALSE ;"Generic" KERMIT-80 for DECMATE II.
-gener EQU FALSE ;"Generic" Kermit-80, CP/M calls only.
- ; (terminal required)
-mikko EQU FALSE ;"Generic" KERMIT-80 for MikroMikko
-robin EQU FALSE ;DEC VT180 = Generic + VT100 screen control
-
-;.. \and Systems supporting direct IN / OUT handling of ports
-advant EQU FALSE ;[10] North Star Advantage
-access EQU FALSE ; Access Matrix .. uses port J5 [12]
- ; (terminal required) [MF]
-ampro EQU FALSE ; Ampro Little Board (terminal required)
-basicns EQU FALSE ; Basic Northstar using printer port (CRT req.)
-bbII EQU FALSE ;BigBoard II (terminal required)
-brainm EQU FALSE ;Select Superbrain Main port **[obs]
-braina EQU FALSE ;Select Superbrain AUX port **[obs]
-comart EQU FALSE ;[10] Comart Communicator
- ; (terminal required)
-compro EQU FALSE ;Compupro Interfacer 4 (or 3) [gv]
- ; (terminal required) [MF]
-cpt85xx EQU FALSE ;CPT-85xx word processor w/CPM (set ADM3A TRUE)
-cmemco EQU FALSE ;[10] Cromemco (TU-ART) (terminal required)
-delphi EQU FALSE ;Digicomp Delphi 100 (terminal required)
-disc EQU FALSE ; Action Computer Enterprises "Discovery"
- ; Port B on an 83U user board (CRT required)
-genie EQU FALSE ;Eaca Genie III
-h8quad EQU FALSE ;[24] Entry for heath-8. NOT same as H-89
-heath EQU FALSE ;For Heath/Zenith H89.
-kpII EQU FALSE ;Kaypro-II
-horizon EQU FALSE ;[10] North Star Horizon (mother-board)
- ; (terminal required)
-m2215 EQU FALSE ; BT Merlin [23] - uses 2651, Terminal rqd
-mmate EQU FALSE ; PMC - 101 MicroMate (Crt required)
-mmdI EQU FALSE ;Morrow Micro Decision I (terminal required)
-mdI EQU FALSE ;Morrow Decision I (the big sucker)
- ; (terminal required) [Toad Hall]
-ncrdmv EQU FALSE ; NCR Desision Mate V. (2651 USART) (Term rqd.)
-norths EQU FALSE ;[CSM] NorthStar Horizon with HSIO-4 board
- ; (terminal required)
-pci2651 EQU FALSE ; CP/M with 2651 USART. Needs VDU. [11]
-rm380zm EQU FALSE ;[14] Research Machines 380Z MDS (5.25" discs)
-rm380zf EQU FALSE ;[14] Research Machines 380Z FDS (8" discs)
-s1008 EQU FALSE ; US Micro Sales s1008 (Terminal required)
-sb6 EQU FALSE ; SB180 6/9 MHz cpu speed conditionals -
-sb9 EQU FALSE ; set one of these to TRUE, - it will
- ; automatically set sb180 TRUE
- ; (terminal reqd for Sb-180 systems)
-scntpr EQU FALSE ; [majoc 870305] For OEM ScreenTyper
-sanyo EQU FALSE ;For sanyo mbc-1100 series
-telcon EQU FALSE ;For TELCON Zorba portable
-teletek EQU FALSE ; Teletek SYSTEMASTER (terminal rqd)
-trs80lb EQU FALSE ;For Lifeboat 2.25C CP/M Display
-trs80pt EQU FALSE ;For Pickles + Trout CP/M Display
-trsm4 EQU FALSE ;TRS80 Model 4 under Montezuma Micro CPM 2.2
-vector EQU FALSE ;For Vector Graphics.
-xer820 EQU FALSE ;[pcc001] Xerox 820
-z100 EQU FALSE ;For Z-100 under CP/M-85.
-
-;.. and Systems doing neither...
-apmmdm EQU FALSE ;jb Micromodem II in slot 2
-ap6551 EQU FALSE ;jb apple with 6551 ACIA in serial interface
-ap6850 EQU FALSE ;[14] Apple with 6850 ACIA in serial interface
- ;[14] e.g PACT, SSM AIO, Aristocard
-apcps EQU FALSE ;[9] Apple with CP multifunction card
-cpc EQU FALSE ; Amstrad CPC CP/M Plus computers
-cpm3 EQU FALSE ;"Generic" Kermit-80 for CP/M 3.0 (CP/M Plus)
- ; (terminal required)
-lobo EQU FALSE ;Lobo Max-80
-osi EQU FALSE ;For Ohio Scientific.
-osbrn1 EQU FALSE ;For Osborne 1
-pcw EQU FALSE ; Amstrad PCW 8256/8512 computers
-px8 EQU FALSE ;[12] For Epson PX-8
-torch EQU FALSE ;[obs] Torch does comms via Beeb as IO processor
-z80mu EQU FALSE ; CP/M-80 Kermit under z80mu emulator on PC
-hp125 EQU FALSE ;[MF]HP-125 Business Assistant, 8-bit data
- ; path thru Data Comm 1, 7-bit data path
- ; thru Data Comm 2 (requires 8th-bit quoting
- ; for binary transfers on Data Comm 2)
- ; set VT52 TRUE
-mbee EQU FALSE ; Microbee Systems - Microbee
-
-;.. and for Micros, like the MDI, which have "terminals of choice", you must
-;select one of these in addition to selecting the micro itself.
-;Also select a terminal for "gener" and "cpm3": use "crt" for the TRUE generic.
-crt EQU FALSE ;Basic CRT, no cursor positioning
-adm3a EQU FALSE ;Adm3a Display (or CPT built-in display)
-adm22 EQU FALSE ;ADM 22 terminal
-h1500 EQU FALSE ;Hazeltine 1500
-smrtvd EQU FALSE ;Netronics Smartvid terminal.
-soroq EQU FALSE ;Soroq IQ-120.. this a guess [OBS]
-am230 EQU FALSE ;Ampro 230 [13]
-tvi912 EQU FALSE ;[10] TVI912/920
-tvi925 EQU FALSE ;TVI925 Display
- ; (works for Freedom 100 also) [Toad Hall]
-vt52 EQU FALSE ;VT52 or equivalent (or H19)
-vt100 EQU FALSE ;VT100 or equivalent
-wyse EQU FALSE ;Wyse 100 terminal
-;
-; Several systems are basically the same, with very slight variations,
-; so use common code. List these sysems below
-;
-cifer EQU cifer2 OR cifer3 ; DO NOT TOUCH THIS LINE
-brain EQU brainm OR braina ;For Intertec SuperBrain. **[obs]
-;
-; flag 380Z system if either selected
-;
-rm380z EQU rm380zm OR rm380zf ;[14]
-;
-trs80 EQU trs80lb OR trs80pt ; if either, flag TRS-80 system.
-bbI EQU kpII OR xer820 ;[pcc001] flag for bigboard I
-sb180 EQU sb6 OR sb9 ; Micromint SB180 (BYTE Oct 85)
-;
-; flag apple system if either selected
-;
-apple EQU apmmdm OR ap6551 OR ap6850 OR apcps
-;
-; also set termin(al) TRUE if any terminal selected (crt included)
-termin SET crt OR adm3a OR adm22 OR h1500 OR smrtvd OR am230
-termin SET termin OR tvi912 OR tvi925 OR vt52 OR vt100
-termin SET termin OR wyse OR soroq
-
-; Now set iobyt or inout TRUE for those systems doing so
-; IOBYTE systems...
-IF robin OR dmII OR gener OR mikko OR cifer2 OR bbc;[**obs]
-iobyt SET TRUE ;Short conditional for above
-ENDIF;robin OR dmII OR gener OR cifer2 OR bbc
-
-; INOUT systems...
-IF brain OR vector OR sanyo or compro
-inout SET TRUE ;Short conditional for above
-ENDIF;brain OR vector OR sanyo OR compro
-
-IF heath OR h8quad OR z100 OR trs80 OR telcon OR bbI
-inout SET TRUE ;Short conditional for above
-ENDIF;heath OR h8quad OR z100 OR trs80 OR telcon OR bbI
-
-IF bbII OR mmdI OR mdI OR delphi OR cpt85xx OR norths ;running out of room
-inout SET TRUE ;Short conditional for above
-ENDIF;bbII OR mmdI OR mdI OR delphi OR cpt85xx OR norths
-
-IF advant OR rm380z OR comart OR horizon OR cmemco ;[9] [10] more room here
-inout SET TRUE ;Short conditional for above
-ENDIF;advant OR rm380z OR comart OR horizon OR cmemco
-
-IF pci2651 OR m2215 OR sb180 OR ncrdmv OR teletek;[11] and even more room
-inout SET TRUE ;Short conditional for above
-ENDIF ;pci2651 OR m2215 OR sb180 OR ncrdmv OR teletek [11]
-
-IF access OR basicns OR s1008 OR mmate OR disc ; [12]
-inout SET TRUE ;Short conditional for above
-ENDIF ; access OR basicns OR s1008 OR mmate OR disc [12]
-
-IF genie OR trsm4 OR ampro
-inout SET TRUE ;Short conditional for above
-ENDIF ; genie OR trsm4 OR ampro
-
-
-; Toad Hall TAC Trap: If you're going through a TAC, it will
-; cough on its Intercept Character (usually a @ (* - 40H)). Sending it
-; twice forces the TAC to recognize it as a valid ASCII character,
-; and it'll send only one on to the host. If you've SET the TACTrap
-; to OFF, it will be a null character, and nothing will happen. If you
-; set it on, it will be your selected TAC intercept character (or will
-; default to the common intercept char, '@'.
-; If you never expect to have to work through such a beastie, just set
-; TAC to false and forget all this mess. [Toad Hall]
-
-tac EQU FALSE ; gonna work through a TAC?
-tacval EQU '@' ;Typical TAC intercept character
-
-; Processor speed in units of 100KHz
-; for bbII, kpII, cpt85xx, advance, apple,bbc,px8 & rm380z timing loop [12]
-; We have to set these before CPXCOM to make sure we update the CPU speed.
-
-; The following systems I have no idea of cpu speed. Can anyone oblige??
-; robin, dmII, mikko, vector, heath, h8quad, z100, scntpr
-; trs80 (both), telcon, mmdI, mdI, delphi, ncrdmv,
-; cromemco, teletek, osi, lobo
-
-IF z80mu
-cpuspd SET 2 ; a PC is about 200khz Z80 equivalent
-ENDIF; z80mu
-
-IF apple OR cpt85xx OR px8 OR heath OR h8quad ;[9] [12] What rate is heath?
-cpuspd SET 20 ; Apple Softcard, CPT-85xx: 2.0 MHz
- ; ('cause of integral video?)
-ENDIF; apple OR cpt85xx OR px8 OR heath OR h8quad [12]
-
-IF kpII OR xer820 OR scntpr OR osbrn1 ;[9] What speed is scntpr??
-cpuspd SET 25 ; original Kaypro II,Xerox 820: 2.5 MHz
-ENDIF;kpII OR xer820 OR scntpr OR osbrn1
-
-IF PCW or CPC
-cpuspd SET 33 ; all 4MHz but insterted wait states
- ; reduce to an effective 3.3 MHz.
-ENDIF ;pcw OR cpc
-
-IF brain OR advant OR bbII OR torch OR z100 OR genie OR trsm4
-cpuspd SET 40 ; 4.0 MHz CPU
-ENDIF; brain OR advant OR bbII OR torch OR z100 OR genie OR trsm4
-
-IF cifer OR rm380z OR comart OR horizon OR norths
-cpuspd SET 40 ; 4.0 MHz CPU
-ENDIF; cifer OR rm380z OR comart OR horizon OR norths
-
-IF disc OR mmate OR s1008 OR access OR basicns ;[29] This is a guess.. Most are 4Mhz
-cpuspd SET 40 ; 4.0 MHz CPU
-ENDIF ;disc OR mmate OR s1008 OR access OR basicns [29]
-
-IF m2215
-cpuspd SET 50 ; BT Merlin Rair Black Box is 8085 at 5 Mhz
-ENDIF ;m2215
-
-IF bbc or sb6
-cpuspd SET 60 ; BBC or SB-180 with 6Mhz Z80/61480
-ENDIF;bbc OR sb6
-
-IF sb9
-cpuspd SET 90 ; SB-180 with 9 Mhz clock
-ENDIF;sb9
-
-IF hp125 OR telcon
-cpuspd SET 40 ;[MF]HP125 or TELCON
-ENDIF;hp125 OR telcon
-
-IF mbee
-cpuspd SET 33 ; Microbee has 3.375MHz Z80
-ENDIF; mbee
-
-; Set Z80 flag FALSE for non Z80 or unknown CPU systems
-IF FALSE ; assume all systems are not z80 based
-;z80 SET FALSE
-ENDIF ;FALSE
-
-; Now, lets see what family we are assembling for. Reset all
-; family file to FALSE
-
-torfam SET FALSE ; not Torch family file
-ciffam SET FALSE ; not Cifer kit
-appfam SET FALSE ; not Apples
-norfam SET FALSE ; not North Star kit
-pcwfam SET FALSE ; not Amstrad PCW kit
-bbifam SET FALSE ; not the BBI family
-heafam SET FALSE ; not Heath, Z100, telcon,or screentyper
-sbfam SET FALSE ; not an SB180 system
-merfam SET FALSE ; not a BT Merlin system
-sanfam SET FALSE ; not a Sanyo
-comfam SET FALSE ; not a compupro
-genfam SET FALSE ; not a genie
-trsfam SET FALSE ; not a trs-80 Model 4
-z80fam SET FALSE ; not z80mu system
-beefam SET FALSE ; not a Microbee system
-sysfam SET TRUE ; ... but assume the worst, and its in
- ; the CPXSYS.ASM file
-
-
-IF (torch OR pci2651 OR ncrdmv OR brain) ;[15]
-torfam SET TRUE ; we are to use the Torch family file
-.printx * torfam set TRUE *
-;(Yeah, I know, there are more than Torch systems in it)
-ENDIF ;(torch OR pci2651 OR ncrdmv OR brain) [15]
-
-IF (cifer)
-ciffam SET TRUE ; we are to use the cifer family file
-.printx * ciffam set TRUE *
-ENDIF ;cifer
-
-IF apple ;[15]
-appfam SET TRUE ; apples
-.printx * appfam set TRUE *
-ENDIF ;apple [15]
-
-IF (horizon OR basicns OR norths OR advant OR comart) ;[15]
-norfam SET TRUE ; north star kit
-.printx * norfam set TRUE *
-ENDIF ;(horizon OR basicns OR norths OR advant OR comart) [15]
-
-IF (pcw OR cpc) ;[15]
-pcwfam SET TRUE ; Amstrad PCW kit
-.printx * pcwfam set TRUE *
-ENDIF ;pcw OR cpc [15]
-
-IF (kpII OR xer820 OR bbII OR ampro)
-bbifam SET TRUE ; The Bigboard, Kaypro, Xerox and Ampro family
-.printx * bbifam set TRUE *
-ENDIF ;(kpII or xer820 OR bbII OR ampro)
-
-IF (heath OR h8quad OR telcon OR z100 OR scntpr)
-heafam SET TRUE ; Doing Heath, z100, telcon, or screentyper
-.printx * heafam set TRUE *
-ENDIF ;(heath OR h8quad OR telcon OR z100 OR scntpr)
-
-IF sb180
-sbfam SET TRUE ; doing an SB180 system
-.printx * sbfam set TRUE *
-ENDIF ; sb180
-
-IF m2215
-merfam SET TRUE ; doing a BT Merlin system
-.printx * merfam set TRUE *
-ENDIF ; m2215
-
-IF sanyo
-sanfam SET TRUE ; doing a Sanyo MBC-1100 system
-.printx * sanfam set TRUE *
-ENDIF ; sanyo
-
-IF compro
-comfam SET TRUE ; doing a Compupro system
-.printx * comfam set TRUE *
-ENDIF ; compro
-
-IF genie
-genfam SET TRUE ; doing a Genie system
-.printx * genfam set TRUE *
-ENDIF ; genie
-
-IF trsm4
-trsfam SET TRUE ; doing a TRS-80 M4 system
-.printx * trsfam set TRUE *
-ENDIF ; trs4m
-
-IF z80mu
-z80fam SET TRUE ; doing a z80mu emulation
-.printx * z80fam set TRUE *
-ENDIF ; z80mu
-
-IF mbee
-beefam SET TRUE ; doing a Microbee system
-.printx * beefam set TRUE *
-ENDIF ; mbee
-
-; Now, if none of the above, then its the older CPXSYS.ASM file we want
-
-IF (torfam OR ciffam OR appfam OR norfam OR sanfam OR comfam) AND sysfam
-sysfam SET FALSE ; Were not doing the CPXSYS.ASM file
-.printx * sysfam set FALSE *
-ENDIF ; (torfam OR ciffam OR appfam OR norfam OR sanfam OR comfam) AND sysfam
-
-IF (pcwfam OR bbifam OR heafam OR sbfam OR merfam) AND sysfam
-sysfam SET FALSE ; Were not doing the CPXSYS.ASM file
-.printx * sysfam set FALSE *
-ENDIF ; (pcwfam OR bbifam OR heafam OR sbfam OR merfam) AND sysfam
-
-IF (genfam OR trsfam OR z80fam OR beefam) AND sysfam
-sysfam SET FALSE ; Were not doing the CPXSYS.ASM file
-.printx * sysfam set FALSE *
-ENDIF ; (genfam OR trsfam OR z80fam OR mbeefam) AND sysfam
-
-IF sysfam
-.printx * sysfam set TRUE *
-ENDIF
-
-IF lasm
- LINK CPSDEF ; Use the system independent declares
-ENDIF;lasm [Toad Hall]
-
-; If we're still here, must be M80 or MAC80. Collect the rest of
-; the sources.
-.sfcond
-
-
- INCLUDE CPSDEF.ASM ; common definitions
- INCLUDE CPXLNK.ASM ; linkage area description
- INCLUDE CPXCOM.ASM ; include common code
- INCLUDE CPXSWT.ASM ; this wont do much, but will announce machine
-
-IF torfam ;[15]
- INCLUDE CPXTOR.ASM ; we are assembling for Torch, Cifer etc
-ENDIF ;torfam [15]
-
-IF ciffam
- INCLUDE CPXCIF.ASM ; we are assembling for a Cifer
-ENDIF ;ciffam
-
-IF appfam ;[15]
- INCLUDE CPXAPP.ASM ; we are assembling for an apple
-ENDIF ;appfam [15]
-
-IF norfam ;[15]
- INCLUDE CPXNOR.ASM ; we are assembling a NortStar machine
-ENDIF ;norfam [15]
-
-IF pcwfam ;[15]
- INCLUDE CPXPCW.ASM ; we are assembling for the Amstrad PCW machine
-ENDIF ;pcwfam [15]
-
-IF bbifam
- INCLUDE CPXBBI.ASM ; assembling for BigBoard, Kaypro, Xerox
- ; & Ampro Little Board
-ENDIF ;bbifam
-
-IF sysfam ;[15]
- INCLUDE CPXSYS.ASM ; system-dependent code and tables (Part 1)
- INCLUDE CPXSY2.ASM ; system-dependent code and tables (Part 2)
-ENDIF ;sysfam [15]
-
-IF heafam
- INCLUDE CPXHEA.ASM
-ENDIF ;heafam
-
-IF m2215
- INCLUDE CPXMRL.ASM
-ENDIF ;m2215
-
-IF sbfam
- INCLUDE CPXSB.ASM
-ENDIF ;sbfam
-
-IF sanfam
- INCLUDE CPXSYO.ASM
-ENDIF ;sanfam
-
-IF comfam
- INCLUDE CPXPRO.ASM
-ENDIF ;comfam
-
-IF genfam
- INCLUDE CPXGNI.ASM
-ENDIF ;genfam
-
-IF trsfam
- INCLUDE CPXTM4.ASM
-ENDIF ;trsfam
-
-IF z80fam
- INCLUDE CPXZ80.ASM
-ENDIF ;z80fam
-
-IF beefam
- INCLUDE CPXBEE.ASM
-ENDIF ;beefam
-
-IF termin ; any terminal selected?
- INCLUDE CPXVDU.ASM ;[15] Just in case we need a VDU...
-ENDIF ;termin
- END
+; CPXTYP.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This is the header file for building the system-dependent overlay
+; for KERMIT. It contains the definitions used to select the target
+; system, and collects (via INCLUDE or LINK directives) the remaining
+; code. If the target system is one of the supported systems
+; described below, then this is the only file that needs to be
+; edited.
+;
+; revision history:
+;
+;edit 34, 10-Jan-1991 by MF. Put in "terminal required" notation for
+; more machines that need terminals.
+;edit 33, 9-Jan-1991 by MF. Put in "terminal required" notation for Access
+; Matrix and eliminated an extra "sysfam set FALSE" when torfam set TRUE
+;edit 32, 7-Jan-1991 by MF. Added code by Jay. S. Rouman to support the
+; Ampro Little Board (see CPXBBI.ASM).
+; Also put in a couple of missing .printx's
+;edit 31, 2-Nov-1990 by MF. Moved overlay address to 7000H.
+;edit 30, 14-Sep-1990 by MF. Added INCOMPLETE-FILE flag for SET
+; INCOMPLETE-FILE
+;edit 29, 11-Sep-1990 by MF. Moved overlay address for version 4.10.
+; to 6C00H.
+; edit 28, 1st September 1990 by Russell Lang, rjl@monu1.cc.monash.edu.au
+; Added support for MicroBee (CPXBEE.ASM).
+;
+; edit 27, 28-Aug-89 by Mike Freeman, Bonneville Power Administration,
+; P.O. Box 491, Vancouver WA 98666 USA: add support for Hewlett-
+; Packard HP-125 "Business Assistant" computer using a HP-modified
+ ;CP/M Version 2.2.
+;
+; edit 26, 2 December, by OBSchou. Added code for CP/M-80 Kermit to
+; run on an IBM-PC under Z80MU. Perverse?? No, its to allow testing
+; of independent code on a PC running CP/M kermit.
+;
+; edit 25, 27 October, 1987 by OBSchou. Merged in Sanyo, CompuPro, Genie
+; and TRS Model 4 code, and added four new families.
+; CPXSYO.ASM for the Sanyo, CPXPRO.ASM for the Compupro,
+; CPXTRS.ASM for the TRS-80 Model 4, CPXGNI.ASM for the Genie.
+; Many thanks to G. Smith for these latter two systems. Also
+; added the WYSE 100 Terminal type to the VDU table.
+;
+; edit 24, 17 July, 1987 by OBSchou. Added (hopefully) code from
+; CP/M Kermit 3.5 (WOW) for the Heath 8. (h8quad) The actual code
+; has been put into the CPXHEA.ASM family file, but I do not actually
+; *KNOW* if this new version works. Anyone willing to test it out??
+;
+; edit 23 16 July, 1987 for for Will Rose:
+; edit of 15 Jan 1987 by C W Rose
+; Added code for Micromint SB180 and Ampro 230 terminal.
+;
+; edit of 10 Apr 87 by C W Rose
+; Amended code for pci2651 to handle Telecom Merlin M2215.
+; (8085 at 5 MHz, 2651 USART, port TTY1:, Ampro 230 terminal equivalent).
+;
+; edit of 13 Jul 1987 by C W Rose
+; Added Micromint SB180 with 6/9 MHz. option.
+;
+; edit 22, 15th July, 1987 by OBSchou for David Moore.
+; David submitted a paper copy of Kermit 4.05 overlay for a Teletek
+; system: I have (hopefully) correctly appended his code. He also
+; send in the code for ADM 22 terminals.
+;
+; edit 21, 14 July, 1986 by OBSchou for John Shearwood of Birmingham
+; University. His edits:
+; edit of Apr 7th, 1987 by JA Shearwood. Added entry for Cifer Aux port
+; edit of Mar 24 1987 by JA Shearwood, Birmingham. Added code for Cifer
+; 1886 with CP/M Plus
+;
+; Also added in code from Chris Miles:
+; edit of 19 May 26, 1987 by C.J.MILES@UMRCC.
+; Kaypro II, Xerox 820 and Big Board II code seperated
+; from CPXSYS.ASM and put in a new family file called
+; CPXBBI.ASM.
+;
+; Finally added code from MJ Carter of Nottingham University:
+; edit 16a of 5th Mar 1987 by M J Carter, Nottingham Uni [majoc], to add
+; entry for OEM ScreenTyper (scntpr). See also CPXFRK.ASM ("fork"),
+; the tail end of CPXLNK.ASM, and the Heath-Zenith family file
+; CPXHEA.ASM (heath, z100, telcon, and scntpr).
+;
+; [Note: Martins CPXFRK is another version of CPXSWT.ASM]
+;
+;
+; edit 20, 21 May 1987 by OBSchou for Colin Burns of the Institute
+; of Neurological Sciences, Glasgow. Added flag for Hazeltine 1500
+; VDU (h1500)
+;
+; edit 19, 6th April, 1987 by OBSchou.
+; Added in EQUs for Amstrad 664 and 6128 machines (CPC) and NCR
+; Decsision mate V, bot sets of code submitted by Chris Miles of
+; Manchester University. NCR code is similar to the PCI2651 code, so
+; NCRDMV chains to CPXTOR.ASM. CPC cahins to the modified CPXPCW file
+; as submitted by Chris. *** NOTE *** All Amstrad versions require
+; CP/M 3, so the 664 version must both have the system upgraded to
+; CP/M 3 and have an aditional RAM pack. All Amstrad systems require
+; a serial interface.
+;
+; edit 18, 30 March, 1986. OBSchou.
+; * * * Here Begineth kermit-80 Version 4.09 * * *
+;
+; Biggest change is the overlay address has been moved (again) to 6000h
+; and the files have all been diced into families. M80 (almost) back
+; in, though I have found some bugs. Will worry about those later.
+; CPXSYS.ASM (CP4SYS.ASM in V4.05) now is a family file as well.
+;
+; Comments and all that would be much appreciated.
+;
+; Bertil Schou,
+; The Computer Centre,
+; Loughborough University of Technology,
+; Loughborough
+; Leicestershire, LE11 3TU
+; Great Britain
+;
+; tel (0509) 222313
+; E-Mail (Janet) OBSchou at LOUGHBOROUGH.MULTICS
+;
+;
+; edit 17, March 15, by OBSchou to add in support for M80 Macro Assembler.
+; Now its a little messy using the M80 Assembler,asn we have family files
+; and how are we gonna tell M80 what files to use?
+; Sort of Simple: we generate a set of EQUs that only INCLUDE the family
+; file being assembled. I hope.
+;
+; edit 16 Dec 1st, 1986 by OBSchou. Added entry for Amstrad PCW range (PCW)
+; Code in Family file CPXPCW.ASM, submitted by Ian Young of Lattice
+; Logic Systems.
+;
+; Edit 15 June 20 1986. Had to chand org address to 5000h to give room for
+; multi-fcb space for DIR command and other additions in the system
+; indepentent part. This starts Kermit-80 version 4.08...
+;
+; Edit 14: March 20, 1986 by OBSchou Loughborough University for
+; B Robertson, Aberdeen Univ. Computing Centre.
+; Add support for APPLE II with serial cards based on the 6850 ACIA.
+; Mod 380Z support to allow both MDS (5 1/4" discs) and FDS (8" discs)
+; configurations. Any mistakes on this merge all my fault (OBSchou)
+;
+; edit 13 22 April, 1986 by OBSchou Loughborough University
+; Changed org address to 4000h to allow for mods to the system
+; independent part for kermit version 4.06
+;
+; edit 12 5 Febuary, 1986 by OBSchou
+; merged in conditionals for Epson PX8 (px8). Code from Tony Addyman
+; Salford University, England.
+; Added code from other contibutors for Basic Northstar (basicns),
+; Access-Matrix (access), US Micro Sales s1008 (s1008),
+; Micro Mate (mmate), A.C.E. Discovery (disc).
+; These I cannot test: please send comments back if these are buggy.
+;
+; edit 11 29 January 1985 by OBSchou @ multics.lut.ac.uk
+; added in code for 2651 USART for use with CP/M and a VDU
+;
+; edit 10: 21 November, 1985 by ajcole @ leeds.ai
+; Merged in support for the following:
+; North Star Horizon without SIO-4 (horizon)
+; Comart Communicator (comart)
+; Cromemco TU-ART interface (cmemco)
+; TVI912/920 VDUs (tvi912)
+;
+; edit 9 24 October by OBSchou. Merged code from B Robertson from
+; Aberdeen University. He writes:
+; September 20, 1985 by B Robertson, Aberdeen Univ. Computing Centre.
+; Add support for Research Machines 380Z, North Star Advantage, Acorn
+; BBC with Z80 co-processor and APPLE II with Mountain Computers CPS
+; Multifunction card.
+;
+; edit 8: 11 October, 1985 by OBSchou
+; tidied up code around Superbrain main/aux port business
+;
+; edit 7: 11 June, 1985 by O B Schou, Loughborough University of Tech.
+; Loughborough, Leics, England.
+; Added code for Torch (Second processor to BBC-B) and Cifer 1886
+; Hopefully this code will work with Torchpacks, and Cifer 26xx
+; and 28xx series computers. Edits marked by OBS
+;
+; edit 6: 9-Feb-85 by CJC
+; Merge Northstar Horizon, Lobo MAX, and Xerox 820 changes:
+; 13-Dec-84 Add Northstar Horizon with SIO-4 board, port 5 at 1200 [CSM]
+; 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809
+;
+;pcc001 27-Dec-84 vjc modules: cp4sys,cp4typ
+; Add conditional for Xerox 820. I thought at first I could
+; live with the kaypro conditional, but it's enough of a pain
+; that I added it back in. The clear-to-end-of-screen char
+; is different, breaking many programs in VT52 mode, and the
+; default escape char control-\, is not at all obvious how
+; to type on the 820 keyboard. If you muddle through the
+; key translation table, it turns out to be control-comma.
+; Rather than OR xer820 all the occurances of kpII conditionals
+; I added a bbI conditional for all common code for the big
+; board I based machines that is automatically turned on by
+; either kpII or xer820. This will also make it easier in
+; the future if another flavor of bigboard is added.
+;
+;pcc010 2-Jan-85 vjc modules:cp4pkt,cp4typ
+; Control-C during send or recieve clobbers some of the screen
+; and doesn't look nice. Position the cursor to end of screen
+; before returning to main loop.
+;
+;pcc013 8-Jan-85 vjc modules:cp4mit,cp4utl,cp4typ
+; Replace CLOSE command to cancel session logging to SET
+; LOGGING ON/OFF. This seems to fit in with the command
+; structure better. Default the log file to KERMIT.LOG
+; incase no previous LOG command. Logging is also enabled
+; by LOG command, as before.
+;
+; edit 5: October 13, 1984 by L M Jones, JCC, for New York Botanical Garden
+; Add support for CPT-85xx series of word processors when running CP/M.
+;
+; edit 4: August 29, 1984 by Bdale Garbee @ CMU
+; Add support for Digicomp Delphi 100 and Netronics Smartvid terminal.
+;
+; edit 3: July 27, 1984 (CJC)
+; Shuffle files around for easier assembly by both M80 and LASM.
+;
+; edit 2: June 4, 1984 [Toad Hall]
+; Added Morrow Decision I (the big S100 bus sucker, not the
+; little single motherboard one); added Toad Hall TACTrap to deal
+; with those working through a TAC and its intercept character.
+;
+; edit 1: May, 1984 (CJC)
+; extracted from CPMBASE.M80 version 3.9; modifications are described
+; in the accompanying .UPD file.
+;
+
+FALSE EQU 0
+TRUE EQU NOT FALSE
+
+;
+; Assembler type. Define the appropriate one TRUE, the rest FALSE. (We can't
+; use ASM, because it cannot handle multiple input files)
+mac80 EQU FALSE ; For assembly via MAC80 cross-assembler.
+m80 EQU FALSE ; For assembly via Microsoft's M80.
+lasm EQU TRUE ; For assembly via LASM, a public-domain
+ ; assembler.
+;
+; Address at which the overlay should be loaded. This will not
+; change often (no more than once per version of KERMIT); it should
+; be updated when a new version of KERMIT is released.
+;
+
+ovladr EQU 7000H ; [18] address = 6c00h for Kermit v4.10
+ ;[MF]...
+
+cpsker EQU FALSE ; building the system-dependent part...
+
+; SET some options to FALSE, then SET them TRUE if needed
+iobyt SET FALSE ;assume we dont want IOBYTE..
+inout SET FALSE ;... or IN/OUT code
+termin SET FALSE ; we are not using a terminal
+; Also set the CPU speed to a default 2.0 Mhz
+cpuspd SET 20 ; default to 2 Mhz, in case we dont know
+; Assume kit is Z80 based, and set z80 false for non z80 systems.
+;z80 SET TRUE
+
+;Which CP/M system hardware are we building KERMIT-80 for?
+;One of the following should be TRUE, the rest FALSE:
+;
+;We have basically three "classes" of systems:
+
+;Systems supporting the IO-redirection via I/O-Byte
+
+bbc EQU FALSE ;[9] Acorn BBC model B
+;added code by JAS
+cifer2 EQU FALSE ; Cifer 1886 using io byte flipping [OBS]
+cifer3 EQU FALSE ; Cifer 1886 with CP/M Plus [JAS]
+ ; (Not IOBYTE but easier to keep together)
+cifaux EQU FALSE ; One of above Cifers using AUX port else VL port
+dmII EQU FALSE ;"Generic" KERMIT-80 for DECMATE II.
+gener EQU FALSE ;"Generic" Kermit-80, CP/M calls only.
+ ; (terminal required)
+mikko EQU FALSE ;"Generic" KERMIT-80 for MikroMikko
+robin EQU FALSE ;DEC VT180 = Generic + VT100 screen control
+
+;.. \and Systems supporting direct IN / OUT handling of ports
+advant EQU FALSE ;[10] North Star Advantage
+access EQU FALSE ; Access Matrix .. uses port J5 [12]
+ ; (terminal required) [MF]
+ampro EQU FALSE ; Ampro Little Board (terminal required)
+basicns EQU FALSE ; Basic Northstar using printer port (CRT req.)
+bbII EQU FALSE ;BigBoard II (terminal required)
+brainm EQU FALSE ;Select Superbrain Main port **[obs]
+braina EQU FALSE ;Select Superbrain AUX port **[obs]
+comart EQU FALSE ;[10] Comart Communicator
+ ; (terminal required)
+compro EQU FALSE ;Compupro Interfacer 4 (or 3) [gv]
+ ; (terminal required) [MF]
+cpt85xx EQU FALSE ;CPT-85xx word processor w/CPM (set ADM3A TRUE)
+cmemco EQU FALSE ;[10] Cromemco (TU-ART) (terminal required)
+delphi EQU FALSE ;Digicomp Delphi 100 (terminal required)
+disc EQU FALSE ; Action Computer Enterprises "Discovery"
+ ; Port B on an 83U user board (CRT required)
+genie EQU FALSE ;Eaca Genie III
+h8quad EQU FALSE ;[24] Entry for heath-8. NOT same as H-89
+heath EQU FALSE ;For Heath/Zenith H89.
+kpII EQU FALSE ;Kaypro-II
+horizon EQU FALSE ;[10] North Star Horizon (mother-board)
+ ; (terminal required)
+m2215 EQU FALSE ; BT Merlin [23] - uses 2651, Terminal rqd
+mmate EQU FALSE ; PMC - 101 MicroMate (Crt required)
+mmdI EQU FALSE ;Morrow Micro Decision I (terminal required)
+mdI EQU FALSE ;Morrow Decision I (the big sucker)
+ ; (terminal required) [Toad Hall]
+ncrdmv EQU FALSE ; NCR Desision Mate V. (2651 USART) (Term rqd.)
+norths EQU FALSE ;[CSM] NorthStar Horizon with HSIO-4 board
+ ; (terminal required)
+pci2651 EQU FALSE ; CP/M with 2651 USART. Needs VDU. [11]
+rm380zm EQU FALSE ;[14] Research Machines 380Z MDS (5.25" discs)
+rm380zf EQU FALSE ;[14] Research Machines 380Z FDS (8" discs)
+s1008 EQU FALSE ; US Micro Sales s1008 (Terminal required)
+sb6 EQU FALSE ; SB180 6/9 MHz cpu speed conditionals -
+sb9 EQU FALSE ; set one of these to TRUE, - it will
+ ; automatically set sb180 TRUE
+ ; (terminal reqd for Sb-180 systems)
+scntpr EQU FALSE ; [majoc 870305] For OEM ScreenTyper
+sanyo EQU FALSE ;For sanyo mbc-1100 series
+telcon EQU FALSE ;For TELCON Zorba portable
+teletek EQU FALSE ; Teletek SYSTEMASTER (terminal rqd)
+trs80lb EQU FALSE ;For Lifeboat 2.25C CP/M Display
+trs80pt EQU FALSE ;For Pickles + Trout CP/M Display
+trsm4 EQU FALSE ;TRS80 Model 4 under Montezuma Micro CPM 2.2
+vector EQU FALSE ;For Vector Graphics.
+xer820 EQU FALSE ;[pcc001] Xerox 820
+z100 EQU FALSE ;For Z-100 under CP/M-85.
+
+;.. and Systems doing neither...
+apmmdm EQU FALSE ;jb Micromodem II in slot 2
+ap6551 EQU FALSE ;jb apple with 6551 ACIA in serial interface
+ap6850 EQU FALSE ;[14] Apple with 6850 ACIA in serial interface
+ ;[14] e.g PACT, SSM AIO, Aristocard
+apcps EQU FALSE ;[9] Apple with CP multifunction card
+cpc EQU FALSE ; Amstrad CPC CP/M Plus computers
+cpm3 EQU FALSE ;"Generic" Kermit-80 for CP/M 3.0 (CP/M Plus)
+ ; (terminal required)
+lobo EQU FALSE ;Lobo Max-80
+osi EQU FALSE ;For Ohio Scientific.
+osbrn1 EQU FALSE ;For Osborne 1
+pcw EQU FALSE ; Amstrad PCW 8256/8512 computers
+px8 EQU FALSE ;[12] For Epson PX-8
+torch EQU FALSE ;[obs] Torch does comms via Beeb as IO processor
+z80mu EQU FALSE ; CP/M-80 Kermit under z80mu emulator on PC
+hp125 EQU FALSE ;[MF]HP-125 Business Assistant, 8-bit data
+ ; path thru Data Comm 1, 7-bit data path
+ ; thru Data Comm 2 (requires 8th-bit quoting
+ ; for binary transfers on Data Comm 2)
+ ; set VT52 TRUE
+mbee EQU FALSE ; Microbee Systems - Microbee
+
+;.. and for Micros, like the MDI, which have "terminals of choice", you must
+;select one of these in addition to selecting the micro itself.
+;Also select a terminal for "gener" and "cpm3": use "crt" for the TRUE generic.
+crt EQU FALSE ;Basic CRT, no cursor positioning
+adm3a EQU FALSE ;Adm3a Display (or CPT built-in display)
+adm22 EQU FALSE ;ADM 22 terminal
+h1500 EQU FALSE ;Hazeltine 1500
+smrtvd EQU FALSE ;Netronics Smartvid terminal.
+soroq EQU FALSE ;Soroq IQ-120.. this a guess [OBS]
+am230 EQU FALSE ;Ampro 230 [13]
+tvi912 EQU FALSE ;[10] TVI912/920
+tvi925 EQU FALSE ;TVI925 Display
+ ; (works for Freedom 100 also) [Toad Hall]
+vt52 EQU FALSE ;VT52 or equivalent (or H19)
+vt100 EQU FALSE ;VT100 or equivalent
+wyse EQU FALSE ;Wyse 100 terminal
+;
+; Several systems are basically the same, with very slight variations,
+; so use common code. List these sysems below
+;
+cifer EQU cifer2 OR cifer3 ; DO NOT TOUCH THIS LINE
+brain EQU brainm OR braina ;For Intertec SuperBrain. **[obs]
+;
+; flag 380Z system if either selected
+;
+rm380z EQU rm380zm OR rm380zf ;[14]
+;
+trs80 EQU trs80lb OR trs80pt ; if either, flag TRS-80 system.
+bbI EQU kpII OR xer820 ;[pcc001] flag for bigboard I
+sb180 EQU sb6 OR sb9 ; Micromint SB180 (BYTE Oct 85)
+;
+; flag apple system if either selected
+;
+apple EQU apmmdm OR ap6551 OR ap6850 OR apcps
+;
+; also set termin(al) TRUE if any terminal selected (crt included)
+termin SET crt OR adm3a OR adm22 OR h1500 OR smrtvd OR am230
+termin SET termin OR tvi912 OR tvi925 OR vt52 OR vt100
+termin SET termin OR wyse OR soroq
+
+; Now set iobyt or inout TRUE for those systems doing so
+; IOBYTE systems...
+IF robin OR dmII OR gener OR mikko OR cifer2 OR bbc;[**obs]
+iobyt SET TRUE ;Short conditional for above
+ENDIF;robin OR dmII OR gener OR cifer2 OR bbc
+
+; INOUT systems...
+IF brain OR vector OR sanyo or compro
+inout SET TRUE ;Short conditional for above
+ENDIF;brain OR vector OR sanyo OR compro
+
+IF heath OR h8quad OR z100 OR trs80 OR telcon OR bbI
+inout SET TRUE ;Short conditional for above
+ENDIF;heath OR h8quad OR z100 OR trs80 OR telcon OR bbI
+
+IF bbII OR mmdI OR mdI OR delphi OR cpt85xx OR norths ;running out of room
+inout SET TRUE ;Short conditional for above
+ENDIF;bbII OR mmdI OR mdI OR delphi OR cpt85xx OR norths
+
+IF advant OR rm380z OR comart OR horizon OR cmemco ;[9] [10] more room here
+inout SET TRUE ;Short conditional for above
+ENDIF;advant OR rm380z OR comart OR horizon OR cmemco
+
+IF pci2651 OR m2215 OR sb180 OR ncrdmv OR teletek;[11] and even more room
+inout SET TRUE ;Short conditional for above
+ENDIF ;pci2651 OR m2215 OR sb180 OR ncrdmv OR teletek [11]
+
+IF access OR basicns OR s1008 OR mmate OR disc ; [12]
+inout SET TRUE ;Short conditional for above
+ENDIF ; access OR basicns OR s1008 OR mmate OR disc [12]
+
+IF genie OR trsm4 OR ampro
+inout SET TRUE ;Short conditional for above
+ENDIF ; genie OR trsm4 OR ampro
+
+
+; Toad Hall TAC Trap: If you're going through a TAC, it will
+; cough on its Intercept Character (usually a @ (* - 40H)). Sending it
+; twice forces the TAC to recognize it as a valid ASCII character,
+; and it'll send only one on to the host. If you've SET the TACTrap
+; to OFF, it will be a null character, and nothing will happen. If you
+; set it on, it will be your selected TAC intercept character (or will
+; default to the common intercept char, '@'.
+; If you never expect to have to work through such a beastie, just set
+; TAC to false and forget all this mess. [Toad Hall]
+
+tac EQU FALSE ; gonna work through a TAC?
+tacval EQU '@' ;Typical TAC intercept character
+
+; Processor speed in units of 100KHz
+; for bbII, kpII, cpt85xx, advance, apple,bbc,px8 & rm380z timing loop [12]
+; We have to set these before CPXCOM to make sure we update the CPU speed.
+
+; The following systems I have no idea of cpu speed. Can anyone oblige??
+; robin, dmII, mikko, vector, heath, h8quad, z100, scntpr
+; trs80 (both), telcon, mmdI, mdI, delphi, ncrdmv,
+; cromemco, teletek, osi, lobo
+
+IF z80mu
+cpuspd SET 2 ; a PC is about 200khz Z80 equivalent
+ENDIF; z80mu
+
+IF apple OR cpt85xx OR px8 OR heath OR h8quad ;[9] [12] What rate is heath?
+cpuspd SET 20 ; Apple Softcard, CPT-85xx: 2.0 MHz
+ ; ('cause of integral video?)
+ENDIF; apple OR cpt85xx OR px8 OR heath OR h8quad [12]
+
+IF kpII OR xer820 OR scntpr OR osbrn1 ;[9] What speed is scntpr??
+cpuspd SET 25 ; original Kaypro II,Xerox 820: 2.5 MHz
+ENDIF;kpII OR xer820 OR scntpr OR osbrn1
+
+IF PCW or CPC
+cpuspd SET 33 ; all 4MHz but insterted wait states
+ ; reduce to an effective 3.3 MHz.
+ENDIF ;pcw OR cpc
+
+IF brain OR advant OR bbII OR torch OR z100 OR genie OR trsm4
+cpuspd SET 40 ; 4.0 MHz CPU
+ENDIF; brain OR advant OR bbII OR torch OR z100 OR genie OR trsm4
+
+IF cifer OR rm380z OR comart OR horizon OR norths
+cpuspd SET 40 ; 4.0 MHz CPU
+ENDIF; cifer OR rm380z OR comart OR horizon OR norths
+
+IF disc OR mmate OR s1008 OR access OR basicns ;[29] This is a guess.. Most are 4Mhz
+cpuspd SET 40 ; 4.0 MHz CPU
+ENDIF ;disc OR mmate OR s1008 OR access OR basicns [29]
+
+IF m2215
+cpuspd SET 50 ; BT Merlin Rair Black Box is 8085 at 5 Mhz
+ENDIF ;m2215
+
+IF bbc or sb6
+cpuspd SET 60 ; BBC or SB-180 with 6Mhz Z80/61480
+ENDIF;bbc OR sb6
+
+IF sb9
+cpuspd SET 90 ; SB-180 with 9 Mhz clock
+ENDIF;sb9
+
+IF hp125 OR telcon
+cpuspd SET 40 ;[MF]HP125 or TELCON
+ENDIF;hp125 OR telcon
+
+IF mbee
+cpuspd SET 33 ; Microbee has 3.375MHz Z80
+ENDIF; mbee
+
+; Set Z80 flag FALSE for non Z80 or unknown CPU systems
+IF FALSE ; assume all systems are not z80 based
+;z80 SET FALSE
+ENDIF ;FALSE
+
+; Now, lets see what family we are assembling for. Reset all
+; family file to FALSE
+
+torfam SET FALSE ; not Torch family file
+ciffam SET FALSE ; not Cifer kit
+appfam SET FALSE ; not Apples
+norfam SET FALSE ; not North Star kit
+pcwfam SET FALSE ; not Amstrad PCW kit
+bbifam SET FALSE ; not the BBI family
+heafam SET FALSE ; not Heath, Z100, telcon,or screentyper
+sbfam SET FALSE ; not an SB180 system
+merfam SET FALSE ; not a BT Merlin system
+sanfam SET FALSE ; not a Sanyo
+comfam SET FALSE ; not a compupro
+genfam SET FALSE ; not a genie
+trsfam SET FALSE ; not a trs-80 Model 4
+z80fam SET FALSE ; not z80mu system
+beefam SET FALSE ; not a Microbee system
+sysfam SET TRUE ; ... but assume the worst, and its in
+ ; the CPXSYS.ASM file
+
+
+IF (torch OR pci2651 OR ncrdmv OR brain) ;[15]
+torfam SET TRUE ; we are to use the Torch family file
+.printx * torfam set TRUE *
+;(Yeah, I know, there are more than Torch systems in it)
+ENDIF ;(torch OR pci2651 OR ncrdmv OR brain) [15]
+
+IF (cifer)
+ciffam SET TRUE ; we are to use the cifer family file
+.printx * ciffam set TRUE *
+ENDIF ;cifer
+
+IF apple ;[15]
+appfam SET TRUE ; apples
+.printx * appfam set TRUE *
+ENDIF ;apple [15]
+
+IF (horizon OR basicns OR norths OR advant OR comart) ;[15]
+norfam SET TRUE ; north star kit
+.printx * norfam set TRUE *
+ENDIF ;(horizon OR basicns OR norths OR advant OR comart) [15]
+
+IF (pcw OR cpc) ;[15]
+pcwfam SET TRUE ; Amstrad PCW kit
+.printx * pcwfam set TRUE *
+ENDIF ;pcw OR cpc [15]
+
+IF (kpII OR xer820 OR bbII OR ampro)
+bbifam SET TRUE ; The Bigboard, Kaypro, Xerox and Ampro family
+.printx * bbifam set TRUE *
+ENDIF ;(kpII or xer820 OR bbII OR ampro)
+
+IF (heath OR h8quad OR telcon OR z100 OR scntpr)
+heafam SET TRUE ; Doing Heath, z100, telcon, or screentyper
+.printx * heafam set TRUE *
+ENDIF ;(heath OR h8quad OR telcon OR z100 OR scntpr)
+
+IF sb180
+sbfam SET TRUE ; doing an SB180 system
+.printx * sbfam set TRUE *
+ENDIF ; sb180
+
+IF m2215
+merfam SET TRUE ; doing a BT Merlin system
+.printx * merfam set TRUE *
+ENDIF ; m2215
+
+IF sanyo
+sanfam SET TRUE ; doing a Sanyo MBC-1100 system
+.printx * sanfam set TRUE *
+ENDIF ; sanyo
+
+IF compro
+comfam SET TRUE ; doing a Compupro system
+.printx * comfam set TRUE *
+ENDIF ; compro
+
+IF genie
+genfam SET TRUE ; doing a Genie system
+.printx * genfam set TRUE *
+ENDIF ; genie
+
+IF trsm4
+trsfam SET TRUE ; doing a TRS-80 M4 system
+.printx * trsfam set TRUE *
+ENDIF ; trs4m
+
+IF z80mu
+z80fam SET TRUE ; doing a z80mu emulation
+.printx * z80fam set TRUE *
+ENDIF ; z80mu
+
+IF mbee
+beefam SET TRUE ; doing a Microbee system
+.printx * beefam set TRUE *
+ENDIF ; mbee
+
+; Now, if none of the above, then its the older CPXSYS.ASM file we want
+
+IF (torfam OR ciffam OR appfam OR norfam OR sanfam OR comfam) AND sysfam
+sysfam SET FALSE ; Were not doing the CPXSYS.ASM file
+.printx * sysfam set FALSE *
+ENDIF ; (torfam OR ciffam OR appfam OR norfam OR sanfam OR comfam) AND sysfam
+
+IF (pcwfam OR bbifam OR heafam OR sbfam OR merfam) AND sysfam
+sysfam SET FALSE ; Were not doing the CPXSYS.ASM file
+.printx * sysfam set FALSE *
+ENDIF ; (pcwfam OR bbifam OR heafam OR sbfam OR merfam) AND sysfam
+
+IF (genfam OR trsfam OR z80fam OR beefam) AND sysfam
+sysfam SET FALSE ; Were not doing the CPXSYS.ASM file
+.printx * sysfam set FALSE *
+ENDIF ; (genfam OR trsfam OR z80fam OR mbeefam) AND sysfam
+
+IF sysfam
+.printx * sysfam set TRUE *
+ENDIF
+
+IF lasm
+ LINK CPSDEF ; Use the system independent declares
+ENDIF;lasm [Toad Hall]
+
+; If we're still here, must be M80 or MAC80. Collect the rest of
+; the sources.
+.sfcond
+
+
+ INCLUDE CPSDEF.ASM ; common definitions
+ INCLUDE CPXLNK.ASM ; linkage area description
+ INCLUDE CPXCOM.ASM ; include common code
+ INCLUDE CPXSWT.ASM ; this wont do much, but will announce machine
+
+IF torfam ;[15]
+ INCLUDE CPXTOR.ASM ; we are assembling for Torch, Cifer etc
+ENDIF ;torfam [15]
+
+IF ciffam
+ INCLUDE CPXCIF.ASM ; we are assembling for a Cifer
+ENDIF ;ciffam
+
+IF appfam ;[15]
+ INCLUDE CPXAPP.ASM ; we are assembling for an apple
+ENDIF ;appfam [15]
+
+IF norfam ;[15]
+ INCLUDE CPXNOR.ASM ; we are assembling a NortStar machine
+ENDIF ;norfam [15]
+
+IF pcwfam ;[15]
+ INCLUDE CPXPCW.ASM ; we are assembling for the Amstrad PCW machine
+ENDIF ;pcwfam [15]
+
+IF bbifam
+ INCLUDE CPXBBI.ASM ; assembling for BigBoard, Kaypro, Xerox
+ ; & Ampro Little Board
+ENDIF ;bbifam
+
+IF sysfam ;[15]
+ INCLUDE CPXSYS.ASM ; system-dependent code and tables (Part 1)
+ INCLUDE CPXSY2.ASM ; system-dependent code and tables (Part 2)
+ENDIF ;sysfam [15]
+
+IF heafam
+ INCLUDE CPXHEA.ASM
+ENDIF ;heafam
+
+IF m2215
+ INCLUDE CPXMRL.ASM
+ENDIF ;m2215
+
+IF sbfam
+ INCLUDE CPXSB.ASM
+ENDIF ;sbfam
+
+IF sanfam
+ INCLUDE CPXSYO.ASM
+ENDIF ;sanfam
+
+IF comfam
+ INCLUDE CPXPRO.ASM
+ENDIF ;comfam
+
+IF genfam
+ INCLUDE CPXGNI.ASM
+ENDIF ;genfam
+
+IF trsfam
+ INCLUDE CPXTM4.ASM
+ENDIF ;trsfam
+
+IF z80fam
+ INCLUDE CPXZ80.ASM
+ENDIF ;z80fam
+
+IF beefam
+ INCLUDE CPXBEE.ASM
+ENDIF ;beefam
+
+IF termin ; any terminal selected?
+ INCLUDE CPXVDU.ASM ;[15] Just in case we need a VDU...
+ENDIF ;termin
+ END
diff --git a/cpxvdu.asm b/cpxvdu.asm
index 332fd8f..85704a6 100644
--- a/cpxvdu.asm
+++ b/cpxvdu.asm
@@ -1,462 +1,462 @@
-IF NOT lasm
-.printx * CPXVDU.ASM *
-ENDIF ;NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-;edit 6, 12-Oct-1990 by MF. Added a semicolon to the comment "If we
-; need cursor ..." so it isn't seen as an undefined symbol
-; edit 5, 20 July by OBSchou. Put in the cursor positioning code for
-; all the terminal supported, and moved the vtval EQUs and defesc EQUs
-; here if the system requires andn external terminal. If the system
-; has a 'built in' terminal (ie own scrteen driver) you will not come
-; to this file, so you must declare these three lables etc in your
-; own code.
-; This will allow only those systems requiring a terminal to require
-; CPXVDU.ASM during assembly.
-;
-; edit 4, 16 July, 1987 by OBSchou for will Rose.
-; Added code for Ampro 230 terminal
-;
-; edit 3, 15 July, 1987 by OBSchou for David Moore. Added adm22 terminal
-; codes.
-;
-; edit 2 21 May, 1987 by OBSchou. Added in definitions for Hazeltine 1500
-; submitted by Colin Burns of the Institute of Neurological Sciences
-; in Glasgow.
-; edit 1 ??? date. Split the terminal codes off from the CPXSYS.ASM file
-;
-vduver: db 'CPXVDU.ASM (6) 12-Oct-1990 $' ;file, edit version,, date.
-
-
-; First, print out what terminal (if any) we are assembling for
-
-IF crt
-.printx * generic CRT selected *
-ENDIF
-
-IF adm3a
-.printx * ADM3A selected *
-ENDIF
-
-IF adm22
-.printx * ADM22 selected *
-ENDIF
-
-IF smrtvd ;[7]
-.printx * Netronics Smartvid-80 selected *
-ENDIF ;[7]
-
-IF tvi912
-.printx * TVI912/920 selected *
-ENDIF
-
-IF tvi925
-.printx * TVI925 selected *
-ENDIF
-
-IF vt52
-.printx * VT52 selected *
-ENDIF
-
-IF vt100
-.printx * VT100 selected *
-ENDIF
-
-IF am230
-.printx * Ampro 230 terminal selected *
-ENDIF
-
-IF wyse
-.printx * Wyse 100 terminal selected *
-ENDIF
-;
-
-;
-; If we need cursor positioning, here is the code to do it
-;
-; Screen manipulation routines
-; csrpos - move to row B, column C
-;
-; csrpos for terminals that use a leadin sequence followed
-; by (row + 31.) and (column + 31.)
-;
-IF NOT (vt100 OR crt OR h1500)
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,h ; get row
- adi (' '-1) ; space is row one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,l ; get column
- adi (' '-1) ; space is column one
- mov e,a
- jmp outcon ; output it and return
-ENDIF;NOT (vt100 OR crt OR h1500)
-;
-;
-;
-;
-; csrpos for ANSI terminals
-;
-IF vt100
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; peek at coordinates
- push h ; then save away again
- mov l,h ; l = row
- mvi h,0 ; hl = row
- call nout ; output in decimal
- mvi e,';' ; follow with semicolon
- call outcon ; print it
- pop h ; restore column
- mvi h,0 ; hl = column
- call nout
- mvi e,'H' ; terminate with 'move cursor' command
- jmp outcon ; output it and return
-ENDIF;vt100
-
-;Definition for Hazeltine 1500 does things a little strange.
-;
-IF h1500
-csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,l ; get col
- nop
- nop
-; adi (' '-1) ; space is row one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,h ; get row
- adi (' '-1) ; space is column one
- mov e,a
- jmp outcon ; output it and return
-ENDIF; h1500
-
-
-IF crt ; systems without cursor positioning
-csrpos: ret ; dummy routine referenced by linkage section
-ENDIF;crt
-;
-;
-;
-; Now for the rest of CPXVDU.ASM
-;
-;
-;
-IF crt ;Set flags etc for systems with CRT selected
-defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
-vtval EQU 0FFH ; we can't support VT52 emulation
-ttytyp: db 'Generic (Dumb) CRT Terminal type selected $'
-ENDIF;crt
-
-;
-
-IF vt52 ; DEC VT52
-ttytyp: db 'VT52$'
-ENDIF;vt52
-
-IF vt52
-vtval EQU 0 ; we don't need VT52 emulation
-defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
-outlin: db esc,'H',esc,'J',cr,lf,tab,tab,'$'
-erascr: db esc,'H',esc,'J$' ;Clear screen and go home.
-eralin: db cr,esc,'K$' ;Clear line.
-curldn: db esc,'Y$' ;cursor leadin
-ttab: ;Table start location.
-ta: db esc,'A$',0 ;Cursor up.
-tb: db esc,'B$',0 ;Cursor down.
-tc: db esc,'C$',0 ;Cursor right.
-td: db esc,'D$',0 ;Cursor left
-te: db esc,'E$',0 ;Clear display
-tf: db esc,'F$',0 ;Enter Graphics Mode
-tg: db esc,'G$',0 ;Exit Graphics mode
-th: db esc,'H$',0 ;Cursor home.
-ti: db esc,'I$',0 ;Reverse linefeed.
-tj: db esc,'J$',0 ;Clear to end of screen.
-tk: db esc,'K$',0 ;Clear to end of line.
-ENDIF;vt52
-;
-
-IF adm22
-vtval EQU 1 ; we can do VT52 emulation
-defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
-ttytyp: db 'ADM22$'
-outlin: db 1ah,cr,lf,tab,tab,'$'
-erascr: db 1ah,'$' ;Clear screen and go home.
-eralin: db esc,'>$' ;Clear line.
-curldn: db esc,'=$' ;Cursor lead-in
-ttab: ;Table start location.
-ta: db 0BH,'$',0,0 ;Cursor up.
-tb: db lf,'$',0,0 ;Cursor down.
-tc: db 0CH,'$',0,0 ;Cursor right.
-td: db bs,'$',0,0 ;Cursor left
-te: db 1ah,':$',0 ;Clear display
-tf: db '$',0,0,0 ;(can't) Enter Graphics Mode
-tg: db '$',0,0,0 ;(can't) Exit Graphics mode
-th: db 1EH,'$',0,0 ;Cursor home.
-ti: db 0BH,'$',0,0 ;Reverse linefeed.
-tj: db esc,'Y$',0 ;Clear to end of screen.
-tk: db esc,'T$',0 ;Clear to end of line.
-ENDIF;adm22
-;
-
-IF am230
-; Select initial setting for VT-52 emulation flag.
-vtval EQU 1
-defesc EQU '\'-100O ;The default is Control-\ -- it's easier
-ttytyp: db 'Am230$'
-outlin: db 'Z'-64,0,0,cr,lf,'$'
-erascr: db 'Z'-64,0,0,'$' ;Clear screen and home
-eralin: db esc,'R$',0 ;Erase line
-curldn: db cr,esc,'=$' ;Cursor lead-in
-ttab: ;Table start location ;(MUST be 4 bytes each)
-ta: db 'K'-64,'$',0,0 ;Cursor up, stop at top
-tb: db 'V'-64,'$',0,0 ;Cursor down, stop at bottom
-tc: db 'L'-64,'$',0,0 ;Cursor right, stop at right
-td: db 'H'-64,'$',0,0 ;Cursor left, stop at left
-te: db 'Z'-64,0,0,'$' ;Clear display (2 pad nulls)
-tf: db '$',0,0,0 ;(can't) Enter Graphics mode
-tg: db '$',0,0,0 ;(can't) Exit Graphics mode
-th: db 1EH,'$',0,0 ;Cursor home
-ti: db esc,'j$',0 ;Reverse linefeed, scroll
-tj: db esc,'Y$',0 ;Clear to end of sreen
-tk: db esc,'T$',0 ;Clear to end of line
-ENDIF
-;
-;
-
-
-IF vt100
-ttytyp: db 'VT100$'
-ENDIF;vt100
-
-
-IF vt100
-; Note that we cannot support Graphics Mode or the H19 erase-screen command
-; (<esc>E), because the sequences are more than three bytes.
-defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
-vtval EQU 0 ; we probably don't want VT52 emulation
-outlin: db esc,3CH,esc,'[H',esc,'[J',cr,lf,tab,tab,'$'
-erascr: db esc,'[H',esc,'[J$' ;Clear screen and go home.
-eralin: db cr,esc,'[K$' ;Clear line.
-curldn: db esc,'[$' ; Cursor leadin
-ttab:
-ta: db esc,'[A$' ; Cursor up.
-tb: db esc,'[B$' ; Cursor down.
-tc: db esc,'[C$' ; Cursor right.
-td: db esc,'[D$' ; Cursor left
-te: db '$',0,0,0 ; (can't) Clear display
-tf: db '$',0,0,0 ; (don't) Enter Graphics Mode
-tg: db '$',0,0,0 ; (don't) Exit Graphics mode
-th: db esc,'[H$' ; Cursor home.
-ti: db esc,'M$',0 ; Reverse linefeed.
-tj: db esc,'[J$' ; Clear to end of screen.
-tk: db esc,'[K$' ; Clear to end of line.
-ENDIF;vt100
-;
-
-IF gener or cpm3
-sysver: db 'Generic CP/M-80$'
-ENDIF;gener or cpm3
-
-
-IF soroq ;[29] Should this not be with terminals.....
-ttytyp: db 'Soroc IQ-120$'
-outlin: db 1EH,esc,'Y',cr,lf,tab,tab,'$'
-erascr: db 1EH,esc,'Y$' ;clear screen and home cursor
-eralin: db cr,esc,'T$' ;clear line
-curldn: db esc,'=$' ;cursor lead-in string
-delstr: db bs,' ',bs,bs,'$' ;??adjust for echoing delete
-ttab: ;table start location
-ta: db 0BH,'$',0 ;cursor up
-tb: db 0AH,'$',0 ;cursor down
-tc: db 0CH,'$',0 ;cursor right
-td: db 08H,'$',0 ;cursor left
-te: db esc,'*$',0 ;clear display (homes cursor)
-tf: db esc,')$',0 ;enter inverse video mode
-tg: db esc,'($',0 ;exit inverse video mode
-th: db 01EH,'$',0 ;home cursor
-ti: db 0BH,'$',0 ;reverse linefeed (insert line)
-tj: db esc,'Y$',0 ;clear to end of screen
-tk: db esc,'T$',0 ;clear to end of line
-ENDIF;soroq
-
-IF crt
-outlin: db cr,lf,'Starting ...$'
-erascr equ crlf ;"Home & clear" (best we can do).
-eralin: db '^U',cr,lf,'$' ;Clear line.
-prpack: db cr,lf,'RPack: $'
-pspack: db cr,lf,'SPack: $'
-ttab equ 0 ; no VT52 table
-ENDIF;crt
-;
-
-IF tvi912
-vtval EQU 1 ; we do emulation
-defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
-ttytyp: db 'TVI912/920$'
-outlin: db 'Z'-64,0,0,cr,lf,'$'
-erascr: db 'Z'-64,0,0,'$' ;Clear screen and home
-eralin: db esc,'Y$',0 ;Clear to end of sreen
-curldn: db cr,esc,'=$' ;Cursor lead-in
-ttab: ;Table start location ;(MUST be 4 bytes each)
-ta: db 'K'-64,'$',0,0 ;Cursor up, stop at top
-tb: db 'J'-64,'$',0,0 ;Cursor down, stop at bottom
-tc: db 'L'-64,'$',0,0 ;Cursor right, stop at right
-td: db 'H'-64,'$',0,0 ;Cursor left, stop at left
-te: db 'Z'-64,0,0,'$' ;Clear display (2 pad nulls)
-tf: db '$',0,0,0 ;(can't) Enter Graphics mode
-tg: db '$',0,0,0 ;(can't) Exit Graphics mode
-th: db 1EH,'$',0,0 ;Cursor home
-ti: db esc,'j$',0 ;Reverse linefeed, scroll
-tj: db esc,'Y$',0 ;Clear to end of sreen
-tk: db esc,'T$',0 ;Clear to end of line
-ENDIF;tvi912
-;
-;
-
-IF tvi925
-;(incidentally, works fine for Freedom 100 also [Toad Hall])
-;adm3a entry and tvi925 entry separated to remove warning message.
-vtval EQU 1 ; we VT52 emulation
-defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
-ttytyp: db 'TVI925$'
-outlin: db 'Z'-64,0,0,cr,lf,'$'
-erascr: db 'Z'-64,0,0,'$' ;Clear screen and home
-eralin: db esc,'Y$',0 ;Clear to end of sreen
-curldn: db cr,esc,'=$' ;Cursor lead-in
-ttab: ;Table start location ;(MUST be 4 bytes each)
-ta: db 'K'-64,'$',0,0 ;Cursor up, stop at top
-tb: db 'V'-64,'$',0,0 ;Cursor down, stop at bottom
-tc: db 'L'-64,'$',0,0 ;Cursor right, stop at right
-td: db 'H'-64,'$',0,0 ;Cursor left, stop at left
-te: db 'Z'-64,0,0,'$' ;Clear display (2 pad nulls)
-tf: db '$',0,0,0 ;(can't) Enter Graphics mode
-tg: db '$',0,0,0 ;(can't) Exit Graphics mode
-th: db 1EH,'$',0,0 ;Cursor home
-ti: db esc,'j$',0 ;Reverse linefeed, scroll
-tj: db esc,'Y$',0 ;Clear to end of sreen
-tk: db esc,'T$',0 ;Clear to end of line
-ENDIF;tvi925
-;
-;
-
-IF adm3a
-defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
-ttytyp: db 'ADM3A$'
-outlin: db 'Z'-64,0,0,cr,lf,'$'
-erascr: db 'Z'-64,0,0,'$' ;Clear screen and home
-eralin: db esc,'Y$',0 ;Clear to end of sreen
-curldn: db cr,esc,'=$' ;Cursor lead-in
-ttab: ;Table start location ;(MUST be 4 bytes each)
-ta: db 'K'-64,'$',0,0 ;Cursor up, stop at top
-tb: db 'J'-64,'$',0,0 ;Cursor down CTRL-J
-tc: db 'L'-64,'$',0,0 ;Cursor right, stop at right
-td: db 'H'-64,'$',0,0 ;Cursor left, stop at left
-te: db 'Z'-64,0,0,'$' ;Clear display (2 pad nulls)
-tf: db '$',0,0,0 ;(can't) Enter Graphics mode
-tg: db '$',0,0,0 ;(can't) Exit Graphics mode
-th: db 1EH,'$',0,0 ;Cursor home
-ti: db 'K'-64,'$',0,0 ;Reverse linefeed
-tj: db '$',0,0,0 ;(can't) Clear to end of screen
-tk: db '$',0,0,0 ;(can't) Clear to end of line
-ENDIF;adm3a
-
-
-IF smrtvd ; [7] new terminal
-vtval EQU 1 ; we do VT52 emulation
-defesc EQU '\'-100O ; escpae character, ok?
-ttytyp: db 'Smartvid-80$'
-outlin: db esc,'+',cr,lf,tab,tab,'$'
-eralin: db cr,esc,'T$' ;Clear to end of line.
-erascr: db esc,'+$' ;Clear screen and go home.
-curldn: db esc,'=$' ;Cursor lead-in
-ttab: ;Table start location.
-ta: db ('K'-100O),'$',0,0 ;Cursor up.
-tb: db 12O,'$',0,0 ;Cursor down.
-tc: db ('A'-100O),'$',0,0 ;Cursor right.
-td: db ('H'-100O),'$',0,0 ;Cursor left.
-te: db ('L'-100O),'$',0,0 ;Clear screen and home cursor
-tf: db '$',0,0,0 ;(can't) Enter Graphics mode
-tg: db '$',0,0,0 ;(can't) Exit Graphics mode
-th: db ('Z'-100O),'$',0,0 ;Cursor home.
-ti: db ('K'-100O),'$',0,0 ;Reverse linefeed.
-tj: db esc,'Y$',0 ;Clear to end of screen.
-tk: db esc,'T$',0 ;Clear to end of line.
-ENDIF;smrtvd
-
-IF h1500
-vtval EQU 1 ; we can do VT52 emulation
-defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
-ttytyp: db 'Hazeltine$'
-outlin: db 7eh,1ch,7eh,12h,'$'
-erascr: db 7eh,1ch,7eh,12h,'$' ;Clear screen and home
-eralin: db 7eh,13h,'$',0 ;Clear to end of sreen
-curldn: db 7eh,11h,'$',0 ;Cursor lead-in
-ttab: ;Table start location ;(MUST be 4 bytes each)
-ta: db 7eh,0ch,'$',0 ;Cursor up, stop at top
-tb: db 7eh,0bh,'$',0 ;Cursor down CTRL-J
-tc: db 10h,'$',0,0 ;Cursor right, stop at right
-td: db 8h,'$',0,0 ;Cursor left, stop at left
-te: db 7eh,1ch,'$',0 ;Clear display (2 pad nulls)
-tf: db '$',0,0,0 ;(can't) Enter Graphics mode
-tg: db '$',0,0,0 ;(can't) Exit Graphics mode
-th: db 7eh,0ch,'$',0 ;Cursor home
-ti: db 7eh,0ch,'$',0 ;Reverse linefeed
-tj: db '$',0,0,0 ;(can't) Clear to end of screen
-tk: db 7eh,0fh,'$',0 ;Clear to end of line
-ENDIF;h1500
-
-IF wyse ;[gv]
-vtval equ 1 ; we can do VT52 emulation
-defesc EQU '\' ;Still Control-\ (just ran out of room...)
-ttytyp: db ' [Wyse 100]',cr,lf,'$'
-outlin: db esc,'+$',0 ;Clear screen and home
-erascr: db esc,'+$',0 ;Clear screen and home
-eralin: db esc,'Y$',0 ;Clear to end of sreen
-curldn: db cr,esc,'=$' ;Cursor lead-in
-ttab: ;Table start location ;(MUST be 4 bytes each)
-ta: db 03h,'$',0,0 ;Cursor up, stop at top
-tb: db lf,'$',0,0 ;Cursor down, stop at bottom
-tc: db ff,'$',0,0 ;Cursor right, stop at right
-td: db bs,'$',0,0 ;Cursor left, stop at left
-te: db sub,0,0,'$' ;Clear display (2 pad nulls)
-tf: db '$',0,0,0 ;Enter Graphics mode NONE
-tg: db '$',0,0,0 ;Exit Graphics mode NONE
-th: db 1eh,'$',0,0 ;Cursor home
-ti: db esc,'v$',0 ;Reverse linefeed, scroll ???
-tj: db esc,'Y$',0 ;Clear to end of sreen
-tk: db esc,'T$',0 ;Clear to end of line
-ENDIF;wyse
-
-
-
-ovlend equ $ ; End of overlay
-
-IF lasm ;Not really needed, as M80 ignores END in include files
- END
-ENDIF ;lasm
+IF NOT lasm
+.printx * CPXVDU.ASM *
+ENDIF ;NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+;edit 6, 12-Oct-1990 by MF. Added a semicolon to the comment "If we
+; need cursor ..." so it isn't seen as an undefined symbol
+; edit 5, 20 July by OBSchou. Put in the cursor positioning code for
+; all the terminal supported, and moved the vtval EQUs and defesc EQUs
+; here if the system requires andn external terminal. If the system
+; has a 'built in' terminal (ie own scrteen driver) you will not come
+; to this file, so you must declare these three lables etc in your
+; own code.
+; This will allow only those systems requiring a terminal to require
+; CPXVDU.ASM during assembly.
+;
+; edit 4, 16 July, 1987 by OBSchou for will Rose.
+; Added code for Ampro 230 terminal
+;
+; edit 3, 15 July, 1987 by OBSchou for David Moore. Added adm22 terminal
+; codes.
+;
+; edit 2 21 May, 1987 by OBSchou. Added in definitions for Hazeltine 1500
+; submitted by Colin Burns of the Institute of Neurological Sciences
+; in Glasgow.
+; edit 1 ??? date. Split the terminal codes off from the CPXSYS.ASM file
+;
+vduver: db 'CPXVDU.ASM (6) 12-Oct-1990 $' ;file, edit version,, date.
+
+
+; First, print out what terminal (if any) we are assembling for
+
+IF crt
+.printx * generic CRT selected *
+ENDIF
+
+IF adm3a
+.printx * ADM3A selected *
+ENDIF
+
+IF adm22
+.printx * ADM22 selected *
+ENDIF
+
+IF smrtvd ;[7]
+.printx * Netronics Smartvid-80 selected *
+ENDIF ;[7]
+
+IF tvi912
+.printx * TVI912/920 selected *
+ENDIF
+
+IF tvi925
+.printx * TVI925 selected *
+ENDIF
+
+IF vt52
+.printx * VT52 selected *
+ENDIF
+
+IF vt100
+.printx * VT100 selected *
+ENDIF
+
+IF am230
+.printx * Ampro 230 terminal selected *
+ENDIF
+
+IF wyse
+.printx * Wyse 100 terminal selected *
+ENDIF
+;
+
+;
+; If we need cursor positioning, here is the code to do it
+;
+; Screen manipulation routines
+; csrpos - move to row B, column C
+;
+; csrpos for terminals that use a leadin sequence followed
+; by (row + 31.) and (column + 31.)
+;
+IF NOT (vt100 OR crt OR h1500)
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; restore coordinates
+ mov a,h ; get row
+ adi (' '-1) ; space is row one
+ mov e,a
+ push h
+ call outcon ; output row
+ pop h
+ mov a,l ; get column
+ adi (' '-1) ; space is column one
+ mov e,a
+ jmp outcon ; output it and return
+ENDIF;NOT (vt100 OR crt OR h1500)
+;
+;
+;
+;
+; csrpos for ANSI terminals
+;
+IF vt100
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; peek at coordinates
+ push h ; then save away again
+ mov l,h ; l = row
+ mvi h,0 ; hl = row
+ call nout ; output in decimal
+ mvi e,';' ; follow with semicolon
+ call outcon ; print it
+ pop h ; restore column
+ mvi h,0 ; hl = column
+ call nout
+ mvi e,'H' ; terminate with 'move cursor' command
+ jmp outcon ; output it and return
+ENDIF;vt100
+
+;Definition for Hazeltine 1500 does things a little strange.
+;
+IF h1500
+csrpos: push b ; save coordinates
+ lxi d,curldn ; get cursor leadin sequence
+ call prtstr ; print it
+ pop h ; restore coordinates
+ mov a,l ; get col
+ nop
+ nop
+; adi (' '-1) ; space is row one
+ mov e,a
+ push h
+ call outcon ; output row
+ pop h
+ mov a,h ; get row
+ adi (' '-1) ; space is column one
+ mov e,a
+ jmp outcon ; output it and return
+ENDIF; h1500
+
+
+IF crt ; systems without cursor positioning
+csrpos: ret ; dummy routine referenced by linkage section
+ENDIF;crt
+;
+;
+;
+; Now for the rest of CPXVDU.ASM
+;
+;
+;
+IF crt ;Set flags etc for systems with CRT selected
+defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
+vtval EQU 0FFH ; we can't support VT52 emulation
+ttytyp: db 'Generic (Dumb) CRT Terminal type selected $'
+ENDIF;crt
+
+;
+
+IF vt52 ; DEC VT52
+ttytyp: db 'VT52$'
+ENDIF;vt52
+
+IF vt52
+vtval EQU 0 ; we don't need VT52 emulation
+defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
+outlin: db esc,'H',esc,'J',cr,lf,tab,tab,'$'
+erascr: db esc,'H',esc,'J$' ;Clear screen and go home.
+eralin: db cr,esc,'K$' ;Clear line.
+curldn: db esc,'Y$' ;cursor leadin
+ttab: ;Table start location.
+ta: db esc,'A$',0 ;Cursor up.
+tb: db esc,'B$',0 ;Cursor down.
+tc: db esc,'C$',0 ;Cursor right.
+td: db esc,'D$',0 ;Cursor left
+te: db esc,'E$',0 ;Clear display
+tf: db esc,'F$',0 ;Enter Graphics Mode
+tg: db esc,'G$',0 ;Exit Graphics mode
+th: db esc,'H$',0 ;Cursor home.
+ti: db esc,'I$',0 ;Reverse linefeed.
+tj: db esc,'J$',0 ;Clear to end of screen.
+tk: db esc,'K$',0 ;Clear to end of line.
+ENDIF;vt52
+;
+
+IF adm22
+vtval EQU 1 ; we can do VT52 emulation
+defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
+ttytyp: db 'ADM22$'
+outlin: db 1ah,cr,lf,tab,tab,'$'
+erascr: db 1ah,'$' ;Clear screen and go home.
+eralin: db esc,'>$' ;Clear line.
+curldn: db esc,'=$' ;Cursor lead-in
+ttab: ;Table start location.
+ta: db 0BH,'$',0,0 ;Cursor up.
+tb: db lf,'$',0,0 ;Cursor down.
+tc: db 0CH,'$',0,0 ;Cursor right.
+td: db bs,'$',0,0 ;Cursor left
+te: db 1ah,':$',0 ;Clear display
+tf: db '$',0,0,0 ;(can't) Enter Graphics Mode
+tg: db '$',0,0,0 ;(can't) Exit Graphics mode
+th: db 1EH,'$',0,0 ;Cursor home.
+ti: db 0BH,'$',0,0 ;Reverse linefeed.
+tj: db esc,'Y$',0 ;Clear to end of screen.
+tk: db esc,'T$',0 ;Clear to end of line.
+ENDIF;adm22
+;
+
+IF am230
+; Select initial setting for VT-52 emulation flag.
+vtval EQU 1
+defesc EQU '\'-100O ;The default is Control-\ -- it's easier
+ttytyp: db 'Am230$'
+outlin: db 'Z'-64,0,0,cr,lf,'$'
+erascr: db 'Z'-64,0,0,'$' ;Clear screen and home
+eralin: db esc,'R$',0 ;Erase line
+curldn: db cr,esc,'=$' ;Cursor lead-in
+ttab: ;Table start location ;(MUST be 4 bytes each)
+ta: db 'K'-64,'$',0,0 ;Cursor up, stop at top
+tb: db 'V'-64,'$',0,0 ;Cursor down, stop at bottom
+tc: db 'L'-64,'$',0,0 ;Cursor right, stop at right
+td: db 'H'-64,'$',0,0 ;Cursor left, stop at left
+te: db 'Z'-64,0,0,'$' ;Clear display (2 pad nulls)
+tf: db '$',0,0,0 ;(can't) Enter Graphics mode
+tg: db '$',0,0,0 ;(can't) Exit Graphics mode
+th: db 1EH,'$',0,0 ;Cursor home
+ti: db esc,'j$',0 ;Reverse linefeed, scroll
+tj: db esc,'Y$',0 ;Clear to end of sreen
+tk: db esc,'T$',0 ;Clear to end of line
+ENDIF
+;
+;
+
+
+IF vt100
+ttytyp: db 'VT100$'
+ENDIF;vt100
+
+
+IF vt100
+; Note that we cannot support Graphics Mode or the H19 erase-screen command
+; (<esc>E), because the sequences are more than three bytes.
+defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
+vtval EQU 0 ; we probably don't want VT52 emulation
+outlin: db esc,3CH,esc,'[H',esc,'[J',cr,lf,tab,tab,'$'
+erascr: db esc,'[H',esc,'[J$' ;Clear screen and go home.
+eralin: db cr,esc,'[K$' ;Clear line.
+curldn: db esc,'[$' ; Cursor leadin
+ttab:
+ta: db esc,'[A$' ; Cursor up.
+tb: db esc,'[B$' ; Cursor down.
+tc: db esc,'[C$' ; Cursor right.
+td: db esc,'[D$' ; Cursor left
+te: db '$',0,0,0 ; (can't) Clear display
+tf: db '$',0,0,0 ; (don't) Enter Graphics Mode
+tg: db '$',0,0,0 ; (don't) Exit Graphics mode
+th: db esc,'[H$' ; Cursor home.
+ti: db esc,'M$',0 ; Reverse linefeed.
+tj: db esc,'[J$' ; Clear to end of screen.
+tk: db esc,'[K$' ; Clear to end of line.
+ENDIF;vt100
+;
+
+IF gener or cpm3
+sysver: db 'Generic CP/M-80$'
+ENDIF;gener or cpm3
+
+
+IF soroq ;[29] Should this not be with terminals.....
+ttytyp: db 'Soroc IQ-120$'
+outlin: db 1EH,esc,'Y',cr,lf,tab,tab,'$'
+erascr: db 1EH,esc,'Y$' ;clear screen and home cursor
+eralin: db cr,esc,'T$' ;clear line
+curldn: db esc,'=$' ;cursor lead-in string
+delstr: db bs,' ',bs,bs,'$' ;??adjust for echoing delete
+ttab: ;table start location
+ta: db 0BH,'$',0 ;cursor up
+tb: db 0AH,'$',0 ;cursor down
+tc: db 0CH,'$',0 ;cursor right
+td: db 08H,'$',0 ;cursor left
+te: db esc,'*$',0 ;clear display (homes cursor)
+tf: db esc,')$',0 ;enter inverse video mode
+tg: db esc,'($',0 ;exit inverse video mode
+th: db 01EH,'$',0 ;home cursor
+ti: db 0BH,'$',0 ;reverse linefeed (insert line)
+tj: db esc,'Y$',0 ;clear to end of screen
+tk: db esc,'T$',0 ;clear to end of line
+ENDIF;soroq
+
+IF crt
+outlin: db cr,lf,'Starting ...$'
+erascr equ crlf ;"Home & clear" (best we can do).
+eralin: db '^U',cr,lf,'$' ;Clear line.
+prpack: db cr,lf,'RPack: $'
+pspack: db cr,lf,'SPack: $'
+ttab equ 0 ; no VT52 table
+ENDIF;crt
+;
+
+IF tvi912
+vtval EQU 1 ; we do emulation
+defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
+ttytyp: db 'TVI912/920$'
+outlin: db 'Z'-64,0,0,cr,lf,'$'
+erascr: db 'Z'-64,0,0,'$' ;Clear screen and home
+eralin: db esc,'Y$',0 ;Clear to end of sreen
+curldn: db cr,esc,'=$' ;Cursor lead-in
+ttab: ;Table start location ;(MUST be 4 bytes each)
+ta: db 'K'-64,'$',0,0 ;Cursor up, stop at top
+tb: db 'J'-64,'$',0,0 ;Cursor down, stop at bottom
+tc: db 'L'-64,'$',0,0 ;Cursor right, stop at right
+td: db 'H'-64,'$',0,0 ;Cursor left, stop at left
+te: db 'Z'-64,0,0,'$' ;Clear display (2 pad nulls)
+tf: db '$',0,0,0 ;(can't) Enter Graphics mode
+tg: db '$',0,0,0 ;(can't) Exit Graphics mode
+th: db 1EH,'$',0,0 ;Cursor home
+ti: db esc,'j$',0 ;Reverse linefeed, scroll
+tj: db esc,'Y$',0 ;Clear to end of sreen
+tk: db esc,'T$',0 ;Clear to end of line
+ENDIF;tvi912
+;
+;
+
+IF tvi925
+;(incidentally, works fine for Freedom 100 also [Toad Hall])
+;adm3a entry and tvi925 entry separated to remove warning message.
+vtval EQU 1 ; we VT52 emulation
+defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
+ttytyp: db 'TVI925$'
+outlin: db 'Z'-64,0,0,cr,lf,'$'
+erascr: db 'Z'-64,0,0,'$' ;Clear screen and home
+eralin: db esc,'Y$',0 ;Clear to end of sreen
+curldn: db cr,esc,'=$' ;Cursor lead-in
+ttab: ;Table start location ;(MUST be 4 bytes each)
+ta: db 'K'-64,'$',0,0 ;Cursor up, stop at top
+tb: db 'V'-64,'$',0,0 ;Cursor down, stop at bottom
+tc: db 'L'-64,'$',0,0 ;Cursor right, stop at right
+td: db 'H'-64,'$',0,0 ;Cursor left, stop at left
+te: db 'Z'-64,0,0,'$' ;Clear display (2 pad nulls)
+tf: db '$',0,0,0 ;(can't) Enter Graphics mode
+tg: db '$',0,0,0 ;(can't) Exit Graphics mode
+th: db 1EH,'$',0,0 ;Cursor home
+ti: db esc,'j$',0 ;Reverse linefeed, scroll
+tj: db esc,'Y$',0 ;Clear to end of sreen
+tk: db esc,'T$',0 ;Clear to end of line
+ENDIF;tvi925
+;
+;
+
+IF adm3a
+defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
+ttytyp: db 'ADM3A$'
+outlin: db 'Z'-64,0,0,cr,lf,'$'
+erascr: db 'Z'-64,0,0,'$' ;Clear screen and home
+eralin: db esc,'Y$',0 ;Clear to end of sreen
+curldn: db cr,esc,'=$' ;Cursor lead-in
+ttab: ;Table start location ;(MUST be 4 bytes each)
+ta: db 'K'-64,'$',0,0 ;Cursor up, stop at top
+tb: db 'J'-64,'$',0,0 ;Cursor down CTRL-J
+tc: db 'L'-64,'$',0,0 ;Cursor right, stop at right
+td: db 'H'-64,'$',0,0 ;Cursor left, stop at left
+te: db 'Z'-64,0,0,'$' ;Clear display (2 pad nulls)
+tf: db '$',0,0,0 ;(can't) Enter Graphics mode
+tg: db '$',0,0,0 ;(can't) Exit Graphics mode
+th: db 1EH,'$',0,0 ;Cursor home
+ti: db 'K'-64,'$',0,0 ;Reverse linefeed
+tj: db '$',0,0,0 ;(can't) Clear to end of screen
+tk: db '$',0,0,0 ;(can't) Clear to end of line
+ENDIF;adm3a
+
+
+IF smrtvd ; [7] new terminal
+vtval EQU 1 ; we do VT52 emulation
+defesc EQU '\'-100O ; escpae character, ok?
+ttytyp: db 'Smartvid-80$'
+outlin: db esc,'+',cr,lf,tab,tab,'$'
+eralin: db cr,esc,'T$' ;Clear to end of line.
+erascr: db esc,'+$' ;Clear screen and go home.
+curldn: db esc,'=$' ;Cursor lead-in
+ttab: ;Table start location.
+ta: db ('K'-100O),'$',0,0 ;Cursor up.
+tb: db 12O,'$',0,0 ;Cursor down.
+tc: db ('A'-100O),'$',0,0 ;Cursor right.
+td: db ('H'-100O),'$',0,0 ;Cursor left.
+te: db ('L'-100O),'$',0,0 ;Clear screen and home cursor
+tf: db '$',0,0,0 ;(can't) Enter Graphics mode
+tg: db '$',0,0,0 ;(can't) Exit Graphics mode
+th: db ('Z'-100O),'$',0,0 ;Cursor home.
+ti: db ('K'-100O),'$',0,0 ;Reverse linefeed.
+tj: db esc,'Y$',0 ;Clear to end of screen.
+tk: db esc,'T$',0 ;Clear to end of line.
+ENDIF;smrtvd
+
+IF h1500
+vtval EQU 1 ; we can do VT52 emulation
+defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
+ttytyp: db 'Hazeltine$'
+outlin: db 7eh,1ch,7eh,12h,'$'
+erascr: db 7eh,1ch,7eh,12h,'$' ;Clear screen and home
+eralin: db 7eh,13h,'$',0 ;Clear to end of sreen
+curldn: db 7eh,11h,'$',0 ;Cursor lead-in
+ttab: ;Table start location ;(MUST be 4 bytes each)
+ta: db 7eh,0ch,'$',0 ;Cursor up, stop at top
+tb: db 7eh,0bh,'$',0 ;Cursor down CTRL-J
+tc: db 10h,'$',0,0 ;Cursor right, stop at right
+td: db 8h,'$',0,0 ;Cursor left, stop at left
+te: db 7eh,1ch,'$',0 ;Clear display (2 pad nulls)
+tf: db '$',0,0,0 ;(can't) Enter Graphics mode
+tg: db '$',0,0,0 ;(can't) Exit Graphics mode
+th: db 7eh,0ch,'$',0 ;Cursor home
+ti: db 7eh,0ch,'$',0 ;Reverse linefeed
+tj: db '$',0,0,0 ;(can't) Clear to end of screen
+tk: db 7eh,0fh,'$',0 ;Clear to end of line
+ENDIF;h1500
+
+IF wyse ;[gv]
+vtval equ 1 ; we can do VT52 emulation
+defesc EQU '\' ;Still Control-\ (just ran out of room...)
+ttytyp: db ' [Wyse 100]',cr,lf,'$'
+outlin: db esc,'+$',0 ;Clear screen and home
+erascr: db esc,'+$',0 ;Clear screen and home
+eralin: db esc,'Y$',0 ;Clear to end of sreen
+curldn: db cr,esc,'=$' ;Cursor lead-in
+ttab: ;Table start location ;(MUST be 4 bytes each)
+ta: db 03h,'$',0,0 ;Cursor up, stop at top
+tb: db lf,'$',0,0 ;Cursor down, stop at bottom
+tc: db ff,'$',0,0 ;Cursor right, stop at right
+td: db bs,'$',0,0 ;Cursor left, stop at left
+te: db sub,0,0,'$' ;Clear display (2 pad nulls)
+tf: db '$',0,0,0 ;Enter Graphics mode NONE
+tg: db '$',0,0,0 ;Exit Graphics mode NONE
+th: db 1eh,'$',0,0 ;Cursor home
+ti: db esc,'v$',0 ;Reverse linefeed, scroll ???
+tj: db esc,'Y$',0 ;Clear to end of sreen
+tk: db esc,'T$',0 ;Clear to end of line
+ENDIF;wyse
+
+
+
+ovlend equ $ ; End of overlay
+
+IF lasm ;Not really needed, as M80 ignores END in include files
+ END
+ENDIF ;lasm
diff --git a/cpxz80.asm b/cpxz80.asm
index 9e80e8b..82a5692 100644
--- a/cpxz80.asm
+++ b/cpxz80.asm
@@ -1,350 +1,350 @@
-IF NOT LASM
-.printx * CPXZ80.ASM *
-ENDIF ;NOT lasm
-; KERMIT - (Celtic for "FREE")
-;
-; This is the CP/M-80 implementation of the Columbia University
-; KERMIT file transfer protocol.
-;
-; Version 4.0
-;
-; Copyright June 1981,1982,1983,1984,1985
-; Columbia University
-;
-; Originally written by Bill Catchings of the Columbia University Center for
-; Computing Activities, 612 W. 115th St., New York, NY 10025.
-;
-; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
-; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
-; others.
-;
-; This file contains the system-dependent code and data for
-; Kermit-80 emulated on an IBM PC or clone running Z80MU.
-;
-; revision history (last edit first)
-;
-; edit 1, 2 December, 1987. Built code for Z80MU emulation. Uses BIOS
-; calls to 0FF12-15 to read/write from/to the PC COM1 port.
-;
-
-.printx * Assembling for Z80MU system *
-
-;
-; Family is the string used in VERSION to say which of several
-; smaller overlay files are used. These are (will be) derived from
-; the juge CP4SYS.ASM file, in which case we will never get here.
-; Just a Dollar, but put a sting in for a family of machines.
-;
-family: db 'CPXZ80.ASM (1) 2-Dec-87$' ; Used for family versions....
-
-
-
-sysxin: ; continuation of system dependent initialisation code
- ret ; return from system-dependent routine
-;
-;
-; system-dependent termination processing
-; If we've changed anything, this is our last chance to put it back.
-sysexit:
- ret
-
-;
-; system-dependent processing for start of CONNECT command
-;
-syscon:
- ret
-
-conmsg: ; Messages printed when entering transparent (CONNECT) mode:
-;
-;
-; syscls - system-dependent close routine
-; called when exiting transparent session.
-;
-syscls:
- ret
-;
-; sysinh - help for system-dependent special functions.
-; called in response to <escape>?, after listing all the
-; system-independent escape sequences.
-;
-sysinh:
- ret
-
-;
-; sysint - system dependent special functions
-; called when transparent escape character has been typed;
-; the second character of the sequence is in A (and in B).
-; returns:
-; non-skip: sequence has been processed
-; skip: sequence was not recognized
-sysint: ani 137O ; convert lower case to upper, for testing...
- jmp rskp ; take skip return - command not recognized.
-
-
-;
-;
-; sysflt - system-dependent filter
-; called with character in E.
-; if this character should not be printed, return with A = zero.
-; preserves bc, de, hl.
-; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
-sysflt:
- mov a,e ; get character for testing
- ret
-
-; mdmflt - modem filter [30]
-; called with character to be sent to printer in E
-; with parity set as appropriate.
-; return with accumulator = 0 do do nothing,
-; <> 0 to send char in E.
-mdmflt:
- mov a,e ;[30] get character to test
- ret
-
-
-
-; prtflt - printer filter [30]
-; called with character to be sent to printer in E
-; returns with a = 0 to do nothing
-; a <> 0 to print it.
-;
-; this routine for those printer that automatically insert
-; a lf on cr, or cr for lf. Should this be shifted to
-; the system indep. stuff, in say 4.06?
-prtflt:
- mov a,e ; [30] get character to test
- ret
-
-
-;
-; system-dependent processing for BYE command.
-; for apmmdm, heath, and lobo, hang up the phone.
-sysbye:
- ret
-;
-;
-; This is the system-dependent command to change the baud rate.
-; DE contains the two-byte value from the baud rate table; this
-; value is also stored in 'speed'.
-sysspd:
- ret
-;
-;
-; The following conditionals were once a huge if not statement. There
-; wasn't enough room to add the lobo to the list, so it had to be broken
-; into 2, which you can't do with an if not. I redid it as two ifs and
-; applied them to those that wouldn't set baud. [Hal Hostetler]
-spdtbl EQU 0 ;[hh] SET BAUD not supported.
-sphtbl EQU 0 ;[hh] ran out of room above...
-;
-;
-; This is the system-dependent SET PORT command.
-; HL contains the argument from the command table.
-sysprt:
- ret
-
-prttbl equ 0 ; SET PORT not supported
-prhtbl equ 0
-;
-
-;
-; selmdm - select modem port
-; selcon - select console port
-; selmdm is called before using inpmdm or outmdm;
-; selcon is called before using inpcon or outcon.
-; For iobyt systems, diddle the I/O byte to select console or comm port;
-; For Decision I, switches Multi I/O board to console or modem serial
-; port. [Toad Hall]
-; For the rest, does nothing.
-; preserves bc, de, hl.
-selmdm:
-selcon:
- ret
-;
-
-; Get character from console, or return zero.
-; result is returned in A. destroys bc, de, hl.
-;
-inpcon:
- mvi c,dconio ;Direct console I/O BDOS call.
- mvi e,0FFH ;Input.
- call BDOS
- ret
-;
-
-;
-; Output character in E to the console.
-; destroys bc, de, hl
-;
-outcon:
- mov c,e ;Console output via BIOS
- jmp bcnout
-;
-
-;
-; outmdm - output a char from E to the modem.
-; the parity bit has been set as necessary.
-; returns nonskip; bc, de, hl preserved.
-outmdm:
- mov c,e ; get char to c
- call 0ff12h ; send to com1 via PC BIOS
- ret
-;
-;
-; get character from modem; return zero if none available.
-; for IOBYT systems, the modem port has already been selected.
-; destroys bc, de, hl.
-inpmdm:
-;Note: modem port should already be selected for mdI. [Toad Hall]
- call 0ff15h ;Get the port status into A.
- ana a ;See if the is non-null.
- ret ; return with character or NULL in A.
-
-
-;
-; flsmdm - flush comm line.
-; Modem is selected.
-; Currently, just gets characters until none are available.
-
-flsmdm: call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-;
-
-;
-; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not.
-lptstat:
- xra a ; assume it is ok.. this may not be necessary
- ret
-
-;
-; outlpt - output character in E to printer
-; console is selected.
-; preserves de.
-outlpt:
- push d ; save DE in either case
- call prtflt ; go through printer filter [30]
- ana a ; if A = 0 do nothing,
- jz outlp1 ; [30] if a=0 do nothing
- mvi c,lstout
- call bdos ;Char to printer
-outlp1: pop d ; restore saved register pair
- ret
-
-;
-; delchr - make delete look like a backspace. Unless delete is a printing
-; character, we just need to print a backspace. (we'll output clrspc
-; afterwards)
-; For Kaypro and Vector General, delete puts a blotch on the screen.
-; For Apple and Osborne 1, delete moves but doesn't print.
-delchr:
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the character at the current cursor position
-clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
-; erase the current line
-clrlin: lxi d,eralin
- jmp prtstr
-
-; erase the whole screen, and go home. preserves b (but not c)
-clrtop: lxi d,erascr
- jmp prtstr
-
-
-sysver: db 'Z80MU on IBM PC $'
-IF lasm
-LINK CPXVDU.ASM
-ENDIF ;lasm - m80 will INCLUDE CPXVDU.ASM
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+IF NOT LASM
+.printx * CPXZ80.ASM *
+ENDIF ;NOT lasm
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984,1985
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; This file contains the system-dependent code and data for
+; Kermit-80 emulated on an IBM PC or clone running Z80MU.
+;
+; revision history (last edit first)
+;
+; edit 1, 2 December, 1987. Built code for Z80MU emulation. Uses BIOS
+; calls to 0FF12-15 to read/write from/to the PC COM1 port.
+;
+
+.printx * Assembling for Z80MU system *
+
+;
+; Family is the string used in VERSION to say which of several
+; smaller overlay files are used. These are (will be) derived from
+; the juge CP4SYS.ASM file, in which case we will never get here.
+; Just a Dollar, but put a sting in for a family of machines.
+;
+family: db 'CPXZ80.ASM (1) 2-Dec-87$' ; Used for family versions....
+
+
+
+sysxin: ; continuation of system dependent initialisation code
+ ret ; return from system-dependent routine
+;
+;
+; system-dependent termination processing
+; If we've changed anything, this is our last chance to put it back.
+sysexit:
+ ret
+
+;
+; system-dependent processing for start of CONNECT command
+;
+syscon:
+ ret
+
+conmsg: ; Messages printed when entering transparent (CONNECT) mode:
+;
+;
+; syscls - system-dependent close routine
+; called when exiting transparent session.
+;
+syscls:
+ ret
+;
+; sysinh - help for system-dependent special functions.
+; called in response to <escape>?, after listing all the
+; system-independent escape sequences.
+;
+sysinh:
+ ret
+
+;
+; sysint - system dependent special functions
+; called when transparent escape character has been typed;
+; the second character of the sequence is in A (and in B).
+; returns:
+; non-skip: sequence has been processed
+; skip: sequence was not recognized
+sysint: ani 137O ; convert lower case to upper, for testing...
+ jmp rskp ; take skip return - command not recognized.
+
+
+;
+;
+; sysflt - system-dependent filter
+; called with character in E.
+; if this character should not be printed, return with A = zero.
+; preserves bc, de, hl.
+; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
+sysflt:
+ mov a,e ; get character for testing
+ ret
+
+; mdmflt - modem filter [30]
+; called with character to be sent to printer in E
+; with parity set as appropriate.
+; return with accumulator = 0 do do nothing,
+; <> 0 to send char in E.
+mdmflt:
+ mov a,e ;[30] get character to test
+ ret
+
+
+
+; prtflt - printer filter [30]
+; called with character to be sent to printer in E
+; returns with a = 0 to do nothing
+; a <> 0 to print it.
+;
+; this routine for those printer that automatically insert
+; a lf on cr, or cr for lf. Should this be shifted to
+; the system indep. stuff, in say 4.06?
+prtflt:
+ mov a,e ; [30] get character to test
+ ret
+
+
+;
+; system-dependent processing for BYE command.
+; for apmmdm, heath, and lobo, hang up the phone.
+sysbye:
+ ret
+;
+;
+; This is the system-dependent command to change the baud rate.
+; DE contains the two-byte value from the baud rate table; this
+; value is also stored in 'speed'.
+sysspd:
+ ret
+;
+;
+; The following conditionals were once a huge if not statement. There
+; wasn't enough room to add the lobo to the list, so it had to be broken
+; into 2, which you can't do with an if not. I redid it as two ifs and
+; applied them to those that wouldn't set baud. [Hal Hostetler]
+spdtbl EQU 0 ;[hh] SET BAUD not supported.
+sphtbl EQU 0 ;[hh] ran out of room above...
+;
+;
+; This is the system-dependent SET PORT command.
+; HL contains the argument from the command table.
+sysprt:
+ ret
+
+prttbl equ 0 ; SET PORT not supported
+prhtbl equ 0
+;
+
+;
+; selmdm - select modem port
+; selcon - select console port
+; selmdm is called before using inpmdm or outmdm;
+; selcon is called before using inpcon or outcon.
+; For iobyt systems, diddle the I/O byte to select console or comm port;
+; For Decision I, switches Multi I/O board to console or modem serial
+; port. [Toad Hall]
+; For the rest, does nothing.
+; preserves bc, de, hl.
+selmdm:
+selcon:
+ ret
+;
+
+; Get character from console, or return zero.
+; result is returned in A. destroys bc, de, hl.
+;
+inpcon:
+ mvi c,dconio ;Direct console I/O BDOS call.
+ mvi e,0FFH ;Input.
+ call BDOS
+ ret
+;
+
+;
+; Output character in E to the console.
+; destroys bc, de, hl
+;
+outcon:
+ mov c,e ;Console output via BIOS
+ jmp bcnout
+;
+
+;
+; outmdm - output a char from E to the modem.
+; the parity bit has been set as necessary.
+; returns nonskip; bc, de, hl preserved.
+outmdm:
+ mov c,e ; get char to c
+ call 0ff12h ; send to com1 via PC BIOS
+ ret
+;
+;
+; get character from modem; return zero if none available.
+; for IOBYT systems, the modem port has already been selected.
+; destroys bc, de, hl.
+inpmdm:
+;Note: modem port should already be selected for mdI. [Toad Hall]
+ call 0ff15h ;Get the port status into A.
+ ana a ;See if the is non-null.
+ ret ; return with character or NULL in A.
+
+
+;
+; flsmdm - flush comm line.
+; Modem is selected.
+; Currently, just gets characters until none are available.
+
+flsmdm: call inpmdm ; Try to get a character
+ ora a ; Got one?
+ jnz flsmdm ; If so, try for another
+ ret ; Receiver is drained. Return.
+;
+
+;
+; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not.
+lptstat:
+ xra a ; assume it is ok.. this may not be necessary
+ ret
+
+;
+; outlpt - output character in E to printer
+; console is selected.
+; preserves de.
+outlpt:
+ push d ; save DE in either case
+ call prtflt ; go through printer filter [30]
+ ana a ; if A = 0 do nothing,
+ jz outlp1 ; [30] if a=0 do nothing
+ mvi c,lstout
+ call bdos ;Char to printer
+outlp1: pop d ; restore saved register pair
+ ret
+
+;
+; delchr - make delete look like a backspace. Unless delete is a printing
+; character, we just need to print a backspace. (we'll output clrspc
+; afterwards)
+; For Kaypro and Vector General, delete puts a blotch on the screen.
+; For Apple and Osborne 1, delete moves but doesn't print.
+delchr:
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the character at the current cursor position
+clrspc: mvi e,' '
+ call outcon
+ mvi e,bs ;get a backspace
+ jmp outcon
+
+; erase the current line
+clrlin: lxi d,eralin
+ jmp prtstr
+
+; erase the whole screen, and go home. preserves b (but not c)
+clrtop: lxi d,erascr
+ jmp prtstr
+
+
+sysver: db 'Z80MU on IBM PC $'
+IF lasm
+LINK CPXVDU.ASM
+ENDIF ;lasm - m80 will INCLUDE CPXVDU.ASM
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mload.asm b/mload.asm
index 668796a..14df5c3 100644
--- a/mload.asm
+++ b/mload.asm
@@ -1,1493 +1,1493 @@
- title 'MLOAD MULTI-FILE HEX LOAD UTILITY'
-;
-; *********************************
-; * MLOAD.ASM *
-; * Multi-file Hex Load Utility *
-; * for CP/M *
-; *********************************
-;
-;
-; Replacement for the cp/m "LOAD" program: this program
-; fixes many of the problems associated with the "CP/M"
-; load program, and adds many new features.
-;
-; ----------------
-;
-; Rev 2.5
-; 03/10/88
-; Property of NightOwl Software, Inc. Fort Atkinson, WI 53538
-; Written by Ron Fowler, Nightowl Software, Inc.
-;
-; ----------------
-; Notice: this program is NOT public domain; copyright is retained by
-; NightOwl Software, Inc. of Fort Atkinson, WI ... All Rights Reserved.
-;
-; License is granted for free use and re-distribution this program, as
-; long as such use and re-distribution is done without profit.
-;
-; ----------------
-;
-; modification history:
-;
-; 2.5 (WOD) This version corrects a bug that overlayed the first six
-; bytes of the CCP. The error did not show up unless a
-; jump to the CCP was done without a warm boot since MLOAD
-; used. This source file has been modified here with
-; concurrence of the author of MLOAD, Ron Fowler.
-;
-; 2.4 (RGF) We apologize for this relatively insubstantial update,
-; but someone has caused what we consider to be a problem,
-; by making changes to the program, and re-releasing under
-; the same version number. The changes in this case were
-; conversion of the opcode fields (but not the comments,
-; can you believe that??) of every line to upper case! That
-; totally invalidated the CRC of the source file, since there
-; are now two different MLOAD 2.3's running around.
-;
-; We DO NOT want these stupid mixed upper/lower case changes.
-; Someone somewhere has decided that this is the way assembly
-; language source should be, and we most VEHEMENTLY disagree.
-; It's a pain in the neck to make changes to and we don't
-; care to run our programs through conversion programs every
-; time we make changes.
-;
-; So ... leave the case of this file AS IS. Any changes made
-; to this program and not co-ordinated through us may very
-; well endanger availability of source code when we make
-; future updates. 'nuff said --NightOwl Software
-;
-; 2.3 (RGF) Trivial cosmetic changes
-; 2.2 (RGF) Modified copyright notice to show new owner of the
-; program.
-; 2.1 (RGF) Fixed problem on disk-full when writing output file
-; (mload previously didn't error out on a full disk)
-; 2.0 (RGF) Added the ability to pre-load a non-hex file, allowing
-; mload to be used to load hex file patches (obviating any
-; need to use DDT). The normal mload syntax is preserved.
-; the first (and only the first) filespec (after the "=",
-; if used) may be non-hex; the filetype must be specified.
-; Examples:
-;
-; 1) mload ws.com,wspatch
-; 2) mload MEXTEST=MEX112.COM,MXO-US13
-; 3) mload ws.ovr,ovrpatch
-;
-; The first example loads WS.COM, overlays it with
-; wspatch.hex, and writes the output to WS.COM. The
-; second example loads MEX112.COM, overlays it with
-; MXO-US13.HEX, and writes the output file to MEXTEST.COM.
-; (note that the second example is the recommended technique,
-; since it preserves the original file). The third example
-; loads WS.OVR and patches it with the file "OVRPATCH.HEX".
-;
-; Also added this rev: ZCPR2-style du specs are now fully
-; supported, for both input and output files. Thus, the
-; following command lines are permissable:
-;
-; b3>mload a4:myfile.com=0:bigfil,b6:patch1,c9:patch2
-; a6>mload b5:=c3:mdm717.com,mdmpatch
-;
-; After loading, an additional information line is now printed
-; in the statistics report, which displays the true size of the
-; saved image (the previous report was technically correct, but
-; could result in confusion for certain kinds of files with
-; imbedded "DS" and "ORG" statements in the original source code).
-;
-; 1.0 - 1.4 (RGF) change log removed to conserve space
-;
-; originally written by ron fowler, fort atkinson, wisconsin
-;
-;
-;
-; For assembly with asm.com or mac (delete above title line if
-; assembling with asm.com).
-;
-; This program is a replacement for the cp/m "LOAD" program.
-; Why replace "LOAD"? well... LOAD.COM has a few deficiencies.
-; For example, if your hex file's origin is above 100h, LOAD.COM
-; prepends blank space to the output file to insure it will work
-; as a CP/M transient. It cares not if the file is not intended
-; as a CP/M transient. it also doesn't like hex records with mixed
-; load addresses (for example, one that loads below a previous record --
-; which is a perfectly legitimate happenstance). Also, LOAD.COM
-; can load only one program at a time, and has no provision for
-; a load bias in the command specification. Finally, there is no
-; provision for user specification of the output file name.
-;
-;
-; Hence, this program....
-;
-;------------------------------------------------------------
-;
-; Syntax is as follows:
-;
-; mload [<outnam=] <filename>[,<filename>...] [bias]
-;
-; where <outnam> is the (optional!;) output file name (only the drive
-; spec and primary filename may be specified; the output filetype is
-; derived exclusively from the 3-byte string at 103h within MLOAD),
-; <filename> specifies files to load and <bias> is the offset within
-; the saved image to apply when loading the file.
-;
-; MLOAD with no arguments prints a small help message -- this message
-; is also printed whenever a command line syntax error occurs.
-;
-; Filenames may contain drive/user specs, and must not contain wildcards.
-; Input filenames must be separated by commas, and a space is required
-; between the last filename and the optional bias.
-;
-; A load information summary is printed at the successful conclusion
-; of the load. Any errors in loading will generally include the name
-; of the file in question.
-;
-; If no output filename is specified, it will be derived from the first
-; input filename, with filetype of 'COM', if not otherwise specified
-; (this default filetype may be patched directly into mload via DDT
-; (or with MLOAD itself, using a patch file) -- its location is at 103H
-; in MLOAD.COM). Note that a command line of the form "C:=<FILENAME>"
-; will place the output file on the "C" drive with the same primary
-; filename as the input file.
-;
-; In its simplest form, MLOAD's syntax is identical to LOAD.COM; thus
-; there should be no problem in learning to use the new program. The
-; only significant difference here is that, under LOAD.COM, all files
-; are output starting at 100h, even if they originate elsewhere. MLOAD
-; outputs starting at the hex file origin (actually, the first hex rec-
-; ord specifies the output load address). The bias option may be used
-; to override this.
-;
-; An example should clarify this. Suppose you have a file that loads
-; at 1000h. LOAD.COM would save an output file that begins at 100h and
-; loads past 1000h (to wherever the program ends). MLOAD will save an
-; output file starting from 1000h only. If, for some reason you need the
-; file to start at 100h in spite of its 1000h origin (i can think of sev-
-; eral circumstances where this would be necessary), you'd have to specify
-; a bias to mload. thus, using this example, "MLOAD MYFILE 0F00" would do.
-;
-; Note that this program re-initializes itself each time it is run.
-; Thus, if your system supports a direct branch to the tpa (via a zero-length
-; .COM file, or the ZCPR "GO" command), you may safely re-execute MLOAD.
-;
-; Please report any bugs, bug fixes, or enhancements to
-;
-; "FORT FONE FILE FOLDER" rcpm/cbbs
-; Fort Atkinson, Wisconsin
-; (414) 563-9932 (no ring back)
-;
-; --Ron Fowler
-; 03/08/84 updated 1/31/85
-;
-;------------------------------------------------------------
-;
-; CP/M equates
-;
-warmbt equ 0 ;warm boot
-system equ 5 ;system entry (also top of mem pntr)
-dfcb equ 5ch ;default file control block
-ft equ 9 ;fcb offset to filetype
-tbuf equ 80h ;default buffer
-tpa equ 100h ;transient program area
-eof equ 1ah ;cp/m end-of-file mark
-fcbsiz equ 33 ;size of file control block
-;
-; CP/M system calls
-;
-pcharf equ 2 ;print char
-seldf equ 14 ;select disk drive
-openf equ 15 ;open file
-closef equ 16 ;close file
-fsrchf equ 17 ;search for first
-fsrchn equ 18 ;search for next
-erasef equ 19 ;delete file
-readf equ 20 ;read record
-writef equ 21 ;write record
-creatf equ 22 ;create file
-getdrf equ 25 ;return dflt drive #
-sdmaf equ 26 ;set dma address
-gsuser equ 32 ;get/set user #
-rrand equ 33 ;read random
-wrand equ 34 ;write random
-filszf equ 35 ;compute file size
-srand equ 36 ;set random
-;
-; ASCII character constants
-;
-cr equ 13
-lf equ 10
-bel equ 7
-tab equ 9
-;
-; without further ado...
-;
- org tpa
-;
- jmp begin ;jump over default output filetype
-;
-; the default output filetype is located at 103h for easy patching
-;
-outtyp: db 'COM'
-;
-begin: lxi h,0 ;save system stackpointer
- dad sp
- shld spsave
- lxi sp,stack ;load local stack
- call ilprnt ;sign on
- db 'MLOAD ver. 2.5 Copyright (C) 1983, 1984, 1985'
- db cr,lf
- db 'by NightOwl Software, Inc.'
- db cr,lf,0
- call setup ;initialize
-main: call nxtfil ;parse and read next input file
- jc done ;no more...
- call lodfil ;yep, load it
- call closfl ;close it (in case MP/M or TurboDOS)
- jmp main ;maybe more
-done: call wrtfil ;write the output file
-;
-; exit to cp/m
-;
-exit: lxi d,tbuf ;restore dma address
- mvi c,sdmaf
- call bdos
- lda system+2 ;get top of memory pointer
- sui 9 ;allow for ccp+slop
- lxi h,hiload+1 ;highest load address
- sub m ;above ccp?
- jc warmbt ;then warm-boot
- lhld spsave ;nope, ccp still in memory
- sphl ;restore its stack
- ret ;return to ccp
-;
-; load program initialization
-;
-setup: lxi h,varset ;initialize variables
- lxi d,vars
- mvi b,varlen ;by moving in default values
- call move
- lhld cmdptr ;get first free mem pointer
- xchg ;in de
- lxi h,tbuf ;point to command tail bufr
- mov a,m ;get its length
- inx h
- ora a ;does it have any length?
- jz help ;nope, go give usage help
- mov b,a ;yep, get length to b
- call move ;move cmd tail to buffer
- xchg ;end of dest to hl
- mvi m,0 ;stuff a terminator
- inx h ;point to first free memory
- shld filbuf ;set up file buffer
- xchg ;file bufr adrs to de
- lhld system+1 ;get top of memory pointer
- xra a ;round system to page boundary
- sub e
- mov c,a ;with result in bc
- mov a,h
- sui 9 ;allow for ccp
- sbb d
- mov b,a
- xchg ;buffer pointer to hl
-nitmem: mvi m,0 ;clear buffer
- inx h
- dcx b
- mov a,b
- ora c
- jnz nitmem
-;
-; look for a bias specification in command line
-;
- lhld cmdptr ;point to command buffer-1
- dcx h
- call scanbk ;scan past blanks
- ora a ;no non-blank chars?
- jz help ;then go print help text
-fndspc: inx h ;point to next
- mov a,m ;fetch it
- ora a ;test it
- rz ;line ended, return
- cpi ' ' ;nope, test for blank
- jnz fndspc ;not blank, continue
- call scanbk ;skip blanks
- ora a ;end-of-line?
- rz ;return if so
-;
-; hl points to bias in command line
-;
- lxi d,0 ;init bias
- call hexdig ;insure a hex digit
- jc synerr ;bad...
-hexlp: mov a,m ;no. get next char
- inx h ;skip over it
- call hexdig ;test for hex digit
- jnc digok ;jump if good hex digit
- ora a ;must end on null terminator
- jnz synerr
- xchg ;good end, get bias to hl
- shld bias ;stuff it
- ret ;done
-digok: xchg ;bias to hl
- dad h ;skift left 4 to make room
- dad h ; for new hex digit
- dad h
- dad h
- xchg ;back to de
- add e ;add in new digit
- mov e,a
- jnc hexlp ;jump if no 8-bit ovfl
- inr d ;carry
- jmp hexlp
-;
-; parse next input name, and open resultant file
-;
-nxtfil: lhld cmdptr ;get command line pointer
-next2: lxi d,dfcb ;destination fcb
- call fparse ;parse a filename
- cpi '=' ;stopped on output specifier?
- jnz noteq
- lda outnam+2 ;insure no name yet specified
- cpi ' '
- jnz synerr ;syntax error if already named
- lda outflg ;already been here?
- ora a
- jnz synerr ;can't be here twice
- inr a ;flag that we've been here
- sta outflg
- inr b ;insure no ambiguous output name
- dcr b
- jnz afnerr
- inx h ;skip over '='
- push h ;save cmd line pointer
- lxi h,dfcb-1 ;move the name to output name hold
- lxi d,outnam
- mvi b,13 ;drive spec too
- call move
- pop h ;restore command line pointer
- jmp next2 ;go parse another
-noteq: cpi ',' ;stopped on comma?
- jz gcomma ;jump if so
- mvi m,0 ;nope, insure end of input
- jmp nxt2 ;don't advance over fake end
-gcomma: inx h ;skip over comma
-nxt2: shld cmdptr ;save new command line pntr
- mov a,b ;get ambig char count
- ora a ;test it
- jnz afnerr ;allow no ambig characters
- sta bufptr ;force a disk read
- lxi d,dfcb+1 ;look at parsed filename
- ldax d
- cpi ' ' ;blank? (input ended?)
- stc ;get carry ready in case so
- rz ;return cy if input gone
- dcx d ;nope, point de to start of fcb
-open2: push d ;try to open the file
- mvi c,openf
- call bdos
- pop d
- inr a ;return=0ffh?
- jnz openok ;jump if not
-;
-; file not found: if filetype blank, set to 'hex' and try again
-;
- lxi h,dfcb+ft ;point to file type
- mov a,m ;anything there?
- cpi ' '
- jnz fnferr ;yes, so file not found
- mvi m,'H' ;nope, fill in 'hex'
- inx h
- mvi m,'E'
- inx h
- mvi m,'X'
- jmp open2 ;go try again
-;
-; here after a good file open
-;
-openok: call hexchk ;is this a hex file?
- rz ;if so, all done
- lxi h,comflg ;no, get pointer to flag
- mov a,m ;loading first file?
- ora a
- rnz ;if not, ignore type, consider hex
- inr m ;else, set the flag
- ret
-;
-; load current file
-;
-lodfil: lxi h,comflg ;loading a com file?
- mov a,m ;get flag
- ani 1
- jnz lodcom ;jump if so
- lhld bias ;else get bias on top of stack
- push h
-;
-; load a hex record
-;
-loadlp: call gnb ;get next file byte
- sbi ':' ;look for start-record mark
- jnz loadlp ;scan until found
- sta cksum ;got it, init checksum to zero
- mov d,a ;upper byte of rec cnt=0
- pop b ;retrieve bias adrs
- push b ;save it again
- call ghbcks ;get hex byte w/checksum
- mov e,a ;de now has record length
- ora a ;test it
- jnz notend ;jump if len<>0 (not eof rec)
- pop h ;all done
- ret
-notend: call ghbcks ;hi byte of rec ld adrs
- mov h,a ;accumulate in hl
- call ghbcks ;get lo byte
- mov l,a ;put lo in l
- lda lodflg ;test load flag
- ora a
- cz lodnit ;not first record, initialize
- push h ;save load address
- dad d ;add in record length
- dcx h ;make highest, not next
- lda hipc ;a new high?
- sub l
- lda hipc+1
- sbb h
- jnc notgt ;jump if not
- shld hipc ;yep, update hipc
- push d ;save reclen
- xchg ;load adrs to de
- lhld offset ;get offset to form true memory adrs
- dad d ;add in offset
- dad b ;and bias
- shld hiload ;mark highest true memory load adrs
- lda system+2 ;validate against top-mem pointer
- cmp h
- jc memful ;jump if out of memory
- pop d ;restore reclen
-notgt: pop h ;restore load address
- dad b ;add bias to load adrs
- push d ;save record length
- push h
- lhld bytcnt ;add record length to byte count
- dad d
- shld bytcnt
- pop h
- xchg
- lhld offset ;calculate true memory adrs
- dad d ;hl=true loading adrs
- pop d ;restore record length
- call ghbcks ;skip unused byte of intel format
-;
-; move the record into memory
-;
-reclp: call ghbcks ;get hex byte
- mov m,a ;store it in buffer
- inx h ;point to next
- dcr e ;count down
- jnz reclp ;until record all read
- call ghbcks ;get checksum byte
- jnz cserr ;final add cksum should sum 0
- jmp loadlp ;good load, go do nxt record
-;
-; get next hex byte from input, and
-; accumulate a checksum
-;
-ghbcks: push b ;save em all
- push h
- push d
- call hexin ;get hex byte
- mov b,a ;save in b
- lxi h,cksum ;add to checksum
- mov a,m
- add b
- mov m,a
- mov a,b ;get byte back
- pop d ;restore checksum
- pop h ;restore other regs
- pop b
- ret
-;
-; routine to get next byte from input...forms
-; byte from two ascii hex characters
-;
-hexin: call gnb ;get next input file byte
- call hexval ;convert to binary w/validation
- rlc ;move into ms nybble
- rlc
- rlc
- rlc
- ani 0f0h ;kill possible garbage
- push psw ;save it
- call gnb ;get next byte
- call hexval ;convert it, w/validation
- pop b ;get back first
- ora b ;or in second
- ret ;good byte in a
-;
-; gnb - utility subroutine to get next
-; byte from disk file
-gnb: push h ;save all regs
- push d
- push b
- lda bufptr ;get input bufr pointer
- ani 7fh ;wound back to 0?
- jz diskrd ;go read sector if so
-gnb1: mvi d,0 ;else form 16 bit offset
- mov e,a
- lxi h,tbuf ;from tbuf
- dad d ;add in offset
- mov a,m ;get next byte
- cpi eof ;end of file?
- jz eoferr ;error if so
- lxi h,bufptr ;else bump buf ptr
- inr m
- ora a ;return carry clear
- pop b ;restore and return
- pop d
- pop h
- ret
-;
-; read next sector from disk
-;
-diskrd: mvi c,readf ;bdos "READ SEC" function
- lxi d,dfcb
- call bdos ;read sector
- ora a
- jnz eoferr ;error if phys end of file
- sta bufptr ;store 0 as new buf ptr
- jmp gnb1 ;go re-join gnb code
-;
-; load a com file
-;
-lodcom: inr m ;bump the comfile flag
- lxi h,tpa ;set origin
- call lodnit ;and initialize
- xchg ;load address in de
- lhld bias ;add in bias
- dad d
- xchg
- lhld offset ;and offset
- dad d
- xchg ;de has absolute mem adrs of load
-;
-comlp: lxi h,128 ;calculate next dma
- dad d
- lda system+2 ;check for space
- cmp h
- jc memful ;jump if none
- push h ;else save next dma
- push d ;and this dma
- mvi c,sdmaf ;set this dma
- call bdos
- lxi d,dfcb ;read next record
- mvi c,readf
- call bdos
- pop h ;recall this dma
- pop d ;de=next dma
- ora a ;end of read?
- jnz lodend ;jump if so
- lhld comsiz ;no, advance com byte count
- lxi b,128
- dad b
- shld comsiz
- jmp comlp ;continue
-;
-lodend: dcx h ;one less byte is highest
- shld hiload ;set a new high
- lhld comsiz ;hi pc=bytecount+100h
- lxi d,tpa
- dad d
- xchg ;to de
- lhld bias ;add in bias
- dad d
- shld hipc
- lxi d,tbuf ;reset dma for hex files
- mvi c,sdmaf
- call bdos
- ret
-;
-; write output file
-;
-wrtfil: lxi d,dfcb ;point to fcb
- push d ;save 2 copies of pointer
- push d
- call nitfcb ;initialize output fcb
- lxi h,outnam ;move output name in
- dcx d ;point to user # (prior to fcb)
- mvi b,10 ;move user, drive, primary name
- call move
- mov a,m ;output type blank?
- cpi ' '
- jnz wrtnb ;jump if not
- lxi h,outtyp ;yes, move dflt output filetype in
-wrtnb: mvi b,3
- call move
- pop d ;restore fcb pointer
- mvi c,erasef ;erase any existing file
- call bdos
- pop d ;restore fcb pointer
- mvi c,creatf ;create a new file
- call bdos
- inr a ;good create?
- jz dirful ;goto directory full error if not
- lhld hiload ;yep, get top of bufr pntr
- xchg ;in de
- lhld filbuf ;get start of bufr adrs
- mov a,e ;calculate output file size
- sub l
- mov c,a ;with result in bc
- mov a,d
- sbb h
- mov b,a
- mov a,b ;test length
- ora c
- jz loderr ;nothing to write???
- lxi d,dfcb ;get fcb pointer
-wrlp: push b ;save count
- push d ;and fcb pointer
- xchg ;get memory pointer to de
- lxi h,128 ;add in sector length for next pass
- dad d
- xthl ;save next dma
- push h ;above fcb
- mvi c,sdmaf ;set transfer address
- call bdos
- pop d ;fetch fcb pointer
- push d ;save it again
- mvi c,writef ;write a sector
- call bdos
- ora a ;test result
- jnz dskful ;disk full error...
- lhld reccnt ;no,increment count of records
- inx h
- shld reccnt
- pop d ;restore fcb pointer
- pop h ;and memory write pointer
- pop b ;and count
- mov a,c ;subtract 128 (sec size) from count
- sui 128
- mov c,a
- jnc wrlp ;jump if some left
- mov a,b ;hi-order borrow
- sui 1 ;do it (can't "DCR B", doesn't affect cy)
- mov b,a ;restore
- jnc wrlp ;jump if more left
- call closfl ;close output file
-;
-; report statistics to console
-;
- call ilprnt
- db 'Loaded ',0
- lhld bytcnt ;print # bytes
- call decout
- call ilprnt
- db ' bytes (',0
- call hexout
- call ilprnt
- db 'H)',0
- call ilprnt
- db ' to file %',0
- lda comflg ;did we load a comfile too?
- ora a
- jz notcom ;jump if not
- call ilprnt
- db cr,lf,'Over a ',0
- lhld comsiz
- call decout
- call ilprnt
- db ' byte binary file',0
-notcom: call ilprnt
- db cr,lf,'Start address: ',0
- lhld lodadr ;print loading address
- call hexout
- call ilprnt
- db 'H Ending address: ',0
- lhld hipc ;print ending load address
- call hexout
- call ilprnt
- db 'H Bias: ',0
- lhld bias
- call hexout
- call ilprnt
- db 'H',cr,lf,0
- call ilprnt
- db 'Saved image size: ',0
- lhld reccnt ;get count of image records
- push h ;save it
- mvi b,7 ;convert to bytes
-xlp: dad h
- dcr b
- jnz xlp
- call decout ;print it
- call ilprnt
- db ' bytes (',0
- call hexout ;now in hex
- call ilprnt
- db 'H, - ',0
- pop h ;recall record count
- call decout ;print it
- call ilprnt
- db ' records)',cr,lf,0
- lhld lodadr ;fetch loading address
- mov a,l ;test if =tpa
- ora a
- jnz nottpa ;tpa always on page boundary
- mov a,h ;lo ok, test hi
- cpi (tpa shr 8) and 0ffh
- rz ;return if tpa
-nottpa: call ilprnt ;not, so print warning msg
- db cr,lf,bel
- db '++ Warning: program origin NOT at 100H ++'
- db cr,lf,0
- ret ;done
-;
-; ***********************
-; * utility subroutines *
-; ***********************
-;
-;
-; routine to close any open file
-;
-closfl: lxi d,dfcb
- mvi c,closef
- call bdos
- inr a ;test close result
- jz clserr ;jump if error
- ret
-;
-; print message in-line with code
-;
-ilprnt: xthl ;message pntr to hl
- call prathl ;print it
- xthl ;restore and return
- ret
-;
-; print msg pointed to by hl until null. expand
-; '%' char to current filename.
-;
-prathl: mov a,m ;fetch char
- inx h ;point to next
- ora a ;terminator?
- rz ;then done
- cpi '%' ;want filename?
- jz prtfn ;go do it if so
- call type ;nope, just print char
- jmp prathl ;continue
-;
-prtfn: push h ;save pointer
- push b
- lda dfcb ;fetch dr field of dfcb
- ora a ;default drive?
- jnz prndf ;jump if not
- call getdsk ;get logged-in drive #
- inr a ;make it one-relative (as in fcb)
-prndf: adi 'A'-1 ;make drive name printable
- call type ;print it
- lda dfcb-1 ;get user #
- cpi 0ffh ;null?
- cz getusr ;iff so, get current user
- mov l,a ;to hl
- mvi h,0
- call decout ;print it
- mvi a,':' ;drive names followed by colon
- call type
- lxi h,dfcb+1 ;setup for name
- mvi b,8 ;print up to 8
- call prtnam
- mvi a,'.' ;print dot
- call type
- mvi b,3 ;print filetype field
- call prtnam
- pop b
- pop h ;restore and continue
- jmp prathl
-;
-; print file name .HL max length in b. don't print spaces
-;
-prtnam: mov a,m ;fetch a char
- cpi ' ' ;blank?
- jz pwind ;go wind if so
- inx h ;nope, move to next
- call type ;print it
- dcr b ;count down
- jnz prtnam ;continue
- ret
-pwind: inx h ;skip remainder of blank name
- dcr b
- jnz pwind
- ret
-;
-; print HL in decimal on console
-;
-decout: push h ;save everybody
- push d
- push b
- lxi b,-10 ;conversion radix
- lxi d,-1
-declp: dad b
- inx d
- jc declp
- lxi b,10
- dad b
- xchg
- mov a,h
- ora l
- cnz decout ;this is recursive
- mov a,e
- adi '0'
- call type
- pop b
- pop d
- pop h
- ret
-;
-; newline on console
-;
-crlf: mvi a,cr
- call type
- mvi a,lf
- jmp type
-;
-; print hl on console in hex
-;
-hexout: mov a,h ;get hi
- call hexbyt ;print it
- mov a,l ;get lo, fall into hexbyt
-;
-; type accumulator on console in hex
-;
-hexbyt: push psw ;save byte
- rar ;get ms nybble..
- rar ;..into lo 4 bits
- rar
- rar
- call nybble
- pop psw ;get back byte
-nybble: ani 0fh ;mask ms nybble
- adi 90h ;add offset
- daa ;decimal adjust a-reg
- aci 40h ;add offset
- daa ;fall into type
-;
-; type char in a on console
-;
-type: push h ;save all
- push d
- push b
- mov e,a ;cp/m outputs from e
- mvi c,pcharf
- call bdos
- pop b
- pop d
- pop h
- ret
-;
-; move: from @hl to @de, count in b
-;
-move: inr b ;up one
-movlp: dcr b ;count down
- rz ;return if done
- mov a,m ;not done, continue
- stax d
- inx h ;pointers=pointers+1
- inx d
- jmp movlp
-;
-; scan to first non-blank char in string @hl
-;
-scanbk: inx h ;next
- mov a,m ;fetch it
- cpi ' '
- jz scanbk
- ret
-;
-; get hex digit and validate
-;
-hexval: call hexdig ;get hex digit
- jc formerr ;jump if bad
- ret
-;
-; get hex digit, return cy=1 if bad digit
-;
-hexdig: cpi '0' ;lo boundary test
- rc ;bad already?
- cpi '9'+1 ;no, test hi
- jc hexcvt ;jump if numeric
- cpi 'A' ;test alpha
- rc ;bad?
- cpi 'F'+1 ;no, upper alpha bound
- cmc ;pervert carry
- rc ;bad?
- sui 7 ;no, adjust to 0-f
-hexcvt: ani 0fh ;make it binary
- ret
-;
-; ******************
-; * error handlers *
-; ******************
-;
-synerr: call crlf
- call ilprnt
- db ' Command line syntax error',cr,lf,cr,lf,0
- jmp help ;give help msg too
-;
-afnerr: call errxit ;exit with message
- db 'Ambiguous file name: % not allowed.',0
-;
-fnferr: call errxit
- db 'File % not found.',0
-;
-dskful: call errxit
- db 'Disk full.',0
-;
-dirful: call errxit
- db 'Directory full.',0
-;
-eoferr: call errxit
- db 'Premature end-of-file in %',0
-;
-cserr: call errxit
- db 'Checksum error in %',0
-;
-clserr: call errxit
- db 'Can''t close %',0
-;
-memful: call errxit
- db 'Memory full while loading %',0
-;
-formerr:call errxit
- db 'Format error in file %',0
-;
-loderr: call errxit
- db 'Writing %, nothing loaded',0
-;
-help: call errxit ;print help text
- db 'MLOAD syntax:',cr,lf,cr,lf
- db 'MLOAD [<OUTFIL>=] <FILE1>[,<FILE2>...] [<BIAS>]',cr,lf
- db tab,' (brackets denote optional items)',cr,lf,cr,lf
- db tab,'<OUTFIL> is the optional output filename',cr,lf
- db tab,'<FILEn> are input file(s)',cr,lf
- db tab,'<BIAS> is a hex load offset within the output file'
- db cr,lf,cr,lf
- db tab,'<FILE1> may be an optional non-HEX file to be patched',cr,lf
- db tab,'by subsequently named HEX files (specifying',cr,lf
- db tab,'The filetype enables this function).'
- db cr,lf,cr,lf
- db 'Note that ZCPR2-style drive/user notation may be used in all'
- db cr,lf
- db 'file specifications (e.g., "B3:MYFILE.COM, "A14:MDM7.HEX").'
- db cr,lf,0
-;
-; general error handler
-;
-errxit: call crlf ;new line
- pop h ;fetch error msg pointer
- call prathl ;print it
- call crlf
- jmp exit ;done
-;
-; initialize load parameters
-;
-lodnit: mvi a,1 ;first record, set load flag
- sta lodflg
- shld lodadr ;save load address
- shld hipc ;and hi load
- push d ;save record length
- xchg ;de=load address
- lhld filbuf ;get address of file buffer
- mov a,l ;subtract load adrs from file buffer
- sub e
- mov l,a
- mov a,h
- sbb d
- mov h,a
- shld offset ;save as load offset
- push d ;save load address on stack
- push b ;save bias
- lxi d,outnam+2 ;check output filename
- ldax d ;(first char)
- cpi ' '
- jnz namskp ;jump if so
- lxi h,dfcb+1 ;get first name pointer
- mvi b,8 ;(don't include drive spec)
- call move
-;
-; check for outflg=1 (presence of an "="). note that the
-; filename may well be blank, and yet outflg <>0, for example
-; in the case of "A:=<FILENAME>" or "C4:=<FILENAME>". in
-; this case, we want to remember the drive/user specified, but
-; use the first input file to form the output name. otherwise,
-; we use the current drive/user.
-;
- lda outflg ;was there an "="?
- ora a
- jnz namskp ;jump if so
- lxi h,outnam ;get destination pointer
- call getusr ;get current user #
- mov m,a
- inx h ;point to drive
- call getdsk ;get it
- inr a ;fcb's drive is 1-relative
- mov m,a
-namskp: mvi a,1 ;insure "=" cannot occur anymore
- sta outflg
- pop b ;restore bias
- pop h ;load address to hl
- pop d ;restore record length
- ret
-;
-; *********************************
-; * file name parsing subroutines *
-; *********************************
-;
-; credit where credit's due:
-; --------------------------
-; these routines were lifted from bob van valzah's
-; "FAST" program.
-;
-;
-;
-; *********************************
-; * file name parsing subroutines *
-; *********************************
-;
-;
-; getfn gets a file name from text pointed to by reg hl into
-; an fcb pointed to by reg de. leading delimeters are
-; ignored. allows drive spec of the form <du:> (drive/user).
-; this routine formats all 33 bytes of the fcb (but not ran rec).
-;
-; entry de first byte of fcb
-; exit b=# of '?' in name
-; fcb-1= user # parsed (if specified) or 255
-;
-;
-fparse: call nitfcb ;init 1st half of fcb
- call gstart ;scan to first character of name
- call getdrv ;get drive/user spec. if present
- mov a,b ;get user # or 255
- cpi 0ffh ;255?
- jz fpars1 ;jump if so
- dcx d ;back up to byte preceeding fcb
- dcx d
- stax d ;stuff user #
- inx d ;onward
- inx d
-fpars1: call getps ;get primary and secondary name
- ret
-;
-; nitfcb fills the fcb with dflt info - 0 in drive field
-; all-blank in name field, and 0 in ex,s1,s2,rc, disk
-; allocation map, and random record # fields
-;
-nitfcb: push h
- push d
- call getusr ;init user field
- pop d
- pop h
- push d ;save fcb loc
- dcx d
- stax d ;init user # to currnt user #
- inx d
- xchg ;move it to hl
- mvi m,0 ;drive=default
- inx h ;bump to name field
- mvi b,11 ;zap all of name fld
-nitlp: mvi m,' '
- inx h
- dcr b
- jnz nitlp
- mvi b,33-11 ;zero others, up to nr field
-zlp: mvi m,0
- inx h
- dcr b
- jnz zlp
- xchg ;restore hl
- pop d ;restore fcb pointer
- ret
-;
-; gstart advances the text pointer (reg hl) to the first
-; non delimiter character (i.e. ignores blanks). returns a
-; flag if end of line (00h or ';') is found while scaning.
-; exit hl pointing to first non delimiter
-; a clobbered
-; zero set if end of line was found
-;
-gstart: call getch ;see if pointing to delim?
- rnz ;nope - return
- ora a ;physical end?
- rz ;yes - return w/flag
- inx h ;nope - move over it
- jmp gstart ;and try next char
-;
-; getdrv checks for the presence of a du: spec at the text
-; pointer, and if present formats drive into fcb and returns
-; user # in b.
-;
-; entry hl text pointer
-; de pointer to first byte of fcb
-; exit hl possibly updated text pointer
-; de pointer to second (primary name) byte of fcb
-; b user # if specified or 0ffh
-;
-getdrv: mvi b,0ffh ;default no user #
- push h ;save text pointer
-dscan: call getch ;get next char
- inx h ;skip pointer over it
- jnz dscan ;scan until delimiter
- cpi ':' ;delimiter a colon?
- inx d ;skip dr field in fcb in case not
- pop h ;and restore text pointer
- rnz ;return if no du: spec
- mov a,m ;got one, get first char
- call cvtuc ;may be drive name, cvt to upper case
- cpi 'A' ;alpha?
- jc isnum ;jump to get user # if not
- sui 'A'-1 ;yes, convert from ascii to #
- dcx d ;back up fcb pointer to dr field
- stax d ;store drive # into fcb
- inx d ;pass pointer over drv
- inx h ;skip drive spec in text
-isnum: mov a,m ;fetch next
- inx h
- cpi ':' ;du delimiter?
- rz ;done then
- dcx h ;nope, back up text pointer
- mvi b,0 ;got a digit, init user value
-uloop: mov a,b ;get accumulated user #
- add a ;* 10 for new digit
- add a
- add b
- add a
- mov b,a ;back to b
- mov a,m ;get text char
- sui '0' ;make binary
- add b ;add to user #
- mov b,a ;updated user #
- inx h ;skip over it
- mov a,m ;get next
- cpi ':' ;end of spec?
- jnz uloop ;jump if not
- inx h ;yep, return txt pointer past du:
- ret
-;
-; getps gets the primary and secondary names into the fcb.
-; entry hl text pointer
-; exit hl character following secondary name (if present)
-;
-getps: mvi c,8 ;max length of primary name
- mvi b,0 ;init count of '?'
- call getnam ;pack primary name into fcb
- mov a,m ;see if terminated by a period
- cpi '.'
- rnz ;nope - secondary name not given
- ;return default (blanks)
- inx h ;yup - move text pointer over period
-ftpoint:mov a,c ;yup - update fcb pointer to secondary
- ora a
- jz getft
- inx d
- dcr c
- jmp ftpoint
-getft: mvi c,3 ;max length of secondary name
- call getnam ;pack secondary name into fcb
- ret
-;
-; getnam copies a name from the text pointer into the fcb for
-; a given maximum length or until a delimiter is found, which
-; ever occurs first. if more than the maximum number of
-; characters is present, character are ignored until a
-; a delimiter is found.
-; entry hl first character of name to be scanned
-; de pointer into fcb name field
-; c maximum length
-; exit hl pointing to terminating delimiter
-; de next empty byte in fcb name field
-; c max length - number of characters transfered
-;
-getnam: call getch ;are we pointing to a delimiter yet?
- rz ;if so, name is transfered
- inx h ;if not, move over character
- cpi '*' ;ambigious file reference?
- jz ambig ;if so, fill the rest of field with '?'
- cpi '?' ;afn reference?
- jnz notqm ;skip if not
- inr b ;else bump afn count
-notqm: call cvtuc ;if not, convert to upper case
- stax d ;and copy into name field
- inx d ;increment name field pointer
- dcr c ;if name field full?
- jnz getnam ;nope - keep filling
- jmp getdel ;yup - ignore until delimiter
-ambig: mvi a,'?' ;fill character for wild card match
-fillq: stax d ;fill until field is full
- inx d
- inr b ;increment count of '?'
- dcr c
- jnz fillq ;fall thru to ingore rest of name
-getdel: call getch ;pointing to a delimiter?
- rz ;yup - all done
- inx h ;nope - ignore antoher one
- jmp getdel
-;
-; getch gets the character pointed to by the text pointer
-; and sets the zero flag if it is a delimiter.
-; entry hl text pointer
-; exit hl preserved
-; a character at text pointer
-; z set if a delimiter
-;
-getch: mov a,m ;get the character, test for delim
-;
-; global entry: test char in a for filename delimiter
-;
-fndelm: cpi '/'
- rz
- cpi '.'
- rz
- cpi ','
- rz
- cpi ' '
- rz
- cpi ':'
- rz
- cpi '='
- rz
- ora a ;set zero flag on end of text
- ret
-;
-; bdos entry: preserves bc, de. if system call is a file
-; function, this routine logs into the drive/
-; user area specified, then logs back after
-; the call.
-;
-bdos: call filfck ;check for a file function
- jnz bdos1 ;jump if not a file function
- call getdu ;get drive/user
- shld savedu
- ldax d ;get fcb's drive
- sta fcbdrv ;save it
- dcr a ;make 0-relative
- jm bdos0 ;if not default drive, jump
- mov h,a ;copy to h
-bdos0: xra a ;set fcb to default
- stax d
- dcx d ;get fcb's user #
- ldax d
- mov l,a
- inx d ;restore de
- call setdu ;set fcb's user
-;
-; note that unspecified user # (value=0ffh) becomes
-; a getusr call, preventing ambiguity.
-;
- call bdos1 ;do user's system call
- push psw ;save result
- push h
- lda fcbdrv ;restore fcb's drive
- stax d
- lhld savedu ;restore prior drive/user
- call setdu
- pop h ;restore bdos result registers
- pop psw
- ret
-;
-; local variables for bdos replacement routine
-;
-savedu: dw 0 ;saved drive,user
-fcbdrv: db 0 ;fcb's drive
-dmadr: dw 80h ;current dma adrs
-;
-bdos1: push d
- push b
- mov a,c ;doing setdma?
- cpi sdmaf
- jnz bdos1a ;jump if not
- xchg ;yep, keep a record of dma addresses
- shld dmadr
- xchg
-bdos1a: call system
- pop b
- pop d
- ret
-;
-; get drive, user: h=drv, l=user
-;
-getdu: push b ;don't modify bc
- push d
- mvi c,gsuser ;get user #
- mvi e,0ffh
- call bdos1
- push psw ;save it
- mvi c,getdrf ;get drive
- call bdos1
- mov h,a ;drive returned in h
- pop psw
- mov l,a ;user in l
- pop d
- pop b ;restore caller's bc
- ret
-;
-; set drive, user: h=drv, l=user
-;
-setdu: push b ;don't modify bc
- push d
- push h ;save info
- mov e,h ;drive to e
- mvi c,seldf ;set it
- call bdos1
- pop h ;recall info
- push h
- mov e,l ;user # to e
- mvi c,gsuser
- call bdos1 ;set it
- pop h
- pop d
- pop b
- ret
-;
-; check for file-function: open, close, read random, write
-; random, read sequential, write sequential.
-;
-filfck: mov a,c ;get function #
- cpi openf
- rz
- rc ;ignore lower function #'s
- cpi closef ;(they're not file-related)
- rz
- cpi readf
- rz
- cpi writef
- rz
- cpi rrand
- rz
- cpi wrand
- rz
- cpi fsrchf
- rz
- cpi fsrchn
- rz
- cpi erasef
- rz
- cpi creatf
- rz
- cpi filszf
- rz
- cpi srand
- ret
-;
-; convert char to upper case
-;
-cvtuc: cpi 'a' ;check lo bound
- rc
- cpi 'z'+1 ;check hi
- rnc
- sui 20h ;convert
- ret
-;
-; check for hex filetype in fcb name
-;
-hexchk: push h
- push d
- push b
- mvi b,3 ;type is 3 chars
- lxi d,dfcb+9 ;point de to type field
- lxi h,hextyp ;point hl to "COM"
-hexlop: ldax d
- ani 7fh ;ignore attributes
- cmp m
- inx h
- inx d
- jnz hexit ;jump if not com
- dcr b
- jnz hexlop
-hexit: pop b ;z reg has result
- pop d
- pop h
- ret
-;
-hextyp: db 'HEX'
-;
-; routine to return user # without disturbing registers
-;
-getusr: push h
- push d
- push b
- mvi c,gsuser
- mvi e,0ffh
- call bdos
- pop b
- pop d
- pop h
- ret
-;
-; routine to return drive # without disturbing registers
-;
-getdsk: push h
- push d
- push b
- mvi c,getdrf
- call bdos
- pop b
- pop d
- pop h
- ret
-;
-; these are the initial values of the variables, and
-; are moved into the variables area by the setup routine.
-; if you add variables, be sure to add their intial value
-; into this table in the order corresponding to their
-; occurance in the variables section.
-;
-varset: dw 0 ;bias
- dw 0 ;hiload
- dw 0 ;hipc
- db 0 ;cksum
- dw cmdbuf ;cmdptr
- db 0 ;bufptr
- db 0 ;lodflg
- dw cmdbuf ;filbuf
- dw 0 ;offset
- dw 0 ;lodadr
- db 0,0,' ' ;outnam
- dw 0 ;reccnt
- dw 0 ;bytcnt
- db 0 ;comflg
- dw 0 ;comsiz
- db 0 ;outflg
-;
-varlen equ $-varset ;define length of init table
-;
-; working variables
-;
-vars equ $ ;define variables area start
-;
-bias: ds 2 ;load offset
-hiload: ds 2 ;highest true load address
-hipc: ds 2 ;highest pc
-cksum: ds 1 ;record checksum
-cmdptr: ds 2 ;command line pointer
-bufptr: ds 1 ;input buffer pointer
-lodflg: ds 1 ;something-loaded flag
-filbuf: ds 2 ;file buffer location
-offset: ds 2 ;load offset into buffer
-lodadr: ds 2 ;load address
-outnam: ds 13 ;output drive+name
-reccnt: ds 2 ;output file record count
-bytcnt: ds 2 ;output file bytes loaded count
-comflg: ds 1 ;flags com file encountered
-comsiz: ds 2 ;size of a loaded com file
-outflg: ds 1 ;flags an "=" present in cmd line
-;
-; end of working variables
-;
-;
-;
-; stack stuff
-;
-spsave: ds 2 ;system stack pntr save
-;
-;
- ds 100 ;50-level stack
-;
-stack equ $
-cmdbuf equ $ ;command buffer location
-;
-;
- end
+ title 'MLOAD MULTI-FILE HEX LOAD UTILITY'
+;
+; *********************************
+; * MLOAD.ASM *
+; * Multi-file Hex Load Utility *
+; * for CP/M *
+; *********************************
+;
+;
+; Replacement for the cp/m "LOAD" program: this program
+; fixes many of the problems associated with the "CP/M"
+; load program, and adds many new features.
+;
+; ----------------
+;
+; Rev 2.5
+; 03/10/88
+; Property of NightOwl Software, Inc. Fort Atkinson, WI 53538
+; Written by Ron Fowler, Nightowl Software, Inc.
+;
+; ----------------
+; Notice: this program is NOT public domain; copyright is retained by
+; NightOwl Software, Inc. of Fort Atkinson, WI ... All Rights Reserved.
+;
+; License is granted for free use and re-distribution this program, as
+; long as such use and re-distribution is done without profit.
+;
+; ----------------
+;
+; modification history:
+;
+; 2.5 (WOD) This version corrects a bug that overlayed the first six
+; bytes of the CCP. The error did not show up unless a
+; jump to the CCP was done without a warm boot since MLOAD
+; used. This source file has been modified here with
+; concurrence of the author of MLOAD, Ron Fowler.
+;
+; 2.4 (RGF) We apologize for this relatively insubstantial update,
+; but someone has caused what we consider to be a problem,
+; by making changes to the program, and re-releasing under
+; the same version number. The changes in this case were
+; conversion of the opcode fields (but not the comments,
+; can you believe that??) of every line to upper case! That
+; totally invalidated the CRC of the source file, since there
+; are now two different MLOAD 2.3's running around.
+;
+; We DO NOT want these stupid mixed upper/lower case changes.
+; Someone somewhere has decided that this is the way assembly
+; language source should be, and we most VEHEMENTLY disagree.
+; It's a pain in the neck to make changes to and we don't
+; care to run our programs through conversion programs every
+; time we make changes.
+;
+; So ... leave the case of this file AS IS. Any changes made
+; to this program and not co-ordinated through us may very
+; well endanger availability of source code when we make
+; future updates. 'nuff said --NightOwl Software
+;
+; 2.3 (RGF) Trivial cosmetic changes
+; 2.2 (RGF) Modified copyright notice to show new owner of the
+; program.
+; 2.1 (RGF) Fixed problem on disk-full when writing output file
+; (mload previously didn't error out on a full disk)
+; 2.0 (RGF) Added the ability to pre-load a non-hex file, allowing
+; mload to be used to load hex file patches (obviating any
+; need to use DDT). The normal mload syntax is preserved.
+; the first (and only the first) filespec (after the "=",
+; if used) may be non-hex; the filetype must be specified.
+; Examples:
+;
+; 1) mload ws.com,wspatch
+; 2) mload MEXTEST=MEX112.COM,MXO-US13
+; 3) mload ws.ovr,ovrpatch
+;
+; The first example loads WS.COM, overlays it with
+; wspatch.hex, and writes the output to WS.COM. The
+; second example loads MEX112.COM, overlays it with
+; MXO-US13.HEX, and writes the output file to MEXTEST.COM.
+; (note that the second example is the recommended technique,
+; since it preserves the original file). The third example
+; loads WS.OVR and patches it with the file "OVRPATCH.HEX".
+;
+; Also added this rev: ZCPR2-style du specs are now fully
+; supported, for both input and output files. Thus, the
+; following command lines are permissable:
+;
+; b3>mload a4:myfile.com=0:bigfil,b6:patch1,c9:patch2
+; a6>mload b5:=c3:mdm717.com,mdmpatch
+;
+; After loading, an additional information line is now printed
+; in the statistics report, which displays the true size of the
+; saved image (the previous report was technically correct, but
+; could result in confusion for certain kinds of files with
+; imbedded "DS" and "ORG" statements in the original source code).
+;
+; 1.0 - 1.4 (RGF) change log removed to conserve space
+;
+; originally written by ron fowler, fort atkinson, wisconsin
+;
+;
+;
+; For assembly with asm.com or mac (delete above title line if
+; assembling with asm.com).
+;
+; This program is a replacement for the cp/m "LOAD" program.
+; Why replace "LOAD"? well... LOAD.COM has a few deficiencies.
+; For example, if your hex file's origin is above 100h, LOAD.COM
+; prepends blank space to the output file to insure it will work
+; as a CP/M transient. It cares not if the file is not intended
+; as a CP/M transient. it also doesn't like hex records with mixed
+; load addresses (for example, one that loads below a previous record --
+; which is a perfectly legitimate happenstance). Also, LOAD.COM
+; can load only one program at a time, and has no provision for
+; a load bias in the command specification. Finally, there is no
+; provision for user specification of the output file name.
+;
+;
+; Hence, this program....
+;
+;------------------------------------------------------------
+;
+; Syntax is as follows:
+;
+; mload [<outnam=] <filename>[,<filename>...] [bias]
+;
+; where <outnam> is the (optional!;) output file name (only the drive
+; spec and primary filename may be specified; the output filetype is
+; derived exclusively from the 3-byte string at 103h within MLOAD),
+; <filename> specifies files to load and <bias> is the offset within
+; the saved image to apply when loading the file.
+;
+; MLOAD with no arguments prints a small help message -- this message
+; is also printed whenever a command line syntax error occurs.
+;
+; Filenames may contain drive/user specs, and must not contain wildcards.
+; Input filenames must be separated by commas, and a space is required
+; between the last filename and the optional bias.
+;
+; A load information summary is printed at the successful conclusion
+; of the load. Any errors in loading will generally include the name
+; of the file in question.
+;
+; If no output filename is specified, it will be derived from the first
+; input filename, with filetype of 'COM', if not otherwise specified
+; (this default filetype may be patched directly into mload via DDT
+; (or with MLOAD itself, using a patch file) -- its location is at 103H
+; in MLOAD.COM). Note that a command line of the form "C:=<FILENAME>"
+; will place the output file on the "C" drive with the same primary
+; filename as the input file.
+;
+; In its simplest form, MLOAD's syntax is identical to LOAD.COM; thus
+; there should be no problem in learning to use the new program. The
+; only significant difference here is that, under LOAD.COM, all files
+; are output starting at 100h, even if they originate elsewhere. MLOAD
+; outputs starting at the hex file origin (actually, the first hex rec-
+; ord specifies the output load address). The bias option may be used
+; to override this.
+;
+; An example should clarify this. Suppose you have a file that loads
+; at 1000h. LOAD.COM would save an output file that begins at 100h and
+; loads past 1000h (to wherever the program ends). MLOAD will save an
+; output file starting from 1000h only. If, for some reason you need the
+; file to start at 100h in spite of its 1000h origin (i can think of sev-
+; eral circumstances where this would be necessary), you'd have to specify
+; a bias to mload. thus, using this example, "MLOAD MYFILE 0F00" would do.
+;
+; Note that this program re-initializes itself each time it is run.
+; Thus, if your system supports a direct branch to the tpa (via a zero-length
+; .COM file, or the ZCPR "GO" command), you may safely re-execute MLOAD.
+;
+; Please report any bugs, bug fixes, or enhancements to
+;
+; "FORT FONE FILE FOLDER" rcpm/cbbs
+; Fort Atkinson, Wisconsin
+; (414) 563-9932 (no ring back)
+;
+; --Ron Fowler
+; 03/08/84 updated 1/31/85
+;
+;------------------------------------------------------------
+;
+; CP/M equates
+;
+warmbt equ 0 ;warm boot
+system equ 5 ;system entry (also top of mem pntr)
+dfcb equ 5ch ;default file control block
+ft equ 9 ;fcb offset to filetype
+tbuf equ 80h ;default buffer
+tpa equ 100h ;transient program area
+eof equ 1ah ;cp/m end-of-file mark
+fcbsiz equ 33 ;size of file control block
+;
+; CP/M system calls
+;
+pcharf equ 2 ;print char
+seldf equ 14 ;select disk drive
+openf equ 15 ;open file
+closef equ 16 ;close file
+fsrchf equ 17 ;search for first
+fsrchn equ 18 ;search for next
+erasef equ 19 ;delete file
+readf equ 20 ;read record
+writef equ 21 ;write record
+creatf equ 22 ;create file
+getdrf equ 25 ;return dflt drive #
+sdmaf equ 26 ;set dma address
+gsuser equ 32 ;get/set user #
+rrand equ 33 ;read random
+wrand equ 34 ;write random
+filszf equ 35 ;compute file size
+srand equ 36 ;set random
+;
+; ASCII character constants
+;
+cr equ 13
+lf equ 10
+bel equ 7
+tab equ 9
+;
+; without further ado...
+;
+ org tpa
+;
+ jmp begin ;jump over default output filetype
+;
+; the default output filetype is located at 103h for easy patching
+;
+outtyp: db 'COM'
+;
+begin: lxi h,0 ;save system stackpointer
+ dad sp
+ shld spsave
+ lxi sp,stack ;load local stack
+ call ilprnt ;sign on
+ db 'MLOAD ver. 2.5 Copyright (C) 1983, 1984, 1985'
+ db cr,lf
+ db 'by NightOwl Software, Inc.'
+ db cr,lf,0
+ call setup ;initialize
+main: call nxtfil ;parse and read next input file
+ jc done ;no more...
+ call lodfil ;yep, load it
+ call closfl ;close it (in case MP/M or TurboDOS)
+ jmp main ;maybe more
+done: call wrtfil ;write the output file
+;
+; exit to cp/m
+;
+exit: lxi d,tbuf ;restore dma address
+ mvi c,sdmaf
+ call bdos
+ lda system+2 ;get top of memory pointer
+ sui 9 ;allow for ccp+slop
+ lxi h,hiload+1 ;highest load address
+ sub m ;above ccp?
+ jc warmbt ;then warm-boot
+ lhld spsave ;nope, ccp still in memory
+ sphl ;restore its stack
+ ret ;return to ccp
+;
+; load program initialization
+;
+setup: lxi h,varset ;initialize variables
+ lxi d,vars
+ mvi b,varlen ;by moving in default values
+ call move
+ lhld cmdptr ;get first free mem pointer
+ xchg ;in de
+ lxi h,tbuf ;point to command tail bufr
+ mov a,m ;get its length
+ inx h
+ ora a ;does it have any length?
+ jz help ;nope, go give usage help
+ mov b,a ;yep, get length to b
+ call move ;move cmd tail to buffer
+ xchg ;end of dest to hl
+ mvi m,0 ;stuff a terminator
+ inx h ;point to first free memory
+ shld filbuf ;set up file buffer
+ xchg ;file bufr adrs to de
+ lhld system+1 ;get top of memory pointer
+ xra a ;round system to page boundary
+ sub e
+ mov c,a ;with result in bc
+ mov a,h
+ sui 9 ;allow for ccp
+ sbb d
+ mov b,a
+ xchg ;buffer pointer to hl
+nitmem: mvi m,0 ;clear buffer
+ inx h
+ dcx b
+ mov a,b
+ ora c
+ jnz nitmem
+;
+; look for a bias specification in command line
+;
+ lhld cmdptr ;point to command buffer-1
+ dcx h
+ call scanbk ;scan past blanks
+ ora a ;no non-blank chars?
+ jz help ;then go print help text
+fndspc: inx h ;point to next
+ mov a,m ;fetch it
+ ora a ;test it
+ rz ;line ended, return
+ cpi ' ' ;nope, test for blank
+ jnz fndspc ;not blank, continue
+ call scanbk ;skip blanks
+ ora a ;end-of-line?
+ rz ;return if so
+;
+; hl points to bias in command line
+;
+ lxi d,0 ;init bias
+ call hexdig ;insure a hex digit
+ jc synerr ;bad...
+hexlp: mov a,m ;no. get next char
+ inx h ;skip over it
+ call hexdig ;test for hex digit
+ jnc digok ;jump if good hex digit
+ ora a ;must end on null terminator
+ jnz synerr
+ xchg ;good end, get bias to hl
+ shld bias ;stuff it
+ ret ;done
+digok: xchg ;bias to hl
+ dad h ;skift left 4 to make room
+ dad h ; for new hex digit
+ dad h
+ dad h
+ xchg ;back to de
+ add e ;add in new digit
+ mov e,a
+ jnc hexlp ;jump if no 8-bit ovfl
+ inr d ;carry
+ jmp hexlp
+;
+; parse next input name, and open resultant file
+;
+nxtfil: lhld cmdptr ;get command line pointer
+next2: lxi d,dfcb ;destination fcb
+ call fparse ;parse a filename
+ cpi '=' ;stopped on output specifier?
+ jnz noteq
+ lda outnam+2 ;insure no name yet specified
+ cpi ' '
+ jnz synerr ;syntax error if already named
+ lda outflg ;already been here?
+ ora a
+ jnz synerr ;can't be here twice
+ inr a ;flag that we've been here
+ sta outflg
+ inr b ;insure no ambiguous output name
+ dcr b
+ jnz afnerr
+ inx h ;skip over '='
+ push h ;save cmd line pointer
+ lxi h,dfcb-1 ;move the name to output name hold
+ lxi d,outnam
+ mvi b,13 ;drive spec too
+ call move
+ pop h ;restore command line pointer
+ jmp next2 ;go parse another
+noteq: cpi ',' ;stopped on comma?
+ jz gcomma ;jump if so
+ mvi m,0 ;nope, insure end of input
+ jmp nxt2 ;don't advance over fake end
+gcomma: inx h ;skip over comma
+nxt2: shld cmdptr ;save new command line pntr
+ mov a,b ;get ambig char count
+ ora a ;test it
+ jnz afnerr ;allow no ambig characters
+ sta bufptr ;force a disk read
+ lxi d,dfcb+1 ;look at parsed filename
+ ldax d
+ cpi ' ' ;blank? (input ended?)
+ stc ;get carry ready in case so
+ rz ;return cy if input gone
+ dcx d ;nope, point de to start of fcb
+open2: push d ;try to open the file
+ mvi c,openf
+ call bdos
+ pop d
+ inr a ;return=0ffh?
+ jnz openok ;jump if not
+;
+; file not found: if filetype blank, set to 'hex' and try again
+;
+ lxi h,dfcb+ft ;point to file type
+ mov a,m ;anything there?
+ cpi ' '
+ jnz fnferr ;yes, so file not found
+ mvi m,'H' ;nope, fill in 'hex'
+ inx h
+ mvi m,'E'
+ inx h
+ mvi m,'X'
+ jmp open2 ;go try again
+;
+; here after a good file open
+;
+openok: call hexchk ;is this a hex file?
+ rz ;if so, all done
+ lxi h,comflg ;no, get pointer to flag
+ mov a,m ;loading first file?
+ ora a
+ rnz ;if not, ignore type, consider hex
+ inr m ;else, set the flag
+ ret
+;
+; load current file
+;
+lodfil: lxi h,comflg ;loading a com file?
+ mov a,m ;get flag
+ ani 1
+ jnz lodcom ;jump if so
+ lhld bias ;else get bias on top of stack
+ push h
+;
+; load a hex record
+;
+loadlp: call gnb ;get next file byte
+ sbi ':' ;look for start-record mark
+ jnz loadlp ;scan until found
+ sta cksum ;got it, init checksum to zero
+ mov d,a ;upper byte of rec cnt=0
+ pop b ;retrieve bias adrs
+ push b ;save it again
+ call ghbcks ;get hex byte w/checksum
+ mov e,a ;de now has record length
+ ora a ;test it
+ jnz notend ;jump if len<>0 (not eof rec)
+ pop h ;all done
+ ret
+notend: call ghbcks ;hi byte of rec ld adrs
+ mov h,a ;accumulate in hl
+ call ghbcks ;get lo byte
+ mov l,a ;put lo in l
+ lda lodflg ;test load flag
+ ora a
+ cz lodnit ;not first record, initialize
+ push h ;save load address
+ dad d ;add in record length
+ dcx h ;make highest, not next
+ lda hipc ;a new high?
+ sub l
+ lda hipc+1
+ sbb h
+ jnc notgt ;jump if not
+ shld hipc ;yep, update hipc
+ push d ;save reclen
+ xchg ;load adrs to de
+ lhld offset ;get offset to form true memory adrs
+ dad d ;add in offset
+ dad b ;and bias
+ shld hiload ;mark highest true memory load adrs
+ lda system+2 ;validate against top-mem pointer
+ cmp h
+ jc memful ;jump if out of memory
+ pop d ;restore reclen
+notgt: pop h ;restore load address
+ dad b ;add bias to load adrs
+ push d ;save record length
+ push h
+ lhld bytcnt ;add record length to byte count
+ dad d
+ shld bytcnt
+ pop h
+ xchg
+ lhld offset ;calculate true memory adrs
+ dad d ;hl=true loading adrs
+ pop d ;restore record length
+ call ghbcks ;skip unused byte of intel format
+;
+; move the record into memory
+;
+reclp: call ghbcks ;get hex byte
+ mov m,a ;store it in buffer
+ inx h ;point to next
+ dcr e ;count down
+ jnz reclp ;until record all read
+ call ghbcks ;get checksum byte
+ jnz cserr ;final add cksum should sum 0
+ jmp loadlp ;good load, go do nxt record
+;
+; get next hex byte from input, and
+; accumulate a checksum
+;
+ghbcks: push b ;save em all
+ push h
+ push d
+ call hexin ;get hex byte
+ mov b,a ;save in b
+ lxi h,cksum ;add to checksum
+ mov a,m
+ add b
+ mov m,a
+ mov a,b ;get byte back
+ pop d ;restore checksum
+ pop h ;restore other regs
+ pop b
+ ret
+;
+; routine to get next byte from input...forms
+; byte from two ascii hex characters
+;
+hexin: call gnb ;get next input file byte
+ call hexval ;convert to binary w/validation
+ rlc ;move into ms nybble
+ rlc
+ rlc
+ rlc
+ ani 0f0h ;kill possible garbage
+ push psw ;save it
+ call gnb ;get next byte
+ call hexval ;convert it, w/validation
+ pop b ;get back first
+ ora b ;or in second
+ ret ;good byte in a
+;
+; gnb - utility subroutine to get next
+; byte from disk file
+gnb: push h ;save all regs
+ push d
+ push b
+ lda bufptr ;get input bufr pointer
+ ani 7fh ;wound back to 0?
+ jz diskrd ;go read sector if so
+gnb1: mvi d,0 ;else form 16 bit offset
+ mov e,a
+ lxi h,tbuf ;from tbuf
+ dad d ;add in offset
+ mov a,m ;get next byte
+ cpi eof ;end of file?
+ jz eoferr ;error if so
+ lxi h,bufptr ;else bump buf ptr
+ inr m
+ ora a ;return carry clear
+ pop b ;restore and return
+ pop d
+ pop h
+ ret
+;
+; read next sector from disk
+;
+diskrd: mvi c,readf ;bdos "READ SEC" function
+ lxi d,dfcb
+ call bdos ;read sector
+ ora a
+ jnz eoferr ;error if phys end of file
+ sta bufptr ;store 0 as new buf ptr
+ jmp gnb1 ;go re-join gnb code
+;
+; load a com file
+;
+lodcom: inr m ;bump the comfile flag
+ lxi h,tpa ;set origin
+ call lodnit ;and initialize
+ xchg ;load address in de
+ lhld bias ;add in bias
+ dad d
+ xchg
+ lhld offset ;and offset
+ dad d
+ xchg ;de has absolute mem adrs of load
+;
+comlp: lxi h,128 ;calculate next dma
+ dad d
+ lda system+2 ;check for space
+ cmp h
+ jc memful ;jump if none
+ push h ;else save next dma
+ push d ;and this dma
+ mvi c,sdmaf ;set this dma
+ call bdos
+ lxi d,dfcb ;read next record
+ mvi c,readf
+ call bdos
+ pop h ;recall this dma
+ pop d ;de=next dma
+ ora a ;end of read?
+ jnz lodend ;jump if so
+ lhld comsiz ;no, advance com byte count
+ lxi b,128
+ dad b
+ shld comsiz
+ jmp comlp ;continue
+;
+lodend: dcx h ;one less byte is highest
+ shld hiload ;set a new high
+ lhld comsiz ;hi pc=bytecount+100h
+ lxi d,tpa
+ dad d
+ xchg ;to de
+ lhld bias ;add in bias
+ dad d
+ shld hipc
+ lxi d,tbuf ;reset dma for hex files
+ mvi c,sdmaf
+ call bdos
+ ret
+;
+; write output file
+;
+wrtfil: lxi d,dfcb ;point to fcb
+ push d ;save 2 copies of pointer
+ push d
+ call nitfcb ;initialize output fcb
+ lxi h,outnam ;move output name in
+ dcx d ;point to user # (prior to fcb)
+ mvi b,10 ;move user, drive, primary name
+ call move
+ mov a,m ;output type blank?
+ cpi ' '
+ jnz wrtnb ;jump if not
+ lxi h,outtyp ;yes, move dflt output filetype in
+wrtnb: mvi b,3
+ call move
+ pop d ;restore fcb pointer
+ mvi c,erasef ;erase any existing file
+ call bdos
+ pop d ;restore fcb pointer
+ mvi c,creatf ;create a new file
+ call bdos
+ inr a ;good create?
+ jz dirful ;goto directory full error if not
+ lhld hiload ;yep, get top of bufr pntr
+ xchg ;in de
+ lhld filbuf ;get start of bufr adrs
+ mov a,e ;calculate output file size
+ sub l
+ mov c,a ;with result in bc
+ mov a,d
+ sbb h
+ mov b,a
+ mov a,b ;test length
+ ora c
+ jz loderr ;nothing to write???
+ lxi d,dfcb ;get fcb pointer
+wrlp: push b ;save count
+ push d ;and fcb pointer
+ xchg ;get memory pointer to de
+ lxi h,128 ;add in sector length for next pass
+ dad d
+ xthl ;save next dma
+ push h ;above fcb
+ mvi c,sdmaf ;set transfer address
+ call bdos
+ pop d ;fetch fcb pointer
+ push d ;save it again
+ mvi c,writef ;write a sector
+ call bdos
+ ora a ;test result
+ jnz dskful ;disk full error...
+ lhld reccnt ;no,increment count of records
+ inx h
+ shld reccnt
+ pop d ;restore fcb pointer
+ pop h ;and memory write pointer
+ pop b ;and count
+ mov a,c ;subtract 128 (sec size) from count
+ sui 128
+ mov c,a
+ jnc wrlp ;jump if some left
+ mov a,b ;hi-order borrow
+ sui 1 ;do it (can't "DCR B", doesn't affect cy)
+ mov b,a ;restore
+ jnc wrlp ;jump if more left
+ call closfl ;close output file
+;
+; report statistics to console
+;
+ call ilprnt
+ db 'Loaded ',0
+ lhld bytcnt ;print # bytes
+ call decout
+ call ilprnt
+ db ' bytes (',0
+ call hexout
+ call ilprnt
+ db 'H)',0
+ call ilprnt
+ db ' to file %',0
+ lda comflg ;did we load a comfile too?
+ ora a
+ jz notcom ;jump if not
+ call ilprnt
+ db cr,lf,'Over a ',0
+ lhld comsiz
+ call decout
+ call ilprnt
+ db ' byte binary file',0
+notcom: call ilprnt
+ db cr,lf,'Start address: ',0
+ lhld lodadr ;print loading address
+ call hexout
+ call ilprnt
+ db 'H Ending address: ',0
+ lhld hipc ;print ending load address
+ call hexout
+ call ilprnt
+ db 'H Bias: ',0
+ lhld bias
+ call hexout
+ call ilprnt
+ db 'H',cr,lf,0
+ call ilprnt
+ db 'Saved image size: ',0
+ lhld reccnt ;get count of image records
+ push h ;save it
+ mvi b,7 ;convert to bytes
+xlp: dad h
+ dcr b
+ jnz xlp
+ call decout ;print it
+ call ilprnt
+ db ' bytes (',0
+ call hexout ;now in hex
+ call ilprnt
+ db 'H, - ',0
+ pop h ;recall record count
+ call decout ;print it
+ call ilprnt
+ db ' records)',cr,lf,0
+ lhld lodadr ;fetch loading address
+ mov a,l ;test if =tpa
+ ora a
+ jnz nottpa ;tpa always on page boundary
+ mov a,h ;lo ok, test hi
+ cpi (tpa shr 8) and 0ffh
+ rz ;return if tpa
+nottpa: call ilprnt ;not, so print warning msg
+ db cr,lf,bel
+ db '++ Warning: program origin NOT at 100H ++'
+ db cr,lf,0
+ ret ;done
+;
+; ***********************
+; * utility subroutines *
+; ***********************
+;
+;
+; routine to close any open file
+;
+closfl: lxi d,dfcb
+ mvi c,closef
+ call bdos
+ inr a ;test close result
+ jz clserr ;jump if error
+ ret
+;
+; print message in-line with code
+;
+ilprnt: xthl ;message pntr to hl
+ call prathl ;print it
+ xthl ;restore and return
+ ret
+;
+; print msg pointed to by hl until null. expand
+; '%' char to current filename.
+;
+prathl: mov a,m ;fetch char
+ inx h ;point to next
+ ora a ;terminator?
+ rz ;then done
+ cpi '%' ;want filename?
+ jz prtfn ;go do it if so
+ call type ;nope, just print char
+ jmp prathl ;continue
+;
+prtfn: push h ;save pointer
+ push b
+ lda dfcb ;fetch dr field of dfcb
+ ora a ;default drive?
+ jnz prndf ;jump if not
+ call getdsk ;get logged-in drive #
+ inr a ;make it one-relative (as in fcb)
+prndf: adi 'A'-1 ;make drive name printable
+ call type ;print it
+ lda dfcb-1 ;get user #
+ cpi 0ffh ;null?
+ cz getusr ;iff so, get current user
+ mov l,a ;to hl
+ mvi h,0
+ call decout ;print it
+ mvi a,':' ;drive names followed by colon
+ call type
+ lxi h,dfcb+1 ;setup for name
+ mvi b,8 ;print up to 8
+ call prtnam
+ mvi a,'.' ;print dot
+ call type
+ mvi b,3 ;print filetype field
+ call prtnam
+ pop b
+ pop h ;restore and continue
+ jmp prathl
+;
+; print file name .HL max length in b. don't print spaces
+;
+prtnam: mov a,m ;fetch a char
+ cpi ' ' ;blank?
+ jz pwind ;go wind if so
+ inx h ;nope, move to next
+ call type ;print it
+ dcr b ;count down
+ jnz prtnam ;continue
+ ret
+pwind: inx h ;skip remainder of blank name
+ dcr b
+ jnz pwind
+ ret
+;
+; print HL in decimal on console
+;
+decout: push h ;save everybody
+ push d
+ push b
+ lxi b,-10 ;conversion radix
+ lxi d,-1
+declp: dad b
+ inx d
+ jc declp
+ lxi b,10
+ dad b
+ xchg
+ mov a,h
+ ora l
+ cnz decout ;this is recursive
+ mov a,e
+ adi '0'
+ call type
+ pop b
+ pop d
+ pop h
+ ret
+;
+; newline on console
+;
+crlf: mvi a,cr
+ call type
+ mvi a,lf
+ jmp type
+;
+; print hl on console in hex
+;
+hexout: mov a,h ;get hi
+ call hexbyt ;print it
+ mov a,l ;get lo, fall into hexbyt
+;
+; type accumulator on console in hex
+;
+hexbyt: push psw ;save byte
+ rar ;get ms nybble..
+ rar ;..into lo 4 bits
+ rar
+ rar
+ call nybble
+ pop psw ;get back byte
+nybble: ani 0fh ;mask ms nybble
+ adi 90h ;add offset
+ daa ;decimal adjust a-reg
+ aci 40h ;add offset
+ daa ;fall into type
+;
+; type char in a on console
+;
+type: push h ;save all
+ push d
+ push b
+ mov e,a ;cp/m outputs from e
+ mvi c,pcharf
+ call bdos
+ pop b
+ pop d
+ pop h
+ ret
+;
+; move: from @hl to @de, count in b
+;
+move: inr b ;up one
+movlp: dcr b ;count down
+ rz ;return if done
+ mov a,m ;not done, continue
+ stax d
+ inx h ;pointers=pointers+1
+ inx d
+ jmp movlp
+;
+; scan to first non-blank char in string @hl
+;
+scanbk: inx h ;next
+ mov a,m ;fetch it
+ cpi ' '
+ jz scanbk
+ ret
+;
+; get hex digit and validate
+;
+hexval: call hexdig ;get hex digit
+ jc formerr ;jump if bad
+ ret
+;
+; get hex digit, return cy=1 if bad digit
+;
+hexdig: cpi '0' ;lo boundary test
+ rc ;bad already?
+ cpi '9'+1 ;no, test hi
+ jc hexcvt ;jump if numeric
+ cpi 'A' ;test alpha
+ rc ;bad?
+ cpi 'F'+1 ;no, upper alpha bound
+ cmc ;pervert carry
+ rc ;bad?
+ sui 7 ;no, adjust to 0-f
+hexcvt: ani 0fh ;make it binary
+ ret
+;
+; ******************
+; * error handlers *
+; ******************
+;
+synerr: call crlf
+ call ilprnt
+ db ' Command line syntax error',cr,lf,cr,lf,0
+ jmp help ;give help msg too
+;
+afnerr: call errxit ;exit with message
+ db 'Ambiguous file name: % not allowed.',0
+;
+fnferr: call errxit
+ db 'File % not found.',0
+;
+dskful: call errxit
+ db 'Disk full.',0
+;
+dirful: call errxit
+ db 'Directory full.',0
+;
+eoferr: call errxit
+ db 'Premature end-of-file in %',0
+;
+cserr: call errxit
+ db 'Checksum error in %',0
+;
+clserr: call errxit
+ db 'Can''t close %',0
+;
+memful: call errxit
+ db 'Memory full while loading %',0
+;
+formerr:call errxit
+ db 'Format error in file %',0
+;
+loderr: call errxit
+ db 'Writing %, nothing loaded',0
+;
+help: call errxit ;print help text
+ db 'MLOAD syntax:',cr,lf,cr,lf
+ db 'MLOAD [<OUTFIL>=] <FILE1>[,<FILE2>...] [<BIAS>]',cr,lf
+ db tab,' (brackets denote optional items)',cr,lf,cr,lf
+ db tab,'<OUTFIL> is the optional output filename',cr,lf
+ db tab,'<FILEn> are input file(s)',cr,lf
+ db tab,'<BIAS> is a hex load offset within the output file'
+ db cr,lf,cr,lf
+ db tab,'<FILE1> may be an optional non-HEX file to be patched',cr,lf
+ db tab,'by subsequently named HEX files (specifying',cr,lf
+ db tab,'The filetype enables this function).'
+ db cr,lf,cr,lf
+ db 'Note that ZCPR2-style drive/user notation may be used in all'
+ db cr,lf
+ db 'file specifications (e.g., "B3:MYFILE.COM, "A14:MDM7.HEX").'
+ db cr,lf,0
+;
+; general error handler
+;
+errxit: call crlf ;new line
+ pop h ;fetch error msg pointer
+ call prathl ;print it
+ call crlf
+ jmp exit ;done
+;
+; initialize load parameters
+;
+lodnit: mvi a,1 ;first record, set load flag
+ sta lodflg
+ shld lodadr ;save load address
+ shld hipc ;and hi load
+ push d ;save record length
+ xchg ;de=load address
+ lhld filbuf ;get address of file buffer
+ mov a,l ;subtract load adrs from file buffer
+ sub e
+ mov l,a
+ mov a,h
+ sbb d
+ mov h,a
+ shld offset ;save as load offset
+ push d ;save load address on stack
+ push b ;save bias
+ lxi d,outnam+2 ;check output filename
+ ldax d ;(first char)
+ cpi ' '
+ jnz namskp ;jump if so
+ lxi h,dfcb+1 ;get first name pointer
+ mvi b,8 ;(don't include drive spec)
+ call move
+;
+; check for outflg=1 (presence of an "="). note that the
+; filename may well be blank, and yet outflg <>0, for example
+; in the case of "A:=<FILENAME>" or "C4:=<FILENAME>". in
+; this case, we want to remember the drive/user specified, but
+; use the first input file to form the output name. otherwise,
+; we use the current drive/user.
+;
+ lda outflg ;was there an "="?
+ ora a
+ jnz namskp ;jump if so
+ lxi h,outnam ;get destination pointer
+ call getusr ;get current user #
+ mov m,a
+ inx h ;point to drive
+ call getdsk ;get it
+ inr a ;fcb's drive is 1-relative
+ mov m,a
+namskp: mvi a,1 ;insure "=" cannot occur anymore
+ sta outflg
+ pop b ;restore bias
+ pop h ;load address to hl
+ pop d ;restore record length
+ ret
+;
+; *********************************
+; * file name parsing subroutines *
+; *********************************
+;
+; credit where credit's due:
+; --------------------------
+; these routines were lifted from bob van valzah's
+; "FAST" program.
+;
+;
+;
+; *********************************
+; * file name parsing subroutines *
+; *********************************
+;
+;
+; getfn gets a file name from text pointed to by reg hl into
+; an fcb pointed to by reg de. leading delimeters are
+; ignored. allows drive spec of the form <du:> (drive/user).
+; this routine formats all 33 bytes of the fcb (but not ran rec).
+;
+; entry de first byte of fcb
+; exit b=# of '?' in name
+; fcb-1= user # parsed (if specified) or 255
+;
+;
+fparse: call nitfcb ;init 1st half of fcb
+ call gstart ;scan to first character of name
+ call getdrv ;get drive/user spec. if present
+ mov a,b ;get user # or 255
+ cpi 0ffh ;255?
+ jz fpars1 ;jump if so
+ dcx d ;back up to byte preceeding fcb
+ dcx d
+ stax d ;stuff user #
+ inx d ;onward
+ inx d
+fpars1: call getps ;get primary and secondary name
+ ret
+;
+; nitfcb fills the fcb with dflt info - 0 in drive field
+; all-blank in name field, and 0 in ex,s1,s2,rc, disk
+; allocation map, and random record # fields
+;
+nitfcb: push h
+ push d
+ call getusr ;init user field
+ pop d
+ pop h
+ push d ;save fcb loc
+ dcx d
+ stax d ;init user # to currnt user #
+ inx d
+ xchg ;move it to hl
+ mvi m,0 ;drive=default
+ inx h ;bump to name field
+ mvi b,11 ;zap all of name fld
+nitlp: mvi m,' '
+ inx h
+ dcr b
+ jnz nitlp
+ mvi b,33-11 ;zero others, up to nr field
+zlp: mvi m,0
+ inx h
+ dcr b
+ jnz zlp
+ xchg ;restore hl
+ pop d ;restore fcb pointer
+ ret
+;
+; gstart advances the text pointer (reg hl) to the first
+; non delimiter character (i.e. ignores blanks). returns a
+; flag if end of line (00h or ';') is found while scaning.
+; exit hl pointing to first non delimiter
+; a clobbered
+; zero set if end of line was found
+;
+gstart: call getch ;see if pointing to delim?
+ rnz ;nope - return
+ ora a ;physical end?
+ rz ;yes - return w/flag
+ inx h ;nope - move over it
+ jmp gstart ;and try next char
+;
+; getdrv checks for the presence of a du: spec at the text
+; pointer, and if present formats drive into fcb and returns
+; user # in b.
+;
+; entry hl text pointer
+; de pointer to first byte of fcb
+; exit hl possibly updated text pointer
+; de pointer to second (primary name) byte of fcb
+; b user # if specified or 0ffh
+;
+getdrv: mvi b,0ffh ;default no user #
+ push h ;save text pointer
+dscan: call getch ;get next char
+ inx h ;skip pointer over it
+ jnz dscan ;scan until delimiter
+ cpi ':' ;delimiter a colon?
+ inx d ;skip dr field in fcb in case not
+ pop h ;and restore text pointer
+ rnz ;return if no du: spec
+ mov a,m ;got one, get first char
+ call cvtuc ;may be drive name, cvt to upper case
+ cpi 'A' ;alpha?
+ jc isnum ;jump to get user # if not
+ sui 'A'-1 ;yes, convert from ascii to #
+ dcx d ;back up fcb pointer to dr field
+ stax d ;store drive # into fcb
+ inx d ;pass pointer over drv
+ inx h ;skip drive spec in text
+isnum: mov a,m ;fetch next
+ inx h
+ cpi ':' ;du delimiter?
+ rz ;done then
+ dcx h ;nope, back up text pointer
+ mvi b,0 ;got a digit, init user value
+uloop: mov a,b ;get accumulated user #
+ add a ;* 10 for new digit
+ add a
+ add b
+ add a
+ mov b,a ;back to b
+ mov a,m ;get text char
+ sui '0' ;make binary
+ add b ;add to user #
+ mov b,a ;updated user #
+ inx h ;skip over it
+ mov a,m ;get next
+ cpi ':' ;end of spec?
+ jnz uloop ;jump if not
+ inx h ;yep, return txt pointer past du:
+ ret
+;
+; getps gets the primary and secondary names into the fcb.
+; entry hl text pointer
+; exit hl character following secondary name (if present)
+;
+getps: mvi c,8 ;max length of primary name
+ mvi b,0 ;init count of '?'
+ call getnam ;pack primary name into fcb
+ mov a,m ;see if terminated by a period
+ cpi '.'
+ rnz ;nope - secondary name not given
+ ;return default (blanks)
+ inx h ;yup - move text pointer over period
+ftpoint:mov a,c ;yup - update fcb pointer to secondary
+ ora a
+ jz getft
+ inx d
+ dcr c
+ jmp ftpoint
+getft: mvi c,3 ;max length of secondary name
+ call getnam ;pack secondary name into fcb
+ ret
+;
+; getnam copies a name from the text pointer into the fcb for
+; a given maximum length or until a delimiter is found, which
+; ever occurs first. if more than the maximum number of
+; characters is present, character are ignored until a
+; a delimiter is found.
+; entry hl first character of name to be scanned
+; de pointer into fcb name field
+; c maximum length
+; exit hl pointing to terminating delimiter
+; de next empty byte in fcb name field
+; c max length - number of characters transfered
+;
+getnam: call getch ;are we pointing to a delimiter yet?
+ rz ;if so, name is transfered
+ inx h ;if not, move over character
+ cpi '*' ;ambigious file reference?
+ jz ambig ;if so, fill the rest of field with '?'
+ cpi '?' ;afn reference?
+ jnz notqm ;skip if not
+ inr b ;else bump afn count
+notqm: call cvtuc ;if not, convert to upper case
+ stax d ;and copy into name field
+ inx d ;increment name field pointer
+ dcr c ;if name field full?
+ jnz getnam ;nope - keep filling
+ jmp getdel ;yup - ignore until delimiter
+ambig: mvi a,'?' ;fill character for wild card match
+fillq: stax d ;fill until field is full
+ inx d
+ inr b ;increment count of '?'
+ dcr c
+ jnz fillq ;fall thru to ingore rest of name
+getdel: call getch ;pointing to a delimiter?
+ rz ;yup - all done
+ inx h ;nope - ignore antoher one
+ jmp getdel
+;
+; getch gets the character pointed to by the text pointer
+; and sets the zero flag if it is a delimiter.
+; entry hl text pointer
+; exit hl preserved
+; a character at text pointer
+; z set if a delimiter
+;
+getch: mov a,m ;get the character, test for delim
+;
+; global entry: test char in a for filename delimiter
+;
+fndelm: cpi '/'
+ rz
+ cpi '.'
+ rz
+ cpi ','
+ rz
+ cpi ' '
+ rz
+ cpi ':'
+ rz
+ cpi '='
+ rz
+ ora a ;set zero flag on end of text
+ ret
+;
+; bdos entry: preserves bc, de. if system call is a file
+; function, this routine logs into the drive/
+; user area specified, then logs back after
+; the call.
+;
+bdos: call filfck ;check for a file function
+ jnz bdos1 ;jump if not a file function
+ call getdu ;get drive/user
+ shld savedu
+ ldax d ;get fcb's drive
+ sta fcbdrv ;save it
+ dcr a ;make 0-relative
+ jm bdos0 ;if not default drive, jump
+ mov h,a ;copy to h
+bdos0: xra a ;set fcb to default
+ stax d
+ dcx d ;get fcb's user #
+ ldax d
+ mov l,a
+ inx d ;restore de
+ call setdu ;set fcb's user
+;
+; note that unspecified user # (value=0ffh) becomes
+; a getusr call, preventing ambiguity.
+;
+ call bdos1 ;do user's system call
+ push psw ;save result
+ push h
+ lda fcbdrv ;restore fcb's drive
+ stax d
+ lhld savedu ;restore prior drive/user
+ call setdu
+ pop h ;restore bdos result registers
+ pop psw
+ ret
+;
+; local variables for bdos replacement routine
+;
+savedu: dw 0 ;saved drive,user
+fcbdrv: db 0 ;fcb's drive
+dmadr: dw 80h ;current dma adrs
+;
+bdos1: push d
+ push b
+ mov a,c ;doing setdma?
+ cpi sdmaf
+ jnz bdos1a ;jump if not
+ xchg ;yep, keep a record of dma addresses
+ shld dmadr
+ xchg
+bdos1a: call system
+ pop b
+ pop d
+ ret
+;
+; get drive, user: h=drv, l=user
+;
+getdu: push b ;don't modify bc
+ push d
+ mvi c,gsuser ;get user #
+ mvi e,0ffh
+ call bdos1
+ push psw ;save it
+ mvi c,getdrf ;get drive
+ call bdos1
+ mov h,a ;drive returned in h
+ pop psw
+ mov l,a ;user in l
+ pop d
+ pop b ;restore caller's bc
+ ret
+;
+; set drive, user: h=drv, l=user
+;
+setdu: push b ;don't modify bc
+ push d
+ push h ;save info
+ mov e,h ;drive to e
+ mvi c,seldf ;set it
+ call bdos1
+ pop h ;recall info
+ push h
+ mov e,l ;user # to e
+ mvi c,gsuser
+ call bdos1 ;set it
+ pop h
+ pop d
+ pop b
+ ret
+;
+; check for file-function: open, close, read random, write
+; random, read sequential, write sequential.
+;
+filfck: mov a,c ;get function #
+ cpi openf
+ rz
+ rc ;ignore lower function #'s
+ cpi closef ;(they're not file-related)
+ rz
+ cpi readf
+ rz
+ cpi writef
+ rz
+ cpi rrand
+ rz
+ cpi wrand
+ rz
+ cpi fsrchf
+ rz
+ cpi fsrchn
+ rz
+ cpi erasef
+ rz
+ cpi creatf
+ rz
+ cpi filszf
+ rz
+ cpi srand
+ ret
+;
+; convert char to upper case
+;
+cvtuc: cpi 'a' ;check lo bound
+ rc
+ cpi 'z'+1 ;check hi
+ rnc
+ sui 20h ;convert
+ ret
+;
+; check for hex filetype in fcb name
+;
+hexchk: push h
+ push d
+ push b
+ mvi b,3 ;type is 3 chars
+ lxi d,dfcb+9 ;point de to type field
+ lxi h,hextyp ;point hl to "COM"
+hexlop: ldax d
+ ani 7fh ;ignore attributes
+ cmp m
+ inx h
+ inx d
+ jnz hexit ;jump if not com
+ dcr b
+ jnz hexlop
+hexit: pop b ;z reg has result
+ pop d
+ pop h
+ ret
+;
+hextyp: db 'HEX'
+;
+; routine to return user # without disturbing registers
+;
+getusr: push h
+ push d
+ push b
+ mvi c,gsuser
+ mvi e,0ffh
+ call bdos
+ pop b
+ pop d
+ pop h
+ ret
+;
+; routine to return drive # without disturbing registers
+;
+getdsk: push h
+ push d
+ push b
+ mvi c,getdrf
+ call bdos
+ pop b
+ pop d
+ pop h
+ ret
+;
+; these are the initial values of the variables, and
+; are moved into the variables area by the setup routine.
+; if you add variables, be sure to add their intial value
+; into this table in the order corresponding to their
+; occurance in the variables section.
+;
+varset: dw 0 ;bias
+ dw 0 ;hiload
+ dw 0 ;hipc
+ db 0 ;cksum
+ dw cmdbuf ;cmdptr
+ db 0 ;bufptr
+ db 0 ;lodflg
+ dw cmdbuf ;filbuf
+ dw 0 ;offset
+ dw 0 ;lodadr
+ db 0,0,' ' ;outnam
+ dw 0 ;reccnt
+ dw 0 ;bytcnt
+ db 0 ;comflg
+ dw 0 ;comsiz
+ db 0 ;outflg
+;
+varlen equ $-varset ;define length of init table
+;
+; working variables
+;
+vars equ $ ;define variables area start
+;
+bias: ds 2 ;load offset
+hiload: ds 2 ;highest true load address
+hipc: ds 2 ;highest pc
+cksum: ds 1 ;record checksum
+cmdptr: ds 2 ;command line pointer
+bufptr: ds 1 ;input buffer pointer
+lodflg: ds 1 ;something-loaded flag
+filbuf: ds 2 ;file buffer location
+offset: ds 2 ;load offset into buffer
+lodadr: ds 2 ;load address
+outnam: ds 13 ;output drive+name
+reccnt: ds 2 ;output file record count
+bytcnt: ds 2 ;output file bytes loaded count
+comflg: ds 1 ;flags com file encountered
+comsiz: ds 2 ;size of a loaded com file
+outflg: ds 1 ;flags an "=" present in cmd line
+;
+; end of working variables
+;
+;
+;
+; stack stuff
+;
+spsave: ds 2 ;system stack pntr save
+;
+;
+ ds 100 ;50-level stack
+;
+stack equ $
+cmdbuf equ $ ;command buffer location
+;
+;
+ end