diff options
author | Leo C | 2015-12-04 22:40:11 +0100 |
---|---|---|
committer | Leo C | 2015-12-04 22:40:11 +0100 |
commit | e58a7a2546e59e692ea958cbdcdbb184654383be (patch) | |
tree | 698a2b2cb8b95c4b2414e0f50b6c03f13c78fb76 | |
parent | c25f6a44a6e2266617af2f326fa5dc0c4864035f (diff) | |
download | kermit-80-e58a7a2546e59e692ea958cbdcdbb184654383be.zip |
Convert line endings to CP/M format (cr/lf).
-rw-r--r-- | cpscmd.asm | 2280 | ||||
-rw-r--r-- | cpscom.asm | 2742 | ||||
-rw-r--r-- | cpscpm.asm | 1864 | ||||
-rw-r--r-- | cpsdat.asm | 1296 | ||||
-rw-r--r-- | cpsdef.asm | 574 | ||||
-rw-r--r-- | cpsker.asm | 630 | ||||
-rw-r--r-- | cpsmit.asm | 1668 | ||||
-rw-r--r-- | cpspk1.asm | 3808 | ||||
-rw-r--r-- | cpspk2.asm | 2672 | ||||
-rw-r--r-- | cpsrem.asm | 2298 | ||||
-rw-r--r-- | cpsser.asm | 88 | ||||
-rw-r--r-- | cpstt.asm | 1724 | ||||
-rw-r--r-- | cpsutl.asm | 2454 | ||||
-rw-r--r-- | cpswld.asm | 444 | ||||
-rw-r--r-- | cpxapp.asm | 1498 | ||||
-rw-r--r-- | cpxbbi.asm | 1236 | ||||
-rw-r--r-- | cpxbee.asm | 1992 | ||||
-rw-r--r-- | cpxcif.asm | 1492 | ||||
-rw-r--r-- | cpxcom.asm | 972 | ||||
-rw-r--r-- | cpxgni.asm | 880 | ||||
-rw-r--r-- | cpxhea.asm | 1842 | ||||
-rw-r--r-- | cpxlnk.asm | 412 | ||||
-rw-r--r-- | cpxmrl.asm | 908 | ||||
-rw-r--r-- | cpxnor.asm | 1174 | ||||
-rw-r--r-- | cpxpcw.asm | 1824 | ||||
-rw-r--r-- | cpxpro.asm | 1122 | ||||
-rw-r--r-- | cpxsb.asm | 1392 | ||||
-rw-r--r-- | cpxswt.asm | 588 | ||||
-rw-r--r-- | cpxsy2.asm | 2728 | ||||
-rw-r--r-- | cpxsyo.asm | 778 | ||||
-rw-r--r-- | cpxsys.asm | 2772 | ||||
-rw-r--r-- | cpxtm4.asm | 980 | ||||
-rw-r--r-- | cpxtor.asm | 2458 | ||||
-rw-r--r-- | cpxtyp.asm | 1444 | ||||
-rw-r--r-- | cpxvdu.asm | 924 | ||||
-rw-r--r-- | cpxz80.asm | 700 | ||||
-rw-r--r-- | mload.asm | 2986 |
37 files changed, 28822 insertions, 28822 deletions
@@ -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]
@@ -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
@@ -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]
@@ -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
@@ -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
@@ -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...
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
+
@@ -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
@@ -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
@@ -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
@@ -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
+
@@ -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
+
@@ -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
+
+
+
+
+
@@ -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]
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
+;
+
+
+
@@ -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
@@ -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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -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
@@ -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
@@ -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
+
@@ -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
@@ -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
@@ -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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -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
|