From e58a7a2546e59e692ea958cbdcdbb184654383be Mon Sep 17 00:00:00 2001 From: Leo C Date: Fri, 4 Dec 2015 22:40:11 +0100 Subject: [PATCH] Convert line endings to CP/M format (cr/lf). --- cpscmd.asm | 2280 +++++++++++++++---------------- cpscom.asm | 2742 ++++++++++++++++++------------------- cpscpm.asm | 1864 ++++++++++++------------- cpsdat.asm | 1296 +++++++++--------- cpsdef.asm | 574 ++++---- cpsker.asm | 630 ++++----- cpsmit.asm | 1668 +++++++++++------------ cpspk1.asm | 3808 ++++++++++++++++++++++++++-------------------------- cpspk2.asm | 2672 ++++++++++++++++++------------------ cpsrem.asm | 2298 +++++++++++++++---------------- cpsser.asm | 88 +- cpstt.asm | 1724 ++++++++++++------------ cpsutl.asm | 2454 ++++++++++++++++----------------- cpswld.asm | 444 +++--- cpxapp.asm | 1498 ++++++++++----------- cpxbbi.asm | 1236 ++++++++--------- cpxbee.asm | 1992 +++++++++++++-------------- cpxcif.asm | 1492 ++++++++++---------- cpxcom.asm | 972 +++++++------- cpxgni.asm | 880 ++++++------ cpxhea.asm | 1842 ++++++++++++------------- cpxlnk.asm | 412 +++--- cpxmrl.asm | 908 ++++++------- cpxnor.asm | 1174 ++++++++-------- cpxpcw.asm | 1824 ++++++++++++------------- cpxpro.asm | 1122 ++++++++-------- cpxsb.asm | 1392 +++++++++---------- cpxswt.asm | 588 ++++---- cpxsy2.asm | 2728 ++++++++++++++++++------------------- cpxsyo.asm | 778 +++++------ cpxsys.asm | 2772 +++++++++++++++++++------------------- cpxtm4.asm | 980 +++++++------- cpxtor.asm | 2458 ++++++++++++++++----------------- cpxtyp.asm | 1444 ++++++++++---------- cpxvdu.asm | 924 ++++++------- cpxz80.asm | 700 +++++----- mload.asm | 2986 ++++++++++++++++++++-------------------- 37 files changed, 28822 insertions(+), 28822 deletions(-) diff --git a/cpscmd.asm b/cpscmd.asm index 6cff603..6044c7f 100644 --- a/cpscmd.asm +++ b/cpscmd.asm @@ -1,1140 +1,1140 @@ -; CPSCMD.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; -; This file provides a user oriented way of parsing commands. -; It is similar to that of the COMND JSYS in TOPS-20. -; -; revision history (latest first): -; -;edit 13, 17-Jan-1991 by MF. Modified "cmifil" routine to zero the entire -; fcb (not just the extent) to fix a bug in the COPY command which -; prevented successive COPY commands from working properly. -;edit 12, 16-Jan-1991 by MF. Modified routine "cmkeyw" to ignore leading -; spaces/tabs before a keyword. This apparently was the intent in -; "prompt" and "repars" (at least for command-lines) as the variable -; "cmsflg "is set upon command parse and reparse. The intent was , -; subverted, however, as "cmkeyw" did not reset the flag to ignore -; leading white space for each search thru the key tables (even though -; the buffer pointer to the keyword entered was reset). The fix was -; to reset the "spaces seen" flag (cmsflg) after "cmkey2" so that -; it is reset each time a new table entry is compared to the text -; the user has entered from the keyboard/TAKE-file etc. The upshot -; of all this is that the kluge code in "cminbf" at "cminb0" designed -; to force Kermit to ignore leading white space on command-lines in -; TAKE-files and on the CP/M command-line is no longer needed and, -; therefore, has been eliminated. Also modify "comnd" to expect leading -; spaces for functions other than "get keyword". -;edit 11, 26-Dec-1990 by MF. Modified routines to ignore leading white space -; in lines from TAKE-files as well as during input from the CP/M -; command-line (form-feeds are now considered white space under these -; circumstances). -;edit 10, 8-Sep-1990 by Mike Freeman. Modified routines to ignore leading -; spaces/tabs when processing Kermit commands from the CP/M -; command-line. -; Added flag CMBFLG to allow initial word on a command-line -; to be blank (useful for Remote commands such as Remote CWD etc). -; Added flag cmqflg to prevent character-echoing while entering -; commands so Remote CWD etc can have nonechoing password entry. -; edit 9, 15 June, 1987 by OBSchou. Bug fixing to allow a second filename -; (quiet) be entered as d:. 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 '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 ()? - 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:. 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 '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 ()? + ora a ;[MF]... + jnz cminb6 ;[MF]Yes + lda cmccnt ;Have we parsed any chars yet? + cpi 1 + jz prserr ;If not, just start over. +cminb6: mvi a,0FFH ;Set the action flag. + sta cmaflg + jmp cminb9 + +cminb8: + lda cmccnt ; get the command character count + cpi cmbufl ; check for comand buffer length + jm cminb1 ; if less, then all ok + mvi e,bell ; else beep at user + call outcon ; send it to the console + lda cmccnt ; back up one character + dcr a + sta cmccnt + lhld cmcptr ; ditto pointer + dcx h + shld cmcptr ; save it again + jmp cminb1 ; and try again + +cminb9: pop h + pop d + pop psw + ret +; +;Little utility to print the prompt. (We do a LOT of these.) [Toad Hall] +;Enters with nothing. +;Destroys HL (and I suppose B and DE and A). + +prprmp: mvi e,cr ; do a cr first + mvi c,dconio + call bdos + lhld cmprmp ;Get the prompt. + xchg + call prtstr + ret + +; Little code to allow some expansion of code without changing +; every futher address, only up to the end of this file. +; TO BE REMOVED FOR RELEASE! + +; org ($+100h) AND 0FF00H + + +IF lasm +LINK CPSUTL +ENDIF ;lasm [Toad Hall] diff --git a/cpscom.asm b/cpscom.asm index 7f2a57a..a74df7e 100644 --- a/cpscom.asm +++ b/cpscom.asm @@ -1,1371 +1,1371 @@ -; CPSCOM.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains some of the main loop commands, all SET xxx and -; status routines. File split from CPSMIT.ASM as that file -; was getting too big. -; -; revision history: -; -;edit 13, 25-Mar-1991 by MF. Require confirmation if a STAY command -; (code at "noexit") is given and a question-mark is entered. -;edit 12, 21-Mar-1991 by MF. Change SET COLLISSION REPLACE to -; SET COLLISION OVERWRITE to conform with C-Kermit. Modify SET COLLISION -; help text slightly. - -;edit 11, 27-Feb-1991 by MF. Show Kermit version in VERSION command -; ("shover"). -;edit 10, 12-Feb-1991 by MF. Modified OUTPUT command to get a "confirm" -; after accepting the string to be output so that the OUTPUT command -; doesn't immediately execute if a terminator other than 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/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 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 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/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 S commands +; called by: show, status, intchr + +stat01: lda fileio ;Are we in transmit? + ora a + jz sta01b ;No + lxi d,xmtst ;Yes,say so + call prtstr + +; The following block of code - down to RET - re-ordered by [DJR] +; DJR January 1987 to get SHOW/STATUS output in the same [DJR] +; (alphabetical) order as SET's HELP. [DJR] +sta01b: + call stautr ;[MF]Show AUTORECEIVE state + call stabcc ; Tell current block check type + call stabsz ; Tell user about multi-sector buffers + call stacol ;[MF]COLLISION state + call stadbg ; [DJR] Debug mode + call stacurd ; [DJR] Current disk + call stahfs ; Tell user if file sizez are hidden during DIR + call staesc ; Tell current escape character + call stafil ; Tell about file type + call staflo ;[10] Tell about flow control + call staibm ; Tell about IBM flag + call stainc ;[MF]Tell about incomplete file disposition +; +; Ask user to press a key before continuing +; + call pausit ; wait for a while till user presses a key +; + call staeco ; Tell about local echo flag + call stalog ; [pcc003] Tell about log file status + call stapar ; Tell about parity + lhld prttab ;[hh] Got a port table? (is pointer nonzero?) + mov a,h ;[hh] + ora l ;[hh] + cnz stapor ;[hh] If so, tell which port we're using + call stalpt ; Tell about printer copy flag + call starps ;[MF]Show receive packet length + call starsp ;[gnn] tell rec. start-of-pkt char + call stasps ;[MF]Show send packet length + call stassp ;[gnn] tell send start-of-pkt char + lhld spdtab ; Got a speed table? (is pointer nonzero?) + mov a,h + ora l + cnz staspd ; If so, tell what speed we're running. + call statac ; Tell about TAC flag/intercept character. + call statim ; Tell about timer flag + call stusr ;[7] Tell about user + call statvt ; Tell about what emulation we are doing + call stawrn ; Tell about file-warning flag + ret + +; stautr - Show Autoreceive setting [MF] +; +stautr: lxi d,autrst ;[MF]Point to "Autoreceive" string + call prtstr ;[MF]and print it + lda autorc ;[MF]Get Autoreceive flag + jmp staton ;[MF]Say "on" or "off" and return + +; Show the value of the LOCAL-ECHO flag (On or Off). + +staeco: lxi d,locst ;Get the address of the local echo string. + call prtstr + lda ecoflg ;Get the local echo flag. + jmp staton ;Say ON or OFF, and return + +; Show the value of the VT52-EMULATION flag (On, Off, or Not Supported). +; Also show terminal display mode (regular, quiet) + +statvt: lxi d,vtdpst ;[MF]Get address of terminal display string + call prtstr ;[MF]Print it + lxi d,vtdpsr ;[MF]Assume a regular (loud) display + lda quietd ;[MF]Get "quiet" flag + ora a ;[MF]a quiet display? + jz statva ;[MF]No, print "regular" message + lxi d,vtdpsq ;[MF]Yes, point to "quiet" string +statva: call prtstr ;[MF]and print it + lxi d,vtemst ; Get the address of the VT52 emulation string. + call prtstr + lda vtflg ; Get the VT52 emulation flag. + cpi 0ffh ; isterminal emulation possible? + jnz statv0 ; yes, maybe + lxi h,inms11 ; ... no, load up not implemented message ... + jmp prvtv ; so tell user + + +statv0: mov c,a ; save it to C + lxi h,sttert ; get table listing what we can do + mov b,m ; get number of terminal types to b +statv1: inx h ; point to first entry + mov e,m ; get length of entry + mvi d,0 + inx h ; point to text part of entry + xchg ; save address in de + dad d ; start + length + inx h ;... + 1 for the dollar... + inx h ; plus point to seconcd copy of ter. type value + cmp m ; is it the one we want? + jz prvtv ; yes, then print the terminal type value + dcr b ; have we completed? + rz ; yes, then just exit back to status + jmp statv1 ; else try next entry. HL points to next -1 + +prvtv: jmp prtstr ; print string from DE + ;[MF]and return + +; Show the value of the FILE-MODE flag (ASCII, Binary, or Default). + +stafil: lxi d,cpmst ; Get the address of the file mode message. + call prtstr + lda cpmflg ; Get the file mode flag. + lxi d,defstr ; Assume Default (0). + ora a ; Is it? + jz prtstr ; If so, say so, and return. + lxi d,ascstr ; Not default, assume ASCII + cpi 1 ; Is it ASCII? + jz prtstr ; Say ASCII, and return + lxi d,binstr ; Not default or ASCII, must be binary + jmp prtstr ; Print type, and return. +; +;Show current disposition for incomplete files [MF] +; +stainc: lxi d,incst ;[MF]Announce what's to be shown + call prtstr ;[MF]... + lxi d,dscstr ;[MF]Assume "discard" + lda incflg ;[MF]Get flag + ora a ;[MF]Really discarding incomplete files? + jz prtstr ;[MF]Yes, say so and return + lxi d,kepstr ;[MF]No, say we're keeping incomplete files + jmp prtstr ;[MF]and return + +; show if file sizes are hidden during DIR (Would have thought this +; obvious, but its in for completeness +stahfs: lxi d,hfsod ; get hide file size on dir + call prtstr + lda hidefs + jmp staton ; say if on or off + +; Show the value of the IBM-MODE flag (On or Off). + +staibm: lxi d,ibmst ;IBM string. + call prtstr + lda ibmflg ; Get IBM flag. + jmp staton ; Print its value and return + +; Show the value of the FILE-WARNING flag (On or Off). + +stawrn: lxi d,filst ; File warning string. + call prtstr + lda flwflg ; File warning flag. + jmp staton ; Say ON or OFF + +; Show the value of the PRINTER flag (On or Off). + +stalpt: lxi d,prst ;Printer copy string + call prtstr + lda prnflg ;Printer ON/OFF flag + jmp staton ; Say ON or OFF + + +; Show status of log file +stalog: lxi d,logst ;[pcc003] Logging lead-in message + call prtstr ;[pcc003] +; name of logging file +; Code derived from [JD's] code for GET, and uses his FNBUF [DJR] + lxi d,fnbuf ;[DJR] point to destination + lxi h,lognam ;[DJR] source of filespec + mov a,m ;[DJR] get drive byte + ora a ;[DJR] zero = default disc + jnz stalg1 ;[DJR] if drive has been specified + lda curdsk ;[DJR] otherwise get the default +stalg1: adi 'A'-1 ;[DJR] make it printable + stax d ;[DJR] into dest block + inx d ;[DJR] + mvi a,':' ;[DJR] colon after drive + stax d ;[DJR] + inx d ;[DJR] + + mvi c,8 ;[DJR] length of name part + lxi h,lognam+1 ;[DJR] start of name + mvi b,0 ;[DJR] first-time-thru flag +stalga: mov a,m ;[DJR] get a char from the name + inx h ;[DJR] pass it + cpi ' ' ;[DJR] end of this part of name? + jz stalgb ;[DJR] yes, skip rest... + stax d ;[DJR] else drop char into dest + inx d ;[DJR] increment dest ptr + dcr c ;[DJR] decrement count + jnz stalga ;[DJR] and continue if more to go + +stalgb: mov a,b ;[DJR] + ora a ;[DJR] first time thru? + jnz stalgc ;[DJR] no, no period + mvi a,'.' ;[DJR] period between parts + stax d ;[DJR] + inx d ;[DJR] + mvi b,0ffh ;[DJR] not first time thru anymore + mvi c,3 ;[DJR] length of ext part + lxi h,lognam+9 ;[DJR] start of extension + jmp stalga ;[DJR] keep copying + +stalgc: mvi a,'$' + stax d ;[DJR] end the name string + lxi d,fnbuf ;[DJR] Print the file name + call prtstr ;[DJR] + + lxi d,logst2 ;[DJR] second part of message + call prtstr ;[DJR] + +; Show status of logging + lda logflg ;[pcc003] get the flag + ani 7FH ;[pcc003] ignore open flag + cpi 2 ;[pcc003] is it suspended? + jnz staton ;[pcc003] no, must be on or off + lxi d,susstr ;[pcc003] suspended + jp prtstr ;[pcc003] print and return + +; Show the value of the PARITY flag (Odd, Even, Mark, Space, or None). + +stapar: lxi d,parst ;Parity string. + call prtstr + lda parity ;Get the parity setting. + lxi d,pnonst ;Assume parity is NONE + cpi parnon ;Were we right? + jz prtstr ;Yep, go say None, and return + lxi d,pmrkst ;Get ready to say Mark + cpi parmrk ;Is it mark? + jz prtstr ;Yep, go say Mark, and return + lxi d,pspcst ;Get ready to say Space + cpi parspc ;Is it space? + jz prtstr ;Yep, go say Space, and return + lxi d,poddst ;Get ready to say Odd + cpi parodd ;Is it odd? + jz prtstr ;Yep, go say Odd, and return + lxi d,pevnst ;Must be Even. + jmp prtstr ;Say Even, and return. + +; [gnn] Show start of packet characters +stassp: lxi d,sspmsg ;message of send s-o-p + call prtstr + lda sndsop + adi 'A'-1 ;convert to printable character + mov e,a + mvi c,conout + jmp bdos ;and print it +starsp: lxi d,rspmsg ;rec. s-o-p message + call prtstr + lda rcvsop + adi 'A'-1 ;convert to printable character + mov e,a + mvi c,conout + jmp bdos ;and print it +; +;[MF]Show receive packet length +; +starps: lxi d,rpsmsg ;[MF]Point to message + call prtstr ;[MF]and print it + lda rpsiz ;[MF]Get receive packet length + mov l,a ;[MF]Put in HL + mvi h,0 ;[MF]... + jmp nout ;[MF]Print receive packet length in decimal +; +;[MF]stasps - Print send packet length +; +stasps: lxi d,spsmsg ;[MF]Point to message + call prtstr ;[MF]and print it + lda spsiz ;[MF]Get send packet length + mov l,a ;[MF]into HL + mvi h,0 ;[MF]... + jmp nout ;[MF]and print in decimal + +;[hh] Show the current port (if known). + +stapor: lxi d,porst ;[hh] + call prtstr ;[hh] + lda port ;[hh] Get current port value + lxi h,spdust ;[hh] Assume undefined (this error msg is fine) + cpi 0FFH ;[hh] Is it? + jz stat73 ;[hh] Yup. Say so + lhld prttab ;[hh] Address of port keyword table + call fndkyw ;[hh] Look for correct keyword string + jnc stpr1 ;[hh] Found a match + lxi h,spdust ;[hh] No match found - say it's undefined +stpr1: jmp stat73 ;[hh] Print it and return + +; Show the current line speed (if known). + +staspd: lxi d,spdst + call prtstr + lda speed ;Get current speed. + lxi h,spdust ;Assume undefined. + cpi 0FFH ;Is it? + jz stat73 ;Yes. + lhld spdtab ;Start scanning keyword table. + mov d,m ; get count of entries + inx h ; advance over it. +stat70: mov b,m ;Get string length. + inr b ;Account for $. + inx h + shld temp1 ;Save string pointer. +stat71: inx h ;Loop over string. + dcr b + jnz stat71 + mov c,m ;Get speed value + cmp c ;Match? + jz stat72 ;Yes. + inx h ;Bump to next keyword. + inx h + dcr d ; decrement entry count + jnz stat70 ; if more left, check them. + lxi h,spdust ; can't find it. say it's undefined. + jmp stat73 ; print the message. + +stat72: lhld temp1 ;Restore saved string pointer. + xchg ;[MF] Set into DE for display + call prtstr ;[MF] Print speed + lxi h,spdst2 ;[MF] Point to "bps" message +stat73: xchg ;Set into DE for display. + jmp prtstr ; print it, and return. + +; Show the current BLOCK-CHECK-TYPE (1-, 2-, or 3-character). + +stabcc: lxi d,bckst ;Get the string + call prtstr ;Print "Block check type: " + lda chktyp ;Get the type (character 1, 2, or 3) + mov e,a ;Put into E + mvi c,conout ;Want to print it + call BDOS ;Do so + lxi d,bckst1 ;Get rest of text ("-character") + jmp prtstr ;Print it and return +; +;[MF]stacol - Print "SET COLLISION" state +; +stacol: lxi d,collst ;[MF]Get message + call prtstr ;[MF]Print it + lxi h,coltab ;[MF]Point to COLLISION keywords + lda flwflg ;[MF]Get COLLISION state + call fndkyw ;[MF]Get COLLISION state + ;[MF](Since user doesn't control flwflg + ;[MF]directly, no need to check for errors + xchg ;[MF]Prepare for printing + jmp prtstr ;[MF]Print COLLISION state and return + +; Print the current escape character + +staesc: lxi d,escst ;Escape string. + call prtstr + call escpr ;Print the escape char. +; jmp prcrlf ;removed [DJR] Print CR/LF and return [Toad Hall] + ret ;[DJR] added + +; Show number proportion of buffers used in multiple sector buffering +stabsz: lxi d,bufsz1 + call prtstr ; do first bit of string + lxi h,0 + lda bufsec + mov l,a ; get size used... + call nout ;... to screen + lxi d,bufsz2 ; and then say max value + call prtstr + lxi h,0 + lda maxbsc ; get max for this system + mov l,a + call nout ;.. thence to screen +; jmp prcrlf ; removed [DJR] cr lf and out + ret ;[DJR] + +; +; Show the value of the TIMER flag +statim: lxi d,timmsg ;[jd] + call prtstr ;[jd] + lda timflg + jmp staton ;Tell whether it's on or off. + +; Show internal versions (edit strings) +shover: call cfmcmd + call prcrlf + lxi d,version ;[MF]Point to Kermit version + call prtstr ;[MF]and show it + lxi d,modmsg ;[MF]Continue the message + call prtstr ;[MF]... + call prcrlf ;[MF]End the line + lxi h,vertab ; Get address of version list +shovr1: mov e,m ; Get next word from list + inx h + mov d,m ; Next version string is in DE + inx h + mov a,d ; Test for zero (end of list) + ora e + jz shovr2 ; Done with list if zero + push h ; Save position in list + call prtstr ; Not zero. Print it. + call prcrlf ; Follow with crlf + pop h ; Restore position in list + jmp shovr1 ; and go see if there are any more. + +shovr2: lhld ovlver ; Get overlay version string + xchg ; into DE + call prtstr ; Print it + call prcrlf ; Output crlf + lhld family ;[11] New entry in overlay. Get string of + xchg ;[11] family of machines (eg apple) and print + call prtstr ;[11] it. For "common" m/c do a $ only. + jmp kermit ; Return to main loop. + +; table of pointers to version strings. +vertab: dw mitver ; CPSMIT + dw comver ; CPSCOM + dw pk1ver ; CPSPK1 + dw pk2ver ; CPSPK2 + dw remver ; CPSREM + dw server ; CPSSER + dw ttver ; CPSTT + dw cpmver ; CPSCPM + dw wldver ; CPSWLD + dw cmdver ; CPSCMD + dw utlver ; CPSUTL + dw datver ; CPSDAT + dw 0 ; end of list + +; Show TACTrap status (On or Off, and intercept character) +statac: lxi d,tacst ;"Current TACTrap status/char: " + call prtstr + lxi d,offstr ;Assume set off + lda tacflg ;Get the TACTrap char/flag + ora a ;Is it off? + jz prtstr ;Yep, go print OFF... + mvi c,conout ;Display... + mov e,a ;...the current intercept char + call bdos + jmp prcrlf + +; Show if flow control is set on or off +staflo: lxi d,flost ; Flow control string + call prtstr + lda floctl ; get the flag + jmp staton + +; Show if Case sensitvity is on or off +;stasens: +; lxi d,senst ; case sensitivity string +; call prtstr ; +; lda casens +; jmp staton ; say if its on or off + + +; Show the current user. (Should do this under directory...) +stusr: + mvi c,usrcod + mvi e,0ffh ;[9] get the current user + call bdos + mov l,a ;[9] print hl as a number... + mvi h,0 + push h ;[9] got the user number + lxi d,usrst ;[9] tell the user number + call prtstr + pop h ;[9] now do number + call nout ;[6] using routine for writing packet nos. + ret + +; +; +; [DJR] Show debug mode +stadbg: + lxi d,dbgst ;[DJR] Display string + call prtstr ;[DJR] + lda dbgflg ;[DJR] load flag + jmp staton ;[DJR] + + +; [DJR] Show default disk +stacurd: + lxi d,curdst ;[DJR] + call prtstr ;[DJR] + lda curdsk ;[DJR] + adi 'A'-1 ;[DJR] + mov e,a ;[DJR] + mvi c,conout ;[DJR] + jmp bdos ;[DJR] + +; +; Display current state of a boolean flag. +; called with A/ value (zero = Off, non-zero = On) + +staton: lxi d,onstr ; Assume it's on. + ora a ; Is it on? + jnz prtstr ; If so, say so, then return. + lxi d,offstr ; No, say off. + jmp prtstr ; Print the string, then return. + +; STRING command +; get a string from the user and send it to the host. +string: mvi a,cmtxt ; get the text + lxi d,stbuff ; where to put it + call comnd + jmp kermit ; if we cannot do it, then back to command level + sta strcnt ; save the string count + ana a ; if it is zero, then do nowt + jz kermit + call cfmcmd ;[MF]Otherwise, get a "confirm" + call selmdm ; then select the modem + lxi d,stbuff ; where to get the string +stlop: ldax d ; get byte + inx d ; pointer plus one + push d ; update pointer, and save de, and the character + call setpar ; set whatever parity + mov e,a ; outmdm wants character in e + call outmdm ; send character in a to line + pop d + lda strcnt ; get the count + dcr a + sta strcnt ; less one + jnz stlop ; else still looping + call selcon ; re-select the console + jmp kermit + +; Print "(not implemented)". +; here from vt52em, baud, prtset, stavt + +notimp: lxi d,inms12 ; Say it's not implemented. + call prtstr + jmp kermit ; Return to main loop. + +; Little code to allow some expansion of code without changing +; every futher address, only up to the end of this file. +; TO BE REMOVED FRO RELEASE! + +; org ($+100h) AND 0FF00H + +IF lasm ; If using LASM, chain to the next file. + LINK CPSPK1 ;[obs] break down them big files... +ENDIF;lasm diff --git a/cpscpm.asm b/cpscpm.asm index 49df54f..230f147 100644 --- a/cpscpm.asm +++ b/cpscpm.asm @@ -1,932 +1,932 @@ -; CPSCPM.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file duplicates the CP/M DIR and ERA functions so we don't have -; to exit. -; -; revision history: -; -;edit 14, 1-Apr-1991 by MF. Correct a bug which crept in with edit 13 which -; caused any control-key other than ^Y or ^Z to act like ^X after a key -; had been depressed to halt output of the TYPE/PRINT commands. -;edit 13, 25-Mar-1991 by MF. Make the TYPE command always abort to Kermit -; command-level if ^C is entered on the console even if multiple files -; are being typed via wild-cards. Make ^X typed on the console abort -; typeout of the current file and begin typeout of the next file, -; if any, otherwise go back to Kermit command-level. -; The foregoing also applies to the PRINT command. -;edit 12, 14-Feb-1991 by MF. Call "clrtop" in TYPE command at "type1" -; rather than sending a directly to the terminal as some -; terminals don't respond to 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 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 directly to the terminal as some +; terminals don't respond to 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 character. +;type1: mvi a,ff ; do a form feed +; call typit +type1: call clrtop ;[12] Clear the screen + xra a ; clear the character count + sta temp1 ;[MF]alias column counter + +type2: +;[12]Eliminate call to openf in favor of call to "getfil" +; mvi c,openf ; open the file for reading + lxi d,fcb +; xra a ; but first clear bits of fcb... +; sta fcb+12 +; sta fcb+14 +; sta fcb+15 +; sta fcb+32 +; call bdos ; NOW open the file + call getfil ;[12] NOW open the file + +type20: call inbuf ;[MF]Fill input buffers + jmp typex ;[MF]Tru end-of-file reached + jmp type21 ;[MF]Begin typing/printing characters + +type2a: lda chrcnt ;[MF]Get buffer character counter + dcr a ;[MF]and decrement it + jm type20 ;[MF]Get more characters if needed +type21: sta chrcnt ;[MF]else remember new buffer character counter + lhld bufpnt ;[MF]Now get character pointer + mov a,m ; and get character to type (print) + inx h ;[MF]Increment the pointer + shld bufpnt ;[MF]and remember it + ani 7fh ; make sure character is printable + cpi 20h ; is it a control character? + jp type3 + cpi 09h ; if its a tab, then expand it + jnz type2b + +type2c: mvi a,' ' ; send a space + call typit ; type it + lda temp1 ;[MF]Get the number of characters so far + ani 7h ; see if an 8th pos? + jnz type2c ; loop until all spaces done, then exit + jmp type2a ;[MF]and continue + +type2b: cpi cr ; is it a cr or lf? + jnz type2d + call typit ; do a cr + xra a + sta temp1 ; cr or lf => clear character count + jmp type2a ;[MF]and continue + +type2d: cpi lf + jnz type2e + call typit ; print the character + xra a + sta temp1 ; cr or lf clears the character count + jmp type2a ;[MF]and continue + +type2e: cpi cntlz ; is it end of file? + jnz type2f + jmp typex ; yes, so close and try for another file + +type2f: push psw ; control char - save the character + mvi a,'^' ; send control chars as ^A, for ex. + call typit + pop psw + +type3: call typit + jmp type2a ; and continue along + +typex: mvi c,closf + lxi d,fcb + call bdos ; close the file + mvi a,cr ; send cr lf to screen/printer to clear buffers + call typit + mvi a,lf + call typit + call mfname ; and see if there are other files to type + jnc type1 ; yup, so go do it + xra a ; make sure the flag is reset + sta prnfl + jmp kermit ; then exit. + +typex0: mvi c,closf ;[MF]Close the file + lxi d,fcb ;[MF]... + call bdos ;[MF]... + mvi a,cr ;[MF]Clear buffers + call typit ;[MF]... + mvi a,lf ;[MF]... + call typit ;[MF]... + xra a ;[MF]Clear flag + sta prnfl ;[MF]... + lda takflg ;[MF]See if we're TAKEing commands + ani 1 ;[MF]from a file + cnz closet ;[MF]If we are, abort TAKE-file processing + jmp kermit ;[MF]Back to Kermit command-level + +; error for file not found for type +type02: lxi d,nofile ; say no file name (its invalid) + call prtstr + xra a + sta prnfl ; clear the flag + jmp kermit ; so abort + + +typit: mov e,a + call ckqtyp ; see if a cntl-c or other character from user + jmp typit2 ;[MF] Control-C entered, abort + jc typit1 ; CNTL-X entered, so abort file [MF] + push d ; save for a bit + call outcon ; send it to the console + lda temp1 ; update the number of characters sent[MF] + inr a + sta temp1 ;[MF] + pop d + lda prnfl ; see if we have to print it too + ana a + rz + call outprn ; send character to printer (buffer) + ret + +typit1: pop d ; adjust stack again + jmp typex ; and say we are done (for this file) + +typit2: pop d ;[MF] Adjust the stack + jmp typex0 ;[MF] and abort file typeout completely + + +; CKQTYP - CHeck for requested Quiet TYPe (ie hang on a second) +; Routine sees if the user has typed ANY key. If a key HAS been pressed +; see if its a Control-c. If so, flag for an abort, else wait for +; a second entry from the user. If its a Control C, flag an abort +; else continue with the print. +; note: only the DE registers maintained. All others destroyed. +; **NOTE** CKQTYP now gives a nonskip return if Control-C is typed, +; a skip-return with carry set if a Control-X is typed and a skip-return +; with carry clear if any other character is typed as the second +; character. + +ckqtyp: push d ; save the character to be printed + call ckchr ; see if user entered a character + ani 7fh ; strip parity etc + jz ckqty3 ; nothing entered, so go on as usual (See below) + cpi ctrlc ; control c? + jz ckqt1a ;[MF] Yup, give nonskip return + cpi 'X'-100o ;[MF] If Control-X, + jz ckqty1 ; yup, set carry and exit +ckqty2: call ckchr ; another character to wait for (ie pause) + ani 7fh + jz ckqty2 ; wait until some input + cpi ctrlc ; if control c, abort + jz ckqt1a ;[MF] ... + cpi 'X'-100o ;[MF] Control-X? + jz ckqty1 ; yuss, so flag abort file [MF] +ckqty3: pop d ; else restore the character to be typed [MF] +; ret ; no, so continue with type/print + stc ;[MF]Set carry + cmc ;[MF]Then clear it + jmp rskp ;[MF] Continue with type/print (skip ret) + +ckqty1: pop d ; restore stack again + stc ; set carry and return +; ret + jmp rskp ;[MF] ... + +ckqt1a: pop d ;[MF] Adjust stack + ret ;[MF] and return + +;[MF][14]No longer need these lines +;ckqty3: pop d ; restore stack again +;; ret +; stc ;[MF] Clear carry +; cmc ;[MF] ... +; jmp rskp ;[MF] and give skip return + +ckchr: call selcon ; make sure we are talking to the console + mvi e,0ffh ; see if user has any input for us + mvi c,dconio +; call bdos ;[11]Don't go thru bdos trap + call 0005h ;[11]Call bdos directly + ret ; This routine does not care what comes back + + +; +; COPY - routine to copy from a source file to a destination file +; from the Kermit command state. +; +; Note. This could be tricky, as there are several forms of copy +; copy d:source.ext d:dest.ext (Easy one) +; copy d:source.ext d: (File to another drive) +; copy d:source.??? d: (several files) +; copy d:*.* d: (Several files) +; +; Initially, lets make it top one, and see how we go, ok? +; +; +;Things to do for copy: +; 1) get source name +; 2) get target name +; 3) if both source and destination = abort +; 4) if source does not exist abort +; 5) attempt to delete destination file if it exists +; 6) open source and destination files +; 7) copy file across +; 8) close all files +; 9) return to command mode +; +copy: ; Here goes... +; 1) get source file name + mvi a,cmofi ; go parse a file name + ;[MF]Nonwild + lxi d,cfcbs ; use the source for copy FCB (Allows copy + call comnd ; from a TAKE file etc) + jmp kermit ; if error, abort + +; 2) get target name + mvi a,cmofi ; go parse a target file name + ;[MF]Again, nonwild + lxi d,cfcbd ; use destination fcb + call comnd ; get it + jmp kermit ;[MF]Couldn't. + mvi a,cmcfm ;[MF]Get a confirm from the user + call comnd ;[MF]... + jmp kermit ;[MF]No? try another command + +; 3) see if both target and source are equal +copy0: mvi b,12 ; we are gonna test drive, file and extention + lxi d,cfcbs ; from source file name... + lxi h,cfcbd ; to destination file name + xra a ; clear flag for difference found + sta equflg +copy1: ldax d ; get source file name character + cmp m ; test with targer file name + jz copy2 ; if equal, do nothing + lda equflg ; else update flage (ie files are different) + inr a + sta equflg +copy2: inx h + inx d + dcr b + jnz copy1 ; up pointers and test for next char + + lda equflg ; if still null, then its a daft thing to do + ana a + jnz copy3 ; its not a daft thing to do + lxi d,samems ; load up "File source and destination the same" + call prtstr ; tell user + jmp kermit ; and try again + +; 4) If source does not exist, abort. Assume we have a full file name. +copy3: + lxi d,cfcbs ; load up source fcb + mvi c,openf ; open file + call bdos + inr a ; error on open? + jnz copy4 + lxi d,nofile ; assume file not found + call prtstr + jmp kermit ; and die + +copy4: lxi d,cfcbd ; load up destination fcb + mvi c,delf ; destroy target name if it exists + call bdos ; ignore error messages + lxi d,cfcbd ; load up destination fcb + mvi c,makef ; make a file + call bdos + inr a ; make error? + jnz copy4a + lxi d,erms12 ; no directory space + call prtstr + jmp copy7 ; close source file + +copy4a: lxi d,cfcbd ; load up destination fcb... + mvi c,openf ; for open + call bdos + inr a ; error on open? + jnz copy5 ; could do with better error detection... + lxi d,erms15 ;... but assume its a disk full + call prtstr + jmp copy7 ; close source file and jmp kermit + +;copy5: lxi d,buff ; set default dma address to 80h +; mvi c,setdma +; call bdos +; +;copy6: lxi d,cfcbs ; copy routine proper.. get a sector +; mvi c,readf +; call bdos +; ana a ; error reading the file? +; jnz copy8 ; yes, then cope with it (could be EOF) +; [MaJoC 910128] The above code, which reads single logical sectors, +; is grossly inefficient with systems (most of them) with larger physical +; disk blocks and a single shared read/write buffer. Use of INBUF below +; is functionally equivalent at this level, but does actual disk reads +; by the Big Buffer-ful. +copy5: + xra a ; Initialise INBUF, to force reading of + sta seccnt ; the first Big Buffer-ful. Redundant + sta endsts ; if file opened by GETFIL (or variant). + sta eoflag ;[MF]... + lxi h,cfcbs ;[MF]Copy source fcb to default fcb + lxi d,fcb ;[MF]since INBUF uses the default fcb + lxi b,33 ;[MF]... + call mover ;[MF]... +copy6: +; INBUF returns a pointer to the next logical bufferful via bufpnt, filling +; the Big Buffer as necessary, with skip return for success and nonskip on +; error or EOF. + call inbuf ; Start of copy proper: get bufferful. + jmp copy8 ; Nonskip return: treat as EOF. + lhld bufpnt ; Skip return => OK: pick up buffer pointer. + xchg + mvi c, setdma ; Tell system where to write from. + call bdos +; [majoc 910128: end] + lxi d,cfcbd ; send sector to destination + mvi c,writef + call bdos + ana a ; error on write (disk full?) + jz copy6 ; no error, so do another sector. + lxi d,erms17 ; say disk is full + call prtstr + lxi d,cfcbd ; close the output file... + mvi c,closf + call bdos + lxi d,cfcbd ; ... and then delete it + mvi c,delf + call bdos ; ... and then drop through to... + +copy7: lxi d,cfcbs ; here to close the source FCB + mvi c,closf + call bdos + jmp kermit + +copy8: lxi d,cfcbd ; orderly close of destination file + mvi c,closf + call bdos + jmp copy7 ; now close the source file as well. + +; +;[MF]RENAME - Rename a file +; +rename: mvi a,cmofi ;[MF]Get nonwild filename + lxi d,cfcbs ;[MF]Use "COPY" fcb's + call comnd ;[MF]... + jmp kermit ;[MF]Couldn't get it. + mvi a,cmofi ;[MF]Get filespec to rename it to + lxi d,cfcbd ;[MF]... + call comnd ;[MF]... + jmp kermit ;[MF]Couldn't. +renam0: lxi d,cfcbs ;[MF]See if file to be renamed exists + mvi c,openf ;[MF]by trying to open it + call bdos ;[MF]... + inr a ;[MF]Does the file exist? + jnz renam1 ;[MF]Yes + lxi d,nofile ;[MF]No, inform the user + call prtstr ;[MF]... + jmp kermit ;[MF]and bomb +renam1: lxi d,cfcbd ;[MF]Point to rename filespec + mvi c,openf ;[MF]Set function code to + call bdos ;[MF]See if rename file exists + inr a ;[MF]Does it? + jz renam2 ;[MF]No + lxi d,erms31 ;[MF]Yes, complain + call prtstr ;[MF]... + jmp kermit ;[MF]and depart with tail between legs +renam2: lxi h,cfcbd ;[MF]Now get rename filespec again + lxi d,cfcbs+16 ;[MF]and where to copy it to + lxi b,16 ;[MF]We copy drive, filename, filetype, extent + call mover ;[MF]... + lxi d,cfcbs ;[MF]Point to fcb for rename + mvi c,renam ;[MF]Get rename function + call bdos ;[MF]Try to rename the file + inr a ;[MF]Did we succeed? + jnz kermit ;[MF]Yes, done + lxi d,erms16 ;[MF]No, complain + call prtstr ;[MF]... + jmp kermit ;[MF]and start over + + +IF lasm + LINK CPSWLD +ENDIF;lasm [Toad Hall] diff --git a/cpsdat.asm b/cpsdat.asm index 729ca52..b8f3f66 100644 --- a/cpsdat.asm +++ b/cpsdat.asm @@ -1,648 +1,648 @@ -; CPSDAT.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; Pure and impure data areas. Previously of CPSUTL.ASM -; -; revision history: -; -;edit 19, 29-Mar-1991 by MF. Add flag "initak" (nonzero) which is cleared -; after the initial automatic TAKE attempt of KERMIT.INI to allow -; "unable to find file" complaints if not doing that initial TAKE. -;edit 18, 21-Mar-1991 by MF. Renamed parameter vermin to revno (revision -; level) since verno is already known as the "minor version number". -;edit 17, 27-Feb-1991 by MF. Corrected typeo in "inms19" and commented out -; "typptr" pointer as the TYPE command now uses the big buffer. -; Also provided for a "minor version number" (1-26=A-Z) and message to -; facilitate display of Kermit version in VERSION command (modmsg) -;edit 16, 12-Feb-1991 by MF. Eliminated storage (message and variable) -; for case sensitivity by commenting it out. -;edit 15, 9-Dec-1990 by MF. Modified message for "directory file size" -; status report to make it clearer when spoken by a speech synthesizer. -;edit 14, 4-Dec-1990 by MF. Added message for Autoreceive status report. -;edit 13, 30-Nov-1990 by MF. Added messages to display regular/quiet status -; of terminal in SHOW and STATUS commands. -;edit 12, 8-Nov-1990 by MF. Added a new message for Set Autoreceive. -;edit 11, 2-Nov-1990 by MF. Moved overlay address to 7000H -- I didn't -; realize I was **that** close to the limit until I made a couple of -; cosmetic changes and REM CD bombed. This is still ver. 4.10 as it -; hasn''t been released yet. -;edit 10, 1-Nov-1990 by MF. Changed message at "spdst" to conform with -; the change of "SET BAUD-RATE" to "SET SPEED". -; Also added message "sdpst2" for speed status (staspd) routine -;edit 9, 17-Oct-1990 by MF. Changed "packet-size" messages to use the -; word "length" to conform with the nomenclature suggested in the -; 6th edition of the Kermit Protocol Manual. -;edit 8, 19-Sep-1990 by MF. Added error message for FRENAME command. -;edit 7, 14-Sep-1990 by MF. Added storage/strings for SET COLLISION command. -; Also added strings/storage for SET INCOMPLETE-FILE command. -;edit 6, 9-Sep-1990 by MF. Added messages and storage for Remote commands. -; and display of packet sizes -; Moved overlay address to 06C00H for Version 4.10. -; edit 5, 8 April, 1987 by OBSchou. Added new entry in jump table to call -; code for an external terminal type. Added some new error messages -; and added more to the packet space. -; -; edit 4, 30 March by OBSchou. Added in space for autoreceive. -; -; edit 3, 19 March, 1987 by OBSchou. Added some more strings etc, and -; increased the stack space fro 32 entries to 64. -; -; edit 2, 11 March, 1987 by OBSchou. -; Added in some more data and strings and things. Nothing special -; -; edit 1, 28 January, 1987 by OBSchou -; Following file the data section of CPSUTL.ASM. This part of the -; CPSUTL.ASM file now seperate as it ws getting too larg. Link to here -; from CPSUTL.ASM (which now has only the utlity routines). -; Also added in bits submitted by Dave Roberts of Leicester: -; DJR 18th January 1987 - David J. Roberts. -; Support for cosmetic changes in CPSMIT: -; New strings DBGST and CURDST -; CRLF in front of TIMMSG -; LOGST changed, and new LOGST2 -; -; -datver: db 'CPSDAT.ASM (19) 29-Mar-1991$' - - - -; - -version:db 'Kermit-80 v4.' - db (verno/10) + '0' ; tenth's digit of version number - db (verno MOD 10) + '0' ; hundredth's digit -IF revno ;[MF]If a revision level, - db revno+'@' ;[MF]put it in (range 1-26=A-Z) -ENDIF ;revno [MF] - db ' $' -modmsg: db ' has been built from the following modules:$';[MF] -kerm: db 'Kermit-80 ' -kerm1: db 'nnx:>$' ;'x' filled in at startup with DRIVE name - ;'nn filled at startup and user with user number -crlf: db cr,lf,'$' -ermes1: db cr,lf,'?Unrecognized command$' -ermes3: db cr,lf,'?Not confirmed$' -ermes4: db '?Unable to receive initiate',cr,lf,'$' -ermes5: db '?Unable to receive file name',cr,lf,'$' -ermes6: db '?Unable to receive end of file',cr,lf,'$' -erms10: db '?Unable to receive data',cr,lf,'$' -erms11: db '?Disk full',cr,lf,'$' -erms12: db '?Directory full',cr,lf,'$' -erms14: db '?Unable to receive an acknowledgement from the host',cr,lf,'$' -erms15: db cr,lf,'?Unable to find file',cr,lf,'$' -erms16: db '?Unable to rename file$' -erms17: db cr,lf,'?Disk full$' -erms18: db cr,lf,'?Unable to tell host that the session is finished$' -erms19: db cr,lf,'?Unable to tell host to logout$' -erms20: db cr,lf,'?Kermit has not been configured for a target system$' -erms21: db cr,lf,'?Consistency check on configuration failed$' -erms22: db cr,lf,'?Error writing to log file',cr,lf,'$' ;[pcc005] -erms23: db cr,lf,'?Invalid user number$' -erms24: db cr,lf,'?Invalid Pause parameter$' -erms25: db cr,lf,'?Invalid BUFFER-SIZE parameter$' -erms26: db cr,lf,'?Invalid packet length (too long)$' -erms27: db cr,lf,'?Invalid Checktype$' -erms28: db cr,lf,'?Too many retries$' -erms29: db cr,lf,'?Failed to exchange parameters$' -erms30: db cr,lf,'?Failed to receive input string in alloted time$' -erms31: db cr,lf,'?File already exists$' ;[MF] - -infms3: db bell,'Completed$' -infms4: db bell,'Failed$' -infms5: db '%Renaming file to $' -infms6: db cr,lf,'[Closing the log file]$' -infms7: db cr,lf,'[Connected to remote host. Type $' -infms8: db 'C to return;',cr,lf,' type $' -inms8a: db '? for command list]',cr,lf,'$' -infms9: db cr,lf,'[Connection closed, back at micro]$' -inms10: db 'Control-$' -inms11: db ' Not implemented.$' -inms12: db ' (Not implemented)',cr,lf,'$' -inms13: db bell,'Interrupted$' -inms14: db TAB,TAB,' Directory for drive ' -dnam14: db 'nnx:',cr,lf,'$' ;filled in by dir routine. -inms15: DB CR,LF,TAB,TAB,'Drive $' -inms16: DB ' has $';filled in by summary code with drive letter -inms17: DB 'K bytes free',CR,LF,'$' -inms18: DB CR,LF,'File(s) erased$',CR,LF -inms19: db cr,lf,'[Transmitting file to host:' - db cr,lf,' 1. Lines automatically sent, and wait for possible reply' - db cr,lf,' 2. CONTROL-C aborts transfer' - db cr,lf,' 3. If transfer hangs, try a return to continue' - db cr,lf,' 4. on exit, you will be placed in CONNECT state.' - db cr,lf,'$' -inms20: db 'R to send the same line again,' - db cr,lf,' or type $' -inms21: db 'C to abort transmission.]',cr,lf,'$' -inms22: db cr,lf,'[Transmission done. Connected normally ' - db 'to remote host,' - db cr,lf,' type $' -inms23: db 'Sending...$' -inms24: db 'Receiving...$' -inms25: db bell,'Warning: eighth bit cannot be sent$' -inms26: db cr,lf,'For help, type ? at any point in a command$' -inms27: db cr,lf,'[Logging suspended]',cr,lf,'$' ;[pcc003] -inms28: db cr,lf,'[Logging resumed]',cr,lf,'$' ;[pcc003] -inms29: db cr,lf,'[Transmission Aborted. Connected normally ' - db 'to remote host,' - db cr,lf,' type $' -autmes: db cr,lf,cr,lf,'[Automatically receiving; type ^C to abort]' - db cr,lf,cr,lf,'$' ;[MF] -anymes: db cr,lf,cr,lf,' * * * Press any key to continue * * * ' - db cr,lf,cr,lf,'$' -escmes: db cr,lf,'Type the new escape character: $' -tacmes: db cr,lf,'Type the new TAC intercept character: $' -sopmes: db cr,lf,'Give the start-of-packet character: $' ;[gnn] -padcms: db cr,lf,'Type the new padding character: $' ;[obs] -xmthlp: db cr,lf,'R Send the same line again$' -loghlp: db cr,lf,'Q Suspend logging' ;[pcc003] - db cr,lf,'R Resume logging$' ;[pcc003] -inthlp: db cr,lf,'? This message' - db cr,lf,'C Close the connection' - db cr,lf,'0 (zero) Transmit a NULL' - db cr,lf,'P Toggle printer on/off' ;[pcc002] - db cr,lf,'S Status of the connection$' -inhlp1: db cr,lf,'Typing another $' -inhlp2: db ' will send it to the host' - db cr,lf,cr,lf,'Command>$' - -xmtst: db cr,lf,'Transmitting a file$' -autrst: db cr,lf,'Autoreceive is$' -locst: db cr,lf,'Local echo$' -onstr: db ' on$' -offstr: db ' off$' -flost: db cr,lf,'Flow control$' -;senst: db cr,lf,'Case sensetivity$' -vtdpst: db cr,lf,'Terminal display is $' -vtdpsr: db 'REGULAR$' -vtdpsq: db 'QUIET$' -vtemst: db cr,lf,'Terminal emulation is $' -cpmst: db cr,lf,'File Mode$' -defstr: db ' default$' -ascstr: db ' ASCII$' -binstr: db ' binary$' -hfsod: db cr,lf,'Display file size on DIRECTORY command$' -ibmst: db cr,lf,'IBM flag$' -incst: db cr,lf,'Disposition for incomplete files is$' -dscstr: db ' discard$' -kepstr: db ' keep$' -filst: db cr,lf,'File warning$' -prst: db cr,lf,'Printer copy$' -logst: db cr,lf,'Logging to $' ;[pcc003][DJR] -logst2: db ' is$' ;[DJR] -susstr: db ' suspended$' ;[pcc003] -sspmsg: db cr,lf,'SEND start-of-pkt char ^$' ;[gnn] -rspmsg: db cr,lf,'RECEIVE start-of-pkt char ^$' ;[gnn] -spsmsg: db cr,lf,'SEND packet length $' ;[MF] -rpsmsg: db cr,lf,'RECEIVE packet length $' ;[MF] -escst: db cr,lf,'Escape char: $' -bufsz1: db cr,lf,'Multi-sector buffering at $' -bufsz2: db ' of a maximum of $' -xmitst: db cr,lf,'Transmit protocol char: $' -bckst: db cr,lf,'Block check type: $' -bckst1: db '-character$' -collst: db cr,lf,'File COLLISION: $';[MF] -parst: db cr,lf,'Parity: $' -pnonst: db 'none$' -pmrkst: db 'mark$' -pspcst: db 'space$' -poddst: db 'odd$' -pevnst: db 'even$' -porst: db cr,lf,'Port in use is: $' -spdst: db cr,lf,'Current speed is: $' -spdst2: db ' bps$' ;[MF] -spdust: db 'indeterminate (not SET)$' -timmsg: db cr,lf,'Timer$' ;[DJR] Added CRLF like the others -tacst: db cr,lf,'Current TACTrap Status/Intercept Character: $' -usrst: db cr,lf,'Current user number: $' -dbgst: db cr,lf,'Debugging$' ;[DJR] -curdst: db cr,lf,'Current default disk: $' ;[DJR] -spac15: db ' $' ; *** 15 spaces *** -samems: db cr,lf,'?Source and destination files the same$' -nofile: db cr,lf,'?File not found$' -cmer00: db cr,lf,'?Program error: Invalid COMND call$' -cmer01: db cr,lf,'?Ambiguous$' -cmer02: db cr,lf,'?Illegal CP/M file specification$' -cmer03: db cr,lf,'?Wild-cards not allowed in file specification$' ;[pcc006] -cmer04: db cr,lf,'?Invalid user number$' -cmer05: db cr,lf,'?Invalid \ parameter$' -cmin00: db ' Confirm with carriage return$' -cmin01: db ' Enter a number$' -cmin02: db ' Confirm with carriage return or enter more$' - -; Diagnostic messages -sstatm: db ' ',0 -rstatm: db ' ',0 -spackm: db ' ',0 -rpackm: db ' ',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 ' ',0 +rstatm: db ' ',0 +spackm: db ' ',0 +rpackm: db ' ',0 +princr: db cr,lf,0 +; +; Remote command messages [MF] +; +newfms: db cr,lf,'New file: $' +pswdms: db cr,lf,'Password: $' +acctms: db cr,lf,'Account: $' +newnms: db cr,lf,'New name: $' +msgms: db cr,lf,'Message: $' +optms: db cr,lf,'Options: $' + +; + ;Impure data + +;COMND storage + +comchr: ds 1 ;[8] save space +floctl: db 0 ;[8] flow control on/off flag +;casens: db 0 ;[8] Upper/lower case sensitive +cmstat: ds 1 ;What is presently being parsed. +cmaflg: ds 1 ;Non-zero when an action char has been found. +cmbflg: ds 1 ;[MF]Nonzero to allow a blank initial keyword +cmqflg: ds 1 ;[MF]Nonzero to prevent character echoing + ;[MF]when entering commands +cmccnt: ds 1 ;Non-zero if a significant char is found. +cmsflg: ds 1 ;Non-zero when the last char was a space. +cmostp: ds 2 ;Old stack pointer for reparse. +cmrprs: ds 2 ;Address to go to on reparse. +cmprmp: ds 2 ;Address of prompt. +cmptab: ds 2 ;Address of present keyword table. +cmhlp: ds 2 ;Address of present help. +cmdbuf: ds 80H ;Buffer for command parsing. +cmbufl equ $-cmdbuf-3 ; set a limit on the command buffer +cmfcb: ds 2 ;Pointer to FCB. +cmfcb2: ds 2 ;Pointer to position in FCB. +cmfwld: ds 1 ;Wildcard flag +cmcptr: ds 2 ;Pointer for next char input. +cmdptr: ds 2 ;Pointer into the command buffer. +cmkptr: ds 2 ;Pointer to keyword. +cmsptr: ds 2 ;Place to save a pointer. +slshsn: db 0 ; slash seen in command line +slashc: db 0 ; count for number of characters in slash sequence +slashn: db 0 ; number to be built for \xxx +; +oldsp: ds 2 ;Room for old system stack. + ds 80H ;Room for 64 levels of calls.[obs] +stack: ds 2 +eoflag: ds 1 ;EOF flag;non-zero on EOF. +curdsk: db 0 ;holds "logged" disk +curusr: db 0 ;[8] holds "user" number +rcvsop: db SOH ;[gnn] receive start-of-packet +sndsop: db SOH ;[gnn] send start-of-packet +prtcnt: db 0 ;[pcc008] prtchr fairness count +timflg: db 0 ;[jd] timer flag: 0 -> no timer +timval: dw 0 ;[jd] timer value +wrn8: db 0 ;[jd] non-zero if 8-bit-lost warning sent +qbchr: db '&' ;[jd] binary quote character. +quot8: db 0 ;[jd] non-zero if doing 8-bit quoting +logflg: db 0 ;Flag for a log file. + ;[pcc005] 0 = no log + ;[pcc005] x1 = logging on + ;[pcc005] x2 = suspended + ;[pcc005] 8xH (bit 7) = file open +lognam: db 0 ;[pcc013] File to use for session logging + db 'KERMIT ' ;[pcc013] + db 'LOG' ;[pcc013] +nexitf: db 0 ; set to 1 for exit to CPM after command tail +takflg: db 0 ;[8] TAKE flag. + ; Bit zero = 1 for take file in progress + ; bit 4 = 1 if command line present/in progress + ; Note: Take has priority over command line. +initak: db 0ffh ;[MF]Cleared after initial TAKE (KERMIT.INI) +taknam: db 0 ;[8] use default drive + db 'KERMIT ' + db 'INI' ;[8] Inital file to TAKE KERMIT.INI +takptr: ds 2 ;[8] Pointer to position in TAKE file input +takfcb: ds 12 ;[8] fcb space for take file + dw 0 ;[8] fill up extents etc with 00 + dw 0 + ds 16 ;[8] used by dos + dw 0 + dw 0 +takdma: ds 128 ;[8]space to read TAKE file... +prnbuf: ds 1 ; printer buffer. Output pointer + ds 1 ; input offset pointer + ds 256 ; give a large buffer + ds 10 ; and a little spare +; +; +; +; Transmit space +; +repcnt: db 0 ; repeat counter +starc: db 0 ; star count +rexbfl: db 0 ; retransmit flag (1=> retransmit) +rexcnt: db 0 ; retransmit character count +rexbuf: ds 128 ; max retransmit line length 128 characters +xmtbuff: + ds 128 ; 128 byte sector buffer +xmtptr: db 0 ; offset pointer to xmtbuff above +xmtfcb: ds 36 ; fcb for transmit file. +; +;INPUT and STRING space +strlen: db 0 ; length of the string from INPUT and STRING + +; Assorted other space +errorc: db 0 ; error level set to xxx +errorl: db 0 ; error level to test against + +remtxt: db 0 ; set <> 0 if D packets to screen + +hosths: ds 1 ; have we told the host to xoff? (is this duplicated) +stbuff: ds 80h ; some space or the string buffer +waitp: ds 2 ; wait command timer +waitp1: ds 2 ; wait/input timer (copy of waitp) +prntmp: ds 1 ; temporary space to put the caracter to print +prnfl: db 0 ; printer flag. Used by TYPE/PRINT +;[MF][17]Following line no longer needed as TYPE uses the big buffer +;typptr: ds 2 ; pointer used by TYPE/PRINT +equflg: db 0 ; set to non zero if copy files same +nquiet: db 0 ; If non zero print from NOUT to display + +escflg: db 0 ;Escape flag (start off). +fileio: db 0 ;Line-by-line from file (default off). +xofflg: db 0 ;X-OFF (=^S) received from COMM-line + ;X-ON (=^Q) received resets this +clkbit: dw 0 ; 32 bit pseudo clock + dw 0 ; MS bits of clock +number: ds 2 ; Number in binary form from user input +initflg:db 0 ; set to non zero when system initialised +maxbsc: ds 1 ; save space to know how big system allows + ; for multi-sector buffering. (Usually 8k?) +; +; Multiple FCB storage space. Used for the DIR command +; Later on, I want to shift this into space after the system +; dependent stuff, but then it becomes messy with pointers +; to pointers etc... [OBS] +; +xfcbptr: + ds 2 ; pointer to current fcb space +fcbcnt: ds 1 ; Number of valid fcbs in space +; +fcb0: ds 12 ; 36 bytes requred for a single fcb +fcblen EQU $-fcb0 ; length of a single fcb + ds maxfcb*fcblen ; space for maximum fcbs + 1 +; +hidefs: db 0ffh ; flag <> 0 if we show file size in DIR + +; FCB sapce for COPY command +cfcbs: ds 33 ; source fcb for copy file ops. + ;[MF]and FRENAME ops. +cfcbd: ds 33 ; destination fcb for copy ops. + ;[MF]and FRENAME ops. + +colfcb: ds 33 ;[MF]Rename fcb for SET COLLISION + +; Command tail data space etc +cbptr: db 2 ; command tail pointer (0= length of tail) +cbuff: ds 128 ; temp. space for potential command tail + +strcnt: db 0 ; string count for string operations... + +vtyval: ds 1 ; holds row number for VT52 cursor positioning +chrcnt: ds 1 ;Number of chars in the file buffer. + +; Various packet variables etc +bytes: dw 0 ; 4 byte 'byte count' space + dw 0 +filcnt: ds 1 ;Number of chars left to fill. +outpnt: ds 2 ;Position in packet. +bufpnt: ds 2 ;Position in file buffer. +fcbptr: ds 2 ;Position in FCB. +datptr: ds 2 ;Position in packet data buffer. +cbfptr: ds 2 ;Position in character buffer. +pktptr: ds 2 ;Position in receive packet. +size: ds 1 ;Size of data from gtchr. +curchk: ds 1 ;Current checksum type +inichk: ds 1 ;Agreed upon checksum type +czseen: ds 1 ;Flag that control-Z was typed +dscflg: ds 1 ;[MF]Discard file if nonzero +pktnum: ds 1 ;Packet number. +numpkt: ds 2 ;Total number of packets sent. +numrtr: ds 2 ;Total number of retries. +numtry: ds 1 ;Number of tries on this packet. +oldtry: ds 1 ;Number of tries on previous packet. +state: ds 1 ;Present state of the automaton. +;*** start of new flags. Do not assume that just because these flags are +; present that the feature is available. I simply put them in 'for future use' +rcapas: +rcap1: db 0 ; receive capabilties byte 0 +rcap2: db 0 ; receive cpabilities byte 1 +scapas: +scap1: db 0 ; send capabilities byte 0 +scap2: db 0 ; send capabilities byte 1 +rtimeo: db 0 ; receive timeout +stimeo: db 0 ; send timeout +rpadc: db 0 ; receive pad character +spadc: db 0 ; send pad character +rrept: db 0 ; receive repeat prefix +srept: db 0 ; send repeat prefix +rwindo: db 0 ; receive window size +swindo: db 0 ; send window size +rdpkt: +rlpkt: dw 0 ; receive long packet length +sdpkt: +slpkt: dw 0 ; send long packet length +sdckt: db 0 ; send default checktype +rdckt: db 0 ; receive checktype (should be same as sdckt) +;*** end of new flags +sohchr: db 1 ;Default Start-of-header chr is cntl-a +; Kermit packet starts here +; Byte 0 = start of packe character +; 1 = length of packet +; 2 = packet number +; 3 = packet type (S R I Z E B etc) +packet: ds 4 ;Packet (data is part of it). +; Data part of packet (variable length - include checksum) +data: ds 5AH ;Data and checksum field of packet. +recpkt: ds 65H ;Receive packet storage (use the following). +recpkx: db cr,'$' ;= = = buffer limit +filbuf: ds 65H ;Character buffer. +fnbuf: ds 20h ;[jd] file name buffer +autorc: db 0 ;[obs] set to ON for autoreceive + +; Temporary data space. Sometimes accesses as 16 bits (eg temp1/2) +;** Temp 1 & 2 must be in order +lstchr: ;Last console input character. +temp1: ds 1 ;Temporary storage. +temp2: ds 1 +lincnt: ; used for counting lines in p20ln +temp3: ds 1 +temp4: ds 1 +temp5: ds 1 +temp6: ds 1 +temp7: ds 1 +temp8: ds 1 +temp9: ds 1 +temp10: ds 1 +temp11: ds 1 + + +getrxflg: + ds 1 ;[obs 22] +quietd: db 0 ;loud display during file transfers +argblk: ds 20H ;Used for subroutine arguments + +maxfil EQU 2 ; currently, only two names used. +fcbblk: ds maxfil*10H ;Used for a list of FCB's + +; [gnn] secondary filename storage (remote on send, local on get) +remnam: ds 60 ;[gnn] +remlen: ds 1 ;[gnn] length of name + +; Bookkeeping storage for multiple-sector buffering. The actual buffer +; is somewhere in the system-dependent overlay. (at the end, I hope). +nxtbuf: ds 2 ; Pointer to next sector +seccnt: ds 1 ; Number of sectors buffered +endsts: ds 1 ; Status for last read into buffer +; +; +; [MF] Storage for Remote Command processing +; +; +rdl: ds 1 ;[MF]Holds accumulated length of remote data +; +rcl: ds 1 ;[MF]Holds length of Remote command line arg +; +remdat: ds 95 ;[MF]Packet data buffer (plenty big) +; +rcom: ds 1 ;[MF] Remote Command type +; +rprmpt: dw 0 ;[MF]Address of prompt strings +; +rptr: dw 0 ;[MF]Remote command packet data pointer +; +rscode: ds 3 ;[MF]Holds Remote Set command ASCII code +; +; + org 7000h ; address for Kermit 4.11 +; ORG ($ + 0ffH) AND 0ff00H ; move to start of next page + +; +; hooks for system-dependent routines: +; This area is overwritten by the system-dependent overlay. +; +lnkflg: dw 0 ; linkage information for consistency check. +lnkent: dw 0 ; more of the same. +ovlver: dw 0 ; pointer to overlay's version string +family: dw 0 ;*NEW* [10] address of the family overlay (not CPSSYS) +; +; Input/output routines. Note that outmdm and outcon may actually be the +; same routine if selmdm and selcon do anything. (the same is true +; of inpmdm and inpcon). +; +selmdm: jmp $-$ ; select modem for I/O +outmdm: jmp $-$ ; output character in E to modem +inpmdm: jmp $-$ ; read character from modem. return character or 0 in A. +flsmdm: jmp $-$ ; flush pending input from modem +selcon: jmp $-$ ; select console for I/O +outcon: jmp $-$ ; output character in E to console +inpcon: jmp $-$ ; read char from console. return character or 0 in A +outlpt: jmp $-$ ; output character in E to printer +lptstat:jmp $-$ ;*NEW*[10] see if printer ready to print a character + ; If 0ffh then ok, if 0h then not ok. +extern: jmp $-$ ;*NEW for 4.09* If $-$ is not zero, then its a jump to + ; a routine to emulate any terminal type the user + ; wants to implement. +xbdos: jmp 0 ;*NEW* address of the bdos trap in this section + ; of code. It is filled in initialisation. +; +; screen formatting routines +clrlin: jmp $-$ ; erase current line +clrspc: jmp $-$ ; erase current position (after backspace) +delchr: jmp $-$ ; make delete look like backspace +clrtop: jmp $-$ ; erase screen and go home +; +; these routines are called to display a field on the screen. +scrend: jmp $-$ ; move to prompt field +screrr: jmp $-$ ; move to error message field +scrfln: jmp $-$ ; move to filename field +scrnp: jmp $-$ ; move to packet count field +scrnrt: jmp $-$ ; move to retry count field +scrst: jmp $-$ ; move to status field +rppos: jmp $-$ ; move to receive packet field (debug) +sppos: jmp $-$ ; move to send packet field (debug) +; +sysinit: jmp $-$ ; program initialization +sysexit: jmp $-$ ; program termination +syscon: jmp $-$ ; remote session initialization +syscls: jmp $-$ ; return to local command level +sysinh: jmp $-$ ; help text for interrupt (escape) extensions +sysint: jmp $-$ ; interrupt (escape) extensions, including break +sysflt: jmp $-$ ; filter for incoming characters. + ; called with character in E. +sysbye: jmp $-$ ; terminate remote session +sysspd: jmp $-$ ; baud rate change routine. + ; called with value from table in DE +sysprt: jmp $-$ ; port change routine. + ; called with value from table in HL +sysscr: jmp $-$ ; screen setup for file transfer + ; called with Kermit's version string in DE +csrpos: jmp $-$ ; move cursor to row B, column C +sysspc: jmp $-$ ; calculate free space for current disk +mover: jmp $-$ ; block move +prtstr: jmp $-$ ; *** NEW *** prtstr moved to overlay +; +; Data initialized by system-dependent overlay: +; +pttab: ds 2 ; points to local equivalents to VT52 escape sequences +spdtab: ds 2 ; address of baud rate command table, or zero +spdhlp: ds 2 ; address of baud rate help table, or zero +prttab: ds 2 ; address of port command table, or zero +prthlp: ds 2 ; address of port help table, or zero +timout: ds 2 ; Initial value for fuzzy timeout +vtflg: ds 1 ; VT52 emulation flag +escchr: ds 1 ; Storage for the escape character. +speed: ds 2 ; storage for the baud rate +port: ds 2 ; storage for port value +prnflg: ds 1 ;[hh] printer copy flag (overlay may need it) +dbgflg: ds 1 ; debugging flag +ecoflg: ds 1 ; Local echo flag (default off). +flwflg: ds 1 ; File warning flag (default on). +ibmflg: ds 1 ; IBM flag (default off). +cpmflg: ds 1 ; File mode flag (ascii/binary/default) +incflg: ds 1 ;[MF]Incomplete flag (keep/discard) + ;[MF](default discard) +parity: ds 1 ; Current parity. +spsiz: ds 1 ; Send packet size. +rpsiz: ds 1 ; Receive packet size. +stime: ds 1 ; Send time out. +rtime: ds 1 ; Receive time out. +spad: ds 1 ; Send padding. +rpad: ds 1 ; Receive padding. +spadch: ds 1 ; Send padding char. +rpadch: ds 1 ; Receive padding char. +seol: ds 1 ; Send EOL char. +reol: ds 1 ; Receive EOL char. +squote: ds 1 ; Send quote char. +rquote: ds 1 ; Receive quote char. +chktyp: ds 1 ; Checksum type desired +tacflg: ds 1 ; TACTrap flag (zero=off, nonzero=on; when non-zero, + ; contains current TAC intercept character) +tacchr: ds 1 ; TAC intercept character +bufadr: ds 2 ; Pointer to big buffer for multiple-sector I/O +bufsec: ds 1 ; Number of sectors big buffer can hold (0 means 256) +ffussy: ds 1 ; if nonzero, don't permit <>.,;?*[] in CP/M filespec. +; space used by directory command; here because space calculation is +; (operating) system-dependent +bmax: ds 2 ; highest block number on drive +bmask: ds 1 ; (records/block)-1 +bshiftf: ds 1 ; number of shifts to multiply by rec/block +nnams: ds 1 ; counter for filenames per line + +lnksiz equ $-lnkflg ; length of linkage section, for consistency check. + + END START diff --git a/cpsdef.asm b/cpsdef.asm index 46e3ba6..4cb4c10 100644 --- a/cpsdef.asm +++ b/cpsdef.asm @@ -1,287 +1,287 @@ -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains definitions used by both modules of Kermit. -; -; revision history: -; -;edit 9, 30-Nov-1990 by MF. Make "fairness" count "prfair" be 50 so -; console gets checked a bit more often. -; edit 8, 11-Sep-1990 by MF. Make default RECEIVE and SEND packet-size -; 80 (per Kermit standard) as packet size is adjustable in Version -; 4.10. -; edit 7 16-Jun-86 OBSchou. Added cmnum in the command opcodes. This gets a -; number from the user inot variable number. No checking on overflow. -; -; edit 6 13-May-86 OBSchou. BDOS calls trapped to check for console use -; as we want to substitute in commands from a TAKE file. Trapping -; means I dont have to go through an check ever BDOS call... -; -; edit 5: 22-Apr-86 by Bertil Schou, Loughborough University, UK -; moved some definitions from the CP4SYS.ASM file to here for -; Kermit version 4.06 -; -; edit 4: 6-Feb-85 by Charles Carvalho -; modify pcc007: replace ffussy assembly switch with runtime test. -; add "getvnm" - get CP/M version number. -; -; edit 3: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809 -; -;pcc007 2-Jan-85 vjc modules:cp4def,cp4cmd -; Cmifil is too fussy about what characters to accept in a -; filespec. My CP/M manual says any printable character is ok -; except <>.,;:?*[], and lower case. In practice, even those work -; sometimes. Kermit itself uses '&' if file warning is on, -; and then won't let you reference the file. Allow all -; printable characters except those above. Add conditional -; ffussy, so that if not ffussy, all special characters will be -; allowed, just convert lower to upper-case. -; -;pcc008 2-Jan-85 vjc modules:cp4def,cp4tt,cp4utl -; Keyboard input during CONNECT mode can get locked out if -; there is enough input from the modem port to keep prtchr -; busy. This can happen for example, if the printer is running -; at the same speed as the modem line, leaving you helpless to -; turn it off or abort the host. Add a fairness count, so that -; at least every prfair characters we look at console input. -; -; edit 2: July 10, 1984 (CJC) -; Remove defines for TRUE and FALSE, during reorganization for LASM -; compatibility. If we're using LASM, this file is linked by CP4KER -; or CP4TYP, and links to CP4MIT or CP4LNK. Also, push comments around -; a little. -; -; edit 1: May, 1984 (CJC) -; extracted from CPMBASE.M80 version 3.9; modifications are described -; in the accompanying .UPD file. -; - -;Symbolic Definitions for some ASCII characters -; -soh EQU 01O ;ASCII SOH (Control-A) -cntlc EQU 03O ;ASCII ETX (Control-C) -ctrlc EQU 03O ;ASCII ETX (Control-C) -bell EQU 07O ;ASCII BEL (Control-G) -bs EQU 10O ;ASCII backspace (Control-H) -tab EQU 11O ;ASCII Tab (Control-I) -lf EQU 12O ;ASCII Line Feed (CTRL-J) -ff EQU 14O ;ASCII Form Feed (CTRL-L) -cr EQU 15O ;ASCII Carriage Return (CTRL-M) -space EQU 20h ;ASCII Space -xon EQU 21O ;ASCII XON (Control-Q) -xoff EQU 23O ;ASCII XOFF (Control-S) -esc EQU 33O ;ASCII ESCape -semico EQU 3bh ;ASCII Semicolon -subt EQU 32O ;ASCII SUB (CTRL-Z) -cntlz EQU subt ;ASCII SUB (Control-z) [6] -ctrlz EQU subt ;ASCII SUB (Control-z) -del EQU 177O ;ASCII DELete (rubout) -; -;BDOS calls -IF NOT cpsker ;[6] If CPSKER is truem then system indep. stuff. We want - ;to trap BDOS calls and test for console activity -bdos EQU 0005H ;BDOS entry point, for the following functions: -ENDIF ;NOT cpsker [6] -; -;Function Name Function Input Parameters Output Parameter -;============= ======== ================ ================ -; (ALL Function Numbers are passed in Register C) -conin EQU 01H ;Read Console NONE ASCII Char in A -conout EQU 02H ;Write Console ASCII Char in E NONE -auxin EQU 03H ;Auxiliary input -rdrin EQU 03H ;Read Reader NONE ASCII Char in A -lstout EQU 05H ;Write List ASCII Char in E NONE -dconio EQU 06H ;Direct Con I/O ASCII Char in E I/O Status in A - ; if E=0FEH, - ; Input if E=0FFH -prstr EQU 09H ;Print String String-Address NONE - ; in DE (term=$) -rdstr EQU 0AH ;Read Buffer Buffer-Address Read Buffer filled -; in DE -; Read Buffer Byte Function -; 1 Maximum Buffer Length -; 2 Current Buffer Length (returned value) -; 3-n Data (returned values) -; -consta EQU 0BH ;Console Stat NONE LSB(A)=1 if char ready -getvnm EQU 0CH ;Version Number NONE H=0 (CP/M), L=BDOS ver -inbdos EQU 0DH ;Init BDOS NONE NONE -logdsk EQU 0EH ;LOG-In disk Value in E NONE - ; A=0,B=1,... -openf EQU 0FH ;Open File FCB-Addr in DE Byte Addr.of FCB, - ; or 0FFH if not -closf EQU 10H ;Close File FCB-Addr in DE Byte Addr.of FCB, - ; or 0FFH if not -sfirst EQU 11H ;Search File FCB-Addr in DE Byte Addr.of FCB(0-3), - ; or 0FFH if not -snext EQU 12H ;Search next FCB-Addr in DE Byte Addr.of next FCB, - ; or 0FFH if not -delf EQU 13H ;Delete File FCB-Addr in DE Byte Addr.of FCB(0-3), - ; or 0FFH if not -readf EQU 14H ;Read Record FCB-Addr in DE 0=successful read - ; 1=read past EOF - ; 2=reading random data -writef EQU 15H ;Write Record FCB-Addr in DE 0=successful write - ; 1=ERROR extending - ; 2=End of disk data - ; 255=No more DIR space -makef EQU 16H ;Make File FCB-Addr in DE 0-3= success, - ; 255= no more dir space -renam EQU 17H ;Rename File FCB-Addr in DE 0-3= success, - ; 255= file not found -rdlog EQU 18H ;Ret. Log Code NONE Login Vector in HL -rddrv EQU 19H ;Read Drive # NONE # of logged in drive in - ; (A=0,B=1,C=2....) -setdma EQU 1AH ;Set DMA Addr. Addr. of 128 NONE - ; byte buffer in DE -wrtprt EQU 1CH ;Write prot dsk NONE NONE -getrov EQU 1DH ;Get R/O Vect. NONE HL= R/O Vect. value -setfat EQU 1EH ;Set File Attr. FCB-Addr.in DE Dir. code in A -gtdpar EQU 1FH ;Get DSK par. NONE HL=DPB Address -usrcod EQU 20H ;Get/Set Usr.Cd E=0FFH (get) A=current code (get) - ; E-code (set) A=no value (set) -rrand EQU 21H ;Read Random FCB-Addr in DE A=Return code -wrand EQU 22H ;Write Random FCB-Addr in DE 1=read'g unwritten data - ; 2=(not used) - ; 3=can't close curr. ext - ; 4=seek to unwr. ext. - ; 5=dir overflow(write) - ; 6=seek past End of DSK -cflsz EQU 23H ;Comp File Sz. FCB Addr.in DE Rand.Rec.field set to - ; File size -setrar EQU 24H ;Set Rand. Rec. FCB-Addr.in DE Rand.Rec.field set - -; CPM 2 only: -punout EQU 04H ;Write Punch ASCII Char in E NONE -gtiob EQU 07H ;Get I/O status NONE I/O Status in A -ptiob EQU 08H ;Put I/O status I/O Status in E NONE -getalv EQU 1BH ;Get All.Vect. NONE All.Vect in HL - -; CPM 3 only: -auxout EQU 04H ;Auxiliary output -auxist EQU 07H ;Get AUXIN: status A=FF if character - ; ready, A=0 if none -auxost EQU 08H ;Get AUXOUT: status A=FF if ready, A=0 - ; if not ready -getfs EQU 2EH ;Get free space E=drive # rec free in dma addr -; -parevn EQU 00H ;Even parity. -parmrk EQU 03H ;Mark parity. -parnon EQU 06H ;No parity (eighth bit is data). -parodd EQU 09H ;Odd parity. -parspc EQU 0CH ;Space parity. - -defpar EQU parnon ;Default parity. -ibmpar EQU parmrk ;IBM COMTEN's parity. - -fcb EQU 5CH ;Location of File Control Block. -fcbext equ fcb+12 -fcbrno equ fcb+33 -buff EQU 80H ;Location of file output buffer (DMA). -bufsiz EQU 80H ;Size of DMA. - -maxfcb equ 64 ; maximum of 64 fcbs to be stored in multiple fcb bock - -maxpkt EQU '~'-' '+2O;Maximum size of a packet. -maxtry EQU 05O ; Number of retries on a packet. -imxtry EQU 20O ; Number of retries send initiate. -prfair EQU 50 ;[pcc008] Prtchr fairness count - -; opcodes for command parser -cmkey EQU 01H ;Parse a keyword. -cmifi EQU 02H ;Parse an input file spec (can be wild). -cmofi EQU 03H ;Parse an output file spec. -cmcfm EQU 04H ;Parse a confirm. -cmtxt EQU 05H ;Parse text. -cmnum EQU 06h ;Parse a number -cmifin EQU 10H ;Parse an input file spec (but no - ;Error output - -;[4] from CP4SYS.ASM -; -;========================================================================= -; I/O Byte assignments (2-bit fields for 4 devices at loc 3) -; -;bits 6+7 LIST field -; 0 LIST is Teletype device (TTY:) -; 1 LIST is CRT device (CRT:) -; 2 LIST is Lineprinter (LPT:) -; 3 LIST is user defined (UL1:) -; -;bits 4+5 PUNCH field -; 0 PUNCH is Teletype device (TTY:) -; 1 PUNCH is high speed punch (PUN:) -; 2 PUNCH is user defined #1 (UP1:) -; 3 PUNCH is user defined #2 (UP2:) -; -;bits 2+3 READER field -; 0 READER is Teletype device (TTY:) -; 1 READER is high speed reader (RDR:) -; 2 READER is user defined #1 (UR1:) -; 3 READER is user defined #2 (UR2:) -; -;bits 0+1 CONSOLE field -; 0 CONSOLE is console printer (TTY:) -; 1 CONSOLE is CRT device (CRT:) -; 2 CONSOLE is in Batch-mode (BAT:);READER = Input, -; LIST = Output -; 3 CONSOLE is user defined (UC1:) -; -;========================================================================= - -iobyte EQU 03H ;Location of I/O byte - -;[4] From CP4SYS.ASM -; -; -; -; Protocol parameters. Some of these can be changed with commands. -; - -drpsiz SET 50H ;Default receive packet size. (maximum is 5EH) -dspsiz SET 50H ;Default send packet size. (maximum is 5EH) -dstime SET 08H ;Default send time out interval. -drtime SET 05 ;Default receive time out interval - -dspad EQU 00H ;Default send padding. -drpad EQU 00H ;Default receive padding. -dspadc EQU 00H ;Default send padding char. -drpadc EQU 00H ;Default receive padding char. -dseol EQU CR ;Default send EOL char. -dreol EQU CR ;Default receive EOL char. -dsquot EQU '#' ;Default send quote char. -drquot EQU '#' ;Default receive quote char. -dschkt EQU '1' ;Default checksum type -; - -; Define VT or Terminal type values -vtdefo EQU 0 ;VT52 emulation by terminal itself. -vtdefv EQU 1 ;VT52 emulation by ttab tables in CPXVDU.ASM etc -vtdefd EQU 2 ;Dumb Terminal (Just prints) -vtdefe EQU 3 ;Termianl emulation done outside (in overlay) - - -; If this is being assembled by LASM, we need to LINK to one of two modules; -; if we're not using LASM, no problem. -; CPSKER.ASM defines "cpsker" TRUE, and CPXTYP.ASM defines it FALSE, so we can -; determine what's going on. -IF lasm AND cpsker ; building CP4KER with LASM? - LINK CPSMIT ; yes, chain to next piece. -ENDIF;lasm AND cpsker -IF lasm AND NOT cpsker ; LASM, but not building CP4KER? - LINK CPXLNK ; yes, chain to different piece. -ENDIF;lasm AND NOT cpsker +; KERMIT - (Celtic for "FREE") +; +; This is the CP/M-80 implementation of the Columbia University +; KERMIT file transfer protocol. +; +; Version 4.0 +; +; Copyright June 1981,1982,1983,1984,1985 +; Columbia University +; +; Originally written by Bill Catchings of the Columbia University Center for +; Computing Activities, 612 W. 115th St., New York, NY 10025. +; +; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, +; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many +; others. +; +; This file contains definitions used by both modules of Kermit. +; +; revision history: +; +;edit 9, 30-Nov-1990 by MF. Make "fairness" count "prfair" be 50 so +; console gets checked a bit more often. +; edit 8, 11-Sep-1990 by MF. Make default RECEIVE and SEND packet-size +; 80 (per Kermit standard) as packet size is adjustable in Version +; 4.10. +; edit 7 16-Jun-86 OBSchou. Added cmnum in the command opcodes. This gets a +; number from the user inot variable number. No checking on overflow. +; +; edit 6 13-May-86 OBSchou. BDOS calls trapped to check for console use +; as we want to substitute in commands from a TAKE file. Trapping +; means I dont have to go through an check ever BDOS call... +; +; edit 5: 22-Apr-86 by Bertil Schou, Loughborough University, UK +; moved some definitions from the CP4SYS.ASM file to here for +; Kermit version 4.06 +; +; edit 4: 6-Feb-85 by Charles Carvalho +; modify pcc007: replace ffussy assembly switch with runtime test. +; add "getvnm" - get CP/M version number. +; +; edit 3: 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809 +; +;pcc007 2-Jan-85 vjc modules:cp4def,cp4cmd +; Cmifil is too fussy about what characters to accept in a +; filespec. My CP/M manual says any printable character is ok +; except <>.,;:?*[], and lower case. In practice, even those work +; sometimes. Kermit itself uses '&' if file warning is on, +; and then won't let you reference the file. Allow all +; printable characters except those above. Add conditional +; ffussy, so that if not ffussy, all special characters will be +; allowed, just convert lower to upper-case. +; +;pcc008 2-Jan-85 vjc modules:cp4def,cp4tt,cp4utl +; Keyboard input during CONNECT mode can get locked out if +; there is enough input from the modem port to keep prtchr +; busy. This can happen for example, if the printer is running +; at the same speed as the modem line, leaving you helpless to +; turn it off or abort the host. Add a fairness count, so that +; at least every prfair characters we look at console input. +; +; edit 2: July 10, 1984 (CJC) +; Remove defines for TRUE and FALSE, during reorganization for LASM +; compatibility. If we're using LASM, this file is linked by CP4KER +; or CP4TYP, and links to CP4MIT or CP4LNK. Also, push comments around +; a little. +; +; edit 1: May, 1984 (CJC) +; extracted from CPMBASE.M80 version 3.9; modifications are described +; in the accompanying .UPD file. +; + +;Symbolic Definitions for some ASCII characters +; +soh EQU 01O ;ASCII SOH (Control-A) +cntlc EQU 03O ;ASCII ETX (Control-C) +ctrlc EQU 03O ;ASCII ETX (Control-C) +bell EQU 07O ;ASCII BEL (Control-G) +bs EQU 10O ;ASCII backspace (Control-H) +tab EQU 11O ;ASCII Tab (Control-I) +lf EQU 12O ;ASCII Line Feed (CTRL-J) +ff EQU 14O ;ASCII Form Feed (CTRL-L) +cr EQU 15O ;ASCII Carriage Return (CTRL-M) +space EQU 20h ;ASCII Space +xon EQU 21O ;ASCII XON (Control-Q) +xoff EQU 23O ;ASCII XOFF (Control-S) +esc EQU 33O ;ASCII ESCape +semico EQU 3bh ;ASCII Semicolon +subt EQU 32O ;ASCII SUB (CTRL-Z) +cntlz EQU subt ;ASCII SUB (Control-z) [6] +ctrlz EQU subt ;ASCII SUB (Control-z) +del EQU 177O ;ASCII DELete (rubout) +; +;BDOS calls +IF NOT cpsker ;[6] If CPSKER is truem then system indep. stuff. We want + ;to trap BDOS calls and test for console activity +bdos EQU 0005H ;BDOS entry point, for the following functions: +ENDIF ;NOT cpsker [6] +; +;Function Name Function Input Parameters Output Parameter +;============= ======== ================ ================ +; (ALL Function Numbers are passed in Register C) +conin EQU 01H ;Read Console NONE ASCII Char in A +conout EQU 02H ;Write Console ASCII Char in E NONE +auxin EQU 03H ;Auxiliary input +rdrin EQU 03H ;Read Reader NONE ASCII Char in A +lstout EQU 05H ;Write List ASCII Char in E NONE +dconio EQU 06H ;Direct Con I/O ASCII Char in E I/O Status in A + ; if E=0FEH, + ; Input if E=0FFH +prstr EQU 09H ;Print String String-Address NONE + ; in DE (term=$) +rdstr EQU 0AH ;Read Buffer Buffer-Address Read Buffer filled +; in DE +; Read Buffer Byte Function +; 1 Maximum Buffer Length +; 2 Current Buffer Length (returned value) +; 3-n Data (returned values) +; +consta EQU 0BH ;Console Stat NONE LSB(A)=1 if char ready +getvnm EQU 0CH ;Version Number NONE H=0 (CP/M), L=BDOS ver +inbdos EQU 0DH ;Init BDOS NONE NONE +logdsk EQU 0EH ;LOG-In disk Value in E NONE + ; A=0,B=1,... +openf EQU 0FH ;Open File FCB-Addr in DE Byte Addr.of FCB, + ; or 0FFH if not +closf EQU 10H ;Close File FCB-Addr in DE Byte Addr.of FCB, + ; or 0FFH if not +sfirst EQU 11H ;Search File FCB-Addr in DE Byte Addr.of FCB(0-3), + ; or 0FFH if not +snext EQU 12H ;Search next FCB-Addr in DE Byte Addr.of next FCB, + ; or 0FFH if not +delf EQU 13H ;Delete File FCB-Addr in DE Byte Addr.of FCB(0-3), + ; or 0FFH if not +readf EQU 14H ;Read Record FCB-Addr in DE 0=successful read + ; 1=read past EOF + ; 2=reading random data +writef EQU 15H ;Write Record FCB-Addr in DE 0=successful write + ; 1=ERROR extending + ; 2=End of disk data + ; 255=No more DIR space +makef EQU 16H ;Make File FCB-Addr in DE 0-3= success, + ; 255= no more dir space +renam EQU 17H ;Rename File FCB-Addr in DE 0-3= success, + ; 255= file not found +rdlog EQU 18H ;Ret. Log Code NONE Login Vector in HL +rddrv EQU 19H ;Read Drive # NONE # of logged in drive in + ; (A=0,B=1,C=2....) +setdma EQU 1AH ;Set DMA Addr. Addr. of 128 NONE + ; byte buffer in DE +wrtprt EQU 1CH ;Write prot dsk NONE NONE +getrov EQU 1DH ;Get R/O Vect. NONE HL= R/O Vect. value +setfat EQU 1EH ;Set File Attr. FCB-Addr.in DE Dir. code in A +gtdpar EQU 1FH ;Get DSK par. NONE HL=DPB Address +usrcod EQU 20H ;Get/Set Usr.Cd E=0FFH (get) A=current code (get) + ; E-code (set) A=no value (set) +rrand EQU 21H ;Read Random FCB-Addr in DE A=Return code +wrand EQU 22H ;Write Random FCB-Addr in DE 1=read'g unwritten data + ; 2=(not used) + ; 3=can't close curr. ext + ; 4=seek to unwr. ext. + ; 5=dir overflow(write) + ; 6=seek past End of DSK +cflsz EQU 23H ;Comp File Sz. FCB Addr.in DE Rand.Rec.field set to + ; File size +setrar EQU 24H ;Set Rand. Rec. FCB-Addr.in DE Rand.Rec.field set + +; CPM 2 only: +punout EQU 04H ;Write Punch ASCII Char in E NONE +gtiob EQU 07H ;Get I/O status NONE I/O Status in A +ptiob EQU 08H ;Put I/O status I/O Status in E NONE +getalv EQU 1BH ;Get All.Vect. NONE All.Vect in HL + +; CPM 3 only: +auxout EQU 04H ;Auxiliary output +auxist EQU 07H ;Get AUXIN: status A=FF if character + ; ready, A=0 if none +auxost EQU 08H ;Get AUXOUT: status A=FF if ready, A=0 + ; if not ready +getfs EQU 2EH ;Get free space E=drive # rec free in dma addr +; +parevn EQU 00H ;Even parity. +parmrk EQU 03H ;Mark parity. +parnon EQU 06H ;No parity (eighth bit is data). +parodd EQU 09H ;Odd parity. +parspc EQU 0CH ;Space parity. + +defpar EQU parnon ;Default parity. +ibmpar EQU parmrk ;IBM COMTEN's parity. + +fcb EQU 5CH ;Location of File Control Block. +fcbext equ fcb+12 +fcbrno equ fcb+33 +buff EQU 80H ;Location of file output buffer (DMA). +bufsiz EQU 80H ;Size of DMA. + +maxfcb equ 64 ; maximum of 64 fcbs to be stored in multiple fcb bock + +maxpkt EQU '~'-' '+2O;Maximum size of a packet. +maxtry EQU 05O ; Number of retries on a packet. +imxtry EQU 20O ; Number of retries send initiate. +prfair EQU 50 ;[pcc008] Prtchr fairness count + +; opcodes for command parser +cmkey EQU 01H ;Parse a keyword. +cmifi EQU 02H ;Parse an input file spec (can be wild). +cmofi EQU 03H ;Parse an output file spec. +cmcfm EQU 04H ;Parse a confirm. +cmtxt EQU 05H ;Parse text. +cmnum EQU 06h ;Parse a number +cmifin EQU 10H ;Parse an input file spec (but no + ;Error output + +;[4] from CP4SYS.ASM +; +;========================================================================= +; I/O Byte assignments (2-bit fields for 4 devices at loc 3) +; +;bits 6+7 LIST field +; 0 LIST is Teletype device (TTY:) +; 1 LIST is CRT device (CRT:) +; 2 LIST is Lineprinter (LPT:) +; 3 LIST is user defined (UL1:) +; +;bits 4+5 PUNCH field +; 0 PUNCH is Teletype device (TTY:) +; 1 PUNCH is high speed punch (PUN:) +; 2 PUNCH is user defined #1 (UP1:) +; 3 PUNCH is user defined #2 (UP2:) +; +;bits 2+3 READER field +; 0 READER is Teletype device (TTY:) +; 1 READER is high speed reader (RDR:) +; 2 READER is user defined #1 (UR1:) +; 3 READER is user defined #2 (UR2:) +; +;bits 0+1 CONSOLE field +; 0 CONSOLE is console printer (TTY:) +; 1 CONSOLE is CRT device (CRT:) +; 2 CONSOLE is in Batch-mode (BAT:);READER = Input, +; LIST = Output +; 3 CONSOLE is user defined (UC1:) +; +;========================================================================= + +iobyte EQU 03H ;Location of I/O byte + +;[4] From CP4SYS.ASM +; +; +; +; Protocol parameters. Some of these can be changed with commands. +; + +drpsiz SET 50H ;Default receive packet size. (maximum is 5EH) +dspsiz SET 50H ;Default send packet size. (maximum is 5EH) +dstime SET 08H ;Default send time out interval. +drtime SET 05 ;Default receive time out interval + +dspad EQU 00H ;Default send padding. +drpad EQU 00H ;Default receive padding. +dspadc EQU 00H ;Default send padding char. +drpadc EQU 00H ;Default receive padding char. +dseol EQU CR ;Default send EOL char. +dreol EQU CR ;Default receive EOL char. +dsquot EQU '#' ;Default send quote char. +drquot EQU '#' ;Default receive quote char. +dschkt EQU '1' ;Default checksum type +; + +; Define VT or Terminal type values +vtdefo EQU 0 ;VT52 emulation by terminal itself. +vtdefv EQU 1 ;VT52 emulation by ttab tables in CPXVDU.ASM etc +vtdefd EQU 2 ;Dumb Terminal (Just prints) +vtdefe EQU 3 ;Termianl emulation done outside (in overlay) + + +; If this is being assembled by LASM, we need to LINK to one of two modules; +; if we're not using LASM, no problem. +; CPSKER.ASM defines "cpsker" TRUE, and CPXTYP.ASM defines it FALSE, so we can +; determine what's going on. +IF lasm AND cpsker ; building CP4KER with LASM? + LINK CPSMIT ; yes, chain to next piece. +ENDIF;lasm AND cpsker +IF lasm AND NOT cpsker ; LASM, but not building CP4KER? + LINK CPXLNK ; yes, chain to different piece. +ENDIF;lasm AND NOT cpsker diff --git a/cpsker.asm b/cpsker.asm index 254d056..b3d4831 100644 --- a/cpsker.asm +++ b/cpsker.asm @@ -1,315 +1,315 @@ -; CPSKER.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; -; This is the header for the system-independent portion of KERMIT, which -; consists of the following files (in this order): -; -; CPSKER.ASM - this file -; CPSDEF.ASM - definitions for both KERMIT and KERSYS -; CPSMIT.ASM - \initialization, main loop, miscellaneous commands -; CPSCOM.ASM - /(BYE, EXIT, LOG, SET, SHOW, and STATUS) (Part1 of 2) -; CPSPK1.ASM - \the KERMIT protocol handler (SEND, RECEIVE, LOGOUT, -; CPSPK2.ASM - / and FINISH commands) (In two parts) -; CPSREM.ASM - REMOTE commands etc -; CPSSER.ASM - SERVER commands etc (Empty as yet) -; CPSTT.ASM - the transparent commands (TRANSMIT, CONNECT) -; CPSCPM.ASM - CP/M commands (DIR, ERA) -; CPSWLD.ASM - the wildcard handler -; CPSCMD.ASM - the command parser -; CPSUTL.ASM - utility routines -; CPSDAT.ASM - Data space and the overlay link space -; -; When building the system-independent part with M80 or MAC80, CPSKER -; INCLUDEs the other files; when building with LASM, each file LINKs to -; the next file. -; -; For now, the system-dependent routines are all in CPSSYS.ASM, with -; the actual configuration defined in CPSTYP.ASM. -; -; revision history (latest first): -; -; Begin CP/M Kermit-80 version 4.11. -;edit 32, 1-Apr-1991 by MF. Official release of work to date as CP/M Kermit -; (Kermit-80) Version 4.11. -; Modified edit level of cpscpm.asm to reflect a bug fix for the TYPE -; command introduced with edit 13. -;edit 31, 29-Mar-1991 by MF. Modified edit levels of cpsker.asm, -; cpscom.asm and cpsdat.asm to reflect rename of parameter vermin to -; revno (revision level) and change of SET COLLISION REPLACE to -; SET COLLISION OVERWRITE to conform with C-Kermit. Modified -; edit level of cpsrem.asm to reflect change from REMOTE SET FILE -; COLLISION REPLACE to REMOTE SET FILE COLLISION OVERWRITE. -; Modified edit level of cpsutl.asm to reflect code tightening and -; edit levels of cpsmit.asm and cpspk2.asm to close any open TAKE-file -; and abort take-file processing if ^C is typed from the console -; Also corrected ^Z test in cpsmit.asm in INPUT command ("inp2b") -; Implement "file not found" complaint if a TAKE command can't find -; the TAKE-file and it's not the initial TAKE (KERMIT.INI) -; Modified edit level of cpscpm.asm to reflect modification of the -; TYPE and PRINT commands to cancel file typeout/printout completely -; if ^C is entered on the console (either immediately or after a key -; has been pressed to induce a pause) and to immediately begin -; typeout/printout of the next file (if the filespec was wild-carded) -; if ^X is entered (either immediately or after a key has been pressed -; to induce a pause). -; Modified edit levels of cpsmit.asm and cpscom.asm to reflect addition -; of the STAY command as a synonym for SET NO-EXIT. -;edit 30, 27-Feb-1991 by MF. Modified edit levels of cpscom.asm, -; cpsmit.asm, cpsutl.asm and cpsdat.asm to reflect provision for -; a "revision level" field (1-26=A-Z), addition of QUIT as a synonym -; for the EXIT command, recognition of C, R and S as abbreviations -; for the CONNECT, RECEIVE and SEND commands, respectively, display -; of Kermit version in the VERSION command and a fix to the TAKE-file -; input routine "r1tchr" to prevent semicolons from being interpreted -; as command separators during TAKE-file execution. This last fix -; allows such commands as REMOTE DELETE *.*;* to Kermit-32 to -; operate as expected. -;edit 29, 14-Feb-1991 by MF. Updated edit levels of cpscom.asm, -; cpscpm.asm, cpsdat.asm and cpsrem.asm to reflect bug fixes, -; code tightening and simplified routine "remcli" (in cpsrem.asm) -; which gets text to be passed on to a remote Kermit in REMOTE -; Kermit commands. -;edit 28, 8-Feb-1991 by MF. Changed edit level of cpscpm.asm to reflect -; a bug fix to make TAKE-files work properly with commands such as -; INPUT which check the keyboard for input. -;edit 27, 30-Jan-1991 by MF. Changed edit levels of cpscpm.asm, cpsrem.asm, -; cpstt.asm and cpsutl.asm to reflect bug fixes and enhancements -;edit 26, 17-Jan-1991 by MF. Changed edit level of cpscmd.asm to -; reflect fixes to allow leading spaces/tabs to be ignored when -; parsing keywords (this was the intent but the code never worked -; correctly) and to blank the entire fcb in "cmifil" to allow successive -; COPY commands to function properly. Also changed edit level of -; cpspk1.asm to reflect further work on "disk full" error reporting. -;edit 25, 14-Jan-1991 by MF. Incremented edit level of cpspk1.asm to -; reflect bug fix to "disk full" error reporting code so -; 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 +; is not sent directly to the Remote Kermit. This per a report from +; Russell Lang of Australia's Monash University. +;edit 24, 10-Jan-1991 by MF. Modified edit level of cpxtyp.asm to +; reflect addition of "terminal required" message for some. +; machines. +;edit 23, 7-Jan-1991 by MF. Modified edit levels of cpxtyp.asm, cpxswt.asm, +; cpxbbi.asm to reflect addition of Ampro Little Board support. +;edit 22, 3-Jan-1991 by MF. Incremented edit levels of cpspk1.asm/cpspk2.asm +; to reflect further mods to "sdata" and "inchr" routines. +;edit 21, 2-Jan-1991 by MF. Incremented edit level of cpspk1.asm to reflect +; code cleanup in "sdata" routine. +;edit 20, 26-Dec-1990 by MF. Modified edit level of CPSCMD.ASM to reflect +; fix to allow leading white space to be skipped in lines from +; TAKE-files as well as from the CP/M command-line tail; this per a +; phoned-in bug-report to Dr. Martin J. Carter of Nottingham +; University in the U.K. (PPZMAJOC@vax.ccc.nottingham.ac.uk) +;edit 19, 14-Dec-1990 by MF. Modified edit level of cpspk2.asm to reflect +; modification to "gofil" to allow drive specifications in 2nd +; filename of GET and RECEIVE commands; also modified edit levels of +; cpspk1.asm and cpsrem.asm to reflect addition of "<<>>" around +; "X" or "F" packets coming as a reply to a REMOTE command and +; deletion of an unnecessary instruction before label remc2d +; in cpsrem.asm. +;edit 18, 9-Dec-1990 by MF. Modified edit levels for Version 4.10 +; yet another time to reflect changes in CPSDAT.ASM to clarify +; "File size on DIR" status message. +;edit 17, 4-Dec-1990 by MF. Adjusted edit levels of cpscom.asm/cpsdat.asm +; to reflect addition of Autoreceive status to SHOW/STATUS display. +;edit 16, 30-Nov-1990 by MF. Adjusted edit levels of cpscom.asm/cpsdat.asm +; to reflect fix to SHOW/STATUS routines to show terminal display +; mode (quiet/regular). Also adjusted edit level of cpsutl.asm to reflect +; change to routine "p20ln" to use "pausit" to save code space. +; Adjusted edit level of cpsdef.asm to reflect change in "fairness" +; counter prfair from 100 to 50 to make terminal a bit more responsive +; during CONNECTs. +;edit 15, 27-Nov-1990 by MF. Adjusted edit level of cpspk1.asm to reflect +; a bug fix. +;edit 14, 27-Nov-1990 by MF. Again adjusted edit level of cpspk1.asm to +; reflect modifications of "disk-full"and SET INCOMPLETE-FILES behavior. +;edit 13, 23 Nov-1990 by MF. Adjusted edit level of cpspk1.asm to reflect +; code changes for "disk full" processing. +;edit 12, 8-Nov-1990 by MF. +; Adjusted edit levels shown for cpscom.asm/cpspk1.asm/cpsdat.asm to +; reflect bug fixes and code revisions. +;edit 11, 5-Nov-1990 by MF. +; Cosmetic changes for main help text for COPY and RENAME commands. +; Begin CP/M Kermit-80 version 4.10. +;edit 10, 2-Nov-1990 by MF. Moved Overlay address to 7000H (cpsdat.asm). +;edit 9, 1-Nov-1990 by Mike Freeman (BPA). Cosmetic changes (command-name +; changes: SET BAUD-RATE==>SET SPEED, FCOPY==>COPY, FRENAME==>RENAME, +; STRING==>OUTPUT, REMOTE CWD==>REMOTE CD per suggestions of FDC +; to aid in uniformity of nomenclature for various Kermits. +;edit 8, 30-Oct-1990 by Michael Freeman; 301 N.E. 107th Street; +; Vancouver, WA 98685 USA; Telephone (206)574-8221. +; Work: Bonneville Power Administration +; P.O. Box 491 M/S MORF +; Vancouver, WA USA 98666 +; Telephone (206)690-2307 +; Implemented FRENAME command to rename a CP/M file. +; Implemented many Remote commands, variable-length packets up thru +; 94 characters in length. Fixed a bug in CPSCOM.ASM in the +; routine "getnp" and a bug in CPSCOM.ASM which caused garbage to appear +; on the screen when PRTSTR was called with QUIETD flag set. +; Modified code in module CPSCMD.ASM to skip leading spaces and tabs +; when getting Kermit commands from the CP/M command line. This also +; obviates the necessity to type a leading semicolon to separate the +; Kermit command from the Kermit commands on the CP/M command line. +; Fixed code in CPSPK2.ASM which handles file collision detection +; and resulting file rename per my entries in CPKERM.BWR. +; and included fix by Russell Lang of Dept. of Electrical and Computer +; Engineering, Monash University, Australia, to prevent renamed +; files with SET WARNING ON from having the attributes (e.g., R/O) +; copied from original file. Mr. Lang's E-mail address is: +; Russell Lang Email: rjl@monu1.cc.monash.edu.au Phone: (03) 565 3460 +; Department of Electrical and Computer Systems Engineering +; Monash University, Australia +; Also fixed a bug in CPSPK2.ASM which prevented completion messages +; from being displayed if terminal was set to QUIET. +; Implemented most proposed SET FILE-COLLISION (COLLISION) commands. +; Implemented SET INCOMPLETE file disposition command. +; Implemented a few of the proposed REMOTE SET commands. +; Implemented other fixes suggested in CPKERM.BWR. +; Moved overlay address to 6C00H. +; Changed location of .printx in this file so LASM doesn't complain. +; In system-dependent modules, included HP-125 support. +; Also modified Telcon Zorba code in CPXHEA.ASM to enable setting +; of baud-rates and sending of a break. +; Included Russell Lang of Monash Univ. Australia's implementation +; for the Microbee series of computers (CPXBEE.ASM). +; Fixed COMPUPRO version of Kermit to compile correctly and to +; conform to current syntax for setting baud-rate. +; edit 7, September, 1987. Added files for SERVER and REMOTE +; modules (CPSSER/CPSREM). SERVER is still empty, and may be +; only wishfull thinking. I have ideas, but I dont think I +; will have the time to implement it. +; +; edit 6: 30 March, 1987 by OBSchou. Start Kermit-80 V4.09 with the +; overlay address at 6000h. Also adjusted the INCLUDEs to allow +; M80 to assmeble these files. +; +; edit 5: 20 June, 1986. Have added so much code etc that the overlay had to +; be moved again.. give it to 5000h. This starts off Kermit-80 V4.08 +; +; edit 4 22 April 1986 +; Start work on 4.06. This should clear up a couple of bugs, add in +; a few features, and split the system dependent stuff into +; smaller units. +; +; edit 3a 7 March 86 OBSchou Loughborough england. Minor additions +; to cpsker.asm, cpscmd.asm and cpspkt.asm. +; +; edit 3: February 10, 1985 (CJC) +; Update for v4.05; add "verno" so CPSUTL doesn't have to change +; just because some other module did. +; +; edit 2: September 10, 1984 (CJC) +; Update for v4.03. +; +; edit 1: July 27, 1984 (CJC) +; Created to allow assembly of Kermit by LASM as well as MAC80 and M80. + +verno EQU 11 ; minor version number +revno EQU 0 ;[MF]Revision level + ;[MF]0-26 yields A-Z + +; Version 4.10 of Kermit consists of the following edit levels: +; cpsker.asm edit 32 +; cpsdef.asm edit 9 +; cpsmit.asm edit 30 +; cpscom.asm edit 13 +; cpspk1.asm edit 23 +; cpspk2.asm edit 11 +; cpsrem.asm edit 13 +; cpsser.asm edit 1 +; cpstt.asm edit 12 +; cpscpm.asm edit 14 +; cpswld.asm edit 4 +; cpscmd.asm edit 13 +; cpsutl.asm edit 30 +; cpsdat.asm edit 19 +; cpxlnk.asm edit 8 (cpslnk.asm is not assembled with cpsker, but it +; defines the linkage area expected by cpsker, and so must +; match the description in cpsutl.asm) +; cpxswt.asm edit 10 +; +; Version 4.10 of Kermit has been tested with the following edit levels of +; the system-dependent files: +; cpxtyp.asm edit 34 +; cpxsys.asm edit 40 +; cpxhea.asm edit 4 +; cpxtor.asm edit 4 +; cpxbbi.asm edit 4 (Ampro Little Board) +; +; Version 4.10 of Kermit is still to be tested fully against all known systems +; so far included in the system dependent overlays. +; + + +FALSE equ 0 +TRUE equ NOT FALSE + +cpsker equ TRUE ; building system-independent part +debug equ FALSE ; set false for running system. True => does some + ; unusual or unexpected things. +; +; Assembler type. Define the appropriate one TRUE, the rest FALSE. (We can't +; use ASM, because it cannot handle multiple input files) +mac80 EQU FALSE ; For assembly via MAC80 cross-assembler. +m80 EQU false ; For assembly via Microsoft's M80. +lasm EQU true ; For assembly via LASM, a public-domain + ; assembler. +; +; Get the other modules... + +IF lasm ; If we're linking, go on to the next file. + LINK CPSDEF +ENDIF;lasm + +; If we're still here, we must be using M80 or MAC80. M80 doesn't +; like ENDs inside conditionals, but the END statement has to be +; in CPSUTL for LASM (otherwise, we'd need a file containing just an +; END statement). So, we leave off the IF m80 OR mac80 conditional +; that ought to be around these INCLUDEs. No problem until the next +; incompatible assembler comes along... +; Let's first say where we are: +; +.printx * CPSKER.ASM (or nearest offer) * +; +.printx * CPSDEF.ASM * + INCLUDE CPSDEF.ASM ; definitions +.printx * CPSMIT.ASM * + INCLUDE CPSMIT.ASM ; initialization, main loop, some commands +.printx * CPSCOM.ASM * + INCLUDE CPSCOM.ASM ; part of command/status/set etc +.printx * CPSPK1.ASM * + INCLUDE CPSPK1.ASM ; KERMIT protocol handler (Part 1) +.printx * CPSPK2.ASM * + INCLUDE CPSPK2.ASM ; KERMIT protocol handler (Part 2) +.printx * CPSREM.ASM * + INCLUDE CPSREM.ASM ; Kermit REMOTE code (little in it, as yet) +.printx * CPSSER.ASM * + INCLUDE CPSSER.ASM ; Kermit SERVER code (As yet, empty) +.printx * CPSTT.ASM * + INCLUDE CPSTT.ASM ; transparent communication handler +.printx * CPSCPM.ASM * + INCLUDE CPSCPM.ASM ; CP/M command support (DIR, ERA) +.printx * CPSWLD.ASM * + INCLUDE CPSWLD.ASM ; wildcard handler +.printx * CPSCMD.ASM * + INCLUDE CPSCMD.ASM ; command parser +.printx * CPSUTL.ASM * + INCLUDE CPSUTL.ASM ; Various utilities and data, and END [ToadHall] +.printx * CPSDAT.ASM * + INCLUDE CPSDAT.ASM + END ; MAC80 ignores END's in included files... diff --git a/cpsmit.asm b/cpsmit.asm index f41ee70..1bf6a58 100644 --- a/cpsmit.asm +++ b/cpsmit.asm @@ -1,834 +1,834 @@ -; CPSMIT.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the system-independent initialization, the main -; loop, and the commands that don't have any place better to go. -; All the SET xxx and status routines now in CPSCOM.ASM as CPSMIT.ASM -; was getting too big. -; -; revision history: -; -;edit 30, 29-Mar-1991 by MF. When looking up a TAKE-file in a TAKE command -; and the file is not found, complain if it's not the first TAKE of -; the current program execution (the automatic TAKE of KERMIT.INI) -;edit 29, 25-Mar-1991 by MF. Add STAY command as a synonym for SET NO-EXIT -; command per Martin J. Carter of Nottingham University in the U.K. -;edit 28, 21-Mar-1991 by MF. Modify code after "inp2a" in INPUT command -; so a ^C will halt TAKE-file processing -;edit 27, 27-Feb-1991 by MF. Add QUIT as a synonym for EXIT per code of -; Dr. Martin J. Carter of Nottingham University, U.K. Recognizing QUIT -; helps those who forget they're not in MS-Kermit, C-Kermit, -; Kermit-32 etc. Also add commands so that CONNECT, RECEIVE and SEND may -; be abbreviated to C, R and S, respectively. -;edit 26, 5-Nov-1990 by MF. Cosmetic changes to main HELP messages for -; COPY and RENAME commands. -;edit 25, 1-Nov-1990 by MF. Made the following command-name changes in the -; interest of uniformity of nomenclature (per suggestions of FDC): -; FCOPY to COPY, FRENAME to RENAME and STRING to OUTPUT. -; This means we'll have to type "CO" for CONNECT and "REC" for -; RECEIVE but with REMOTE now with us we have to do the latter anyway. -;edit 24, 18-Sep-1990 by MF. Implemented FRENAME command to rename a -; CP/M file. -;edit 23, 9-Sep-1990 by MF. Implemented commands to be sent to a -; remote Kermit Server (Remote commands). -; Implemented setting of packet sizes for RECEIVE and SEND. -; Put DIRECTORY/STRING help texts in proper alphabetical position. -; edit 22, July 6th, 1987 by OBSchou. Added a dummy Commandline to be -; loaded for debugging purposes as DDT destroys any command line at 80H -; Also fixed a bug or two... -; -; edit 21, April 8th, 1987. -; Various bits, including more SET SENDRECEIVE options, and make -; PADDING and PADCHAR valid options. Have I wasted my time, or -; there still systems that use padding?? Fixed a bug in the INPUT -; command so we know how many characters there are to check for. Also -; hived off the SET commands to make a new file, CPSCOM.ASM thereby -; reducing the size of CPSMIT.ASM. Also rename COPY command to FCOPY -; hence retaining a single C to imply connect. -; -; edit 20, March 30, 1987 by OBSchou. -; added code for no exit to CPM if a command tail is done (optional) -; by the SET NO-EXIT command. Added bits for SET AUTORECEIVE to enable -; or inhibit automatic receive of several files (if something is coming -; along from the remote side, do a receive. Toss first packet away.) -; This is first step to SERVER??? -; Also added back the INPUT command. -; -; edit 19, March 16, 1987. Moved the code to check for and execute -; command tails (See Richard Russells submission below). -; Added flags to exit to CP/M after executing a command tail. -; The KERMIT.INI file is taken before the command tail is issued. -; -; edit 18, March 11, 1987 by OBSchou. -; Added in code for TYPE and PRINT . 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 Q to suspend logging and R to -; resume. 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 ". 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 and PRINT . 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 Q to suspend logging and R to +; resume. 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 ". Save both bytes of baud +; rate in speed, and check both bytes when displaying baud rate. Move +; header info to CP4KER.ASM. Add onoff and chkkey routines to simplify +; SET command (Toad Hall) +; +; edit 2: June 8, 1984 +; formatting and documentation; delete unreferenced variables and some +; unnecessary labels; move setpar here from cp4pkt; add module version +; string; make this version 4.01. +; +; edit 1: May, 1984 +; extracted from CPMBASE.M80 version 3.9; modifications are described +; in the accompanying .UPD file. + +; + ASEG + ORG 100H + +; The CCP invokes programs with a CALL 100H, with the stack pointer set to +; 100H. When we exit to CP/M, we do so with a RET, avoiding a warm boot. +; Unfortunately, DDT starts programs with a jump, not a call, so when we +; attempt to return to CP/M, we blow the stack and use the word at 100H as +; the new PC. Put a 0 there so we reboot instead of dying horribly. +; (Fortunately, this happens to be two NOP's). + dw 0 + jmp start ; Bypass entry section + +; +; Entry section for system-independent part. This contains +; jumps to routines needed by the system support module. +; +entries: + jmp kermit ; reentry address + jmp nout ; output HL in decimal +entsiz equ $-entries ; length of entry section +; +; End of entry section. As a consistency check, the expected +; length of this section is stored by the system-dependent +; module in the linkage section at the end of Kermit, and +; tested at initialization. + +mitver: db 'CPSMIT.ASM (30) 29-Mar-1991$' ; name, edit number, date +; +; +; Initialization +; +start: lxi h,0 ; Clear out hl pair + dad sp ; and fetch the system stack pointer + shld oldsp ; and save for later restoral + lxi sp,stack ; move in our own stack. + lxi d,version ; print Kermit version + call prtstx ; before we do too much (Use fudged prtstr) + mvi c,rddrv ;Get our logged in drive + call BDOS + inr a ;relative 1 + sta CURDSK ;and save it for later + + lda vtflg ; [OBS] Hangover from VT52 ems not possible... + cpi 0ffh ; ... if 0ff stored, assume terminal = off + mvi a,vtdefo + jnz start0 + sta vtflg ; if 0ffh make it VT52 off +start0: + + +IF debug +;vvvvvvvvvvvvvvvv remove this for run time +; OBS edit 22 - add in a dummy command line to 80H + lxi h,dcomln ;[22] load up dummy command line + lxi d,81h ;[22] where to put it + lxi b,endcoml-dcomln + mov a,c ; get length to a + sta 80h ; ... and save as command line length + call mover ; ... and save rest of line + jmp starta +dcomln: db 'set baud 4800',semico + db 'set dir on',semico + db 'dir' + db 0,0 ; just to make up space +endcoml: +;^^^^^^^^^^^^^^^^ remove this for run time +ENDIF ;debug + + +starta: +; +; Make sure the overlay is in place... +; + lhld lnkflg + mov a,h + ora l ; if lnkflg is still zero, + jz start1 ; the configuration overlay is missing. + lxi d,-lnksiz ; if it's not equal to lnksiz, + dad d ; we've probably got the wrong + mov a,h ; version of the configuration overlay. + ora l + jnz start2 + lhld lnkent ; make sure the overlay knows how long + lxi d,-entsiz ; our entry section is, so they don't miss. + dad d + mov a,h + ora l + jnz start2 + ; might be ok. + lxi h,bdos ; set xbdos address to bdos trap in our code. + shld xbdos+1 ; (they may never use it...) + call sysinit ; do system-dependent initialization + lda bufsec ; get the max no of buffers allowed by system + sta maxbsc ; save for SET BUFFER use to compare + lxi d,inms26 ; offer some advice on getting help + call prtstr + lxi h,buff ;[19] we copy any potential command tail across + lxi d,cbuff + lxi b,80h ;[19] copy all 128 bytes. May use none. + call mover + lda 80h ; see if there is a command tail... + + ana a + + + +; Remove for runtime use +; xra a ; make out there is no command tail +; Runtime => no XRA above + + jz startz + dcr a + jz startz ; one character tail... + lda takflg ; if more characters, say we are have tail + ori 10h ; set bit 4 + sta takflg + sta nexitf ; exit back to CP/M after command line +startz: + mvi a,0ffh ; when here, system basically initiallised,... + sta initflg ; apart from KERMIT.INI, so say initialised. + + call take1 ;[9] take a KERMIT.INI file + xra a ;[MF] Say we've done it + sta initak ;[MF] ... + jmp kermit ; Start main loop. + +start1: lxi d,erms20 ; "Kermit has not been configured" + call prtstx ; print error message (Use bodge for prtstr) + jmp exit2 ; and exit. + +start2: lxi d,erms21 ; "Consistency check on configuration failed" + call prtstx ; print error message + jmp exit2 ; and exit. +; +;This is the main KERMIT loop. It prompts for and gets the users commands. + +kermit: lxi sp,stack ; get new stack pointer, old one might be bad. + call selcon ; make sure console is selected. + xra a + sta mfflg1 ;reset MFNAME + sta mfflg2 ;ditto + sta mfflg3 + sta getrxflg ; clear the get/receive flag + ;0=> receive, non 0 => get + sta cmbflg ;[MF]Initial keyword must not be blank + sta cmqflg ;[MF]Allow character-echoing during commands + sta remtxt ;[MF] Clear remote-text-to-screen flag + lda curdsk ; update the prompt + adi 'A'-1 + sta kerm1+2 + call getun ;[11] get the user number into temp1/2 + lda temp1+1 ;[11] get ms value of user number + cpi '0' ;[11] less than 10 => do a space + jnz kerm4 ;[11] else do MS digit of user number + mvi a,' ' ;[11] +kerm4: sta kerm1 ;[11] + lda temp1 ;[11] get ls digit of user number + sta kerm1+1 ;[11] save that + lda takflg ; are we in TAKE or command line?? + ani 11h ; strip out both bits + jnz kerm5 ; still in either or both... + lda nexitf ; if neither, and no-exit-flag set, we quit. + ana a + jnz exit ;... back to CP/M, else as you were... +kerm5: + lxi d,kerm + call prompt ;Prompt the user. + +kerm7: lxi d,comtab + lxi h,tophlp + call keycmd ; Get a keyword + xchg ; Get result (dispatch address) into HL + pchl ; Dispatch. + +; here from: log, setcom, read, cfmcmd +kermt3: lxi d,ermes3 ;"Not confirmed" + call prtstr + jmp kermit ;Do it again. + +; Structure of command table: +; +; 1) Number of entries. +; 2) Each entry is arranged as follows: +; a) length of command in bytes. +; b) 'name of command and $-sign' +; c) address of routine to process command +; +; ---> Note this command table is in alphabetic order. +; + +comtab: db 32 ; added remote + ;[obs] added in COPY command, now called FCOPY + ;[obs] removed remote simply to issue V4.09 + ;[MF]Make FCOPY/FRENAME COPY/RENAME for + ;[MF]Version 4.10 + ;[MF]Add QUIT as a synonym for EXIT and + ;[MF]C, R and S as abbreviations for + ;[MF]CONNECT, RECEIVE and SEND, respectively + ;[MF]Add STAY as a synonym for SET NO-EXIT + db 5, 'BREAK$' + dw break + db 3, 'BYE$' + dw bye + db 1,'C$' + dw telnet ;[MF]Abbreviation for CONNECT + db 7, 'CONNECT$' + dw telnet + db 4,'COPY$' + dw copy + db 9, 'DIRECTORY$' + dw dir + db 5, 'ERASE$' + dw era + db 4, 'EXIT$' + dw exit + db 6, 'FINISH$' + dw finish + db 3, 'GET$' + dw read ; [gnn] entry for GET + db 4, 'HELP$' + dw help + db 5, 'INPUT$' + dw input + db 3, 'LOG$' + dw log + db 6, 'LOGOUT$' + dw logout + db 6, 'OUTPUT$' + dw string + db 5, 'PAUSE$' + dw pause + db 5, 'PRINT$' + dw printf ;[obs] print a file + db 4,'QUIT$' + dw exit ;[MF]Synonym for EXIT + db 1,'R$' + dw read0 ;[MF]Abbreviation for RECEIVE + db 7, 'RECEIVE$' + dw read0 ; [gnn] not same as GET now + db 6, 'REMOTE$' + dw remote + db 6,'RENAME$' + dw rename ;[MF] + db 1,'S$' + dw send ;[MF]Abbreviation for SEND + db 4, 'SEND$' + dw send + db 3, 'SET$' + dw setcom + db 4, 'SHOW$' + dw show + db 6, 'STATUS$' + dw status + db 4,'STAY$' + dw noexit ;STAY (SET NO-EXIT) + db 4, 'TAKE$' ;[9] + dw take + db 8, 'TRANSMIT$' + dw xmit + db 4, 'TYPE$' + dw type ;[obs] type a file command + db 7, 'VERSION$' + dw shover +; db 4, 'USER$' ; removed [DRJ] +; dw user ;[10] removed [DRJ] +; top-level help message. Caps indicate keywords. +; this text is also printed by the HELP command. + +tophlp: + db cr,lf,'BREAK to send a break to the host' + db cr,lf,'BYE to host (LOGOUT) and exit to CP/M' + db cr,lf,'CONNECT to host on selected port' + db cr,lf,'COPY to copy a CP/M file' + db cr,lf,'DIRECTORY of current used Micro-disk' + db cr,lf,'ERASE a CP/M file' + db cr,lf,'EXIT to CP/M' + db cr,lf,'FINISH running Kermit on the host' + db cr,lf,'GET a file from the host' + db cr,lf,'HELP by giving this message' + db cr,lf,'INPUT to make the micro wait for a string from the host' + db cr,lf,'LOG the terminal sessions to a file' + db cr,lf,'LOGOUT the host' + db cr,lf,'OUTPUT to send a specified string to the host' + db cr,lf,'PAUSE to wait for a little time' + db cr,lf,'PRINT a file to the printer' + db cr,lf,'QUIT to CP/M' + db cr,lf,'RECEIVE file from host' + db cr,lf,'REMOTE to send commands to a remote server' + db cr,lf,'RENAME to rename a CP/M file' + db cr,lf,'SEND file to host' + db cr,lf,'SET a parameter' + db cr,lf,'SHOW the parameters' + db cr,lf,'STATUS of Kermit' + db cr,lf,'STAY at Kermit command-level after a command tail' + db cr,lf,'TAKE commands from a file' ;[9] + db cr,lf,'TRANSMIT file to host (in connect state)' + db cr,lf,'TYPE a file to the console' + db cr,lf,'VERSION of Kermit running' ;[pcc005] +; db cr,lf,'USER to set a different user number' ;removed [DJR] + db '$' ;[obs] added it here to allow for expansion + +; +; This is the BREAK command. It sends a 'B' to the system dependent +; interrupt routines (test for escape-cokebottle xxx) and do a break +; if the overlay can. Else, we tell user not to be so silly. +break: call cfmcmd ; get return + mvi a,'B' ; were gonna do a break if the overlay can + call sysint ; try doing it.. + jmp kermit ; if we can do it, else + lxi d,inms12 ;... say not implemented + jmp kermit + +; +; +; This is the BYE command. It tells the remote KERSRV to logout, +; then exits. + +bye: call cfmcmd + call logo ;Tell the main frame to logout. + jmp kermit ;If it fails, don't exit. + call sysbye ; success. do system-dependent cleanup + jmp exit1 ;Exit Kermit. + +; This is the EXIT command. It leaves KERMIT and returns to CP/M. +; alternate entries: exit1, from BYE command; +; exit2, from initialization (if it fails) + +exit: call cfmcmd ; confirm... +exit1: call sysexit ; do system-dependent termination +exit2: + jmp 0 ; return to CP/M via JUMP instead of RET. + +; lhld oldsp ;Get back the system stack +; sphl ;and restore it. +; ret ;Then return to system. + +; Input command. Syntax: +; INPUT [Wait period] [string] +; where +; Wait period is a time period to wat for +; string is a string to expect back from the host. Control +; characters are entered as \ and an octal number. +; +; I can see uses for this command from other routines... +; +input: mvi a,cmnum ; first get the number + call comnd ; get it + jmp kermit ; if we dont understand it... + lhld number + shld waitp ; and save as the wait period + lxi d,stbuff ; where to put the string + mvi a,cmtxt ; get text + call comnd + jmp kermit ; not quite correct... + sta strcnt ; string count returned in a + call cfmcmd ; get a confirm + + lhld waitp ; multiply the number by + dad h + dad h ; ... 4 + dad h ; ... 8 + inx h ; but make sure it is at least 1 + shld waitp ; and save it away again + shld waitp1 ; save in case we need to reset counter + +; Right, now wait for characters comming from the line, within the +; time allowed (very fuzzy). Compare with STRING buffer +; +inp1: xra a + sta repcnt ; clear the host prompt chars.counter +inp2: lhld waitp ; have we waited long enough + dcx h + shld waitp ; count less one + mov a,h ; test to see if both zero + ora l + jnz inp20 ; nope + mvi a,3 ; error is three ie total failure + sta errorc + jmp inp5 ; take error exit + +inp20: call rd1chl ; read a character from the line + ani 7fh ; set flags + jnz inp4 ; Not zero => we have a character from host + call ckchr ; see if *WE* have a character from console + push psw ; restore to modem + call selmdm ; reselect the modem port + pop psw + ani 7fh ; strip parity (should not be there) + jnz inp2a ; if a null, try again + lda strcnt ; if the string length is zero, dont wait. + ana a + jnz inp2 ; so loop back again + jmp kermit ; else drop out + +inp2a: cpi cntlc ; do we want to abort? +;[MF]Change following line +; jz kermit ; in which case exit back to command loop + jnz inp2b ;[MF] No + lda takflg ;[MF] Yes, are we TAKEing + ani 1 ;[MF] commands from a file? + cnz closet ;[MF] Yes, close and reset to get + ;[MF] commands from the command-line + jmp kermit ;[MF] and exit back to command loop +inp2b: cpi cntlz ; if control z exit back to command loop + jz kermit ; else try for other characters [MF] + jmp inp2 + +inp4: mov e,a ; save it for a while + lda repcnt ; see if this character matches with one in buffer + lxi h,stbuff ; point to string buffer + add l ; make hl = hl + a + mov l,a + mvi a,0 ; ie make hl = hl + character count + adc h + mov h,a ; not using xra, as that clears the Carry flag + mov a,e ; get the character back again + cmp m ; is it = to what we expect? + jnz inp1 ; no, clear counter and try again + lda repcnt ; yes, then update the pointer, and ... + inr a ; ... see if we have received all ... + sta repcnt ; ... we should have received + lhld waitp1 ; get original counter + shld waitp ; and reset the loop (timer) counter + mov e,a ; save length into E again + lda strcnt ; get the length to compare + sub e ; if (e) > string length, we have it + jnz inp2 ; else wait for a little longer + + xra a ; no errors + sta errorc + jmp kermit ; so say nothing +;else if error... + +inp5: lxi d,erms30 ; say message not receive in time... + call prtstr + jmp kermit ; have string, so exit + +; +; + +; This is the HELP command. It gives a list of the commands. + +help: call cfmcmd + lxi d,tophlp ;The address of the help message. + call p20ln ;Print at most 20 lines then pause +; call prtstr + jmp kermit +; +; This is the LOG command. It logs a session to a file. + +log: mvi a,cmofi ;[pcc005] Parse an output file spec. + lxi d,fcb ;[pcc012] where to put it + call comnd + jmp kermt3 + call cfmcmd + lxi h,fcb ;[pcc012] copy file name and ext + lxi d,lognam ;[pcc012] to a safe place + lxi b,12 ;[pcc012] 12 bytes + call mover ;[pcc012] zap ... + mvi a,1 ;[pcc005] set flag for logging + sta logflg ;[pcc005] + jmp kermit ;[pcc005] + +; +; PAUSE [Wait period]. Just wait for a couple of tics... +pause: mvi a,cmnum ; get the number of the wait period + call comnd ; get it + jmp kermit ; we canna do it, so get next command + lhld number + xchg ; move to d + lhld clkbit+1 ; get clock bits 8 to 23 + mov a,h ; strip ms bit so we have space for a possible carry + ani 7fh + mov h,a + dad d ; add the number (ie get the number to wait to + shld number ; save it somewhere +; +; Now, wait for time to be equal to newer NUMBER with Carry +ploop: + call clock ; increment clock + lda takflg ; test if keyboard interrupt.. not for takes + ana a + jnz ploop1 ; do nothing for take command files + mvi c,dconio ; get status from console + mvi e,0ffh ; just get the character + call bdos + ana a ; if non zero return, then quit + jnz kermit ; we got something, so quit +ploop1: lhld number + xchg + lhld clkbit+1 ; get bits 8 to 23 + mov a,h + ani 7fh ; make it 15 bits for a carry... + mov h,a + mov a,e ; now, do (DE with carry) - HL + sub l + mov e,a + mov a,d + sbb h + ora e ; a = OR of result + jnz ploop + jmp kermit ; otherwise we are done. + +; PRINT - Print a file to the console and printer. +; This command is active only from the command level, and not +; from the connect state. Unfortunately, the print command is +; not going to be a background utility. +printf: mvi a,0ffh ; set the print flag on +typent: sta prnfl ; Type file entry. Common for PRINT and TYPE + call type ; and do the rest of the print via type + xra a + sta prnfl ; next clear the print flag + jmp kermit + +; TYPE - Type a file to the console. +; This command is really the same as the print command, but the output +; is not copied to the printer. +typef: xra a ; we want to clear the printer on flag + jmp typent ; go to the type entry in printfile above + + +; +; This is the TAKE command. It take input from a file. +; TAKE1 is the entry for automatically TAKE-ing KERMIT.INI (or whatever +; the file name at taknam is) from the default drive +; [18] code added to accept command tails. See note [18] above +; +take: mvi a,cmifi ;[9] Get filename from user + lxi d,takfcb ;[9] Take file fcb space + call comnd ;[9] get the file spec + jmp kermit ;[9] User failed to specify a good file spec + call take2 ;[MF] Now TAKE the file + jmp kermit ;[MF] Go back to main Kermit command loop +; +take1: lxi b,12 ;[9] copy default drive and file name to take fcb + lxi d,takfcb + lxi h,taknam + call mover ;[9] and do it (all other extents etc are zero) +;[MF][30]No longer need the following line +; jmp take2 ; got the file name, now take it. +; + ;[9] get the file name, now lets open it +; +take2: + lda takflg ; check to see we have not tak-take + ani 1 ; if set, we are in a take already +;[MF]We can do the following test/call more efficiently +; jz take21 +; call closet ; so close current take file + cnz closet ;[MF] So close current take file +take21: + mvi c,setdma + lxi d,takdma ;[9] tell bdos where to send data + call BDOS + xra a ;[9] clear all these extents etc + sta takfcb+14 + sta takfcb+32 + lxi d,takfcb ;[9] open the file + mvi c,openf ;[9] open the file + call BDOS + inr a ;[9] if FF returned, problems +;[MF]Complain if failure and not seeking KERMIT.INI +; jz kermit ;[9] for now, say nowt if no ini file. Else.. + jz ntake ;[9] We'll say file not found + ;[MF] unless the initial TAKE (KERMIT.INI) +; jmp take3 ; a test +; mvi c,readf ;[9] read first bytes from file +; lxi d,takfcb ;[9] +; call BDOS + +take3: lxi h,0 + shld takptr ;[9] point to first byte of take file + lda takflg ; get current flag + ori 1 ;[9] and set flag to tell Kermit we're taking + sta takflg +;[MF][30]Redo next lines so can flag initial TAKE of KERMIT.INI +; call rnsect ;[9] read a sector +; jmp kermit ;(Should use a ret, but this will do) + jmp rnsect ;[9] read a sector and return + +ntake: lda initak ;[MF]Is this the initial TAKE (KERMIT.INI)? + ora a ;[MF]... + rnz ;[MF]Yes, don't complain + lxi d,erms15 ;[9] Say file not found + call prtstr +;[MF][30]Make next line a "jmp" since we've called TAKE2 +; call rstdma ;[9] reset the DMA addres for other files +; jmp kermit + jmp rstdma ;[9] reset the DMA addres for other files + ;[MF] and return + + +; Little code to allow some expansion of code without changing +; every futher address, only up to the end of this file. +; TO BE REMOVED FRO RELEASE! + +; org ($+100h) AND 0FF00H + +IF lasm + LINK CPSCOM +ENDIF ;lasm diff --git a/cpspk1.asm b/cpspk1.asm index 6ea4831..8e2f87c 100644 --- a/cpspk1.asm +++ b/cpspk1.asm @@ -1,1904 +1,1904 @@ -; CPSPK1.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the (system-independent) routines that implement -; the KERMIT protocol, and the commands that use them: -; RECEIVE, SEND, FINISH, and LOGOUT. -; -; revision history: -; -;edit 23, 16-Jan-1991 by MF. The bug of (22) was not fixed (although -; the error described needed to be corrected). Really fixed the bug this: -; time. changed "lda 'E'" after "ptch9b" to "mvi a,'E'" -- Zilog -; mnemonic thinking must've addled my brain! -;edit 22, 14-Jan-1991 by MF. Fix bug in the code which sends an "E" packet -; to the remote Kermit on encountering "disk full" so that -; uncontrollified 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 -; and RECEIVE . 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 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 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 +; and RECEIVE . 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 so + ;[obs 8]pretend get for printing filename + lda rdl ;[gnn] look at first name + ora a ;[gnn] receive or get? + jz read1 ;[gnn] receive + + mvi a,'I' ;[MF]Set state to send "I" packet + sta state ;[MF]... + +; jmp read12 ;[obs] [gnn] does not want this + +read1: ;call init ;Clear the line and initialize the buffers. +read12: xra a + sta czseen ;Clear the ^X/^Z flag initially. + lxi h,0 + shld numpkt ;Set the number of packets to zero. + shld numrtr ;Set the number of retries to zero. + sta pktnum ;Set the packet number to zero. + sta numtry ;Set the number of tries to zero. + lda quietd ; quiet display? + ana a + jnz read13 ; yes, so dont write... + call scrnrt ;Position cursor + lxi h,0 + call nout ;Write the number of retries. +read13: lda rdl ;[MF]Get or receive? + ora a ;[MF]... + jnz read2 ;[MF]Get, don't reset state + mvi a,'R' + sta state ;Set the state to receive initiate. + ;... +; +;RECEIVE state table switcher. + +read2: lda quietd ; noisy display? + ana a + jnz read21 ; no, a quiet one + lda remtxt ;[MF] In Remote command? + ora a + jnz read21 ;[MF] Yes, don't write to screen + call scrnp ;Position cursor + lhld numpkt + call nout ;Write the current packet number. +read21: lda state ;Get the state. + cpi 'D' ;Are we in the DATA receive state? + jnz read22 + call rdata + jmp read2 + +read22: cpi 'X' ; F packet but not an F packet? + jnz read3 ; nope, so try next one + call rfile ; 'get' the filename (but dont open it) + jmp read2 + +read3: cpi 'F' ;Are we in the FILE receive state? + jnz read4 + call rfile ;Call receive file. + jmp read2 + +read4: cpi 'R' ;Are we in the Receive-Initiate state? + jnz read5 + call rinit + lda state ;[jd] get new state + cpi 'F' ;[jd] went into receive state? + jnz read2 ;[jd] no + lxi d,inms24 ;[jd] yes, get receiving... message + call finmes ;[jd] go print it + jmp read2 + +read5: cpi 'C' ;Are we in the Receive-Complete state? + jnz read6 + lxi d,infms3 ;Put in "Complete" message. + lda czseen ;Or was it interrupted? + ora a ; . . . + jz read5a ;No. + xra a ;Yes, clear flag. + sta czseen ; ... + lxi d,inms13 ;Issue "interrupted" message. +read5a: lda remtxt ;[MF] Doing a Remote command? + ora a + cz finmes ;Print completion message in right place if not +; + lda rdl ;[MF]Receive or Get? + ora a ;[MF]... + jnz kermit ;[MF]Get, Autoreceive means nothing. + lda autorc ; see if we want autoreceives + ana a + jz kermit ;[MF]No autoreceives, so drop out + lxi d,autmes ;[MF]Yes, tell the user what we're doing + call prtstr ;[MF]... + jmp read1 ;[MF]Try another Receive (we get one + ;[MF]retry from the sender as the ^A is lost) + +read6: cpi 'Y' ;[MF]Simple ack (from remote command)? + jz kermit ;[MF]Yes + + cpi 'I' ;[MF]Exchanging parameters via info packet? + jnz read7 ;[MF]No + call sinit ;[MF]Yes, send the packet + lda state ;[MF]Now see what happened + cpi 'X' ;[MF]Did we exchange parameters successfully? + jz read6a ;[MF]Yes, go send the filespec + cpi 'A' ;[MF]No, are we in abort state? + jnz read2 ;[MF]No, try again + jmp kermit ;[MF]Yes, it's a real disaster, we must stop +read6a: lda rdl ;[MF]Get length of filespec + sta argblk+1 ;[MF]as length of packet + mov c,a ;[MF]We must copy the filespec + mvi b,0 ;[MF]... + lxi h,remdat ;[MF]from the temporary buffer + lxi d,data ;[MF]to the packet data area + call mover ;[MF]Do it. +; for GET we must send the name of the file we want [gnn] + + mvi a,'1' ;Start with single character checksum + sta curchk ;Save the type + xra a ;Start a packet zero. + sta argblk + mvi a,'R' ;Receive init packet. + call spack ;Send the packet. + jmp kermt3 ; Die! + xra a + sta czseen ;Clear the ^X/^Z flag initially. + lxi h,0 + shld numpkt ;Set the number of packets to zero. + sta pktnum ;Set the packet number to zero. + sta numtry ;Set the number of tries to zero. + mvi a,'R' ;[MF]Set state to Receive-Initiate + sta state ;[MF]... + jmp read21 ;[MF]and go around again + ;[MF]without retyping packet-number + +read7: cpi 'A' ;Are we in the Receive-"Abort" state? + jnz read8 +read8: lxi d,infms4 ;Anything else is equivalent to "abort". + call finmes + jmp kermit +; +; Receive routines + +; Receive init +; called by: read + +rinit: lda numtry ;Get the number of tries. + cpi imxtry ;Have we reached the maximum number of tries? + jm rinit2 + lxi d,ermes4 + call error3 ;Move cursor and print an error message. + jmp abort ;Change the state to abort. + +rinit2: inr a ;Increment it. + sta numtry ;Save the updated number of tries. + mvi a,'1' ;Reset block check type to single character + sta curchk ;Store as current type for initialization + call rpack ;Get a packet. + jmp nak ; Trashed packet: nak, retry. + cpi 'S' ;Is it a send initiate packet? + jnz rinit3 ;If not see if its an error. +rini2a: lda numtry ;Get the number of tries. + sta oldtry ;Save it. + xra a + sta numtry ;Reset the number of tries. + lda argblk ;Returned packet number. (Synchronize them.) + call countp + lda argblk+1 ;Get the number of arguments received. + lxi h,data ;Get a pointer to the data. + call spar ;Get the data into the proper variables. + lxi h,data ;Get a pointer to our data block. + call rpar ;Set up the receive parameters. + sta argblk+1 ;Store the returned number of arguments. + mvi a,'Y' ;Acknowledge packet. + call spack ;Send the packet. + jmp abort ; Failed, abort. + lda inichk ;Now switch to agreed upon check-type + sta curchk ;For all future packets + mvi a,'F' ;Set the state to file send. + sta state + ret + +rinit3: cpi 'E' ;Is it an error packet. + jnz nak0 ;If not NAK whatever it is. + call error + jmp abort +; +; Receive file +; called by: read + +rfile: lda numtry ;Get the number of tries. + cpi maxtry ;Have we reached the maximum number of tries? + jm rfile1 + lxi d,ermes5 + call error3 ;Move cursor and print an error message. + jmp abort ;Change the state to abort. + +rfile1: inr a ;Increment it. + sta numtry ;Save the updated number of tries. + call rpack ;Get a packet. + jmp nak ; Trashed packet: nak, retry. + cpi 'S' ;Is it a send initiate packet? + jnz rfile2 ; No, try next type. + lda oldtry ;Get the number of tries. + cpi imxtry ;Have we reached the maximum number of tries? + jm rfil12 ;If not proceed. + lxi d,ermes4 + call error3 ;Move cursor and print an error message. + jmp abort ;Change the state to abort. + +rfil12: inr a ;Increment it. + sta oldtry ;Save the updated number of tries. + lda pktnum ;Get the present packet number. + dcr a ;Decrement + ani 3FH ; modulo 64 + mov b,a + lda argblk ;Get the packet's number + cmp b ;Is the packet's number one less than now? + jnz nak0 ;No, NAK and try again. + call updrtr ;Update the retry count. + xra a + sta numtry ;Reset the number of tries. + lxi h,data ;Get a pointer to our data block. + call rpar ;Set up the parameter information. + sta argblk+1 ;Save the number of arguments. + mvi a,'Y' ;Acknowledge packet. + call spack ;Send the packet. + jmp abort ; Failed, abort. + ret + +rfile2: cpi 'Z' ;Is it an EOF packet? + jnz rfile3 ; No, try next type. + lda oldtry ;Get the number of tries. + cpi maxtry ;Have we reached the maximum number of tries? + jm rfil21 ;If not proceed. + lxi d,ermes6 + call error3 ;Move cursor and print an error message. + jmp abort ;Change the state to abort. + +rfil21: call tryagn + ret + +rfile3: cpi 'F' ;Start of file? + jnz rfil3b + mov c,a ;[MF]Save packet type + lda remtxt ;[MF]Doing a remote server command? + ora a ;[MF]... + mov a,c ;[MF]Restore packet type + jnz rfil3d ;[MF]If yes, same as x packet + call compp + jnz nak0 ;No, NAK it and try again. + call countp + mov c,a ;[MF] + lda remtxt ;[MF]Doing a remote command? + ora a ;[MF]... + mov a,c ;[MF] + jnz rfil3a ;[MF]Yes, don't open a file + call gofil ;Get a file to write to, and init output buffer. + jmp abort +rfil3a: lda numtry ;Get the number of tries. + sta oldtry ;Save it. + call ackp + mvi a,'D' ;Set the state to data receive. + sta state + lda czseen ;Check if we punted a file + cpi 'Z' ;and didn't want any more + rz ;If that was the request, keep telling other end + xra a ;Otherwise, clear flag (^X is only for one file) + sta czseen ;And store the flag back + ret + +rfil3b: cpi 'X' ;Start of 'file?' , but not a file? + jnz rfile4 +rfil3d: call compp + jnz nak0 ;No, NAK it and try again. + call countp + + call selcon ;[MF]Select Console + lda argblk+1 ; get length + ora a ;[MF]Anything to write? + jz rfil3e ;[MF]No + push psw ;[MF]Yes, save character count + mvi e,'<' ;[MF]Write "<<" as in VMSKermit + push d ;[MF]... + call outcon ;[MF]... + pop d ;[MF]... + call outcon ;[MF]... + pop psw ;[MF]Restore character count + lxi h,data ; lets write the filename (?) to display +rfil3f: push psw ;[MF]Save loop counter + mov e,m ;[MF]Get character to write + inx h ;[MF]and increment character pointer + push h ;[MF]Save the pointer + call outcon ;[MF]Write character to display + pop h ;[MF]Restore pointer + pop psw ;[MF]and loop counter + dcr a ;[MF]Decrement the counter + jnz rfil3f ;[MF]Display entire filename + mvi e,'>' ;[MF]Put in ">>" as in VMSKermit + push d ;[MF]... + call outcon ;[MF]... + pop d ;[MF]... + call outcon ;[MF]... + call prcrlf ;[MF]New line +rfil3e: lda numtry ;Get the number of tries. + sta oldtry ;Save it. + call ackp + mvi a,'D' ; expecting a D packet + sta state + lda czseen ;Check if we punted a file + cpi 'Z' ;and didn't want any more + rz ;If that was the request, keep telling other end + xra a ;Otherwise, clear flag (^X is only for one file) + sta czseen ;And store the flag back + ret + +rfile4: cpi 'B' ;End of transmission. + jnz rfile5 + call compp + jnz nak0 ;No, NAK it and try again. + xra a ;No data. (Packet number already in argblk). + sta argblk+1 + mvi a,'Y' ;Acknowledge packet. + call spack ;Send the packet. + jmp abort + mvi a,'C' ;Set the state to complete. + sta state + ret + +rfile5: cpi 'E' ;Is it an error packet. + jnz abort + call error + jmp abort +; +; Receive data +; called by: read + +rdata: lda numtry ;Get the number of tries. + cpi maxtry ;Have we reached the maximum number of tries? + jm rdata1 + lxi d,erms10 + call error3 ;Display error message. +rdat16: lda remtxt ;[MF]Is a Remote command in progress? + ora a ;[MF]... + jnz abort ;[MF]Yes, don't worry about file disposition + lda incflg ;[MF]Are we keeping incomplete files? + ora a ;[MF]... + jnz rdat17 ;[MF]Yes + lxi d,fcb ;[MF]No, close the file, ignoring errors + push d ;[MF]while protecting the pointer + mvi c,closf ;[MF]... + call bdos ;[MF]... + pop d ;[MF]Now delete the file, ignoring errors + mvi c,delf ;[MF]... + call bdos ;[MF]... + jmp abort ;Change the state to abort. +rdat17: call clofil ;[MF]Try to close the file, writing + ;[MF]outstanding buffers to disk + jmp rdat37 ;[MF]We can't, the disk is full + jmp abort ;[MF]Change the state to "abort" + +rdata1: inr a ;Increment it. + sta numtry ;Save the updated number of tries. + call rpack ;Get a packet. + jmp nak ; Trashed packet: nak, retry. + cpi 'D' ;Is it a data packet? + jnz rdata2 ; No, try next type. + call compp ;check for correct packet number (zero flag = ok) + jz rdat14 ;its correct + lda oldtry ;Get the number of tries. + cpi maxtry ;Have we reached the maximum number of tries? + jm rdat12 ;If not proceed. + lxi d,erms10 + call error3 ;Display err msg. + jmp rdat16 ;[MF]Change the state to abort. + +rdat12: call tryagn + ret + +rdat14: call countp + lda numtry ;Get the number of tries. + sta oldtry ;Save it. + lda argblk+1 ;Get the length of the data. + call ptchr + jmp rdat3b ;[MF] Unable to write out chars;abort. + xra a + sta numtry ;Reset the number of tries. + sta argblk+1 ;No data. (Packet number still in argblk.) + mov c,a ;Assume no data + lda czseen ;Check if control-X typed + ora a ; . . . + jz rdat15 ;Zero if not typed + mov c,a ;Get the type of character typed + mvi a,1 ;One data character + sta argblk+1 ;Save the count + mov a,c ;Get the possible data character + sta data ;Store in data area +rdat15: mvi a,'Y' ;Acknowledge packet. + call spack ;Send the packet. + jmp rdat16 ;[MF] + ret + +rdata2: cpi 'F' ;Start of file? + jnz rdata3 ; No, try next type. + lda oldtry ;Get the number of tries. + cpi maxtry ;Have we reached the maximum number of tries? + jm rdat21 ;If not proceed. + lxi d,ermes5 + call error3 ;Display err msg. + jmp rdat16 ;[MF]Change the state to abort. + +rdat21: call tryagn + ret + +rdata3: cpi 'Z' ;Is it a EOF packet? + jnz rdata4 ;Try and see if its an error. + call compp + jnz nak0 ;No, NAK it and try again. + call countp + lda argblk+1 ;Get the data length + cpi 1 ;Have one item? + jnz rdat33 ;If not, ignore data + lda data ;Yes, get the character + cpi 'D' ;Is it a 'D' for discard? + jz rdat36 ;If so, punt file +rdat33: lda remtxt ;[MF]Writing text to disk? + ora a ;[MF]... + jnz rdat38 ;[MF]No, don't close file + call clofil ;Finish off the file. + jmp rdat37 ; Give up if the disk is full. +rdat38: xra a ;Since we kept the file, + sta czseen ;don't say it was discarded. + lda numtry ;Get the number of tries. [MF] + sta oldtry ;Save it. [MF] + call ackp ;[MF] + jmp rdat39 ;[MF]and get ready to get more files +rdat36: lda numtry ;Get the number of tries. + sta oldtry ;Save it. + call ackp + lda remtxt ;[MF]Is a Remote command in progress? + ora a ;[MF]... + jnz rdat39 ;[MF]Yes, don't worry about file disposition + lda dscflg ;[MF]Is the file being punted because + ora a ;[MF]of a collision? + jnz rdat39 ;[MF]Yes, don't delete the existing file + lda incflg ;[MF]No, are we keeping incomplete files? + ora a ;[MF]... + jnz rdat3a ;[MF]Yes + lxi d,fcb ;[MF]No, close the file, + mvi c,closf ;[MF]ignoring errors + push d ;[MF]... + call bdos ;[MF]... + pop d ;[MF]Now delete the file, + mvi c,delf ;[MF]ignoring errors + call bdos ;[MF]... + jmp rdat39 ;[MF]and continue +rdat3a: call clofil ;[MF]Try to close the file, writing + ;[MF]outstanding buffers to disk + jmp rdat37 ;[MF]Can't, disk is full +rdat39: mvi a,'F' + sta state + ret + +rdat37: call ptchr9 ; Send "?Disk full" on the error line [MF] + ; and to the remote Kermit [MF] +rdat3b: lda remtxt ;[MF]Doing a Remote command? + ora a ;[MF]... + jnz abort ;[MF]Yes, just abort + lxi d,fcb ;[MF]Close the file, ignoring errors + push d ;[MF]Protect fcb pointer + mvi c,closf ;[MF]... + call bdos ;[MF]... + pop d ;[MF]Restore pointer + lda incflg ;[MF]Are we keeping incomplete files? + ora a ;[MF]... + jnz abort ;[MF]Yes, just abort transfer + mvi c,delf ;[MF]No, delete the file, ignoring errors + call bdos ;[MF]... + jmp abort ;[MF] abort transfer + +rdata4: cpi 'E' ;Is it an error packet. + jnz rdat16 ;[MF] + call error + jmp rdat16 ;[MF] +; +; SEND command +; here from: kermit + +send: mvi a,cmifi ;Parse an input file spec. + lxi d,fcb ;Give the address for the FCB. + call comnd + jmp kermit ; Give up on bad parse. +; section to get remote filename [gnn] + lxi d,remnam ;[gnn] where to put filename + mvi a,cmtxt ;[gnn] + call comnd ;[gnn] get the text to end of the line + jmp kermt3 ;[gnn] failure in reading buffer + sta remlen ;[gnn] save length (may be zero) +; + xra a + sta mfflg1 ; clear flags... + sta mfflg2 + sta mfflg3 ;[gnn] + sta fcbcnt ;[gnn] clear fcbcount + lxi h,fcb0 ;[gnn] and fcb pointer + shld xfcbptr +; + call mfname ;handle (multi) files + jnc send14 ;got a valid file-name + lxi d,erms15 + call prtstr ;Display error msg. ([hh] where it's visible) + jmp kermit + +send14: call init ;Clear the line and initialize the buffers. + xra a + sta pktnum ;Set the packet number to zero. + sta numtry ;Set the number of tries to zero. + sta wrn8 ;[jd] we haven't sent the 8-bit-lost warning + lxi h,0 + shld numpkt ;Set the number of packets to zero. + shld numrtr ;Set the number of retries to zero. + lda quietd ; a quiet display? + ana a + jnz send15 ; yup, dont write + call scrnrt ;Position cursor + lxi h,0 + call nout ;Write the number of retries. +send15: mvi a,'1' ;Reset to use single character checksum + sta curchk ;For startup + mvi a,'S' + sta state ;Set the state to receive initiate. + ;... +; +;SEND state table switcher + +send2: lda quietd ; a quiet display? + ana a + jnz send21 ; yes, so dont write + call scrnp ;Position cursor + lhld numpkt + call nout ;Write the packet number. +send21: lda state ;Get the state. + cpi 'D' ;Are we in the data send state? + jnz send3 + call sdata + jmp send2 + +send3: cpi 'F' ;Are we in the file send state? + jnz send4 + call sfile ;Call send file. + jmp send2 + +send4: cpi 'Z' ;Are we in the EOF state? + jnz send5 + call seof + jmp send2 + +send5: cpi 'S' ;Are we in the send initiate state? + jnz send6 + call sinit + lda state ;[jd] get state back + cpi 'F' ;[jd] into file send state yet? + jnz send2 ;[jd] no + lxi d,inms23 ;[jd] yes, print sending... + call finmes ;[jd] + jmp send2 + +send6: cpi 'B' ;Are we in the eot state? + jnz send7 + call seot + jmp send2 + +send7: cpi 'C' ;Are we in the send complete state? + jnz send8 ;No... + lxi d,infms3 ;Yes, write "Complete" message. + lda czseen ;Or was it interrupted? + ora a ; . . . + jz send7a ;No. + lxi d,inms13 ;Yes, then say "Interrupted" instead. +send7a: call finmes + jmp kermit + +send8: cpi 'A' ;Are we in the send "abort" state? + jnz send9 + lxi d,infms4 ;Print message. + call finmes + jmp kermit + +send9: lxi d,infms4 ;Anything else is equivalent to "abort". + call finmes + jmp kermit +; +; Send routines + +; Send initiate +; called by: send + +sinit: lda numtry ;Get the number of tries. + cpi imxtry ;Have we reached the maximum number of tries? + jm sinit2 + lxi d,erms14 + call error3 ;Display ermsg + jmp abort ;Change the state to abort. + +sinit2: inr a ;Increment it. + sta numtry ;Save the updated number of tries. + mvi a,'1' ;Reset to use single character checksum + sta curchk ;For startup + lda chktyp ;Get our desired block check type + sta inichk ;Store so we tell other end + lxi h,data ;Get a pointer to our data block. + call rpar ;Set up the parameter information. + sta argblk+1 ;Save the number of arguments. + lda numpkt ;Get the packet number. + sta argblk + lda state ; load state (I or S) + + call spack ;Send the packet. + jmp abort ; Failed, abort. + call rpack ;Get a packet. + jmp r ; Trashed packet don't change state, retry. + cpi 'Y' ;ACK? + jnz sinit3 ;If not try next. + call compp ;compare packets. If ok, zero flag set + rnz ;If not try again. + call countp ;increment packet number modulo 64 + lda argblk+1 ;Get the number of pieces of data. + lxi h,data ;Pointer to the data. + call spar ;Read in the data. (decode what they want) + lda numtry ;Get the number of tries. + sta oldtry ;Save it. + xra a + sta numtry ;Reset the number of tries. + lda state ; se if S or I state + cpi 'I' ; I state, so set X as next state + jnz sinita +sinitb: mvi a,'X' + sta state + ret + +sinita: lda inichk ;Get the agreed upon block check type + sta curchk ;Store as type to use for packets now + mvi a,'F' ;Set the state to file send. (Assumed) + sta state + call getfil ;Open the file. + ret ; assume success; mfname thinks the file exists. + +sinit3: cpi 'N' ;NAK? + jnz sinit4 ;If not see if its an error. + call updrtr ;Update the number of retries. + lda pktnum ;Get the present packet number. + inr a ;Increment + ani 3FH ; modulo 64 + mov b,a + lda argblk ;Get the packet's number. + cmp b ;Is the packet's number one more than now? + rnz ;If not assume its for this packet, go again. + xra a + sta numtry ;Reset number of tries. + mvi a,'F' ;Set the state to file send. + sta state + ret + +sinit4: cpi 'E' ;Is it an error packet. + jnz abort + lda state ;[MF]Get state + cpi 'I' ;[MF]If an "I" packet was sent, + jz sinitb ;[MF]Ignore the error, pretend success + call error ;[MF]else display the error info + jmp abort ;[MF]and abort +; +; Send file header +; called by: send +;[5a] Question [majoc]: Why could not the filename +; parsing have been done by comnd, like all the rest? + +sfile: lda numtry ;Get the number of tries. + cpi maxtry ;Have we reached the maximum number of tries? + jm sfile1 + lxi d,erms14 + call error3 + jmp abort ;Change the state to abort. + +sfile1: inr a ;Increment it. + sta numtry ;Save the updated number of tries. + xra a ;Clear A + sta czseen ;No control-Z or X seen + lxi h,data ;Get a pointer to our data block. + shld datptr ;Save it. +; use remote name if given, else use local name [gnn] + lda remlen ;[gnn] anything given? + ora a ;[gnn] + jnz sfile4 ;[gnn] use remote name + + lxi h,fcb+1 ;Pointer to the file name in the FCB. + shld fcbptr ;Save position in FCB. + mvi b,0 ;No chars yet. + mvi c,0 +sfil11: mov a,b + cpi 8H ;Is this the ninth char? + jnz sfil12 ;If not proceed. + mvi a,'.' ;Get a dot. + lhld datptr + mov m,a ;Put the char in the data packet. + inx h + shld datptr ;Save position in data packet. + inr c +sfil12: inr b ;Increment the count. + mov a,b + cpi 0CH ;Twelve? + jp sfil13 + lhld fcbptr + mov a,m + ani 7fH ;Turn off CP/M 2 or 3's high bits. + inx h + shld fcbptr ;Save position in FCB. + cpi '!' ;Is it a good character? + jm sfil11 ;If not get the next. + lhld datptr + mov m,a ;Put the char in the data packet. + inx h + shld datptr ;Save position in data packet. + inr c + jmp sfil11 ;Get another. + +sfil13: mov a,c ;Number of char in file name. + sta argblk+1 + lhld datptr + mvi a,'$' + mov m,a ;Put in a dollar sign for printing. + lda quietd ; a quiet display + ana a + jnz sfi13a ; yes, dont write + call scrfln ;Position cursor +sfi13a: lxi d,data ;Print the file name though, in either case + call prtstr + lda pktnum ;Get the packet number. + sta argblk + mvi a,'F' ;File header packet. + call spack ;Send the packet. + jmp abort ; Failed, abort. + call rpack ;Get a packet. + jmp r ; Trashed packet don't change state, retry. + cpi 'Y' ;ACK? + jnz sfile2 ;If not try next. + call compp + rnz ;If not hold out for the right one. +sfil14: call countp + lda numtry ;Get the number of tries. + sta oldtry ;Save it. + xra a + sta numtry ;Reset the number of tries. + sta bytes ;[10] clear the "bytes transferred" counter + sta bytes+1 ;[10] + sta bytes+2 ;[10] + sta bytes+3 ;[10] + call gtchr ;Fill the first data packet + jmp sfil16 ;Error go see if its EOF. +; ;Got the chars, proceed. + sta size ;Save the size of the data gotten. + mvi a,'D' ;Set the state to data send. + sta state + ret + +sfil16: cpi 0FFH ;Is it EOF? + jnz abort ;If not give up. + mvi a,'Z' ;Set the state to EOF. + sta state + ret + +sfile2: cpi 'N' ;NAK? + jnz sfile3 ;Try if error packet. + call updrtr ;Update the number of retries. + lda pktnum ;Get the present packet number. + inr a ;Increment + ani 3FH ; modulo 64 + mov b,a + lda argblk ;Get the packet's number. + cmp b ;Is the packet's number one more than now? + rnz ;If not go try again. + jmp sfil14 ;Just as good as a ACK;go to the ACK code. + +sfile3: cpi 'E' ;Is it an error packet. + jnz abort + call error + jmp abort + +; copy remote name into packet to send [gnn] +sfile4: xchg ;[gnn] keep pointer to packet + lxi h,remnam ;[gnn] set pointer to name + mov c,a ;[gnn] keep count of length + mov b,a ;[gnn] and set as loop counter +sfil41: mov a,m ;[gnn] get a character + stax d ;[gnn] copy it to packet + inx h ;[gnn] + inx d ;[gnn] move pointers + dcr b ;[gnn] + mov a,b ;[gnn] + ora a ;[gnn] done them all? + jnz sfil41 ;[gnn] repeat until done + xchg ;[gnn] get final position + shld datptr ;[gnn] and save it + jmp sfil13 ;[gnn] now go and send packet + +; +; Send data +; called by: send + +sdata: lda numtry ;Get the number of tries. + cpi maxtry ;Have we reached the maximum number of tries? + jm sdata1 + lxi d,erms14 + call error3 + jmp abort ;Change the state to abort. + +sdata1: inr a ;Increment it. + sta numtry ;Save the updated number of tries. + lxi h, data ;Get a pointer to our data block. + shld datptr ;Save it. + lxi h,filbuf ;Pointer to chars to be sent. + shld cbfptr ;Save position in char buffer. + mvi b,1 ;First char. +sdat11: lhld cbfptr + mov a,m + inx h + shld cbfptr ;Save position in char buffer. + mov c,a ;[jd] preserve character temporarily + lda quot8 ;[jd] doing eighth-bit quoting? + ora a ;[jd] + mov a,c ;[jd] restore char + jnz sdat4 ;[jd] using eighth-bit quoting, no warning + lda parity ;[jd] get parity + cpi parnon ;[jd] none? + mov a,c ;[jd] restore character + jz sdat4 ;[jd] no parity, leave char alone + lda wrn8 ;[jd] look at warning flag + ora a ;[jd] have we already given the warning? + jnz sdat5 ;[jd] yes, skip this + mov a,c ;[jd] restore character... + ani 80h ;[jd] examine parity + jz sdat5 ;[jd] no parity, no warning. + call parwrn ;[jd] ...print warning - parity lost + mvi a,0ffh ;[jd] remember that we sent the message + sta wrn8 ;[jd] +sdat5: mov a,c ;[jd] restore character again + ani 7fh ;[jd] strip parity so not checksummed +sdat4: lhld datptr + mov m,a ;Put the char in the data packet. + inx h + shld datptr ;Save position in data packet. + inr b ;Increment the count. + lda size ;Get the number of chars in char buffer. + cmp b ;Have we transfered that many? + jp sdat11 ;If not get another. + lda size ;Number of char in char buffer. + sta argblk+1 + lda pktnum ;Get the packet number. + sta argblk + mvi a,'D' ;Data packet. + call spack ;Send the packet. + jmp abort ; Failed, abort. + call rpack ;Get a packet. + jmp r ; Trashed packet don't change state, retry. + cpi 'Y' ;ACK? + jnz sdata2 ;If not try next. + call compp + rnz ;If not hold out for the right one. + lda argblk ;Get the packet number back + call countp + lda numtry ;Get the number of tries. + sta oldtry ;Save it. + xra a + sta numtry ;Reset the number of tries. + lda argblk+1 ;Get the data length + cpi 1 ;Check if only 1 character? + jnz sdat15 ;If not, just continue + lda data ;Got one character, get it from data + cpi 'Z' ;Want to abort entire stream? + jnz sdat14 ;If not, check for just this file + sta czseen ;Yes, remember it + jmp sdat16 ;[MF] and set EOF state +sdat14: cpi 'X' ;Desire abort of current file? + jnz sdat15 ;If not, just continue + sta czseen ;Yes, remember that + jmp sdat16 ;[MF] and set EOF +sdat15: lda czseen ;Also get control-Z flag + ora a ;Check if either given + jz sdat12 ;If neither given, continue +sdat16: mvi a,'Z' ;Change state to EOF + sta state ; . . . + ret ;And return + +sdat12: call gtchr + jmp sdat13 ;Error go see if its EOF. + sta size ;Save the size of the data gotten. + ret + +sdat13: cpi 0FFH ;Is it EOF? + jnz abort ;If not give up. + mvi a,'Z' ;Set the state to EOF. + sta state + ret + +sdata2: cpi 'N' ;NAK? + jnz sdata3 ;See if is an error packet. + call updrtr ;Update the number of retries. + lda pktnum ;Get the present packet number. + inr a ;Increment + ani 3FH ; modulo 64 + mov b,a + lda argblk ;Get the packet's number. + cmp b ;Is the packet's number one more than now? + rnz ;If not go try again. + jmp sdat12 ;Just as good as a ACK;go to the ACK code. + +sdata3: cpi 'E' ;Is it an error packet. + jnz abort + call error + jmp abort +; +; Send EOF +; called by: send + +seof: lda numtry ;Get the number of tries. + cpi maxtry ;Have we reached the maximum number of tries? + jm seof1 + lxi d,erms14 + call error3 + jmp abort ;Change the state to abort. + +seof1: inr a ;Increment it. + sta numtry ;Save the updated number of tries. + lda pktnum ;Get the packet number. + sta argblk + xra a + sta argblk+1 ;No data. + lda czseen ;Check if C-Z or C-X typed + ora a ; . . . + jz seof14 ;If not aborted, just keep going + mvi a,'D' ;Tell other end to discard packet + sta data ;Store in data portion + mvi a,1 ;One character + sta argblk+1 ;Store the length +seof14: mvi a,'Z' ;EOF packet. + call spack ;Send the packet. + jmp abort ; Failed, abort. + call rpack ;Get a packet. + jmp r ; Trashed packet don't change state, retry. + cpi 'Y' ;ACK? + jnz seof2 ;If not try next. + call compp + rnz ;If not hold out for the right one. +seof12: call countp + lda numtry ;Get the number of tries. + sta oldtry ;Save it. + xra a + sta numtry ;Reset the number of tries. + mvi c,closf ;Close the file. + lxi d,fcb + call bdos +;* Check if successful + lda czseen ;Desire abort of entire stream? + cpi 'Z' ;Desire abort of entire stream? + jz seof13 ;If so, just give up now + call mfname ;Get the next file. + jc seof13 ; No more. + call getfil ;and open it (assume success) + xra a ;Clear A + sta czseen ;Since we have not aborted this file + mvi a,'F' ;Set the state to file send. + sta state + ret + +seof13: mvi a,'B' ;Set the state to EOT. + sta state + ret + +seof2: cpi 'N' ;NAK? + jnz seof3 ;Try and see if its an error packet. + call updrtr ;Update the number of retries. + lda pktnum ;Get the present packet number. + inr a ;Increment + ani 3FH ; modulo 64 + mov b,a + lda argblk ;Get the packet's number. + cmp b ;Is the packet's number one more than now? + rnz ;If not go try again. + jmp seof12 ;Just as good as a ACK;go to the ACK code. + +seof3: cpi 'E' ;Is it an error packet. + jnz abort + call error + jmp abort +; +; Send EOT +; called by: send + +seot: lda numtry ;Get the number of tries. + cpi maxtry ;Have we reached the maximum number of tries? + jm seot1 + lxi d,erms14 + call error3 + jmp abort ;Change the state to abort. + +seot1: inr a ;Increment it. + sta numtry ;Save the updated number of tries. + lda pktnum ;Get the packet number. + sta argblk + xra a + sta argblk+1 ;No data. + mvi a,'B' ;EOF packet. + call spack ;Send the packet. + jmp abort ; Failed, abort. + call rpack ;Get a packet. + jmp r ; Trashed packet don't change state, retry. + cpi 'Y' ;ACK? + jnz seot2 ;If not try next. + call compp + rnz ;If not hold out for the right one. +seot12: call countp + lda numtry ;Get the number of tries. + sta oldtry ;Save it. + xra a + sta numtry ;Reset the number of tries. + mvi a,'C' ;Set the state to file send. + sta state + ret + +seot2: cpi 'N' ;NAK? + jnz seot3 ;Is it error. + call updrtr ;Update the number of retries. + lda pktnum ;Get the present packet number. + inr a ;Increment + ani 3FH ; modulo 64 + mov b,a + lda argblk ;Get the packet's number. + cmp b ;Is the packet's number one more than now? + rnz ;If not go try again. + jmp seot12 ;Just as good as a ACK;go to the ACK code. + +seot3: cpi 'E' ;Is it an error packet. + jnz abort + call error + jmp abort +; +; This routine sets up the data for init packet (either the +; Send_init or ACK packet). +; called by: rinit, rfile, sinit +; +; Called by rinit, rfile and sinit. See what WE want from the other fella +; +; [11] by OBS - Stripped out all the new capas code etc and reverted +; to Good Ol' Basic Kermit again! +; Those keen should study the followin gode with care, and remove +; or add semicolons as indicated. +; +; See also SPAR which decodes what comes in. It also decodes bits in +; the "capability" fields. (Two CAPAS files allowed from remote +; machines, but we will only send one at max.) Note that not all +; if any of the capability bits will be used. +; +; Definitions - init packet (data section only.. rest of header assumed OK) +; Byte 0 Maximum length I want to send +; 1 The Timeout I want you to use +; 2 Number of PAD characters I want tot use (May be null) +; 3 The PAD character I want to use (May be Null) +; 4 The End-of-Line character I will use (Carriage Return) +; 5 The control character Quote Character I will use (#) +; 6 The parity bit Quote Character I will use (&) +; 7 The Checktype I will use +; 8 The repeat prefix I will use (Null, as we cannot to repeats) +; 9 Capability Byte 0 (See SPAR for defs) +; 10 Capability byte 1 ( --- " --- but we will not send it.) +; 11 The number of packets I will send per window (not used) +; 12 MAXL1 - Long packet size, ms count +; 13 MAXL2 - Long packet size, ls count +; +; +; Enter with HL pointing to the "data" part of the packet. + +; +; older part of rpar follows... +; +; +rpar: lda rpsiz ;Get the receive packet size. + adi space ;Add a space to make it printable. + mov m,a ;Put it in the packet. + inx h ;Point to the next char. + lda rtime ;Get the receive packet time out. + adi space ;Add a space. + mov m,a ;Put it in the packet. + inx h + lda rpad ;Get the number of padding chars. + adi space + mov m,a + inx h + lda rpadch ;Get the padding char. + adi 100O ;Uncontrol it. + ani 7FH + mov m,a + inx h + lda reol ;Get the EOL char. + adi space + mov m,a + inx h + lda rquote ;Get the quote char. + mov m,a + inx h + mvi m,'Y' ;[jd] we know how to do 8-bit quoting + lda parity ;[jd] + cpi parnon ;[jd] parity none? + jz rpar1 ;[jd] yes, keep going + lda qbchr ;[jd] no, better request 8-bit quoting + mov m,a + +rpar1: + inx h ;Advance to next + lda chktyp ;Get desired block check type + mov m,a ;Store it + inx h ;Advance pointer + +; Comment out the next two lines for capas etc. WILL require debugging + mvi a,8 ; this id the older end for this routine. May be useful. + ret + +; [11] Rest not needed for now, commented out +; [10] (to ret) +; New additions to rpar follows... + +; lda rcap1 ; get the first capability byte +; ani 3eh ; mask out bit 0, ie only one CAPAS byte +; adi space ; tochar it +; mov m,a +; inx h +; mvi m,space ; No windows, ie space to packet +; inx h +; push h ; we need the HL regs for maths. +; lhld rdpkt ; get receive packet length +; lxi d,95 ; we want hl div 95 and hl mod 95 +; call divide ; return with divsion in hl, remainder in de +; mov a,l ; two sets of bytes +; pop h +; adi space ; tochar(maxl1) +; mov m,a +; inx h +; mov a,l +; adi space ; tochar(maxl2) +; mov m,a +; +; done all, set databytes = 12 and return +; mvi a,12 ; 12 bits of data +; ret + +;[11] End of commented out code for rpar + + +; +; This routine reads in all the send_init packet information. +; called by: rinit, sinit + +;[11] As for rpar, restore the "old" kermit code for non-capas Kermit. +;[10] (to ret at end) +; +; SPAR - routine to decode parameters received from the remote end +; +; Called by rinit,sinit +; +; Entry: a: Number of databytes in packet +; hl: Pointer to "data" part of packet +; +;spar: sta temp4 ; save for a while +; ; first clear some variables +; lda dspsiz ; get default "send" packet length +; sta spktl +; lda dstime ; get default time-out +; sta stimeo +; xra a ; set no pad characters by default +; sta spad +; lda dspadc ; get the default padding character +; sta spadc +; mvi a,cr ; default end of line character (CR) +; sta seol +; mvi a,dsquot ; default quote character +; sta squote +; mvi a,dsbqut ; default binary quote character +; sta qbchr +; mvi a,dschkt ; set checktype = 1 for inits +; sta inichk +; mvi a,space ; no repeat prefixing ( otherwise ~) +; sta srept +; +; Now follows the "capabilities" bits... 5 bits per capas byte. +; +; Note: Before extracting any data bits, apply unchar() to get the +; six ls bits. If bit 0 = 1 the a subsequent capaa byte follows +; +; Byte0: Bit 0: Set to 1 if there are subsequent CAPAS bytes +; 1: (Cap. 5) Set to 1 for long packets. Second byte +; AFTER the last capas byte has packet length DIV 95 +; and Thire byte has length MOD 95 +; 2: (Cap. 4) Sliding Windows. If used, first byte AFTER +; last capas byte has TOCHAR(no. of packets in window) +; 3: (Cap. 3) Ability to accept "A" (attribute packets) +; 4: (Cap. 2) Reserved +; 5: (Cap. 1) Reserved +; Byte 2 onward: not used in this implementation. Any capas bytes sent +; will be stored, however. +; +; lda temp4 ; get the number of bytes to test +; mov c,a ; to a count register +; mov a,m ; get first byte +; call decc ; unchar it, and decrement c +; sta spsiz ; save a send packet size +; jz sparx ; if no more, exit +; +; mov a,m ; get timout +; call decc +; sta stime ; save timeout +; jz sparx +; +; mov a,m ; get pad characters +; call decc +; sta spadc ; save it +; jz sparx +; +; mov a,m ; get pad character count +; call decc +; sta spad +; jz sparx +; +; mov a,m ; get send EOL +; call decc +; sta seol +; jz sparx +; +; mov a,m ; get control quote character +; call decc +; sta squote +; jz sparx +; +; mov a,m ; get binary (parity) quote char +; mov b,a ; this time we actually WANT accumulator +; cpi space ; are we doing 8th bit quoteing +; jz spar1 ; dont know, assume not +; cpi 'N' ; definately not? +; jz spar1 +; cpi 'Y' ; definately - use & +; jz spar2 +; sta squote ; else save the new character +;spar2: lda parity ; see if we are using the parity bit +; cpi parnon ; no parity => no quoting +; jz spar3 ; yup, so use the default quote character & +; +;spar1: xra a ; save not quoting +; sta squote +;spar3: call decc ; update counters etc +; jz sparx +; +; mov a,m ; get repeat prefixing +; call decc +; push psw ; save flags +; cpi space-32 ; we want it? +; jz spar4 +; sta srept +;spar4: pop psw ; restore flags +; jz sparx +; +; lxi d,scapas ; point to start of capability byte(s) +; push psw ; must do this... +;spar5: pop psw ; cos we restore the spack +; mov a,m +; call decc ; get scap1 (or n) +; sta scap1 +; push psw +; ani 01 ; another byte following? +; jnz spar5 +; pop psw ; see if any other data bytes (Windows etc) +; jz sparx +; +; mov a,m ; get window size +; call decc +; sta swindo +; jz sparx +; +; mov a,m ; get long packets ms bits +; call decc ; +; mov d,a ; unchared ms bits-ish +; mov a,m +; call decc ; ls bits-ish +; push h ; and we are doing maths +; push b ; and an intermediate result in c +; push psw ; we want flags and the ls bits... +; mvi b,0 +; mov c,d ; get ms bits-ish to bc +; push b ; get number to hl +; pop h +; now multipy by 95 +; dad h ;*2 +; dad h ;*4 +; dad h ;*8 +; dad h ;*16 +; push h ; *16 to ... +; pop d ; ... de +; dad h ;*32 +; dad d ; *(32+16) = *48 +; dad h ; *96 +; mov a,l ; *(96-1) +; sub c +; mov l,a +; mov a,0 +; sbb h +; mov h,a +; pop psw ; restore ls bitsish +; mov e,a +; mvi d,0 +; dad d ; *95 + ls bits. Phew. +; shld sdpkt ; save long packet length +; pop b +; pop h ; restore regs +; +;sparx: ret ; if here, (assume) no more data to read in +;[10] routines required follow +;decc: mov a,m ; get data byte +; sui space ; unchar it +; inx h ; increment input pointer +; dcr c ; decrement data counter +; ret ; return +;[10] end or spar replacement + +;[11] Restore older spar.... +; Older spar follows... +spar: sta temp4 ;Save the number of arguments. +; Initialize some variables to their required default values, so we use +; the right values even if the remote Kermit doesn't send the full packet: +; ; we don't do anything with timeout values yet. +; ; no default pad count/pad character? + mvi a,cr ; EOL character = carriage-return + sta seol + mvi a,'#' ; quote character = '#' + sta squote + mvi a,'&' ; eighth-bit quote character = '&' + sta qbchr + mvi a,'1' ; block-check = 1-character-checksum + sta inichk +; + mov a,m ;Get the max packet size. + sbi space ;Subtract a space. + sta spsiz ;Save it. + lda temp4 + cpi 3 ;Fewer than three pieces? + rm ;If so we are done. + inx h + inx h ;Increment past the time out info. + mov a,m ;Get the number of padding chars. + sbi space + sta spad + lda temp4 + cpi 4 ;Fewer than four pieces? + rm ;If so we are done. + inx h + mov a,m ;Get the padding char. + adi 100O ;Re-controlify it. + ani 7FH + sta spadch + lda temp4 + cpi 5 ;Fewer than five pieces? + rm ;If so we are done. + inx h + mov a,m ;Get the EOL char. + sbi space + sta seol + lda temp4 + cpi 6 ;Fewer than six pieces? + rm ;If so we are done. + inx h + mov a,m ;Get the quote char. + sta squote + lda temp4 ;Get the amount of data supplied + cpi 7 ;Have an 8-bit quote? + rm ;If not there, all done + inx h ;Yes, get the character + mvi a,0 ;[jd] + sta quot8 ;[jd] assume not quoting + mov a,m ;Get the supplied character + cpi 'N' ;[jd] No? + jz spar1 ;[jd] then don't try to do it + cpi space ;[jd] maybe they don't know about it... + jz spar1 ;[jd] then don't try to do it. + cpi 'Y' ;[jd] Yes? + jnz spar2 ;[jd] if not 'Y', assume it's a quote char. + lda parity ;[jd] using parity? + cpi parnon ;[jd] no, don't need quoting... + jz spar1 ;[jd] + mvi a,0ffh ;[jd] else turn on... + sta quot8 ;[jd] ...quote flag + jmp spar1 + +;[11] Note: If capas etc required, beware of the next two lables, as these +; are used elswhere. + +spar2: sta qbchr ;[jd] use their quote char (should validate) + mvi a,0ffh + sta quot8 ;[jd] turn quote flag and fall thru... + +spar1: lda temp4 ;Determine if block check type given + cpi 8 ;Is the field there? + rm ;If not, all done + inx h ;Point to the character + mov a,m ;Get the value + mov b,a ;Copy value + lda chktyp ;Get our type + cmp b ;Is it our desired type? + rnz ; If not, use default (1-character-checksum) + sta inichk ; Match, store as type to use after init + ret ; and return +;[10] end of replacement +;[11] end of replacement of replacement (ie back to original code) +; + +; Copy characters from packet to disk (or screen) +; called by: rdata + +ptchr: sta temp1 ;Save the size. + lda remtxt ;[MF]Get remote command flag + ora a ;[MF]Remote command in progress? + jnz ptchr0 ;[MF]Yes, don't check for file collisions + lda flwflg ;[MF]Get File Warning (Set Collision) flag + cpi 3 ;[MF]SET COLLISION DISCARD? + jnz ptchr0 ;[MF]No + lda dscflg ;[MF]Yes, get "discard" flag + ora a ;[MF]Discarding file? + jz ptchr0 ;[MF]No + mvi a,'X' ;[MF]Yes, simulate a user rejection + sta czseen ;[MF]... + jmp rskp ;[MF]and pretend success +ptchr0: ;[MF] + lxi h,data ;Beginning of received packet data. + shld outpnt ;Remember where we are. + lda rquote + mov b,a ;Keep the quote char in b. + mvi c,0 ;[jd] assume no 8-bit quote char + lda quot8 ;[jd] doing 8-bit quoting? + ora a + jz ptchr1 ;[jd] no, keep going + lda qbchr ;[jd] else get 8-bit quote char + mov c,a ;[jd] keep this in c +ptchr1: lxi h,temp1 + dcr m ;Decrement # of chars in packet. + jm rskp ;Return successfully if done. + lda remtxt ; to screen only? + ana a + jnz ptchr2 ; dont do any disk stuff + lxi h,chrcnt ;Number of chars remaining in dma. + dcr m ;Decrement. + jp ptchr2 ;Continue if space left. + call outbuf ;Output it if full. + jmp ptchr9 ; Error return if disk is full. +ptchr2: lhld outpnt ;Get position in output buffer. + mov a,m ;Grab a char. + inx h + shld outpnt ;and bump pointer. + mvi e,0 ;[jd] assume nothing to OR in. + cmp c ;[jd] is it the binary quote char? + jnz ptch2a ;[jd] no, keep going + mvi e,80h ;[jd] include parity bit + lda temp1 + dcr a + sta temp1 ;[jd] decrement character count + mov a,m ;[jd] get next character + inx h + shld outpnt +ptch2a: cmp b ;Is it the quote char? + jnz ptchr3 ;[jd] changed to ptchr3 so includes parity + mov a,m ;Get the quoted character + inx h + shld outpnt ;and bump pointer. + lxi h,temp1 + dcr m ;Decrement # of chars in packet. + mov d,a ;Save the char. + ani 80H ;Turn off all but the parity bit. + ora e ;[jd] let parity come from either (???) + mov e,a ;Save the parity bit. + mov a,d ;Get the char. + ani 7FH ;Turn off the parity bit. + cmp b ;Is it the quote char? + jz ptchr3 ;If so just go write it out. + cmp c ;[jd] maybe it's the 8-bit prefix character? + jz ptchr3 ;[jd] then don't controllify. + mov a,d ;Get the char. + adi 40H ;Make the character a control char again. + ani 7FH ;Modulo 128. +ptchr3: ora e ;Or in the parity bit. + sta temp3 ; save for a while + lda remtxt ; to screen or disk? + ana a + lda temp3 + jz ptch31 ; to disk + push h + push d + push b + mov e,a ; to display + mvi c,dconio + call bdos + pop b + pop d + pop h + jmp ptchr1 ; continue + +ptch31: lhld bufpnt ;Destination buffer. + mov m,a ;Store it. + inx h + shld bufpnt ;Update the pointer + jmp ptchr1 ;and loop to next char. + +ptchr9: lxi d,erms11 ; "?Disk full" + push d ;[MF] Save pointer + call error3 ; put it on the error line + pop d ;[MF] Restore pointer + lxi h,data ;[MF] Where to put the message for "e" packet + lda argblk ;[MF] Get packet-number + call countp ;[MF]Increment it + sta argblk ;[MF] as packet to send + xra a ;[MF] Zero length of packet data + sta temp1 ;[MF] ... +ptch9a: ldax d ;[MF] Get a character to copy + cpi cr ;[MF] No more to copy? + jz ptch9b ;[MF] Yes, we can send the packet + mov m,a ;[MF] No, copy the character + inx d ;[MF] and increment source/dest pointers + inx h ;[MF] ... + lda temp1 ;[MF] Get character count + inr a ;[MF] and increment it + sta temp1 ;[MF] ... + jmp ptch9a ;[MF] Copy entire error message +ptch9b: mvi m,0 ;[MF]Put in a zero + lda temp1 ;[MF] Get number of characters in the message + sta argblk+1 ;[MF] and store as number of packet data chars + mvi a,'E' ;[MF] Make it an error packet + call spack ;[MF] Send the error packet + nop ;[MF] Don't really care if + nop ;[MF] the send fails since we're + nop ;[MF] bombing off anyway + ret ; take error return. +; +; Fill a data packet from file +; called by: sfile, sdata + +gtchr: lda squote ;Get the quote char. + mov c,a ;Keep quote char in c. + lda curchk ;Get current block check type + sui '1' ;Get the extra overhead + mov b,a ;Get a copy + lda spsiz ;Get the maximum packet size. + sui 5 ;Subtract the overhead. + sub b ;Determine max packet length + sta temp1 ;This is the number of chars we are to get. + lxi h,filbuf ;Where to put the data. + shld cbfptr ;Remember where we are. + mvi b,0 ;No chars. +gtchr1: lda temp1 + dcr a ;Decrement the number of chars left. + jp gtchr2 ;Go on if there is more than one left. + mov a,b ;Return the count in A. + jmp rskp + +gtchr2: sta temp1 + lda chrcnt ;Space left in the DMA. + dcr a +;* Can improve order here. + jm gtchr3 + sta chrcnt + jmp gtchr4 + +gtchr3: call inbuf ;Get another buffer full. + jmp gtch30 ; If no more return what we got. + jmp gtchr4 ;If we got some, proceed. + +gtch30: mov a,b ;Return the count in A. + ora a ;Get any chars? + jnz rskp ;If so return them. + jmp gtceof ;If not, say we found the end of the file. + +gtchr4: lhld bufpnt ;Position in DMA. + mov a,m ;Get a char from the file. + inx h + shld bufpnt + mov d,a ;Save the char. + ani 80H ;Turn off all but parity. + mov e,a ;Save the parity bit. + jz gtch4a ;[jd] no parity, skip this check... + lda quot8 ;[jd] doing eighth-bit quoting? + ora a + jz gtch4a ;[jd] no, just proceed normally + lda temp1 ;[jd] get space remaining + cpi 2 ;[jd] 3 chrs left (one cnted already)? + jm gtchr9 ;[jd] no, skip this + dcr a ;[jd] decrement space remaining + sta temp1 ;[jd] put back. + lhld cbfptr ;[jd] Position in character buffer. + lda qbchr ;[jd] get quote character + mov m,a ;]jd] Put the quote char in the buffer. + inx h ;[jd] increment destination buffer pointer + shld cbfptr ;[jd] store the pointer back + inr b ;[jd] Increment the char count. + mvi e,0 ;[jd] no parity bit to OR in. +;[jd] fall thru... + +gtch4a: mov a,d ;Restore the char. + ani 7FH ;Turn off the parity. + mov d,a ;[jd] save here for later... + cpi space ;Compare to a space. + jm gtchr5 ;If less then its a control char, handle it. + cpi del ;Is the char a delete? + jz gtchr5 ;Go quote it. + lda quot8 ; Are we doing 8th-bit quoting? + ora a + jz gtch4c ; if not, skip this test and restore character. + lda qbchr ; get 8th-bit quote character + cmp d ; same as current character? + jz gtch4b ; yes, have to quote it... +gtch4c: mov a,d ; no. get character back again. + cmp c ;Is it the quote char? + jnz gtchr8 ;If not proceed. +gtch4b: lxi h,temp1 ;[jd] point to char count + dcr m ;[jd] decrement (know room for at least one) + lhld cbfptr ;Position in character buffer. + mov m,c ;Put the (quote) char in the buffer. + inx h + shld cbfptr + inr b ;Increment the char count. + mov a,d ;[jd] restore character again + jmp gtchr8 + +gtchr5: + ;[gnn] ignore parity for checking +; ora e ;Turn on the parity bit. + + cpi ('Z'-100O) ;Is it a ^Z? + jnz gtchr7 ;If not just proceed. + lda cpmflg ;Was the file created by CPM... + cpi 1 ;in ASCII-mode ? + jz gtch52 ;Control-Z stops text + cpi 2 ;in BINARY mode? + jz gtchr6 ;Yes, pass the ^Z +;At this point file-mode is DEFAULT. +;If the rest of the record is filled with ^Zs, we're at EOF, otherwise +;its a regular character. + lhld bufpnt ;since CHRCNT is ZERO at EOF-time + lda chrcnt ;(set by INBUF5 B.G.E) + mov d,a ;Get the number of chars left in the DMA. +gtch51: dcr d + mov a,d + jp gtch53 ;Any chars left? +gtch52: xra a ;If not, get a zero. + sta chrcnt ;Say no more chars in buffer. + mov a,b ;Return the count in A. + jmp rskp + +;Scan rest of buffer for non ^Z -- If we find a non ^Z, fall into gtchr6. +;If we get to the end of the buffer before finding a non ^Z, fall into gtch52. +gtch53: mov a,m ;Get the next char. + inx h ;Move the pointer. + cpi ('Z'-100O) ;Is it a ^Z? + jz gtch51 ;If so see if the rest are. + +gtchr6: mvi a,('Z'-100O) ;Restore the ^Z. +gtchr7: sta temp2 ;Save the char. + lxi h,temp1 ;Point to the char total remaining. + dcr m ;Decrement it. + lhld cbfptr ;Position in character buffer. + mov m,c ;Put the quote in the buffer. + inx h + shld cbfptr + inr b ;Increment the char count. + lda temp2 ;Get the control char back. + adi 40H ;Make the non-control. + ani 7fH ;Modulo 200 octal. +gtchr8: lhld cbfptr ;Position in character buffer. + ora e ;Or in the parity bit. + mov m,a ;Put the char in the buffer. + inx h + shld cbfptr + inr b ;Increment the char count. + jmp gtchr1 ;Go around again. + +gtchr9: ;[jd] not enough room left in buffer... + lhld bufpnt + dcx h + shld bufpnt ;[jd] back up over last character + lxi h,chrcnt ;[jd] point to character count + inr m ;[jd] increment it + mov a,b ;[jd] count of chars transferred + jmp rskp ;[jd] return it + +gtceof: mvi a,0FFH ;Get a minus one. + ret +; + +; Little code to allow some expansion of code without changing +; every futher address, only up to the end of this file. +; TO BE REMOVED FRO RELEASE! + +; org ($+100h) AND 0FF00H + +IF lasm + LINK CPSPK2 ;[obs] Link to part two of the packet file +ENDIF ;lasm diff --git a/cpspk2.asm b/cpspk2.asm index b246967..724c6d2 100644 --- a/cpspk2.asm +++ b/cpspk2.asm @@ -1,1336 +1,1336 @@ -; CPSPK2.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the (system-independent) routines that implement -; the KERMIT protocol, and the commands that use them: -; RECEIVE, SEND, FINISH, and LOGOUT. -; -; revision history: -; -;edit 11, 21-Mar-1991 by MF. After "inchr7", close TAKE-file (if any) so -; ^C will halt all processing (including commands from TAKE-files) -; and put the user back at Kermit command-level. -;edit 10, 3-Jan-1991 by MF. Modify routine "inchr" after label "inchr5" to -; not take retry (nonskip) return if ^X/^Z seen on the Console. This -; will prevent multiple copies of packets being sent if user aborts -; some files in a stream being sent via ^X and is a better fix to this -; problem than flushing comm input before sending the "Z" packet -; requesting the remote Kermit to discard the current file being -; received (as implemented in CPSPK1.ASM edit of 2-jan-1991). -;edit 9, 14-Dec-1990 by MF. Modified "gofil" routine to allow for -; specification of a drive in the local filespec for GET and -; RECEIVE commands. Thus commands such as -; GET HELLO.TXT B:GOODBYE.TXT -; and -; RECEIVE B:GOODBYE.TXT -; now work as expected. -;edit 8, 22-Oct-1990 by MF. Fixed bug in completion-message routine -; "finmes" wherein the completion message was not printed if the -; terminal was set to QUIET because the message pointer was clobbered -; by prcrlf. -;edit 7, 14-Sep-1990 by MF. Add hooks for SET COLLISION command. -; Eliminate commented-out old file warning rename routine. -; Clear communication input buffers (call flsmdm) before -; BYE, FINISH and LOGOUT commands. -;edit 6, 9-Sep-1990 by MF. Implemented fixes in CPKERM.BWR for -; garbage printout during quiet transfers and for file existence/ -; rename algorithm. -; Also implemented hooks for Remote commands. -; edit 5, 18 June 1990 by Russell Lang [rjl@monu1.cc.monash.edu.au] -; When trying to generate a unique file name on receive, zero -; the attribute bits between file opening attempts. This is -; to fix a bug which caused the unique file name to have the -; attributes of the already existing file. If the attribute -; was R/O, a bdos error occured later when an attempt was made -; to write to the file. -; -; edit 4, 27 October, 1987 By OBSchou. Changed the rename routine to -; be more like the MSDOS issue. -; -; edit 3, 28 July, by OBSchou. Added traps to NOT print to screen during -; file transfers if quietd is non zero (ie we SET TERMINAL QUIET) -; This hopefully speeds up transfers in systems spending an age -; updating the screen. -; -; edit 2, 8 April, 1987 by OBSchou. Minor edit to put drive and user number -; in the "filename" field on the transfer screen. This means that the -; offset on the line foe the file name proper has moved along 4 space. -; Also, it writes 15 spaces AFER the xxd: string to clear the field -; of any prevous file. Needed for thos terminals that cannot -; clear to end of line... -; -; edit 1, 28 January, 1987 by OBSchou. -; Hived off about 1/2 of CPSPKT.ASM to form two (smaller => easier -; to handle) files. -; -; - -pk2ver: db 'CPSPK2.ASM (11) 21-Mar-1991$' ; name, edit number, date - - -; -; Get the file name (including host to micro translation) -; called by: rfile - -gofil: xra a - sta fcb ;Set the drive to default to current. - lxi h,data ;Get the address of the file name. -; allow use of local name if one was given [gnn] - lda remlen ;[gnn] - ora a ;[gnn] anything there? - jz gofil0 ;[gnn] no, use the one in the data packet - lxi h,remnam ;[gnn] yes, use this instead - lda remnam+1 ;[MF]Get 2nd char of local filename - cpi ':' ;[MF]Was a drive specified? - jnz gofil0 ;[MF]No, proceed as of old - mov a,m ;[MF]Yes, get drive - ani 5fh ;[MF]Force uppercase - sui 'A'-1 ;[MF]Make valid drive for fcb - sta fcb ;[MF]and store in fcb - inx h ;[MF]Skip drive and delimiter - inx h ;[MF]... -gofil0: ;[gnn] continue to set up the file [gnn] -; - shld datptr ;Store the address. - lxi h,fcb+1 ;Address of the FCB. - shld fcbptr ;Save it. - xra a - sta temp1 ;Initialize the char count. - sta temp2 - mvi b,' ' -gofil1: mov m,b ;Blank the FCB. - inx h - inr a -; cpi 0CH ;Twelve?[5a] - cpi 0BH ; Eleven? [5a] - jm gofil1 - mvi m,0 ; [5a] Specify extent 0 -gofil2: lhld datptr ;Get the NAME field. - mov a,m - cpi 'a' ;Force upper case - jm gofl2a ; - ani 5FH ; -gofl2a: inx h - cpi '.' ;Seperator? - jnz gofil3 - shld datptr ;[jd] update ptr (moved from above) - lxi h,fcb+9H - shld fcbptr - lda temp1 - sta temp2 - mvi a,9H - sta temp1 - jmp gofil6 - -gofil3: ora a ;Trailing null? - jz gofil7 ;Then we're done. - shld datptr ;[jd] no, can update ptr now. - lhld fcbptr - mov m,a - inx h - shld fcbptr - lda temp1 ;Get the char count. - inr a - sta temp1 - cpi 8H ;Are we finished with this field? - jm gofil2 -gofil4: sta temp2 - lhld datptr - mov a,m - inx h - shld datptr - ora a - jz gofil7 - cpi '.' ;Is this the terminator? - jnz gofil4 ;Go until we find it. -gofil6: lhld datptr ;Get the TYPE field. - mov a,m - cpi 'a' ;Force upper case - jm gofl6a ; - ani 5FH ; -gofl6a: ora a ;Trailing null? - jz gofil7 ;Then we're done. -;[jd] move above two lines so we don't increment pointer if char is null - inx h - shld datptr - lhld fcbptr - mov m,a - inx h - shld fcbptr - lda temp1 ;Get the char count. - inr a - sta temp1 - cpi 0CH ;Are we finished with this field? - jm gofil6 -gofil7: lhld datptr - mvi m,'$' ;Put in a dollar sign for printing. - lda quietd ; quiet display? - ana a - jnz gofi70 ; yes, so skip it. - call scrfln ;Position cursor -gofi70: lxi d,data ;Print the file name - lda getrxflg ;[obs 8] are we doing a get or receive? - ana a ;[obs 8] - jz gofi7a ;[obs 8] if zero, receive - lxi d,remnam ;[obs 8] -gofi7a: ;[obs 8] - - call prtstr -gofi7b: xra a ;[MF]Zero "discard" flag - sta dscflg ;[MF]... - lda flwflg ;Is file warning on? - ora a - jz gofil9 ;If not, just proceed. - mvi c,openf ;See if the file exists. - lxi d,fcb - call bdos - cpi 0FFH ;Does it exist? - jz gofil9 ;If not create it. -; - lda flwflg ;[MF]Get flag again - cpi 3 ;[MF]SET COLLISION DISCARD? - jnz gofi7h ;[MF]No - mvi a,0ffh ;[MF]Yes, order rejection of the file - sta dscflg ;[MF]... - jmp rskp ;[MF]and pretend successful open -gofi7h: push psw ;[MF]Save Collision status - lxi d,infms5 - call error3 - pop psw ;[MF]Restore Collision status - cpi 1 ;[MF]SET COLLISION RENAME? - jz gofi7i ;[MF]Yes, same as SET WARNING ON - ;[MF]If we come here, SET COLLISION BACKUP - lxi h,fcb ;[MF]Copy original fcb to a safe place - lxi d,colfcb ;[MF]... - lxi b,33 ;[MF]... - call mover ;[MF]... - ;[MF]and fall into rename code -gofi7i: ;[MF] -; -; Replacement file name renamer routine. Incomming -; files are renamed in this manner: -; original file name: filex.ext -; first rename: filex001.ext -; ... ... -; ninth rename filex009.ext -; 10th rename fail - would we really want 10 -; files of the same name?? -; -; -; 1) -; Assume that we need to "rename" the file, so lets make sure -; that there is a full. 8 character filename. (We make it if -; it does not already exist) -; 1a) If full file name, last character is to be replaced -; by a zero. This gives us up to no#ine renames. -; 2)open file -; 2a)If exists, increment last character by one -; 2b)if = '9' then abort -; 2c)If does not exist, got 2) -; 3)we have a valid 'renamed' file -; -;Part 1) - fill out filename part - - mvi c,8 ; max 8 characters to test for - mvi a,'0' ; spaces to be replaced by a zero. - lxi h,fcb+8 ; start at the end -gofi7c: mov m,a ; put a zero in here - dcr c ; come to the end? - jz gofi7d ; should not have, but just in case... - dcx h ; previous chararcter - mov a,m ; get it - cpi ' ' ; if this character a space as well, zero it - mvi a,'0' ; set it to ascii zero just in case... - jz gofi7c ; -; -; Part 2) open the file (if success, then it exists) - -gofi7d: -;zero the attribute bits. [rjl@monu1.cc.monash.edu.au] - lxi h,fcb+1 ;[rjl] - mvi c,11 ;[rjl] -gofi7z: mov a,m ;[rjl] - ani 07fh ;[rjl] - mov m,a ;[rjl] - inx h ;[rjl] - dcr c ;[rjl] - jnz gofi7z ;[rjl] - lxi d,fcb - mvi c,openf - call BDOS - inr a ; if 0ffh returned, error (ie does not exist) - jz gofi7e - lda fcb+8 ; get last character - inr a - sta fcb+8 - cpi '9'+1 ; more than '9' => too far, lets give up. - jnz gofi7d ; else try again -;Giving up, so lets exit - lxi d,erms16 ; - call prtstr - ret ; return to error routine - -gofi7e: lxi d,fnbuf ; make the file name into a character string - lxi h,fcb+1 ; point to source file name, less drive name - mvi c,8 ; 11 characters (8+3) + dot to copy across -; -gofi7f: mov a,m ; get character - stax d - inx h - inx d - dcr c - jnz gofi7f ; loop until all done - - mvi a,'.' ; then the dot - stax d - inx d - - mvi c,3 ; then the file extention - -gofi7g: mov a,m - stax d - inx h - inx d - dcr c - jnz gofi7g ; loop until extention copied across - - mvi a,'$' ; dollar terminate string - stax d - lxi d,fnbuf ;[MF]Point to string - call prtstr ; write string to console - - lda flwflg ;[MF]Get warning (SET COLLISION) flag - cpi 2 ;[MF]SET COLLISION BACKUP? - jnz gofil9 ;[MF]No - lxi h,fcb ;[MF]Yes, get new filename fcb - lxi d,colfcb+16 ;[MF]Where to copy to for rename - lxi b,16 ;[MF]Copy 16 bytes - call mover ;[MF]... - lxi d,colfcb ;[MF]Point to rename fcb - mvi c,renam ;[MF]Rename function - call bdos ;[MF]Try to rename original file - cpi 0ffh ;[MF]Did we win? - jnz gofl82 ;[MF]Yes - lxi d,erms16 ;[MF]No, complain and bomb - jmp error3 ;[MF]... -gofl82: lxi h,colfcb ;[MF]Now recopy original filename into fcb - lxi d,fcb ;[MF]to create new file with original name - lxi b,16 ;[MF]... - call mover ;[MF]... -; -; -;Now lets make the file (create it) - -gofil9: call makfil ; Create the file. - jmp gofl91 ; Disk was full. - jmp rskp ; Success. - -gofl91: lxi d,erms11 - call error3 - ret -; -; This is the FINISH command. It tells the remote KERSRV to exit. -; here from kermit - -finish: call cfmcmd - call selmdm ;[MF]Select modem - call flsmdm ;[MF]Flush buffers - call selcon ;[MF]Select keyboard again - xra a - sta numtry ;Inititialize count. - mvi a,'1' ;Reset block check type to single character - sta curchk ; . . . - -finsh1: lda numtry ;How many times have we tried? - cpi maxtry ;Too many times? - jm finsh3 ;No, try it. -finsh2: lxi d,erms18 ;Say we couldn't do it. - call prtstr - jmp kermit ;Go home. - -finsh3: inr a ;Increment the number of tries. - sta numtry - xra a - sta argblk ;Make it packet number zero. - mvi a,1 - sta argblk+1 ;One piece of data. - lxi h,data - mvi m,'F' ;Finish running Kermit. - mvi a,'G' ;Generic command packet. - call spack - jmp finsh2 ; Tell the user and die. - call rpack ;Get an acknowledgement. - jmp finsh1 ; Go try again. - cpi 'Y' ;ACK? - jz kermit ;Yes, we are done. - cpi 'E' ;Is it an error packet? - jnz finsh1 ;Try sending the packet again. - call error1 ;Print the error message. - jmp kermit -; -; This is the LOGOUT command. It tells the remote KERSRV to logout. -; here from: kermit - -logout: call cfmcmd - call logo ;Send the logout packet. - jmp kermit ;Go get another command - jmp kermit ; whether we succeed or not. - -; do logout processing. -; called by: bye, logout - -logo: call selmdm ;[MF]Select modem - call flsmdm ;[MF]Flush buffers - call selcon ;[MF]Select keyboard again - xra a - sta numtry ;Inititialize count. - mvi a,'1' ;Reset block check type to single character - sta curchk ; . . . - -logo1: lda numtry ;How many times have we tried? - cpi maxtry ;Too many times? - jm logo3 ;No, try it. -logo2: lxi d,erms19 ;Say we couldn't do it. - call prtstr - ret ;Finished. - -logo3: inr a ;Increment the number of tries. - sta numtry - xra a - sta argblk ;Make it packet number zero. - mvi a,1 - sta argblk+1 ;One piece of data. - lxi h,data - mvi m,'L' ;Logout the remote host. - mvi a,'G' ;Generic command packet. - call spack - jmp logo2 ; Tell the user and die. - call rpack ;Get an acknowledgement - jmp logo1 ; Go try again. - cpi 'Y' ;ACK? - jz rskp ;Yes, we are done. - cpi 'E' ;Is it an error packet? - jnz logo1 ;Try sending the packet again. - call error1 ;Print the error message. - ret ;All done. -; -; Packet routines - -; Send_Packet -; This routine assembles a packet from the arguments given and sends it -; to the host. -; -; Expects the following: -; A - Type of packet (D,Y,N,S,R,E,F,Z,T) -; ARGBLK - Packet sequence number -; ARGBLK+1 - Number of data characters -; Returns: nonskip if failure -; skip if success -; called by: read, rinit, rfile, rdata, sinit, sfile, sdata, seof, seot, -; finish, logout, nak, ackp - -spack: sta argblk+2 - lxi h,packet ;Get address of the send packet. - lda sndsop ;[gnn] send start-of-pkt char. - mov m,a ;Put in the packet. - inx h ;Point to next char. - lda curchk ;Get current checksum type - sui '1' ;Determine extra length of checksum - mov b,a ;Copy length - lda argblk+1 ;Get the number of data chars. - adi ' '+3 ;Real packet character count made printable. - add b ;Determine overall length - mov m,a ;Put in the packet. - inx h ;Point to next char. - lxi b,0 ;Zero the checksum AC. - mov c,a ;Start the checksum. - lda argblk ;Get the packet number. - adi ' ' ;Add a space so the number is printable. - mov m,a ;Put in the packet. - inx h ;Point to next char. - add c - mov c,a ;Add the packet number to the checksum. - mvi a,0 ;Clear A (Cannot be XRA A, since we can't - ; touch carry flag) - adc b ;Get high order portion of checksum - mov b,a ;Copy back to B - lda argblk+2 ;Get the packet type. - mov m,a ;Put in the packet. - inx h ;Point to next char. - add c - mov c,a ;Add the packet number to the checksum. - mvi a,0 ;Clear A - adc b ;Get high order portion of checksum - mov b,a ;Copy back to B -spack2: lda argblk+1 ;Get the packet size. - ora a ;Are there any chars of data? - jz spack3 ; No, finish up. - dcr a ;Decrement the char count. - sta argblk+1 ;Put it back. - mov a,m ;Get the next char. - inx h ;Point to next char. - add c - mov c,a ;Add the packet number to the checksum. - mvi a,0 ;Clear A - adc b ;Get high order portion of checksum - mov b,a ;Copy back to B - jmp spack2 ;Go try again. - -spack3: lda curchk ;Get the current checksum type - cpi '2' ;Two character? - jz spack4 ;Yes, go handle it - jnc spack5 ;No, go handle CRC if '3' - mov a,c ;Get the character total. - ani 0C0H ;Turn off all but the two high order bits. - ;Shift them into the low order position. - rlc ;Two left rotates same as 6 rights - rlc ; . . . - add c ;Add it to the old bits. - ani 3FH ;Turn off the two high order bits. (MOD 64) - adi ' ' ;Add a space so the number is printable. - mov m,a ;Put in the packet. - inx h ;Point to next char. - jmp spack7 ;Go store eol character - -;Here for 3 character CRC-CCITT - -spack5: mvi m,0 ;Store a null for current end - push h ;Save H - lxi h,packet+1 ;Point to first checksumed character - call crcclc ;Calculate the CRC - pop h ;Restore the pointer - mov c,e ;Get low order half for later - mov b,d ;Copy the high order - mov a,d ;Get the high order portion - rlc ;Shift off low 4 bits - rlc ; . . . - rlc ; . . . - rlc ; . . . - ani 0FH ;Keep only low 4 bits - adi ' ' ;Put into printing range - mov m,a ;Store the character - inx h ;Point to next position - -;Here for two character checksum - -spack4: mov a,b ;Get high order portion - ani 0FH ;Only keep last four bits - rlc ;Shift up two bits - rlc ; . . . - mov b,a ;Copy back into safe place - mov a,c ;Get low order half - rlc ;Shift high two bits - rlc ;to low two bits - ani 03H ;Keep only two low bits - ora b ;Get high order portion in - adi ' ' ;Convert to printing character range - mov m,a ;Store the character - inx h ;Point to next character - mov a,c ;get low order portion - ani 3FH ;Keep only six bits - adi ' ' ;Convert to printing range - mov m,a ;Store it - inx h ;Bump the pointer - -spack7: lda dbgflg - ora a ; is debugging enabled? - jz spack8 - push h ; yes. save address of end of packet - mvi m,0 ; null-terminate the packet for display - lda quietd ; a quiet display? - ana a - jnz spac7a ; so dont say a thing - call sppos ; position cursor - lxi h,packet+1 ; print the packet - call dmptxt - lda prnflg ; is the printer on too? - ana a - jz spac7a - lxi h,sstatm ; print state - call printm ; dumptext but to printer - lda state - mov e,a - call outprn - lxi h,princr ; cr lf to printer - call printm - lxi h,spackm - call printm - lxi h,packet+1 - call printm - lxi h,princr - call printm - lxi h,princr - call printm - -spac7a: pop h ; restore address of end of packet -spack8: lda seol ;Get the EOL the other host wants. - mov m,a ;Put in the packet. - inx h ;Point to next char. - xra a ;Get a null. - mov m,a ;Put in the packet. -; Write out the packet. -outpkt: call selmdm ; Set up for output to comm port if iobyt - lda spad ;Get the number of padding chars. - sta temp1 -outpk2: lda temp1 ;Get the count. - dcr a - ora a - jm outpk6 ;If none left proceed. - sta temp1 - lda spadch ;Get the padding char. - call setpar ;Set parity appropriately - mov e,a ;Put the char in right AC. - call outmdm ;Output it. - jmp outpk2 - -outpk6: lxi h,packet ; Point to the packet. -outlup: mov a,m ; Get the next character. - ora a ; Is it a null? - jz outlud ; If so return success. - call setpar ; Set parity for the character - mov e,a ; Put it in right AC - call outmdm ; and output it. -; TAC trap: If this character is the TAC intercept character, and the TAC -; trap is enabled, we have to output it twice. If the TAC trap is enabled, -; tacflg contains the intercept character. (The current character cannot -; be NUL, so we don't have to worry about doubling nulls in the message) - lda tacflg ; get current intercept character, or zero. - cmp m ; compare against current data character. - jnz outpk8 ; if different, do nothing. - call setpar ; match. set appropriate parity, - mov e,a ; put it in the right register, - call outmdm ; and output it a second time. -outpk8: - inx h ; Increment the char pointer. - jmp outlup - -outlud: call selcon ; select console - jmp rskp ; and return success -; -; Receive_Packet -; This routine waits for a packet to arrive from the host. It reads -; characters until it finds a SOH. It then reads the packet into packet. -; -; Returns: nonskip if failure (checksum wrong or packet trashed) -; skip if success, with -; A - message type -; ARGBLK - message number -; ARGBLK+1 - length of data -; called by: rinit, rfile, rdata, -; sinit, sfile, sdata, seof, seot, finish, logout - -rpack: call inpkt ;Read up to the end-of-line character - jmp r ; Return bad. -rpack0: call getchr ;Get a character. - jmp rpack ; Hit eol;null line;just start over. - lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. - cmp m ;[gnn] - jnz rpack0 ; No, go until it is. -rpack1: call getchr ;Get a character. - jmp r ; Hit end of line, return bad. - lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. - cmp m ;[gnn] - jz rpack1 ; Yes, then go start over. - sta packet+1 ;Store in packet also - mov c,a ;Start the checksum. - lda curchk ;Get block check type - sui '1' ;Determine extra length of block check - mov b,a ;Get a copy - mov a,c ;Get back length character - sui ' '+3 ;Get the real data count. - sub b ;Get total length - sta argblk+1 - mvi b,0 ;Clear high order half of checksum - call getchr ;Get a character. - jmp r ; Hit end of line, return bad. - lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. - cmp m ;[gnn] - jz rpack1 ; Yes, then go start over. - sta argblk - sta packet+2 ;Save also in packet - add c - mov c,a ;Add the character to the checksum. - mvi a,0 ;Clear A - adc b ;Get high order portion of checksum - mov b,a ;Copy back to B - lda argblk - sui ' ' ;Get the real packet number. - sta argblk - call getchr ;Get a character. - jmp r ; Hit end of line, return bad. - lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. - cmp m ;[gnn] - jz rpack1 ; Yes, then go start over. - sta temp1 ;Save the message type. - sta packet+3 ;Save in packet - add c - mov c,a ;Add the character to the checksum. - mvi a,0 ;Clear A - adc b ;Get high order portion of checksum - mov b,a ;Copy back to B - lda argblk+1 ;Get the number of data characters. - sta temp2 - lxi h,data ;Point to the data buffer. - shld datptr -rpack2: lda temp2 - sui 1 ;Any data characters? - jm rpack3 ; If not go get the checksum. - sta temp2 - call getchr ;Get a character. - jmp r ; Hit end of line, return bad. - lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. - cmp m ;[gnn] - jz rpack1 ; Yes, then go start over. - lhld datptr - mov m,a ;Put the char into the packet. - inx h ;Point to the next character. - shld datptr - add c - mov c,a ;Add the character to the checksum. - mvi a,0 ;Clear A - adc b ;Get high order portion of checksum - mov b,a ;Copy back to B - jmp rpack2 ;Go get another. - -rpack3: call getchr ;Get a character. - jmp r ; Hit end of line, return bad. - lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. - cmp m ;[gnn] - jz rpack1 ; Yes, then go start over. - sui ' ' ;Turn the char back into a number. - sta temp3 -;Determine type of checksum - - lda curchk ;Get the current checksum type - cpi '2' ;1, 2 or 3 character? - jz rpack4 ;If zero, 2 character - jnc rpack5 ;Go handle 3 character - mov a,c ;Get the character total. - ani 0C0H ;Turn off all but the two high order bits. - ;Shift them into the low order position. - rlc ;Two left rotates same as six rights - rlc ; . . . - add c ;Add it to the old bits. - ani 3FH ;Turn off the two high order bits. (MOD 64) - mov b,a - lda temp3 ;Get the real received checksum. - cmp b ;Are they equal? - jz rpack7 ;If so, proceed. -rpack9: call updrtr ;If not, update the number of retries. - ret ;Return error. - -;Here for three character CRC-CCITT - -rpack5: lhld datptr ;Get the address of the data - mvi m,0 ;Store a zero in the buffer to terminate packet - lxi h,packet+1 ;Point at start of checksummed region - call crcclc ;Calculate the CRC - mov c,e ;Save low order half for later - mov b,d ;Also copy high order - mov a,d ;Get high byte - rlc ;Want high four bits - rlc ; . . . - rlc ;And shift two more - rlc ; . . . - ani 0FH ;Keep only 4 bits - mov d,a ;Back into D - lda temp3 ;Get first value back - cmp d ;Correct? - jnz rpack9 ;No, punt - call getchr ;Get a character. - jmp r ; Hit end of line, return bad. - lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. - cmp m ;[gnn] - jz rpack1 ; Yes, then go start over. - sui ' ' ;Remove space offset - sta temp3 ;Store for later check - ;... - -;Here for a two character checksum and last two characters of CRC - -rpack4: mov a,b ;Get high order portion - ani 0FH ;Only four bits - rlc ;Shift up two bits - rlc ; . . . - mov b,a ;Save back in B - mov a,c ;Get low order - rlc ;move two high bits to low bits - rlc ; . . . - ani 03H ;Save only low two bits - ora b ;Get other 4 bits - mov b,a ;Save back in B - lda temp3 ;Get this portion of checksum - cmp b ;Check first half - jnz rpack9 ;If bad, go give up - call getchr ;Get a character. - jmp r ; Hit end of line, return bad. - lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. - cmp m ;[gnn] - jz rpack1 ; Yes, then go start over. - sui ' ' ;Remove space offset - mov b,a ;Save in safe place - mov a,c ;Get low 8 bits of checksum - ani 3FH ;Keep only 6 bits - cmp b ;Correct value - jnz rpack9 ;Bad, give up -rpack7: lhld datptr - mvi m,0 ;Put a null at the end of the data. - lda temp1 ;Get the type. - jmp rskp -; -; inpkt - receive and buffer packet -; returns: nonskip if error (timeout) -; skip if success; packet starts at recpkt (which holds the SOH) -; and is terminated by a null. -; console is selected in either case. -; called by: rpack - -inpkt: lxi h,recpkt ;Point to the beginning of the packet. - shld pktptr -inpkt1: call inchr ;Get first character - jmp r ;Return failure - lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. - cmp m ;[gnn] - jnz inpkt1 ;if not, ignore leading junk - jmp inpkt3 ;else go put it in packet - -inpkt2: call inchr ;Get a character. - jmp r ; Return failure. - lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. - cmp m ;[gnn] - jnz inpkt3 ;if not continue - lxi h,recpkt ;else throw away what we've got so far - shld pktptr ; -inpkt3: lhld pktptr ; - mov m,a ;Put the char in the packet. - inx h - shld pktptr - mov b,a - lxi d,-recpkx ;Start over if packet buffer overflow - dad d ; - jc inpkt ;buffer overflow - lda reol ;Get the EOL char. - cmp b - jnz inpkt2 ;If not loop for another. -;[gnn] *** added by Godfrey Nix Nottingham University *** -;[gnn] to allow Kermit server to echo our packets back - lxi h,recpkt+3 ;[gnn] point to packet type - lda packet+3 ;[gnn] get the one we sent - cmp m ;[gnn] are they the same? - jz inpkt ;[gnn] yes, get another packet -;[gnn] *** end of patch ***** - ;... - ;... - -;Begin IBM change/fdc -;This moved from OUTPK7 -- it appears that waiting until we're -;ready to send a packet before looking for turnaround character -;is long enough for it to get lost. Better to look now. - - lda ibmflg ;Is this the IBM? - ora a - jz inpkt6 ;If not then proceed. - lda state ;Check if this is the Send-Init packet. - cpi 'S' - jz inpkt6 ;If so don't wait for the XON. -inpkt5: call inchr ;Wait for the turn around char. - jmp inpkt6 - cpi xon ;Is it the IBM turn around character? - jnz inpkt5 ;If not, go until it is. -inpkt6: lhld pktptr ;Reload packet pointer -;End IBM change/fdc. - dcx h ;Back up to end of line character - mvi m,0 ;Replace it with a null to stop rpack: - call selcon ;We've got the packet. Return to console. - - lda dbgflg ; Is debugging enabled? - ora a - jz inpkt7 - inx h ; Point to next char. - lda quietd ; a quiet display? - ana a - jnz inpkt7 ; so dont say a thing - call rppos ; position cursor - lxi h,recpkt+1 ; print the packet - call dmptxt - - lda prnflg ; is the printer on too? - ana a - jz inpkt7 - lxi h,rstatm ; print state - call printm ; dumptext but to printer - lda state - mov e,a - call outprn - lxi h,princr ; cr lf to printer - call printm - lxi h,rpackm - call printm - lxi h,recpkt+1 - call printm - lxi h,princr - call printm - lxi h,princr - call printm - - -inpkt7: lxi h,recpkt - shld pktptr ;Save the packet pointer. - jmp rskp ;If so we are done. - -; getchr - get next character from buffered packet. -; returns nonskip at end of packet. -; called by: rpack - -getchr: lhld pktptr ;Get the packet pointer. - mov a,m ;Get the char. - inx h - shld pktptr - ora a ;Is it the null we put at the end of the packet? - jnz rskp ;If not return retskp. - ret ;If so return failure. -; -; -; inchr - character input loop for file transfer -; returns: nonskip if timeout or character typed on console -; (console selected) -; skip with character from modem in A (parity stripped -; if necessary; modem selected) -; preserves bc, de, hl in either case. -; called by: inpkt - -inchr: push h ; save hl and bc - push b - lhld timout ;Get initial value for timeout - shld timval ;[jd] -inchr0: call selmdm ;select modem - call inpmdm ;Try to get a character from the modem - ora a - jz inchr2 ;if zero, nothing there. - mov b,a - lda parity ;Is the parity none? - cpi parnon - mov a,b - jz inchr1 ;If so just return. - ani 7FH ;Turn off the parity bit. -inchr1: pop b ;restore registers - pop h - jmp rskp ;take skip return, character in A - -inchr2: call selcon ;select console - call inpcon ; Try to get a character from the console - ora a - jz inchr6 ;If not go do timer thing - cpi cr ;Is it a carriage return? - jz inchr4 ;If so return - cpi ('Z'-100O) ;Control-Z? - jz inchr5 ;Yes, go flag it - cpi ('C'-100O) ;Control-C? - jz inchr7 ;re-enter, he wants to get out - cpi ('X'-100O) ;Control-X? - jnz inchr6 ;No, ignore it. do timer thing. -inchr5: adi 100O ;Convert to printing range - sta czseen ;Flag we saw a control-Z - jmp inchr6 ;[MF] and do timer thing -inchr4: pop b ; restore registers - pop h - ret ;And return - -inchr6: lda timflg ;[jd] pick up timer flag - ora a ;[jd] are we allowed to use timer? - jz inchr0 ;[jd] no, don't time out - lhld timval ; decrement fuzzy time-out - dcx h ; - shld timval ;((timout-1) * loop time) - mov a,h ;(Retry if not time-out) - ora l ; - jnz inchr0 ; - call updrtr ;Count as retry (?) - pop b ;restore registers - pop h - ret ;and return to do retry - -inchr7: call clrtop ;[hh] clear screen and home cursor - lda takflg ;[MF]Take-file in progress? - ani 1 ;[MF]... - cnz closet ;[MF]Yes, close it and reset TAKE-flag - ;[MF]so all processing is halted - jmp kermit ;[hh] then re-enter kermit - -; -; CRCCLC - Routine to calculate a CRC-CCITT for a string. -; -; This routine will calculate a CRC using the CCITT polynomial for -; a string. -; -; call with: HL/ Address of null-terminated string -; 16-bit CRC value is returned in DE. -; Registers BC and HL are preserved. -; -; called by: spack, rpack - -crcclc: push h ;Save HL - push b ;And BC - lxi d,0 ;Initial CRC value is 0 - -crccl0: mov a,m ;Get a character - ora a ;Check if zero - jz crccl1 ;If so, all done - push h ;Save the pointer - xra e ;Add in with previous value - mov e,a ;Get a copy - ani 0FH ;Get last 4 bits of combined value - mov c,a ;Get into C - mvi b,0 ;And make high order zero - lxi h,crctb2 ;Point at low order table - dad b ;Point to correct entry - dad b ; . . . - push h ;Save the address - mov a,e ;Get combined value back again - rrc ;Shift over to make index - rrc ; . . . - rrc ; . . . - ani 1EH ;Keep only 4 bits - mov c,a ;Set up to offset table - lxi h,crctab ;Point at high order table - dad b ;Correct entry - mov a,m ;Get low order portion of entry - xra d ;XOR with previous high order half - inx h ;Point to high order byte - mov d,m ;Get into D - pop h ;Get back pointer to other table entry - xra m ;Include with new high order half - mov e,a ;Copy new low order portion - inx h ;Point to other portion - mov a,m ;Get the other portion of the table entry - xra d ;Include with other high order portion - mov d,a ;Move back into D - - pop h ;And H - inx h ;Point to next character - jmp crccl0 ;Go get next character - -crccl1: pop b ;Restore B - pop h ;And HL - - ret ;And return, DE=CRC-CCITT - -CRCTAB: DW 00000H - DW 01081H - DW 02102H - DW 03183H - DW 04204H - DW 05285H - DW 06306H - DW 07387H - DW 08408H - DW 09489H - DW 0A50AH - DW 0B58BH - DW 0C60CH - DW 0D68DH - DW 0E70EH - DW 0F78FH - -CRCTB2: DW 00000H - DW 01189H - DW 02312H - DW 0329BH - DW 04624H - DW 057ADH - DW 06536H - DW 074BFH - DW 08C48H - DW 09DC1H - DW 0AF5AH - DW 0BED3H - DW 0CA6CH - DW 0DBE5H - DW 0E97EH - DW 0F8F7H -; -; This is where we go if we get an error during a protocol communication. -; error prints the error packet on line 6 or so, and aborts the -; transfer. -; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, seot -; error1 print CRLF followed by the error packet. -; called by: finish, logout -; error2 just prints the error packet. -; error3 positions cursor and prints error message specified in DE. -; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, -; seot, parwrn, gofil, outbuf - -error: lda quietd ; a quiet display? - ana a - jnz error0 ; so dont say a thing - lda remtxt ;[MF]Doing a remote command? - ora a ;[MF]... - jnz error0 ;[MF]Yes, don't position cursor - call screrr ;Position the cursor. -error0: mvi a,'A' ;Set the state to abort. - sta state - jmp error2 - -error1: lxi d,crlf ;Print a CRLF. - lda quietd ; a quiet display? - ana a - jnz error2 ; so dont say a thing - call prtstr -error2: lda argblk+1 ;Get the length of the data. - mov c,a - mvi b,0 ;Put it into BC - lxi h,data ;Get the address of the data. - dad b ;Get to the end of the string. - mvi m,'$' ;Put a dollar sign at the end. - lxi d,data ;Print error message - lda remtxt ;[MF]Doing a remote command? - ora a ;[MF]... - jnz errr2a ;[MF]Yes, print message, quiet or not! - lda quietd ; a quiet display? - ana a - rnz ; so dont say a thing -errr2a: call prtstr - ret - -error3: lda quietd ; a quiet display? - ana a - rnz ; so dont say a thing - lda remtxt ;[MF]Doing a remote command? - ora a ;[MF]... - jnz err3a ;[MF]Yes, don't position cursor - push d ;Save the pointer to the message. - call screrr ;Position the cursor. - pop d ;Get the pointer back. -err3a: call prtstr ;Print error message - ret -; -; Set up for file transfer. -; called by read, send. - -init: lxi d,version ; point at Kermit's version string - lda quietd ; a quiet display? - ana a - jnz init1 ; so dont say a thing - call sysscr ; fix up screen -init1: call selmdm ; select modem - call flsmdm ; purge any pending data - call selcon ; select console again. - ret - -; Set state to ABORT -; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, seot, -; nak, ackp - -abort: mvi a,'A' ;Otherwise abort. - sta state - ret - -; nak - send NAK packet -; here from: rinit, rfile, rdata -; nak0 - update retry count and send NAK packet -; here from: rinit, rfile, rdata, tryagn - -nak0: call updrtr ;Update number of retries. -nak: lda pktnum ;Get the packet number we're waiting for. - sta argblk - xra a ;No data. - sta argblk+1 - mvi a,'N' ;NAK that packet. - call spack - jmp abort ; Give up. - ret ;Go around again. - -; increment and display retry count -; called by: rfile, sinit, sfile, sdata, seof, seot, -; nak, rpack, inchr, tryagn - -updrtr: lhld numrtr - inx h ;Increment the number of retries - shld numrtr - lda remtxt ;[MF]Doing a remote server command? - ora a ;[MF]... - rnz ;[MF]Yes, keep mum - lda quietd ; a quiet display? - ana a - rnz ; so dont say a thing - call scrnrt ;Position cursor - lhld numrtr ;[MF] -call nout ;Write the number of retries. - ret - -; [jd] this routine prints parity warnings. All registers are -; saved except for a. -; called by: sdata - -parwrn: push b - push d - push h - lxi d,inms25 - call error3 - pop h - pop d - pop b - ret -;[jd] end of addition - -; print message in status field. address of message is in DE. -; called by: read, send - -finmes: lda quietd ; a quiet display? - ana a - jz finme0 ; so do usual stuff - push d ;[MF]Save pointer to completion message - call prcrlf ; best do a new line - pop d ;[MF]Restore completion message pointer - call prtstr ; and send message - mvi e,space ; send a space or two - mvi c,dconio - push b - push d - call bdos - pop d - pop b - call bdos - ret ; and exit back -; -;else for screaming screens... - -finme0: push d ;Save message. - call scrst ;Position cursor - pop d ;Print the termination message - call prtstr - ret ; may not want this ************** - - mvi c,4 ;[2] copy across user no and drive - lxi h,kerm1 ;[2] as we have the text already -finme1: mov e,m - push h ;[2] conout probably destroys these - push b - call conout - pop b - pop h - inx h ;[2] next character - dcr c ;[2] ah, but have we done? - jnz finme1 ;[2] nope - lxi d,spac15 ;[2] send 15 spaces (clears previous filename) - call prtstr ;[2] - call scrend ;Position cursor for prompt - ret - -; Compare expected packet number against received packet number. -; return with flags set (Z = packet number valid) -; called by: rfile, rdata, sinit, sfile, sdata, seof, seot - -compp: lda pktnum ;Get the packet Nr. - mov b,a - lda argblk - cmp b - ret - -; Increment the packet number, modulo 64. -; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, seot - -countp: inr a ;Increment packet Nr. - ani 3FH ;Turn off the two high order bits - sta pktnum ;Save modulo 64 of number - lhld numpkt - inx h ;Increment Nr. of packets - shld numpkt - ret - -; Send an ACK-packet -; called by: rfile, rdata, tryagn - -ackp: xra a - sta numtry ;Reset number of retries - sta argblk+1 ;No data. (The packet number is in argblk) - mvi a,'Y' ;Acknowledge packet - call spack ;Send packet - jmp abort - ret - -; ? -; called with A/ current retry count -; called by: rfile, rdata - -tryagn: inr a ;Increment it. - sta oldtry ;Save the updated number of tries. - lda pktnum ;Get the present packet number. - dcr a ;Decrement - ani 3FH ; modulo 64 - mov b,a - lda argblk ;Get the packet's number - cmp b ;Is the packet's number one less than now? - jnz nak0 ;No, NAK it and try again. - call updrtr ;Update the number of retries. - call ackp - ret - -; Output a null-terminated string to the console. We assume that the -; console has been selected. Called with HL = address of string. -; called by: spack, inpkt - -dmptxt: mov a,m ; get character from string - ora a - rz ; done if null - push h ; save string address - mov e,a ; move character to E for outcon - call outcon ; output character to console - pop h ; restore string address - inx h ; point past printed character - jmp dmptxt ; go output rest of string - - -; Output a null-terminated string to the PRINTER We assume that the -; console has been selected. Called with HL = address of string. -; called by: spack, inpkt - -printm: mov a,m ; get character from string - ora a - rz ; done if null - push h ; save string address - mov e,a ; move character to E for outcon - call outprn ; output character to printer - pop h ; restore string address - inx h ; point past printed character - jmp printm ; go output rest of string - - -; -; test if character in A is the start of header character. We get -; the start of packet character from sohchr, which can be SET -tstsoh: push b ; save these registers for a bit - mov c,a ; we have to test if this is the character - lda sohchr - cmp c ; if zero, then it is - mov a,c ; restore accumulator but not flags - pop b - ret ; return with flags set -; - - -; Little code to allow some expansion of code without changing -; every futher address, only up to the end of this file. -; TO BE REMOVED FRO RELEASE! - -; org ($+100h) AND 0FF00H - - -IF lasm - LINK CPSREM -ENDIF;lasm +; CPSPK2.ASM +; KERMIT - (Celtic for "FREE") +; +; This is the CP/M-80 implementation of the Columbia University +; KERMIT file transfer protocol. +; +; Version 4.0 +; +; Copyright June 1981,1982,1983,1984 +; Columbia University +; +; Originally written by Bill Catchings of the Columbia University Center for +; Computing Activities, 612 W. 115th St., New York, NY 10025. +; +; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, +; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many +; others. +; +; This file contains the (system-independent) routines that implement +; the KERMIT protocol, and the commands that use them: +; RECEIVE, SEND, FINISH, and LOGOUT. +; +; revision history: +; +;edit 11, 21-Mar-1991 by MF. After "inchr7", close TAKE-file (if any) so +; ^C will halt all processing (including commands from TAKE-files) +; and put the user back at Kermit command-level. +;edit 10, 3-Jan-1991 by MF. Modify routine "inchr" after label "inchr5" to +; not take retry (nonskip) return if ^X/^Z seen on the Console. This +; will prevent multiple copies of packets being sent if user aborts +; some files in a stream being sent via ^X and is a better fix to this +; problem than flushing comm input before sending the "Z" packet +; requesting the remote Kermit to discard the current file being +; received (as implemented in CPSPK1.ASM edit of 2-jan-1991). +;edit 9, 14-Dec-1990 by MF. Modified "gofil" routine to allow for +; specification of a drive in the local filespec for GET and +; RECEIVE commands. Thus commands such as +; GET HELLO.TXT B:GOODBYE.TXT +; and +; RECEIVE B:GOODBYE.TXT +; now work as expected. +;edit 8, 22-Oct-1990 by MF. Fixed bug in completion-message routine +; "finmes" wherein the completion message was not printed if the +; terminal was set to QUIET because the message pointer was clobbered +; by prcrlf. +;edit 7, 14-Sep-1990 by MF. Add hooks for SET COLLISION command. +; Eliminate commented-out old file warning rename routine. +; Clear communication input buffers (call flsmdm) before +; BYE, FINISH and LOGOUT commands. +;edit 6, 9-Sep-1990 by MF. Implemented fixes in CPKERM.BWR for +; garbage printout during quiet transfers and for file existence/ +; rename algorithm. +; Also implemented hooks for Remote commands. +; edit 5, 18 June 1990 by Russell Lang [rjl@monu1.cc.monash.edu.au] +; When trying to generate a unique file name on receive, zero +; the attribute bits between file opening attempts. This is +; to fix a bug which caused the unique file name to have the +; attributes of the already existing file. If the attribute +; was R/O, a bdos error occured later when an attempt was made +; to write to the file. +; +; edit 4, 27 October, 1987 By OBSchou. Changed the rename routine to +; be more like the MSDOS issue. +; +; edit 3, 28 July, by OBSchou. Added traps to NOT print to screen during +; file transfers if quietd is non zero (ie we SET TERMINAL QUIET) +; This hopefully speeds up transfers in systems spending an age +; updating the screen. +; +; edit 2, 8 April, 1987 by OBSchou. Minor edit to put drive and user number +; in the "filename" field on the transfer screen. This means that the +; offset on the line foe the file name proper has moved along 4 space. +; Also, it writes 15 spaces AFER the xxd: string to clear the field +; of any prevous file. Needed for thos terminals that cannot +; clear to end of line... +; +; edit 1, 28 January, 1987 by OBSchou. +; Hived off about 1/2 of CPSPKT.ASM to form two (smaller => easier +; to handle) files. +; +; + +pk2ver: db 'CPSPK2.ASM (11) 21-Mar-1991$' ; name, edit number, date + + +; +; Get the file name (including host to micro translation) +; called by: rfile + +gofil: xra a + sta fcb ;Set the drive to default to current. + lxi h,data ;Get the address of the file name. +; allow use of local name if one was given [gnn] + lda remlen ;[gnn] + ora a ;[gnn] anything there? + jz gofil0 ;[gnn] no, use the one in the data packet + lxi h,remnam ;[gnn] yes, use this instead + lda remnam+1 ;[MF]Get 2nd char of local filename + cpi ':' ;[MF]Was a drive specified? + jnz gofil0 ;[MF]No, proceed as of old + mov a,m ;[MF]Yes, get drive + ani 5fh ;[MF]Force uppercase + sui 'A'-1 ;[MF]Make valid drive for fcb + sta fcb ;[MF]and store in fcb + inx h ;[MF]Skip drive and delimiter + inx h ;[MF]... +gofil0: ;[gnn] continue to set up the file [gnn] +; + shld datptr ;Store the address. + lxi h,fcb+1 ;Address of the FCB. + shld fcbptr ;Save it. + xra a + sta temp1 ;Initialize the char count. + sta temp2 + mvi b,' ' +gofil1: mov m,b ;Blank the FCB. + inx h + inr a +; cpi 0CH ;Twelve?[5a] + cpi 0BH ; Eleven? [5a] + jm gofil1 + mvi m,0 ; [5a] Specify extent 0 +gofil2: lhld datptr ;Get the NAME field. + mov a,m + cpi 'a' ;Force upper case + jm gofl2a ; + ani 5FH ; +gofl2a: inx h + cpi '.' ;Seperator? + jnz gofil3 + shld datptr ;[jd] update ptr (moved from above) + lxi h,fcb+9H + shld fcbptr + lda temp1 + sta temp2 + mvi a,9H + sta temp1 + jmp gofil6 + +gofil3: ora a ;Trailing null? + jz gofil7 ;Then we're done. + shld datptr ;[jd] no, can update ptr now. + lhld fcbptr + mov m,a + inx h + shld fcbptr + lda temp1 ;Get the char count. + inr a + sta temp1 + cpi 8H ;Are we finished with this field? + jm gofil2 +gofil4: sta temp2 + lhld datptr + mov a,m + inx h + shld datptr + ora a + jz gofil7 + cpi '.' ;Is this the terminator? + jnz gofil4 ;Go until we find it. +gofil6: lhld datptr ;Get the TYPE field. + mov a,m + cpi 'a' ;Force upper case + jm gofl6a ; + ani 5FH ; +gofl6a: ora a ;Trailing null? + jz gofil7 ;Then we're done. +;[jd] move above two lines so we don't increment pointer if char is null + inx h + shld datptr + lhld fcbptr + mov m,a + inx h + shld fcbptr + lda temp1 ;Get the char count. + inr a + sta temp1 + cpi 0CH ;Are we finished with this field? + jm gofil6 +gofil7: lhld datptr + mvi m,'$' ;Put in a dollar sign for printing. + lda quietd ; quiet display? + ana a + jnz gofi70 ; yes, so skip it. + call scrfln ;Position cursor +gofi70: lxi d,data ;Print the file name + lda getrxflg ;[obs 8] are we doing a get or receive? + ana a ;[obs 8] + jz gofi7a ;[obs 8] if zero, receive + lxi d,remnam ;[obs 8] +gofi7a: ;[obs 8] + + call prtstr +gofi7b: xra a ;[MF]Zero "discard" flag + sta dscflg ;[MF]... + lda flwflg ;Is file warning on? + ora a + jz gofil9 ;If not, just proceed. + mvi c,openf ;See if the file exists. + lxi d,fcb + call bdos + cpi 0FFH ;Does it exist? + jz gofil9 ;If not create it. +; + lda flwflg ;[MF]Get flag again + cpi 3 ;[MF]SET COLLISION DISCARD? + jnz gofi7h ;[MF]No + mvi a,0ffh ;[MF]Yes, order rejection of the file + sta dscflg ;[MF]... + jmp rskp ;[MF]and pretend successful open +gofi7h: push psw ;[MF]Save Collision status + lxi d,infms5 + call error3 + pop psw ;[MF]Restore Collision status + cpi 1 ;[MF]SET COLLISION RENAME? + jz gofi7i ;[MF]Yes, same as SET WARNING ON + ;[MF]If we come here, SET COLLISION BACKUP + lxi h,fcb ;[MF]Copy original fcb to a safe place + lxi d,colfcb ;[MF]... + lxi b,33 ;[MF]... + call mover ;[MF]... + ;[MF]and fall into rename code +gofi7i: ;[MF] +; +; Replacement file name renamer routine. Incomming +; files are renamed in this manner: +; original file name: filex.ext +; first rename: filex001.ext +; ... ... +; ninth rename filex009.ext +; 10th rename fail - would we really want 10 +; files of the same name?? +; +; +; 1) +; Assume that we need to "rename" the file, so lets make sure +; that there is a full. 8 character filename. (We make it if +; it does not already exist) +; 1a) If full file name, last character is to be replaced +; by a zero. This gives us up to no#ine renames. +; 2)open file +; 2a)If exists, increment last character by one +; 2b)if = '9' then abort +; 2c)If does not exist, got 2) +; 3)we have a valid 'renamed' file +; +;Part 1) - fill out filename part + + mvi c,8 ; max 8 characters to test for + mvi a,'0' ; spaces to be replaced by a zero. + lxi h,fcb+8 ; start at the end +gofi7c: mov m,a ; put a zero in here + dcr c ; come to the end? + jz gofi7d ; should not have, but just in case... + dcx h ; previous chararcter + mov a,m ; get it + cpi ' ' ; if this character a space as well, zero it + mvi a,'0' ; set it to ascii zero just in case... + jz gofi7c ; +; +; Part 2) open the file (if success, then it exists) + +gofi7d: +;zero the attribute bits. [rjl@monu1.cc.monash.edu.au] + lxi h,fcb+1 ;[rjl] + mvi c,11 ;[rjl] +gofi7z: mov a,m ;[rjl] + ani 07fh ;[rjl] + mov m,a ;[rjl] + inx h ;[rjl] + dcr c ;[rjl] + jnz gofi7z ;[rjl] + lxi d,fcb + mvi c,openf + call BDOS + inr a ; if 0ffh returned, error (ie does not exist) + jz gofi7e + lda fcb+8 ; get last character + inr a + sta fcb+8 + cpi '9'+1 ; more than '9' => too far, lets give up. + jnz gofi7d ; else try again +;Giving up, so lets exit + lxi d,erms16 ; + call prtstr + ret ; return to error routine + +gofi7e: lxi d,fnbuf ; make the file name into a character string + lxi h,fcb+1 ; point to source file name, less drive name + mvi c,8 ; 11 characters (8+3) + dot to copy across +; +gofi7f: mov a,m ; get character + stax d + inx h + inx d + dcr c + jnz gofi7f ; loop until all done + + mvi a,'.' ; then the dot + stax d + inx d + + mvi c,3 ; then the file extention + +gofi7g: mov a,m + stax d + inx h + inx d + dcr c + jnz gofi7g ; loop until extention copied across + + mvi a,'$' ; dollar terminate string + stax d + lxi d,fnbuf ;[MF]Point to string + call prtstr ; write string to console + + lda flwflg ;[MF]Get warning (SET COLLISION) flag + cpi 2 ;[MF]SET COLLISION BACKUP? + jnz gofil9 ;[MF]No + lxi h,fcb ;[MF]Yes, get new filename fcb + lxi d,colfcb+16 ;[MF]Where to copy to for rename + lxi b,16 ;[MF]Copy 16 bytes + call mover ;[MF]... + lxi d,colfcb ;[MF]Point to rename fcb + mvi c,renam ;[MF]Rename function + call bdos ;[MF]Try to rename original file + cpi 0ffh ;[MF]Did we win? + jnz gofl82 ;[MF]Yes + lxi d,erms16 ;[MF]No, complain and bomb + jmp error3 ;[MF]... +gofl82: lxi h,colfcb ;[MF]Now recopy original filename into fcb + lxi d,fcb ;[MF]to create new file with original name + lxi b,16 ;[MF]... + call mover ;[MF]... +; +; +;Now lets make the file (create it) + +gofil9: call makfil ; Create the file. + jmp gofl91 ; Disk was full. + jmp rskp ; Success. + +gofl91: lxi d,erms11 + call error3 + ret +; +; This is the FINISH command. It tells the remote KERSRV to exit. +; here from kermit + +finish: call cfmcmd + call selmdm ;[MF]Select modem + call flsmdm ;[MF]Flush buffers + call selcon ;[MF]Select keyboard again + xra a + sta numtry ;Inititialize count. + mvi a,'1' ;Reset block check type to single character + sta curchk ; . . . + +finsh1: lda numtry ;How many times have we tried? + cpi maxtry ;Too many times? + jm finsh3 ;No, try it. +finsh2: lxi d,erms18 ;Say we couldn't do it. + call prtstr + jmp kermit ;Go home. + +finsh3: inr a ;Increment the number of tries. + sta numtry + xra a + sta argblk ;Make it packet number zero. + mvi a,1 + sta argblk+1 ;One piece of data. + lxi h,data + mvi m,'F' ;Finish running Kermit. + mvi a,'G' ;Generic command packet. + call spack + jmp finsh2 ; Tell the user and die. + call rpack ;Get an acknowledgement. + jmp finsh1 ; Go try again. + cpi 'Y' ;ACK? + jz kermit ;Yes, we are done. + cpi 'E' ;Is it an error packet? + jnz finsh1 ;Try sending the packet again. + call error1 ;Print the error message. + jmp kermit +; +; This is the LOGOUT command. It tells the remote KERSRV to logout. +; here from: kermit + +logout: call cfmcmd + call logo ;Send the logout packet. + jmp kermit ;Go get another command + jmp kermit ; whether we succeed or not. + +; do logout processing. +; called by: bye, logout + +logo: call selmdm ;[MF]Select modem + call flsmdm ;[MF]Flush buffers + call selcon ;[MF]Select keyboard again + xra a + sta numtry ;Inititialize count. + mvi a,'1' ;Reset block check type to single character + sta curchk ; . . . + +logo1: lda numtry ;How many times have we tried? + cpi maxtry ;Too many times? + jm logo3 ;No, try it. +logo2: lxi d,erms19 ;Say we couldn't do it. + call prtstr + ret ;Finished. + +logo3: inr a ;Increment the number of tries. + sta numtry + xra a + sta argblk ;Make it packet number zero. + mvi a,1 + sta argblk+1 ;One piece of data. + lxi h,data + mvi m,'L' ;Logout the remote host. + mvi a,'G' ;Generic command packet. + call spack + jmp logo2 ; Tell the user and die. + call rpack ;Get an acknowledgement + jmp logo1 ; Go try again. + cpi 'Y' ;ACK? + jz rskp ;Yes, we are done. + cpi 'E' ;Is it an error packet? + jnz logo1 ;Try sending the packet again. + call error1 ;Print the error message. + ret ;All done. +; +; Packet routines + +; Send_Packet +; This routine assembles a packet from the arguments given and sends it +; to the host. +; +; Expects the following: +; A - Type of packet (D,Y,N,S,R,E,F,Z,T) +; ARGBLK - Packet sequence number +; ARGBLK+1 - Number of data characters +; Returns: nonskip if failure +; skip if success +; called by: read, rinit, rfile, rdata, sinit, sfile, sdata, seof, seot, +; finish, logout, nak, ackp + +spack: sta argblk+2 + lxi h,packet ;Get address of the send packet. + lda sndsop ;[gnn] send start-of-pkt char. + mov m,a ;Put in the packet. + inx h ;Point to next char. + lda curchk ;Get current checksum type + sui '1' ;Determine extra length of checksum + mov b,a ;Copy length + lda argblk+1 ;Get the number of data chars. + adi ' '+3 ;Real packet character count made printable. + add b ;Determine overall length + mov m,a ;Put in the packet. + inx h ;Point to next char. + lxi b,0 ;Zero the checksum AC. + mov c,a ;Start the checksum. + lda argblk ;Get the packet number. + adi ' ' ;Add a space so the number is printable. + mov m,a ;Put in the packet. + inx h ;Point to next char. + add c + mov c,a ;Add the packet number to the checksum. + mvi a,0 ;Clear A (Cannot be XRA A, since we can't + ; touch carry flag) + adc b ;Get high order portion of checksum + mov b,a ;Copy back to B + lda argblk+2 ;Get the packet type. + mov m,a ;Put in the packet. + inx h ;Point to next char. + add c + mov c,a ;Add the packet number to the checksum. + mvi a,0 ;Clear A + adc b ;Get high order portion of checksum + mov b,a ;Copy back to B +spack2: lda argblk+1 ;Get the packet size. + ora a ;Are there any chars of data? + jz spack3 ; No, finish up. + dcr a ;Decrement the char count. + sta argblk+1 ;Put it back. + mov a,m ;Get the next char. + inx h ;Point to next char. + add c + mov c,a ;Add the packet number to the checksum. + mvi a,0 ;Clear A + adc b ;Get high order portion of checksum + mov b,a ;Copy back to B + jmp spack2 ;Go try again. + +spack3: lda curchk ;Get the current checksum type + cpi '2' ;Two character? + jz spack4 ;Yes, go handle it + jnc spack5 ;No, go handle CRC if '3' + mov a,c ;Get the character total. + ani 0C0H ;Turn off all but the two high order bits. + ;Shift them into the low order position. + rlc ;Two left rotates same as 6 rights + rlc ; . . . + add c ;Add it to the old bits. + ani 3FH ;Turn off the two high order bits. (MOD 64) + adi ' ' ;Add a space so the number is printable. + mov m,a ;Put in the packet. + inx h ;Point to next char. + jmp spack7 ;Go store eol character + +;Here for 3 character CRC-CCITT + +spack5: mvi m,0 ;Store a null for current end + push h ;Save H + lxi h,packet+1 ;Point to first checksumed character + call crcclc ;Calculate the CRC + pop h ;Restore the pointer + mov c,e ;Get low order half for later + mov b,d ;Copy the high order + mov a,d ;Get the high order portion + rlc ;Shift off low 4 bits + rlc ; . . . + rlc ; . . . + rlc ; . . . + ani 0FH ;Keep only low 4 bits + adi ' ' ;Put into printing range + mov m,a ;Store the character + inx h ;Point to next position + +;Here for two character checksum + +spack4: mov a,b ;Get high order portion + ani 0FH ;Only keep last four bits + rlc ;Shift up two bits + rlc ; . . . + mov b,a ;Copy back into safe place + mov a,c ;Get low order half + rlc ;Shift high two bits + rlc ;to low two bits + ani 03H ;Keep only two low bits + ora b ;Get high order portion in + adi ' ' ;Convert to printing character range + mov m,a ;Store the character + inx h ;Point to next character + mov a,c ;get low order portion + ani 3FH ;Keep only six bits + adi ' ' ;Convert to printing range + mov m,a ;Store it + inx h ;Bump the pointer + +spack7: lda dbgflg + ora a ; is debugging enabled? + jz spack8 + push h ; yes. save address of end of packet + mvi m,0 ; null-terminate the packet for display + lda quietd ; a quiet display? + ana a + jnz spac7a ; so dont say a thing + call sppos ; position cursor + lxi h,packet+1 ; print the packet + call dmptxt + lda prnflg ; is the printer on too? + ana a + jz spac7a + lxi h,sstatm ; print state + call printm ; dumptext but to printer + lda state + mov e,a + call outprn + lxi h,princr ; cr lf to printer + call printm + lxi h,spackm + call printm + lxi h,packet+1 + call printm + lxi h,princr + call printm + lxi h,princr + call printm + +spac7a: pop h ; restore address of end of packet +spack8: lda seol ;Get the EOL the other host wants. + mov m,a ;Put in the packet. + inx h ;Point to next char. + xra a ;Get a null. + mov m,a ;Put in the packet. +; Write out the packet. +outpkt: call selmdm ; Set up for output to comm port if iobyt + lda spad ;Get the number of padding chars. + sta temp1 +outpk2: lda temp1 ;Get the count. + dcr a + ora a + jm outpk6 ;If none left proceed. + sta temp1 + lda spadch ;Get the padding char. + call setpar ;Set parity appropriately + mov e,a ;Put the char in right AC. + call outmdm ;Output it. + jmp outpk2 + +outpk6: lxi h,packet ; Point to the packet. +outlup: mov a,m ; Get the next character. + ora a ; Is it a null? + jz outlud ; If so return success. + call setpar ; Set parity for the character + mov e,a ; Put it in right AC + call outmdm ; and output it. +; TAC trap: If this character is the TAC intercept character, and the TAC +; trap is enabled, we have to output it twice. If the TAC trap is enabled, +; tacflg contains the intercept character. (The current character cannot +; be NUL, so we don't have to worry about doubling nulls in the message) + lda tacflg ; get current intercept character, or zero. + cmp m ; compare against current data character. + jnz outpk8 ; if different, do nothing. + call setpar ; match. set appropriate parity, + mov e,a ; put it in the right register, + call outmdm ; and output it a second time. +outpk8: + inx h ; Increment the char pointer. + jmp outlup + +outlud: call selcon ; select console + jmp rskp ; and return success +; +; Receive_Packet +; This routine waits for a packet to arrive from the host. It reads +; characters until it finds a SOH. It then reads the packet into packet. +; +; Returns: nonskip if failure (checksum wrong or packet trashed) +; skip if success, with +; A - message type +; ARGBLK - message number +; ARGBLK+1 - length of data +; called by: rinit, rfile, rdata, +; sinit, sfile, sdata, seof, seot, finish, logout + +rpack: call inpkt ;Read up to the end-of-line character + jmp r ; Return bad. +rpack0: call getchr ;Get a character. + jmp rpack ; Hit eol;null line;just start over. + lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. + cmp m ;[gnn] + jnz rpack0 ; No, go until it is. +rpack1: call getchr ;Get a character. + jmp r ; Hit end of line, return bad. + lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. + cmp m ;[gnn] + jz rpack1 ; Yes, then go start over. + sta packet+1 ;Store in packet also + mov c,a ;Start the checksum. + lda curchk ;Get block check type + sui '1' ;Determine extra length of block check + mov b,a ;Get a copy + mov a,c ;Get back length character + sui ' '+3 ;Get the real data count. + sub b ;Get total length + sta argblk+1 + mvi b,0 ;Clear high order half of checksum + call getchr ;Get a character. + jmp r ; Hit end of line, return bad. + lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. + cmp m ;[gnn] + jz rpack1 ; Yes, then go start over. + sta argblk + sta packet+2 ;Save also in packet + add c + mov c,a ;Add the character to the checksum. + mvi a,0 ;Clear A + adc b ;Get high order portion of checksum + mov b,a ;Copy back to B + lda argblk + sui ' ' ;Get the real packet number. + sta argblk + call getchr ;Get a character. + jmp r ; Hit end of line, return bad. + lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. + cmp m ;[gnn] + jz rpack1 ; Yes, then go start over. + sta temp1 ;Save the message type. + sta packet+3 ;Save in packet + add c + mov c,a ;Add the character to the checksum. + mvi a,0 ;Clear A + adc b ;Get high order portion of checksum + mov b,a ;Copy back to B + lda argblk+1 ;Get the number of data characters. + sta temp2 + lxi h,data ;Point to the data buffer. + shld datptr +rpack2: lda temp2 + sui 1 ;Any data characters? + jm rpack3 ; If not go get the checksum. + sta temp2 + call getchr ;Get a character. + jmp r ; Hit end of line, return bad. + lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. + cmp m ;[gnn] + jz rpack1 ; Yes, then go start over. + lhld datptr + mov m,a ;Put the char into the packet. + inx h ;Point to the next character. + shld datptr + add c + mov c,a ;Add the character to the checksum. + mvi a,0 ;Clear A + adc b ;Get high order portion of checksum + mov b,a ;Copy back to B + jmp rpack2 ;Go get another. + +rpack3: call getchr ;Get a character. + jmp r ; Hit end of line, return bad. + lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. + cmp m ;[gnn] + jz rpack1 ; Yes, then go start over. + sui ' ' ;Turn the char back into a number. + sta temp3 +;Determine type of checksum + + lda curchk ;Get the current checksum type + cpi '2' ;1, 2 or 3 character? + jz rpack4 ;If zero, 2 character + jnc rpack5 ;Go handle 3 character + mov a,c ;Get the character total. + ani 0C0H ;Turn off all but the two high order bits. + ;Shift them into the low order position. + rlc ;Two left rotates same as six rights + rlc ; . . . + add c ;Add it to the old bits. + ani 3FH ;Turn off the two high order bits. (MOD 64) + mov b,a + lda temp3 ;Get the real received checksum. + cmp b ;Are they equal? + jz rpack7 ;If so, proceed. +rpack9: call updrtr ;If not, update the number of retries. + ret ;Return error. + +;Here for three character CRC-CCITT + +rpack5: lhld datptr ;Get the address of the data + mvi m,0 ;Store a zero in the buffer to terminate packet + lxi h,packet+1 ;Point at start of checksummed region + call crcclc ;Calculate the CRC + mov c,e ;Save low order half for later + mov b,d ;Also copy high order + mov a,d ;Get high byte + rlc ;Want high four bits + rlc ; . . . + rlc ;And shift two more + rlc ; . . . + ani 0FH ;Keep only 4 bits + mov d,a ;Back into D + lda temp3 ;Get first value back + cmp d ;Correct? + jnz rpack9 ;No, punt + call getchr ;Get a character. + jmp r ; Hit end of line, return bad. + lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. + cmp m ;[gnn] + jz rpack1 ; Yes, then go start over. + sui ' ' ;Remove space offset + sta temp3 ;Store for later check + ;... + +;Here for a two character checksum and last two characters of CRC + +rpack4: mov a,b ;Get high order portion + ani 0FH ;Only four bits + rlc ;Shift up two bits + rlc ; . . . + mov b,a ;Save back in B + mov a,c ;Get low order + rlc ;move two high bits to low bits + rlc ; . . . + ani 03H ;Save only low two bits + ora b ;Get other 4 bits + mov b,a ;Save back in B + lda temp3 ;Get this portion of checksum + cmp b ;Check first half + jnz rpack9 ;If bad, go give up + call getchr ;Get a character. + jmp r ; Hit end of line, return bad. + lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. + cmp m ;[gnn] + jz rpack1 ; Yes, then go start over. + sui ' ' ;Remove space offset + mov b,a ;Save in safe place + mov a,c ;Get low 8 bits of checksum + ani 3FH ;Keep only 6 bits + cmp b ;Correct value + jnz rpack9 ;Bad, give up +rpack7: lhld datptr + mvi m,0 ;Put a null at the end of the data. + lda temp1 ;Get the type. + jmp rskp +; +; inpkt - receive and buffer packet +; returns: nonskip if error (timeout) +; skip if success; packet starts at recpkt (which holds the SOH) +; and is terminated by a null. +; console is selected in either case. +; called by: rpack + +inpkt: lxi h,recpkt ;Point to the beginning of the packet. + shld pktptr +inpkt1: call inchr ;Get first character + jmp r ;Return failure + lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. + cmp m ;[gnn] + jnz inpkt1 ;if not, ignore leading junk + jmp inpkt3 ;else go put it in packet + +inpkt2: call inchr ;Get a character. + jmp r ; Return failure. + lxi h,rcvsop ;[gnn] Is it receive start-of-pkt char. + cmp m ;[gnn] + jnz inpkt3 ;if not continue + lxi h,recpkt ;else throw away what we've got so far + shld pktptr ; +inpkt3: lhld pktptr ; + mov m,a ;Put the char in the packet. + inx h + shld pktptr + mov b,a + lxi d,-recpkx ;Start over if packet buffer overflow + dad d ; + jc inpkt ;buffer overflow + lda reol ;Get the EOL char. + cmp b + jnz inpkt2 ;If not loop for another. +;[gnn] *** added by Godfrey Nix Nottingham University *** +;[gnn] to allow Kermit server to echo our packets back + lxi h,recpkt+3 ;[gnn] point to packet type + lda packet+3 ;[gnn] get the one we sent + cmp m ;[gnn] are they the same? + jz inpkt ;[gnn] yes, get another packet +;[gnn] *** end of patch ***** + ;... + ;... + +;Begin IBM change/fdc +;This moved from OUTPK7 -- it appears that waiting until we're +;ready to send a packet before looking for turnaround character +;is long enough for it to get lost. Better to look now. + + lda ibmflg ;Is this the IBM? + ora a + jz inpkt6 ;If not then proceed. + lda state ;Check if this is the Send-Init packet. + cpi 'S' + jz inpkt6 ;If so don't wait for the XON. +inpkt5: call inchr ;Wait for the turn around char. + jmp inpkt6 + cpi xon ;Is it the IBM turn around character? + jnz inpkt5 ;If not, go until it is. +inpkt6: lhld pktptr ;Reload packet pointer +;End IBM change/fdc. + dcx h ;Back up to end of line character + mvi m,0 ;Replace it with a null to stop rpack: + call selcon ;We've got the packet. Return to console. + + lda dbgflg ; Is debugging enabled? + ora a + jz inpkt7 + inx h ; Point to next char. + lda quietd ; a quiet display? + ana a + jnz inpkt7 ; so dont say a thing + call rppos ; position cursor + lxi h,recpkt+1 ; print the packet + call dmptxt + + lda prnflg ; is the printer on too? + ana a + jz inpkt7 + lxi h,rstatm ; print state + call printm ; dumptext but to printer + lda state + mov e,a + call outprn + lxi h,princr ; cr lf to printer + call printm + lxi h,rpackm + call printm + lxi h,recpkt+1 + call printm + lxi h,princr + call printm + lxi h,princr + call printm + + +inpkt7: lxi h,recpkt + shld pktptr ;Save the packet pointer. + jmp rskp ;If so we are done. + +; getchr - get next character from buffered packet. +; returns nonskip at end of packet. +; called by: rpack + +getchr: lhld pktptr ;Get the packet pointer. + mov a,m ;Get the char. + inx h + shld pktptr + ora a ;Is it the null we put at the end of the packet? + jnz rskp ;If not return retskp. + ret ;If so return failure. +; +; +; inchr - character input loop for file transfer +; returns: nonskip if timeout or character typed on console +; (console selected) +; skip with character from modem in A (parity stripped +; if necessary; modem selected) +; preserves bc, de, hl in either case. +; called by: inpkt + +inchr: push h ; save hl and bc + push b + lhld timout ;Get initial value for timeout + shld timval ;[jd] +inchr0: call selmdm ;select modem + call inpmdm ;Try to get a character from the modem + ora a + jz inchr2 ;if zero, nothing there. + mov b,a + lda parity ;Is the parity none? + cpi parnon + mov a,b + jz inchr1 ;If so just return. + ani 7FH ;Turn off the parity bit. +inchr1: pop b ;restore registers + pop h + jmp rskp ;take skip return, character in A + +inchr2: call selcon ;select console + call inpcon ; Try to get a character from the console + ora a + jz inchr6 ;If not go do timer thing + cpi cr ;Is it a carriage return? + jz inchr4 ;If so return + cpi ('Z'-100O) ;Control-Z? + jz inchr5 ;Yes, go flag it + cpi ('C'-100O) ;Control-C? + jz inchr7 ;re-enter, he wants to get out + cpi ('X'-100O) ;Control-X? + jnz inchr6 ;No, ignore it. do timer thing. +inchr5: adi 100O ;Convert to printing range + sta czseen ;Flag we saw a control-Z + jmp inchr6 ;[MF] and do timer thing +inchr4: pop b ; restore registers + pop h + ret ;And return + +inchr6: lda timflg ;[jd] pick up timer flag + ora a ;[jd] are we allowed to use timer? + jz inchr0 ;[jd] no, don't time out + lhld timval ; decrement fuzzy time-out + dcx h ; + shld timval ;((timout-1) * loop time) + mov a,h ;(Retry if not time-out) + ora l ; + jnz inchr0 ; + call updrtr ;Count as retry (?) + pop b ;restore registers + pop h + ret ;and return to do retry + +inchr7: call clrtop ;[hh] clear screen and home cursor + lda takflg ;[MF]Take-file in progress? + ani 1 ;[MF]... + cnz closet ;[MF]Yes, close it and reset TAKE-flag + ;[MF]so all processing is halted + jmp kermit ;[hh] then re-enter kermit + +; +; CRCCLC - Routine to calculate a CRC-CCITT for a string. +; +; This routine will calculate a CRC using the CCITT polynomial for +; a string. +; +; call with: HL/ Address of null-terminated string +; 16-bit CRC value is returned in DE. +; Registers BC and HL are preserved. +; +; called by: spack, rpack + +crcclc: push h ;Save HL + push b ;And BC + lxi d,0 ;Initial CRC value is 0 + +crccl0: mov a,m ;Get a character + ora a ;Check if zero + jz crccl1 ;If so, all done + push h ;Save the pointer + xra e ;Add in with previous value + mov e,a ;Get a copy + ani 0FH ;Get last 4 bits of combined value + mov c,a ;Get into C + mvi b,0 ;And make high order zero + lxi h,crctb2 ;Point at low order table + dad b ;Point to correct entry + dad b ; . . . + push h ;Save the address + mov a,e ;Get combined value back again + rrc ;Shift over to make index + rrc ; . . . + rrc ; . . . + ani 1EH ;Keep only 4 bits + mov c,a ;Set up to offset table + lxi h,crctab ;Point at high order table + dad b ;Correct entry + mov a,m ;Get low order portion of entry + xra d ;XOR with previous high order half + inx h ;Point to high order byte + mov d,m ;Get into D + pop h ;Get back pointer to other table entry + xra m ;Include with new high order half + mov e,a ;Copy new low order portion + inx h ;Point to other portion + mov a,m ;Get the other portion of the table entry + xra d ;Include with other high order portion + mov d,a ;Move back into D + + pop h ;And H + inx h ;Point to next character + jmp crccl0 ;Go get next character + +crccl1: pop b ;Restore B + pop h ;And HL + + ret ;And return, DE=CRC-CCITT + +CRCTAB: DW 00000H + DW 01081H + DW 02102H + DW 03183H + DW 04204H + DW 05285H + DW 06306H + DW 07387H + DW 08408H + DW 09489H + DW 0A50AH + DW 0B58BH + DW 0C60CH + DW 0D68DH + DW 0E70EH + DW 0F78FH + +CRCTB2: DW 00000H + DW 01189H + DW 02312H + DW 0329BH + DW 04624H + DW 057ADH + DW 06536H + DW 074BFH + DW 08C48H + DW 09DC1H + DW 0AF5AH + DW 0BED3H + DW 0CA6CH + DW 0DBE5H + DW 0E97EH + DW 0F8F7H +; +; This is where we go if we get an error during a protocol communication. +; error prints the error packet on line 6 or so, and aborts the +; transfer. +; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, seot +; error1 print CRLF followed by the error packet. +; called by: finish, logout +; error2 just prints the error packet. +; error3 positions cursor and prints error message specified in DE. +; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, +; seot, parwrn, gofil, outbuf + +error: lda quietd ; a quiet display? + ana a + jnz error0 ; so dont say a thing + lda remtxt ;[MF]Doing a remote command? + ora a ;[MF]... + jnz error0 ;[MF]Yes, don't position cursor + call screrr ;Position the cursor. +error0: mvi a,'A' ;Set the state to abort. + sta state + jmp error2 + +error1: lxi d,crlf ;Print a CRLF. + lda quietd ; a quiet display? + ana a + jnz error2 ; so dont say a thing + call prtstr +error2: lda argblk+1 ;Get the length of the data. + mov c,a + mvi b,0 ;Put it into BC + lxi h,data ;Get the address of the data. + dad b ;Get to the end of the string. + mvi m,'$' ;Put a dollar sign at the end. + lxi d,data ;Print error message + lda remtxt ;[MF]Doing a remote command? + ora a ;[MF]... + jnz errr2a ;[MF]Yes, print message, quiet or not! + lda quietd ; a quiet display? + ana a + rnz ; so dont say a thing +errr2a: call prtstr + ret + +error3: lda quietd ; a quiet display? + ana a + rnz ; so dont say a thing + lda remtxt ;[MF]Doing a remote command? + ora a ;[MF]... + jnz err3a ;[MF]Yes, don't position cursor + push d ;Save the pointer to the message. + call screrr ;Position the cursor. + pop d ;Get the pointer back. +err3a: call prtstr ;Print error message + ret +; +; Set up for file transfer. +; called by read, send. + +init: lxi d,version ; point at Kermit's version string + lda quietd ; a quiet display? + ana a + jnz init1 ; so dont say a thing + call sysscr ; fix up screen +init1: call selmdm ; select modem + call flsmdm ; purge any pending data + call selcon ; select console again. + ret + +; Set state to ABORT +; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, seot, +; nak, ackp + +abort: mvi a,'A' ;Otherwise abort. + sta state + ret + +; nak - send NAK packet +; here from: rinit, rfile, rdata +; nak0 - update retry count and send NAK packet +; here from: rinit, rfile, rdata, tryagn + +nak0: call updrtr ;Update number of retries. +nak: lda pktnum ;Get the packet number we're waiting for. + sta argblk + xra a ;No data. + sta argblk+1 + mvi a,'N' ;NAK that packet. + call spack + jmp abort ; Give up. + ret ;Go around again. + +; increment and display retry count +; called by: rfile, sinit, sfile, sdata, seof, seot, +; nak, rpack, inchr, tryagn + +updrtr: lhld numrtr + inx h ;Increment the number of retries + shld numrtr + lda remtxt ;[MF]Doing a remote server command? + ora a ;[MF]... + rnz ;[MF]Yes, keep mum + lda quietd ; a quiet display? + ana a + rnz ; so dont say a thing + call scrnrt ;Position cursor + lhld numrtr ;[MF] +call nout ;Write the number of retries. + ret + +; [jd] this routine prints parity warnings. All registers are +; saved except for a. +; called by: sdata + +parwrn: push b + push d + push h + lxi d,inms25 + call error3 + pop h + pop d + pop b + ret +;[jd] end of addition + +; print message in status field. address of message is in DE. +; called by: read, send + +finmes: lda quietd ; a quiet display? + ana a + jz finme0 ; so do usual stuff + push d ;[MF]Save pointer to completion message + call prcrlf ; best do a new line + pop d ;[MF]Restore completion message pointer + call prtstr ; and send message + mvi e,space ; send a space or two + mvi c,dconio + push b + push d + call bdos + pop d + pop b + call bdos + ret ; and exit back +; +;else for screaming screens... + +finme0: push d ;Save message. + call scrst ;Position cursor + pop d ;Print the termination message + call prtstr + ret ; may not want this ************** + + mvi c,4 ;[2] copy across user no and drive + lxi h,kerm1 ;[2] as we have the text already +finme1: mov e,m + push h ;[2] conout probably destroys these + push b + call conout + pop b + pop h + inx h ;[2] next character + dcr c ;[2] ah, but have we done? + jnz finme1 ;[2] nope + lxi d,spac15 ;[2] send 15 spaces (clears previous filename) + call prtstr ;[2] + call scrend ;Position cursor for prompt + ret + +; Compare expected packet number against received packet number. +; return with flags set (Z = packet number valid) +; called by: rfile, rdata, sinit, sfile, sdata, seof, seot + +compp: lda pktnum ;Get the packet Nr. + mov b,a + lda argblk + cmp b + ret + +; Increment the packet number, modulo 64. +; called by: rinit, rfile, rdata, sinit, sfile, sdata, seof, seot + +countp: inr a ;Increment packet Nr. + ani 3FH ;Turn off the two high order bits + sta pktnum ;Save modulo 64 of number + lhld numpkt + inx h ;Increment Nr. of packets + shld numpkt + ret + +; Send an ACK-packet +; called by: rfile, rdata, tryagn + +ackp: xra a + sta numtry ;Reset number of retries + sta argblk+1 ;No data. (The packet number is in argblk) + mvi a,'Y' ;Acknowledge packet + call spack ;Send packet + jmp abort + ret + +; ? +; called with A/ current retry count +; called by: rfile, rdata + +tryagn: inr a ;Increment it. + sta oldtry ;Save the updated number of tries. + lda pktnum ;Get the present packet number. + dcr a ;Decrement + ani 3FH ; modulo 64 + mov b,a + lda argblk ;Get the packet's number + cmp b ;Is the packet's number one less than now? + jnz nak0 ;No, NAK it and try again. + call updrtr ;Update the number of retries. + call ackp + ret + +; Output a null-terminated string to the console. We assume that the +; console has been selected. Called with HL = address of string. +; called by: spack, inpkt + +dmptxt: mov a,m ; get character from string + ora a + rz ; done if null + push h ; save string address + mov e,a ; move character to E for outcon + call outcon ; output character to console + pop h ; restore string address + inx h ; point past printed character + jmp dmptxt ; go output rest of string + + +; Output a null-terminated string to the PRINTER We assume that the +; console has been selected. Called with HL = address of string. +; called by: spack, inpkt + +printm: mov a,m ; get character from string + ora a + rz ; done if null + push h ; save string address + mov e,a ; move character to E for outcon + call outprn ; output character to printer + pop h ; restore string address + inx h ; point past printed character + jmp printm ; go output rest of string + + +; +; test if character in A is the start of header character. We get +; the start of packet character from sohchr, which can be SET +tstsoh: push b ; save these registers for a bit + mov c,a ; we have to test if this is the character + lda sohchr + cmp c ; if zero, then it is + mov a,c ; restore accumulator but not flags + pop b + ret ; return with flags set +; + + +; Little code to allow some expansion of code without changing +; every futher address, only up to the end of this file. +; TO BE REMOVED FRO RELEASE! + +; org ($+100h) AND 0FF00H + + +IF lasm + LINK CPSREM +ENDIF;lasm diff --git a/cpsrem.asm b/cpsrem.asm index 2f480b9..677f307 100644 --- a/cpsrem.asm +++ b/cpsrem.asm @@ -1,1149 +1,1149 @@ -; CPSREM.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the (system-independent) routines that implement -; the REMOTE commands of the KERMIT protocol. -; -; revision history: -; -;edit 13, 21-Mar-1991 by MF. Renamed REMOTE SET FILE COLLISION REPLACE to -; REMOTE SET FILE COLLISION OVERWRITE and modified the corresponding -; help text slightly. -;edit 12, 13-Feb-1991 by MF. Simplified code at "remcl0" to get REMOTE -; command arguments by calling "cmgtch" in order to get command-line -; characters directly. This means that command-line characters are -; passed literally (except for prefixingand space-compression) to the -; remote Kermit and that one need not send "?" or 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 ). 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 ? - jz remcl2 ;[12]Yes - cpi ff ;[12]an ? - 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 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 ). 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 ? + jz remcl2 ;[12]Yes + cpi ff ;[12]an ? + jz remcl1 ;[12]Yes, diddle command buffer pointer + cpi '?' ;[12]a "?"? + jnz remcl0 ;[12]No, just get more characters +remcl1: push h ;[12]Protect HL + lhld cmdptr ;[12]get "cmgtch"'s character pointer + inx h ;[12]and reverse the action at "cmgtc4" + ;[12]since we don't need a "confirm" and + ;[12]infinite loops are beaucoup bad news + shld cmdptr ;[12]... + pop h ;[12]Restore HL +remcl2: push psw ;[12]Save the character + xra a ;[12]Zero the action flag so we get input + sta cmaflg ;[12]to end-of-line without special action + pop psw ;[12]Restore the character + jmp remcl0 ;[12]Get more characters +remclx: mov a,b ;[12]Get accumulated text length + sta rcl ;[12]and remember it +; + ret ;Return +; +;Remote set values +; +; REMOTE SET FILE TYPE 300 0 = TEXT, 1 = BINARY +; REMOTE SET FILE NAMES 301 0 = CONVERTED, 1 = LITERAL +; REMOTE SET FILE COLLISION 302 0 = RENAME, 1 = OVERWRITE, +; 2 = BACKUP, 3 = APPEND, +; 4 = DISCARD, 5 = ASK +; REMOTE SET FILE REPLACE 303 0 = PRESERVE, 1 = DEFAULT +; REMOTE SET FILE INCOMPLETE 310 0 = DISCARD, 1 = KEEP +; REMOTE SET INCOMPLETE (same as above) +; REMOTE SET BLOCK-CHECK 400 number (1, 2, or 3) +; REMOTE SET RECEIVE PACKET-LENGTH 401 number (10-9024) +; REMOTE SET RECEIVE TIMEOUT 402 number (any, 0 = no timeout) +; REMOTE SET RETRY 403 number (any, 0 = no limit) +; REMOTE SET SERVER TIMEOUT 404 number (any, 0 = no timeout) +;REMOTE SET FILE BLOCKSIZE 311 number +;REMOTE SET FILE RECORD-LENGTH 312 number +;REMOTE SET FILE RECORD-FORMAT 313 F (fixed), V (variable), etc... +;This is just for the record, to assign these numbers to these commands +;for somebody who needed them. Details to be filled in later. +; +;Remote Set command table +; +rmstab: db 7 ;seven entries + db 16,'BLOCK-CHECK-TYPE$' + dw remsbc ;Remote Set Block Check + db 4,'FILE$' + dw remsfl ;Remote Set File + db 10,'INCOMPLETE$' + dw remsfi ;Remote Set (file) Incomplete + db 7,'RECEIVE$' + dw remsrc ;Remote Set Receive + db 7,'REPLACE$' + dw remsfr ;Remote Set (file) Replace + db 5,'RETRY$' + dw remsry ;Remote Set Retry + db 14,'SERVER-TIMEOUT$' + dw remsst ;Remote Set Server Timeout +; +rmshlp: db cr,lf,'BLOCK-CHECK-TYPE for a remote server' + db cr,lf,'FILE parameters for a remote server' + db cr,lf,'INCOMPLETE file disposition for a remote server' + db cr,lf,'RECEIVE parameters for a remote server' + db cr,lf,'REPLACE file attribute handling for a remote server' + db cr,lf,'RETRY maximum for a remote server' + db cr,lf,'SERVER-TIMEOUT interval for a remote server' + db '$' +; +;Remote Set File tables +; +rsftab: db 8 ;eight entries + db 10,'BLOCK-SIZE$' + dw remsbs ;Remote Set File Block-size command + db 9,'COLLISION$' + dw remsfc ;Remote Set File Collision command + db 10,'INCOMPLETE$' + dw remsfi ;Remote Set File Incomplete command + db 5,'NAMES$' + dw remsfn ;Remote Set File Names command + db 13,'RECORD-FORMAT$' + dw remsrf ;Remote Set File Record-format + db 13,'RECORD-LENGTH$' + dw remsrl ;Remote Set File Record-length + db 7,'REPLACE$' + dw remsfr ;Remote Set File Replace command + db 4,'TYPE$' + dw remsft ;Remote Set File Type command +; +rsfhlp: db cr,lf,'BLOCK-SIZE of files for a remote server' + db cr,lf,'COLLISION action on filename conflicts for a remote' + db ' server' + db cr,lf,'INCOMPLETE file disposition for a remote server' + db cr,lf,'NAMES translation of files for a remote server' + db cr,lf,'RECORD-FORMAT of files for a remote server' + db cr,lf,'RECORD-LENGTH for a remote server' + db cr,lf,'REPLACE file attribute handling for a remote server' + db cr,lf,'TYPE of files for a remote server' + db '$' +; +;Remote Set File Record-format tables +; +rcftab: db 2 ;two entries + db 5,'FIXED$' + db 'F','F' ;Remote Set File Record-format Fixed command + db 8,'VARIABLE$' + db 'V','V' ;Remote Set File Record-format Variable cmd +; +rcfhlp: db cr,lf,'FIXED VARIABLE' + db '$' +; +;Remote Set Receive tables +; +rrctab: db 2 ;two entries + db 13,'PACKET-LENGTH$' + dw remrpl ;Remote Set Receive Packet-length command + db 7,'TIMEOUT$' + dw remsrt ;Remote Set Receive Timeout command +; +rrchlp: db cr,lf,'PACKET-length TIMEOUT' + db '$' +; +;Remote Set File-collision table +; +rfctab: db 6 ;six entries + db 6,'APPEND$' + db '3','3' ;Set collision append + db 3,'ASK$' + db '5','5' ;Set collision ask + db 6,'BACKUP$' + db '2','2' ;Set collision backup + db 7,'DISCARD$' + db '4','4' ;Set collision discard + db 9,'OVERWRITE$' + db '1','1' ;Set collision overwrite + db 6,'RENAME$' + db '0','0' ;Set collision rename +; +rfchlp: db cr,lf,'ASK about existing files on a remote system' + db cr,lf,'APPEND to existing files on a remote system' + db cr,lf,'BACKUP (rename) existing files on a remote system' + db cr,lf,'DISCARD new versions of existing files on a' + db ' remote system' + db cr,lf,'OVERWRITE existing files on a remote system' + db cr,lf,'RENAME new versions of existing files on a' + db ' remote system' + db '$' +; +;Remote Set File-Incomplete tables +; +rfitab: db 2 ;2 entries + db 7,'DISCARD$' + db '0','0' ;Remote Set File Incomplete Discard + db 4,'KEEP$' + db '1','1' ;Remote Set File Incomplete Keep +; +rfihlp: db cr,lf,'DISCARD KEEP' + db '$' +; +;Remote Set File-Names tables +; +rfntab: db 2 ;two entries + db 9,'CONVERTED$' + db '0','0' ;Remote Set File Names Converted + db 7,'LITERAL$' + db '1','1' ;Remote Set File Names Literal +; +rfnhlp: db cr,lf,'CONVERTED LITERAL' + db '$' +; +;Remote Set File Replace tables +; +rfrtab: db 2 ;two entries + db 8,'PRESERVE$' + db '0','0' ;Remote Set File Replace Preserve + db 7,'DEFAULT$' + db '1','1' ;Remote Set File Replace Default +; +rfrhlp: db cr,lf,'PRESERVE DEFAULT' + db '$' +; +;Remote Set File Type tables +; +rfttab: db 2 ;two entries + db 6,'BINARY$' + db '1','1' ;Remote Set File Type Binary + db 4,'TEXT$' + db '0','0' ;Remote Set File Type Text +; +rfthlp: db cr,lf,'BINARY TEXT' + db '$' +; +; Remote Set Block-check +; +remsbc: +IF lasm + lxi h,'40' ;1st 2 chars of "400" +ENDIF ;lasm +IF NOT lasm + lxi h,'04' +ENDIF ;NOT lasm + shld remdat+2 ;Store in correct order + mvi a,'0' ;Put last char of type in buffer + sta remdat+4 ;... + lxi d,blktab ;Point to block-check table + lxi h,blkhlp ;and help table + jmp remsc1 ;Do common code +; +;Remote Set File command +; +remsfl: lxi d,rsftab ;Point to Remote Set File tables + lxi h,rsfhlp ;... +remsf0: call keycmd ;Get user's selection + xchg ;Put dispatch address in HL + pchl ;and obey the user's most fervent desires +; +;Remote Set Receive command +; +remsrc: lxi d,rrctab ;Point to the appropriate tables + lxi h,rrchlp ;... + jmp remsf0 ;and do command +; +;Remote Set Block-size command +; +remsbs: +IF lasm + lxi h,'31' ;1st 2 chars of Set code +ENDIF ;lasm +IF NOT lasm + lxi h,'13' +ENDIF ;NOT lasm + shld remdat+2 ;Store chars in correct order + mvi a,'1' ;Put last char in buffer + sta remdat+4 ;... + jmp remscm ;and do common Remote Set code +; +;Remote Set File-collision command +; +remsfc: +IF lasm + lxi h,'30' ;Put set type code in buffer +ENDIF ;lasm +IF NOT lasm + lxi h,'03' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'2' ;... + sta remdat+4 ;... + lxi d,rfctab ;Point to tables + lxi h,rfchlp ;... + jmp remsc1 ;and do common code +; +;Remote Set File Incomplete command +; +remsfi: +IF lasm + lxi h,'31' ;Establish command keyword code +ENDIF ;lasm +IF NOT lasm + lxi h,'13' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'0' ;... + sta remdat+4 ;... + lxi d,rfitab ;Point to tables + lxi h,rfihlp ;... + jmp remsc1 ;and do common code +; +;Remote Set File-Names command +; +remsfn: +IF lasm + lxi h,'30' ;Set command code +ENDIF ;lasm +IF NOT lasm + lxi h,'03' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'1' ;... + sta remdat+4 ;... + lxi d,rfntab ;Point to the appropriate tables + lxi h,rfnhlp ;... + jmp remsc1 ;and do common code +; +;Remote Set File Record Format command +; +remsrf: +IF lasm + lxi h,'31' ;Set command code +ENDIF ;lasm +IF NOT lasm + lxi h,'13' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'3' ;... + sta remdat+4 ;... + lxi d,rcftab ;Point to proper tables + lxi h,rcfhlp ;... + jmp remsc1 ;and do common code +; +;Remote Set File Record Length command +; +remsrl: +IF lasm + lxi h,'31' ;Set command code +ENDIF ;lasm +IF NOT lasm + lxi h,'13' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'2' ;... + sta remdat+4 ;... + jmp remscm ;and do common code +; +;Remote Set File Replace command +; +remsfr: +IF lasm + lxi h,'30' ;Set command code +ENDIF ;lasm +IF NOT lasm + lxi h,'03' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'3' ;... + sta remdat+4 ;... + lxi d,rfrtab ;Point to tables + lxi h,rfrhlp ;... + jmp remsc1 ;and do common code +; +;Remote Set File Type command +; +remsft: +IF lasm + lxi h,'30' ;Set command code +ENDIF ;lasm +IF NOT lasm + lxi h,'03' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'0' ;... + sta remdat+4 ;... + lxi d,rfttab ;Point to tables + lxi h,rfthlp ;... + jmp remsc1 ;and go to common code +; +;Remote Set Receive Packet-length command +; +remrpl: +IF lasm + lxi h,'40' ;Set command code +ENDIF ;lasm +IF NOT lasm + lxi h,'04' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'1' ;... + sta remdat+4 ;... + jmp remscm ;and do common code +; +;Remote Set Receive Timeout command +; +remsrt: +IF lasm + lxi h,'40' ;Set code +ENDIF ;lasm +IF NOT lasm + lxi h,'04' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'2' ;... + sta remdat+4 ;... + jmp remscm ;and do common code +; +;Remote Set Retry command +; +remsry: +IF lasm + lxi h,'40' ;Set code +ENDIF ;lasm +IF NOT lasm + lxi h,'04' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'3' ;... + sta remdat+4 ;... + jmp remscm ;Go to common code +; +;Remote Set Server Timeout command +; +remsst: +IF lasm + lxi h,'40' ;Set code +ENDIF ;lasm +IF NOT lasm + lxi h,'04' +ENDIF ;NOT lasm + shld remdat+2 ;... + mvi a,'4' ;... + sta remdat+4 ;... + jmp remscm ;Do common code + + + + + +; Little code to allow some expansion of code without changing +; every futher address, only up to the end of this file. +; TO BE REMOVED FOR RELEASE + +; ORG ($+100H) AND 0FF00H + + +IF lasm + LINK CPSSER +ENDIF ;lasm diff --git a/cpsser.asm b/cpsser.asm index d49ebe0..707f1c3 100644 --- a/cpsser.asm +++ b/cpsser.asm @@ -1,44 +1,44 @@ -; CPSSER.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the (system-independent) routines that implement -; the SERVER part of the KERMIT protocol. -; -; revision history: -; -; -; edit 1: September, 1987. Created CPSSER.ASM from bits from the two CPSPK? -; files. -; The code herein is to allow remote systems to communicate to -; this Kermit running in SERVER mode. Note that not every server -; command will be supported, mind... -; -server: db 'CPSSER.ASM (1) 8-SEP-87$' ; name, edit number, date - - - -; Little code to allow some expansion of code without changing -; every futher address, only up to the end of this file. -; TO BE REMOVED FOR RELEASE! - -; org ($+100h) AND 0FF00H - - -IF lasm - LINK CPSTT -ENDIF;lasm +; CPSSER.ASM +; KERMIT - (Celtic for "FREE") +; +; This is the CP/M-80 implementation of the Columbia University +; KERMIT file transfer protocol. +; +; Version 4.0 +; +; Copyright June 1981,1982,1983,1984 +; Columbia University +; +; Originally written by Bill Catchings of the Columbia University Center for +; Computing Activities, 612 W. 115th St., New York, NY 10025. +; +; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, +; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many +; others. +; +; This file contains the (system-independent) routines that implement +; the SERVER part of the KERMIT protocol. +; +; revision history: +; +; +; edit 1: September, 1987. Created CPSSER.ASM from bits from the two CPSPK? +; files. +; The code herein is to allow remote systems to communicate to +; this Kermit running in SERVER mode. Note that not every server +; command will be supported, mind... +; +server: db 'CPSSER.ASM (1) 8-SEP-87$' ; name, edit number, date + + + +; Little code to allow some expansion of code without changing +; every futher address, only up to the end of this file. +; TO BE REMOVED FOR RELEASE! + +; org ($+100h) AND 0FF00H + + +IF lasm + LINK CPSTT +ENDIF;lasm diff --git a/cpstt.asm b/cpstt.asm index 41a30af..1e96171 100644 --- a/cpstt.asm +++ b/cpstt.asm @@ -1,862 +1,862 @@ -; CPSTT.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the code for the TRANSMIT and CONNECT commands, -; which communicate with a host which is not running KERMIT. -; -; revision history: -; -;edit 12, 31-Jan-1991 by MF. Delete call to "inbuf" after "xmit1" in -; the TRANSMIT command. "getfil" initializes various counters so that -; when "in1chr" is first called, "inbuf" will be called immediately -; and will read sectors of the file to be transmitted from disk. -; This, along with a fix to "in1chr" in CPSUTL.ASM, fixes a bug -; discovered by Lance Tagliapietra of the University of Wisconsin at -; Platteville wherein the TRANSMIT command was failing to transmit some -; characters in files over one sector in length. See CPSUTL.ASM, -; edit 29. -; edit 11, 10 September, a987, by OBSchou. Modified TRANSMIT command -; to TRANSMIT -; -; 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 -; -; 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 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 Q to suspend logging and R to -; resume. 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 -; 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 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 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 +; +; 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 +; +; 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 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 Q to suspend logging and R to +; resume. 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 +; 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 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 Z. Tell the host we're a VT52. (Sure we are...) +vt52id: mvi a,esc ; response is escape... + call setpar ; (need correct parity) + mov e,a + call outmdm ; (console already selected) + mvi a,'/' ; ... slash ... + call setpar ; (with parity) + mov e,a + call outmdm + mvi a,'K' ; ... K. + call setpar + mov e,a + call outmdm + jmp vtig ; clear escape-sequence flag and return. + +; here when escflg isn't 0 or 1 - processing cursor positioning sequence. +vt52y: cpi 2 ; looking for row? (y-coordinate) + jnz vt52x ; no, must be column. + mov a,e ; yes. get coordinate + sui (' '-1) ; convert from ascii (1 = top line) + sta vtyval ; store for later + mvi a,3 ; advance to next state (x coord) + sta escflg ; store it + ret ; try for another character + +; here when escflag isn't 0, 1, or 2 - it must be 3. (right?) +; E holds the last character of the cursor positioning sequence. +vt52x: xra a ; end of escape sequence, reset state. + sta escflg + mov a,e ; get column (' ' is left margin) + sui (' '-1) ; make left margin be one + mov c,a ; stash column in c + lda vtyval ; get row number + mov b,a ; in b + call selcon ; select console + call csrpos ; call system-dependent cursor positioner + ret ; all through. +; +; +; conchr - copy character from console to comm line, processing +; (kermit's) escape sequences. +; Enter and exit with console selected. +; nonskip return: transparent mode terminated. +; skip return: still in transparent mode. +; called by: rexmit, telnet + +conchr: call inpcon ;Try to get a character from the console + ani 07FH ;Keep only 7 bits + jz rskp ;Null means nothing there. + mov e,a ;Move the char for comparison. + sta lstchr ;Save it + lda escchr ;Get the escape char. + cmp e ;Is it an escape char? + jz intchr ;If so go process it. + call selmdm ; select the modem + mov a,e ;Get the char. + call setpar ;Set parity (if any). + mov e,a ;Restore it. + push d ; need to save e in case we are half dplx [5] + call outmdm ;Output the char to the port. + pop d ; Just in case we are half dplx [5] + call selcon ; reselect console + lda ecoflg ;Get the echo flag. + ora a ;Is it turned on? + jz rskp ;If not we're done here. + mov a,e ;Get the char. + ani 7FH ;Turn off the parity bit. + mov e,a + call outcon ; echo the character. + jmp rskp ; use skip return +; +; transparent escape character has been typed. dispatch on second +; character. (console is still selected) +; here from: conchr + +intchr: call inpcon ; get another character from the console + ora a ; zero means no character available yet. + jz intchr ; If so, loop until we get a char. + mov b,a ;Save the actual char. + cpi ctrlc ;is it Control-C? + jz contc ;yes + ani 137O ;Convert to upper case. + cpi 'C' ;Is it close? + jnz intch0 ;If not proceed. +contc: lxi d,infms9 ;Say we are back. + call prtstr + call syscls ; call system-dependent close routine + lda logflg ;Get the log flag. + ora a ;[pcc005] Check if open + cm logcls ;[pcc005] Close if needed + ret + +;Here if not a 'C' or '^C' + +intch0: cpi 'S' ;Is it status? + jnz inch01 ;If not, proceed. + call stat01 ;Print out the status stuff. + call prcrlf ;[pcc011] add a crlf + jmp rskp ;return from conchr + +inch01: +inch03: mov a,b ;Get the char. + cpi '?' ;Is it a help request? + jnz intch1 ;If not, go to the next check. +inch3a: lda logflg ;[pcc003] Logging flag + ora a ;[pcc003] see if active + jp inch04 ;[pcc005] jump if no file open + lxi d,loghlp ;[pcc003] yes, tell about R AND Q + call prtstr ;[pcc003] +inch04: lxi d,inthlp ;If so, get the address of the help message. + call prtstr + call sysinh ; print system-dependent help message + lxi d,inhlp1 ; Tell about doubling the escape character + call prtstr + call escpr ;Print escape character + lxi d,inhlp2 ;Print the rest + call prtstr + jmp intchr ;Get another char. + +intch1: mov a,b ;Get the character. + cpi '0' ;Is it '0', to send a null? + jnz intch3 ;No. + xra a ;Yes, send an ASCII zero. + call setpar ; with the correct parity + mov e,a + call selmdm ; (to the modem...) + call outmdm + call selcon ; return with console selected + jmp rskp + +intch3: lda escchr ;Get the escape char. + cmp b ;Is it the escape char? + jnz intch4 ;[pcc002] jump if not + mov a,b ;Get the char. + call setpar + mov e,a ;Restore it. + call selmdm + call outmdm ;Output it. + call selcon ;We promised console would be selected... + jmp rskp ;Return, we are done here. +intch4: mov a,b ;[pcc002] get it again + ani 137o ;[pcc002] in upper case + cpi 'P' ;[pcc002] toggle printer? + jnz intch5 ;[pcc003] nope + lda prnflg ;[pcc002] get printer flag + xri 01h ;[pcc002] complement it + sta prnflg ;[pcc002] and put back + jmp rskp ;[pcc002] +intch5: lda logflg ;[pcc003] get log flag + ora a ;[pcc003] See if open + jp intch7 ;[pcc003] no, skip R and Q + mov a,b ;[pcc003] get back chr + ani 137o ;[pcc003] make upper case + cpi 'R' ;[pcc003] Is it R + jnz intch6 ;[pcc003] Jump if not + mvi a,81H ;[pcc003] set flag for logging + sta logflg ;[pcc003] put it back + lxi d,inms28 ;[pcc003] message + call prtstr ;[pcc003] + jmp rskp ;[pcc003] done +intch6: cpi 'Q' ;[pcc003] Quit logging? + jnz intch7 ;[pcc003] no + mvi a,82H ;[pcc003] flag for open, but suspended + sta logflg ;[pcc003] store away + lxi d,inms27 ;[pcc003] keep them informed + call prtstr ;[pcc003] + jmp rskp ;[pcc003] +intch7: ;[pcc003] + +intchz: mov a,b ; not recognized. get saved copy back. + push psw ;[8] save as we will want to test for 'D' + call sysint ; interpret system-dependent sequences + jmp intchy ; done. [10] Now see if D. If so, do a C. + pop psw ;[10] tidy stack + mvi e,'G'-100O ;Otherwise send a beep. + call outcon ; to the console. + jmp rskp + +intchy: pop psw ;[10] adjust stack + ani 5fh ;[10] strip parity, make it upper case + cpi 'D' ;[10] was it a D? + jz contc ;[10] yup, so to the equivalent of an escape-C + jmp rskp +; +; Little code to allow some expansion of code without changing +; every futher address, only up to the end of this file. +; TO BE REMOVED FOR RELEASE! + +; org ($+100h) AND 0FF00H +IF lasm + LINK CPSCPM +ENDIF;lasm diff --git a/cpsutl.asm b/cpsutl.asm index 3081232..9d7244e 100644 --- a/cpsutl.asm +++ b/cpsutl.asm @@ -1,1227 +1,1227 @@ -; CPSUTL.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; Utility routines, pure and impure data. -; -; revision history: -; -;edit 31, 21-Mar-1991 by MF. Implement edit 30 without checking takflg after -; "r1tch1" as we are **always** TAKEing from a file if we get to that -; point in the code. Makes for simplicity. -;edit 30, 27-Feb-1991 by MF. When TAKEing characters from a TAKE-file, -; view semicolons as normal characters (not command separators). -; This will allow such commands as REMOTE DELETE *.*;* to work -; properly from TAKE-files without having to revert to old code in -; cpsrem.asm at "remcl0" to decode Remote command arguments. TAKE-files -; ought not (in my opinion) to have multiple commands per line anyway. -;edit 29, 30-Jan-1991 by MF. Fix bug in IN1CHR which decremented "chrcnt" -; once too often after a call to INBUF (which predecrements it -; already). This, along with a fix in CPSTT.ASM, fixes a bug in the -; TRANSMIT command wherein certain characters in the file were not -; being transmitted. This bug was reported to me by Lance Tagliapietra -; of the University of Wisconsin at Platteville, WI (Email: -; ). -; (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 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 Q to suspend logging and R to -; resume. 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 '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: +; ). +; (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 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 Q to suspend logging and R to +; resume. 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 's +; to terminate the line or other weird stuff. Also need to +; check flag and complain if wild-cards illegal. +; +;pcc008 2-Jan-85 vjc modules:cp4def,cp4tt,cp4utl +; Keyboard input during CONNECT mode can get locked out if +; there is enough input from the modem port to keep prtchr +; busy. This can happen for example, if the printer is running +; at the same speed as the modem line, leaving you helpless to +; turn it off or abort the host. Add a fairness count, so that +; at least every prfair characters we look at console input. +; +;pcc012 4-Jan-85 vjc modules:cp4mit,cp4tt,cp4utl +; Use the big buffer for the log file. Move the log file back +; into the common fcb and only save the drive, name, and +; extension between connects. Add new routines to cp4utl to +; create or append to an existing file, and to conditionally +; advance buffers only if in memory. Remove edit pcc003 that +; allows one more character after the xoff, since it didn't +; really work very well and does not fit in well with the way +; the buffer advancing routines are set up. If someone still +; thinks this would be useful, it could be put back in with a +; little more work. +; +; While testing this edit, I also noticed another bug that +; the command parsing routines do not limit or check the +; length of command lines or file specs, trashing what ever +; comes after them. Currently because of where the fcb and +; command buffer are located, this does not usually cause a +; problem, but could if an extremely long line was typed in, +; or in the future multiple fcbs defined elsewhere in memory +; were used. Maybe this should be put on the bug list +; somewhere. +; +;pcc013 8-Jan-85 vjc modules:cp4mit,cp4utl,cp4typ +; Replace CLOSE command to cancel session logging to SET +; LOGGING ON/OFF. This seems to fit in with the command +; structure better. Default the log file to KERMIT.LOG +; incase no previous LOG command. Logging is also enabled +; by LOG command, as before. +; +; edit 4: September 9, 1984 +; Move command tables and associated help text to CP4MIT. Add +; makfil/clofil routines and modify outbuf to write files in big +; chunks. Update Kermit's version to 4.03. +; +; edit 3: August 21, 1984 +; Make inbuf read files in big chunks to minimize disk start/stop +; delays. Buffer size and address is specified by system-dependent +; overlay. +; +; edit 2: August 3, 1984 +; move "mover" to CP4SYS to allow use of Z80 block move instruction. +; +; edit 1: July 27, 1984 +; extracted from CP4MIT.M80 edit 2, as part of LASM support. This is +; the last file linked for the system-independent code. +; +utlver: db 'CPSUTL.ASM (31) 21-Mar-1991$' + +; Set the parity for a character in A. +; called by: spack, rexmit, logit, vt52, conchr, intchr + +setpar: push h ;Save HL. + push b + lxi h,parity + mov c,m ;Get the parity routine. + mvi b,0 + lxi h,parjmp ;Get the first address. + dad b + pchl + +parjmp: jmp even + jmp mark + jmp none + jmp odd + jmp spacep + +none: jmp parret ;Don't touch the parity bit. + +even: ani 7FH ;Strip parity. + jpe parret ;Already even, leave it. + ori 80H ;Make it even parity. + jmp parret + +mark: ori 80H ;Turn on the parity bit. + jmp parret + +odd: ani 7FH ;Strip parity. + jpo parret ;Already odd, leave it. + ori 80H ;Make it odd parity. + jmp parret + +spacep: ani 7FH ;Turn off the parity bit. + jmp parret + +parret: pop b + pop h ;Restore HL. + ret +; +; Print the escape char. +; called by: stat01, telnet, intchr + +escpr: lda escchr ;Get the escape char. +escpr1: cpi ' ' ;Is it a control char? + jp escpr2 + push psw ; save the character + lxi d,inms10 ;Output "Control-". + call prtstr + pop psw ; restore the character + ori 100O ;De-controlify. +escpr2: mvi c,conout ;Output the char + mov e,a + call bdos + ret + +; fetch keyword; if unsuccessful, return to command level. +; called by: kermit, setcom + +keycmd: mvi a,cmkey + call comnd + jmp keycm2 ;no match + ret + +keycm2: lxi d,ermes1 ;"Unrecognized Command" + call prtstr + jmp kermit ;Do it again. + +; request confirmation; if unsuccessful, return to command level +; called by: bye, exit, help, log, setcom, show, status, send, +; finish, logout, telnet + +cfmcmd: mvi a,cmcfm + call comnd + jmp kermt3 ;"Not confirmed" + ret +; + +; This routine prints the number in HL on the screen in decimal. +; Uses all ACs. +; called by: cp4sys, read, send, updrtr, dir, user + +nout: mvi a,'0' ; fill tempx with zeros + call filltmp + + lxi b,-10 ;Get some useful constants. +nout1: lxi d,-1 + +nout2: dad b ;Subtract as many 10s as possible. + inx d ;Count them. + jc nout2 ;If some left keep going. + push h ;save remainder - 10 + xchg ;Swap the remainder and the quotient. + mov a,h ;Get the number of 10s found. + ora l ;check for quotient non zero + cnz nout1 ;If non zero, recurse. + pop h ;Get the remainder - 10 + mov a,l ;in a + adi '0'+10 ;Make the number printable and add the 10 back + call shiftmp ; cycle temp registers + sta temp1 ; and save digit + mov e,a ;Output the digit. + lda nquiet ; are we to be quiet? + ana a + rnz ; yup, so return here rather than frm bdos + mvi c,conout + jmp bdos + +; prcrlf - print a CR/LF. (Saves no registers.) [Toad Hall] +; prtstr - print string pointed to by DE (now in overlay section.. see prtstx) +; called by: lots of places. +prcrlf: lxi d,crlf ;Point to the CR/LF + jmp prtstr ; Use the one in the overlay + +; prtstx is funtionally the same as prtstr in the overaly but is here as +; we may need a print a string routine in case the overlay is +; either incorrect version or simply not present. +prtstx: ; PRTSTR moved to overlay, but we do need the + ; same function for writing the sign-on + ; message and error message if the overlay + ;is not present. Thence prtstx + mvi c,prstr ; output string + jmp bdos ;a CALL followed by a RET becomes a JMP + + +; Jumping to this location is like retskp. It assumes the instruction +; after the call is a jmp addr. +; here from: many places. +rskp: pop h ;Get the return address. + inx h ;Increment by three. + inx h + inx h + pchl + +; Jumping here is the same as a ret. 'jmp r' is used after routines +; that have skip returns, where the non-skip instruction must be 3 bytes. +; here from: many places. +r: ret + +; Pause-it routine. Informs the user to press any key to continue +; and then waits for a key input. Called by the any routine +; with more than, say, 20 lines of output. + +pausit: lxi d,anymes ; ask user to press any key to continue + call prtstr +pausi1: call ckcon ; see if a key typed + ana a + jz pausi1 ; loop until a key has been pressed. + + ret + +; +; Open a file for reading (with inbuf). The filename is already +; in fcb; upon return, the end of file flag is cleared and chrcnt +; is set to zero, so inbuf will be called to get a buffer when we +; next attempt to get a character. +; called by: sinit, seof + +getfil: xra a + sta chrcnt ;Buffer is empty. + sta seccnt ;No sectors buffered. + sta eoflag ;Not the end of file. + sta endsts ;No EOF/error pending. + sta fcb+0CH ;Zero the extent. + sta fcb+0EH ;Must be zero for MAKEF or OPENF. + sta fcb+20H ;Zero the current record. + mvi c,openf ;Open the file. + lxi d,fcb + call bdos + ret + +; Get next sector. If necessary, read some more from disk. +; preserves bc, de, hl +; returns nonskip if EOF or error; +; returns skip with chrcnt and bufpnt updated if success. +; called by: gtchr, get1xc (from xmt/transmit) + +inbuf: lda eoflag ;Have we reached the end? + ora a + rnz ;Return if so. + push b + push d + push h +inbuf1: lda seccnt ; Do we have any sectors left? + ora a + jz inbuf3 ; If not, go get some more. +inbuf2: lhld nxtbuf ; Yes. Get address of next sector + shld bufpnt ; Update current buffer pointer + lxi b,bufsiz ; Get number of bytes in sector + dad b ; Update HL to point to next sector + shld nxtbuf ; Save for next time + dcr a ; Decrement count of buffered sectors + sta seccnt ; Put it back + mvi a,bufsiz-1 ; Number of bytes in buffer (pre-decremented) + sta chrcnt ; Store for our caller + pop h + pop d + pop b + jmp rskp ; Return success + +; We don't have any sectors buffered. If we've already hit an error or +; EOF, return that status to the user. + +inbuf3: lda endsts ; Check status from previous read + ora a + jz inbuf4 ; It was OK. Get some more sectors. + sta eoflag ; End of file or error. Set the flag. + xra a + sta chrcnt ; Say no characters in buffer. + pop h + pop d + pop b + ret ; Return failure + +; Read sectors until we fill the buffer or get an error or EOF, then return +; the first buffer to the user. (seccnt is zero) + +inbuf4: lhld bufadr ; Get address of big buffer + shld nxtbuf ; Store as next buffer address to give user +inbuf5: shld bufpnt ; Store as next buffer address to read into + xchg ; Move buffer address to DE + mvi c,setdma ; Tell CP/M where to put the data + call bdos ; ... + mvi c,readf ; Read a record. + lxi d,fcb + call bdos + sta endsts ; Save ending status + ora a ; 00H => read O.K + jnz inbuf6 ; EOF/error: stop reading. + lxi h,seccnt ; Success. Get addr of sector count + inr m ; Bump sector count by one + lda bufsec ; Get max number of sectors in buffer + cmp m ; Are we there yet? + jz inbuf7 ; Yes, can't read any more. + lhld bufpnt ; No, try for another. Get buffer address, + lxi d,bufsiz ; and size of sector, + dad d ; giving next buffer address in HL + jmp inbuf5 ; Go read another sector. + +; We hit EOF or got an error. Put the DMA address back where it belongs, +; then go see if we have any sectors (before the one that got the error) +; to return to the caller. Nxtbuf points to the first good sector, if +; any; seccnt contains the count of good sectors. + +inbuf6: call rstdma + jmp inbuf1 ; Go see if we have some data to return + +; We've filled the big buffer. Reset the DMA address, then go return a +; sector to the caller. nxtbuf points to the beginning of the buffer; +; seccnt contains the number of sectors successfully read (except that +; if we've read 256 sectors, seccnt contains zero, so we can't just go +; to inbuf1). + +inbuf7: call rstdma ;[pcc012] + lda seccnt ; Get sector count again. + jmp inbuf2 ; Return a sector. + +; IN1CHR - get a single character from the file. Taken code from old +; TRANSMIT routine. +in1chr: + lda eoflag ;EOF encountered? + ora a + rnz ; Yes, finish. + lxi d,cmdbuf ; Use comnd buffer as line buffer. + lhld bufpnt ; Get current buffer pointer. + lda chrcnt ; Get current byte count + mov b,a ; in B +in1ch1: dcr b ; Assume there's a character there + jp in1ch2 ; If there was, proceed. + call inbuf ; There wasn't. Try for another buffer. + jmp in1che ; End of file. + lhld bufpnt ; Got another buffer. Get new pointer in HL + lda chrcnt ; and new byte count + mov b,a ; in B +;[MF]The modification below was made 30-Jan-1991 per report from +;[MF]Lance Tagliapietra from the University of Wisconsin at Platteville +;[MF]The following instruction should not be executed as the character counter +;[MF]has already been decremented by INBUF. +; dcr b ; we are reading in a character, so less one +in1ch2: mov a,b ; save new count + sta chrcnt + mov a,m ; Get a character from disk buffer. + inx h + shld bufpnt ; save new pointer + ani 7FH ; Mask 7 bits. + jz in1ch1 ; Skip nulls. + ret ; character in a + + +in1che: mvi a,0ffh ; dubious about this one... + sta eoflag + ret ; set end of file flag...????? + +; ;[pcc012] +; appfil - Create or append to an existing file. File name is in FCB. +; Non-skip return if could not be done. Skip return with file +; open and bufpnt pointing to end of file. +; called by logopn +appfil: xra a ;[pcc012] zero out stuff for open + sta fcb+0CH ;[pcc012] extent + sta fcb+0EH ;[pcc012] Must be zero for MAKEF or OPENF. + sta fcb+20H ;[pcc012] Zero the current record. + mvi c,openf ;[pcc012] Try to open the file + lxi d,fcb ;[pcc012] + call bdos ;[pcc012] + cpi 0FFH ;[pcc012] Did we find it? + jz makfi1 ;[pcc012] If not, go create it + mvi c,cflsz ;[pcc012] Compute the file size + lxi d,fcb ;[pcc012] + call bdos ;[pcc012] + lhld fcb+21H ;[pcc012] random record pointer + mov a,h ;[pcc012] See if zero length file + ora l ;[pcc012] + jz makfi2 ;[pcc012] set up pointers if null file + dcx h ;[pcc012] backup to last record written + shld fcb+21H ;[pcc012] store rec ptr back + lhld bufadr ;[pcc012] get buffer address + xchg ;[pcc012] to DE + mvi c,setdma ;[pcc012] set dma address + call bdos ;[pcc012] for read + mvi c,rrand ;[pcc012] read the last block + lxi d,fcb ;[pcc012] + call bdos ;[pcc012] + ora a ;[pcc012] check results + jnz rstdma ;[pcc012] reset dma and return if error + lhld bufadr ;[pcc012] get address again + lxi d,bufsiz ;[pcc012] and and size + mvi a,'Z'-40H ;[pcc012] control-Z for comparison +appcz: cmp m ;[pcc012] Is this the EOF? + jz appxit ;[pcc012] Jump if yes + inx h ;[pcc012] no, bump + dcr e ;[pcc012] and grind + jnz appcz ;[pcc012] until find or buffer empty +appxit: shld bufpnt ;[pcc012] store buffer pointer + dad d ;[pcc012] compute next buffer adr + shld nxtbuf ;[pcc012] and store + mov a,e ;[pcc012] updated chr count + sta chrcnt ;[pcc012] + xra a ;[pcc012] reset sector count + sta seccnt ;[pcc012] + call rstdma ;[pcc012] reset normal dma + jmp rskp ;[pcc012] and give good return + +; Create a file, deleting any previous version. The filename is in +; fcb. +; Returns nonskip if file could not be created. +; If successful, takes skip return with bufpnt and chrcnt initialized +; for output; buffers should be output via outbuf. +; called by: gofil +makfil: mvi c,delf ; delete the file if it exists. + lxi d,fcb + call bdos + xra a + sta fcb+0CH ; zero the extent. + sta fcb+0EH ; must be zero for MAKEF or OPENF. + sta fcb+20H ; zero the current record. +;[pcc012] here from appfil above if file does not exist +makfi1: mvi c,makef ;[pcc012] now create it. + lxi d,fcb + call bdos + cpi 0FFH ; is the disk full? + rz ; take error return if so. +; success. set up pointers and counters for multisector buffering. +;[pcc012] also here from appfil if found zero length file +makfi2: lhld bufadr ;[pcc012] find beginning of buffer space. + shld bufpnt ; make it current buffer. + lxi d,bufsiz ; get sector size. + dad d ; find beginning of next buffer. + shld nxtbuf ; store for later. + mov a,e ; store buffer size + sta chrcnt ; for caller. + xra a + sta seccnt ; no sectors stored yet. + jmp rskp ; take success return. + +;[pcc012] +; outadv - conditionally advance output buffer if disk write not needed. +; preserves BC +; skip return with with next output buffer set up +; non-skip return if memory buffer full and must write to disk. +; called by:logit + +outadv: push b ;[pcc012] save BC as advertised + lxi h,seccnt ;[pcc012] point to sectors buffered + inr m ;[pcc012] count this one + lda bufsec ;[pcc012] how many we can hold + cmp m ;[pcc012] check if full + jnz outbf2 ;[pcc012] continue if not + dcr m ;[pcc012] full, un-advance sector count + pop b ;[pcc012] restore bc + ret ;[pcc012] and give non-skip return + +; get a fresh output buffer, flushing big buffer if necessary. +; returns nonskip if disk full. +; if successful, returns skip with bufpnt and chrcnt updated. Note +; that chrcnt holds one less than the buffer size. +; preserves BC. +; called by: ptchr,logwrt + +outbuf: push b + lxi h,seccnt ; count another buffered sector + inr m ; ... + lda bufsec ; get number of sectors we can hold + cmp m ; full? + jnz outbf2 ; if not, set up pointers and return + call outmbf ; flush the big buffer + jmp outbf9 ; disk error. +;[pcc012] also here from outadv to advance buffer +outbf2: lhld nxtbuf ; get pointer to fresh buffer + shld bufpnt ; store for caller + lxi d,bufsiz ; advance our pointer to next buffer + dad d + shld nxtbuf + mvi a,bufsiz-1 ; get buffer size (pre-decremented) + sta chrcnt ; store for caller + pop b + jmp rskp ; return success. + +outbf9: pop b ; clean up stack + ret ; and take error return. + +; flush incore output buffers. +; returns nonskip if disk full. +; if successful, returns skip with nxtbuf reset to start of buffer and +; seccnt zero. +; destroys all ac's. +; called by: outbuf, clofil. + +outmbf: lhld bufadr ; get start of buffer + shld nxtbuf ; store for next fill cycle + shld bufpnt ; store for empty loop +outmb2: lhld bufpnt ; get address of current sector + xchg ; into DE + lxi h,bufsiz ; advance HL to next sector + dad d ; ... + shld bufpnt ; and store for later + mvi c,setdma + call bdos ; point CP/M at current sector + lxi d,fcb + mvi c,writef + call bdos ; output the sector + ora a ; test for error (A non-zero) + jnz rstdma ;[pcc012] reset dma and take nonskip return if so + lxi h,seccnt + dcr m ; count down buffered sectors + jnz outmb2 ; loop if more saved + call rstdma ;[pcc012] restore normal dma + jmp rskp ; return success. + +; output current buffer, flush incore buffers, and close output file. +; returns nonskip if disk full; skip if successful. +; called by: rdata + +clofil: + lda chrcnt ; get the number of chars left in the buffer. + cpi bufsiz ; Virgin buffer? + jz clofl3 ; yes, don't output it. + lhld bufpnt ; get the buffer pointer. +clofl1: dcr a ; lower the count. + jm clofl2 ; if full then stop. + mvi m,'Z'-100O ; put in a ^Z for EOF. + inx h ; point to the next space. + jmp clofl1 + +clofl2: call outbuf ; output the last buffer. + jmp r ; give up if the disk is full. +clofl3: lda seccnt ; any sectors buffered in memory? + ora a + jz clofl4 ; if not, don't try to flush. + call outmbf ; flush buffers + jmp r ; disk full. +clofl4: mvi c,closf ; close up the file. + lxi d,fcb + call bdos + jmp rskp ; return success. + + +; Reset DMA address to the default buffer +; called from inbuf,appfil,outmbf +rstdma: lxi d,buff ;[pcc012] + mvi c,setdma ;[pcc012] + jmp bdos ;[pcc012] + +; [8] Intercept BDOS calls to check for console input +; This leads to simple trapping for input from disk rather than from the +; keyboard, alowing commands to be stored in a TAKE file. +; Printer is tested for readiness, and the second fuzzy clock is updated. +bdos: ;call print ; print a character to the printer if needed + ;call clock ; update the clock + push psw ; we will need this register + lda takflg ; are we taking from a + ana a ; file or from command line + jz notake ; no, so do usual BDOS stuff + mov a,c ; get bdos function + cpi conin ; is it console in? + jz bd1in ; get a single character + cpi dconio ; direct console in or out? + jz bd1io ; test further for inpu or output + cpi rdstr ; read the console buffer? + jz bdcbuf ; then do it + cpi consta ; get the console status? + jz bdcst ; anything left in buffer? +notake: pop psw ; else we have a kosher BDOS call + jmp 0005h ; Absolute address = BDOS entry point +; +bd1in: ; get a single character from take file + pop psw ; restore stack + call r1tchr ; read a single take character + ret ; and return. We dont expand tabs, + ; check for xon/off or backspaces. + ;Make sure the take file is error free? +; +bd1io: ;get or put a single character from/to console + mov a,e ; get e. If 0ffh then input else output + inr a ; if 0 then input + jnz notake ; its for output, so let notake restore stack + pop psw ; otherwise we do it + call r1tchr ; read a single take character + ret ; and return from out BDOS +; +bdcbuf: ; read a line of edited (?) input from the console + pop psw ; restore stack + inx d ; point to nc +bdosc1: call r1tchr ; get a character + cpi cr ; if a cr then return + jz nomore + cpi lf ; ignore line feeds + jz bdosc1 ; so get another character + push psw ; we will want it later + mvi h,0 + ldax d ; get nc, the no of characters in buffer + mov l,a ; now use as index from de+2 + mvi h,0 + inx d ; de is now de + 2 + dad d + pop psw ; Told you we will want this + mov m,a + dcx d ; point again to nc + xchg ; make hl point to memory + inr m ; update pointer nc + xchg ; restore it + jmp bdosc1 +nomore: dcx d ; restore de to point to buffer + ret + +bdcst: ; get the console status. Returns a 00 if at eof + pop psw + push h ; now save de, hl for return + push d ; + lxi d,takdma ; make a point to next byte... + lhld takptr ; pointer from dma address. There will always + dad d ; be at least one byte, as the buffer is + mov a,m ; ... + pop d ; filled only if a read empties it. + pop h ; restore hl, de + cpi cntlz ; end of file? + mvi a,0ffh ; say there is + rnz ; if it is not a cntl z + jmp closet ; otherwise, close take file etc + +r1tchr: ; read a single character from the take file or command line + push h + push d ; save in case of return + lda takflg ; see if character is to come from file or line + ani 1 ; if bit zero set, from take file + jz r1lchr ; get character from the command line + lxi d,takdma + lhld takptr ; get next data byte + dad d + mov a,m + lhld takptr ; cos it's destroyed with dad + inx h + shld takptr ; update pointer + call p1tchr ; print it (so the user sees it) + push psw ; save the read data for a while + mov a,l ; if l = 0 then read another sector + ana a + jp r1tch1 ;[23] was jnz. jp => 128 byte sectors + call rnsect ;read next sector +r1tch1: pop psw ; now, is this a cntl-z.. in whic case + pop d ; also these... + pop h + cpi lf ; skip if a line feed + jz r1tchr ; +;[MF][31][30]Following lines commented out so semicolons are not considered +;[MF][31][30]command separators and thus are considered part of the command +;[MF][31][30]so commands like REMOTE DELETE *.*;* work correctly. +; cpi semico ; see if its a semicolon +; jnz r1tch2 ; no, ignore it +; mvi a,cr ; else say its a cr (in case of command lines) +r1tch2: cpi cntlz ; end of file?? + rnz + + +c1tchr: call closet ; close file etc, then + mvi a,cr ; fake a carriage return chr + ; ( => clears kermit comnd line) +c1tch1: ret ; and hope that editing etc not required. + +r1lchr: ; read a single character from the command line + lxi d,cbuff ; point to buffer + lda cbptr ; get pointer for next character + mov l,a + lda cbuff ; get total number of characters there + cmp l ; ... less current character + jp r1lch1 ; if positive, we have more characters + lda takflg ; no more, so reset command line bit (bit 4) + ani 0efh + sta takflg + mvi a,cntlz ; fudge an end of file + push psw ; save for common exit (r1tch1) + jmp r1tch1 +; +r1lch1: mov a,l ; get count back again + mvi h,0 + dad d ; get offset to character + inr a + sta cbptr + mov a,m ; get next character + cpi semico ; if a semicolon, make it a carriage return + jnz r1lch2 + mvi a,cr +r1lch2: call p1tchr ; send a copy to the console + push psw ; save it for r1tch1 + jmp r1tch1 ; common exit + + +; rnsect - read the next take sector from disk to the take dma address +; if there is no more then close the file too +rnsect: push b + push d + push h ; save in case we need these later + mvi c,setdma + lxi d,takdma ; set a next read from disk + call bdos ; recursive... + mvi c,readf + lxi d,takfcb + call bdos + ana a + cnz closet ; if returned value not zero, assume eof + lxi h,0 + shld takptr ; pointer restored + call rstdma ; reset the dma address for fussy routines (this one) + pop h + pop d + pop b + ret + +; closet - close the take file and set the take flag to 0 (ie no takes) +; +closet: lda takflg ; reset the take file bit (bit 0) + ani 0feh + sta takflg ; close the take file, and restore the flag + mvi c,closf + lxi d,takfcb + call bdos + call rstdma ; in case we did not do it above, reset dma + ret + +; +; clock - is a 32 bit counter incremented every BDOS call. It serves as a +; timer of sorts and allows a background clock to tick away.. +clock: push psw ; we need flags and hl + push h + lhld clkbit ; get the counter + inx h ; + shld clkbit + mov a,h + ora l ; do we need to update the next lot of clock bits? + jnz clockx + lhld clkbit+2 ; if carry up the top 16 bits + inx h + shld clkbit+2 +clockx: pop h + pop psw + ret + +; p1tchr - print a character in accumulator directly to the console +; bypassing the bdos trap above. + +p1tchr: cpi lf ; if a lf ignore it + jz p1tchx + cpi cr ; ditto carriage returns + jz p1tchx + cpi cntlz ; control z + jz p1tchx ; then dont write it out + push psw ; we do not want to loose it, do we? + push b + push d + push h ; 'cos you never know what bdos does... + mov e,a + mvi c,conout ; direct console io + call 5 ; absolute address as we skip the trap + pop h + pop d + pop b ; ... and we need some of these regs. + pop psw ; +p1tchx: ret ; and return + + + +; outprn - This routine sends charactes to the printer if the latter is ready, +; or to a buffer if the printer is not ready. If the buffer is nearly +; full, an XOFF is sent to the host, asking it to be quiet. The buffer +; is emptied by a series of calls in the connect state only. +; If the buffer is made nearly empty, then an XON is sent to the host. +; +outprn: mov a,e ; get the character to send back to a + sta prntmp ; we need all registers. + jmp outprx ; -testing-testing-testing- avoid buffer +; +outp0: call tstfree ; see how many spaces free + cpi 2 ; (free spaces in a on return) + jp outp1 ; enough free spaces, so keep going + call print ; else see if we can print summat + jmp outp0 ; and try again +; +outp1: cpi 4 ; common test - if three or less then send xoff + cm sndxoff +outpr2: mov a,b ; inc ptr and check for wrap around + call wrapt + mov b,a ; input pointer to b + sta prnbuf+1 ; save the new pointer away + lxi h,prnbuf+2 ; point to first real data entry in buffer + call inchl ; add offset in a to hl + lda prntmp ; get th character to save away + mov m,a ; save the data away + ret + +; outprx - send character in a to the printer. (We have checked to see if +; the printer is ready) +; called by outprn, print +outprx: mov e,a ; character has to be in e register + call outlpt ; send it to printer + ret ; assume we print it + +; TSTFREE - see how many free spacse there are in the buffer +; - returns with free space in a, ip pointer in b, op pointer in c +szecyc equ 127 ; 128 bytes in buffer (less for debugging) +; +tstfree: + lda prnbuf ; get output pointer + mov c,a ;.. to c + lda prnbuf+1 ; and input pointer ... + mov b,a ; ... to b +; +; +; Now comes the tricky bit. We must establish whether there is less than +; three characters left in the buffer. There are two conditions to test for +; 1) the input pointer is a higher value than the output pointer +; 2) the input pointer has been wrapped round and is less than the output pointer +; ie +; |-------|-------|---------------------------------------------| +; Buffer |o/p ptr|i/p ptr| Buffer proper filling ---> | +; |-------|-------|------|-------------|-----------|------------| +; i/p2 o/p i/p1 +; +; If ip = ip1 then if +; (size of buffer - ip ptr + op ptr) < 3 send xoff +; If ip = ip2 then if +; (op ptr - input ptr ) < 3 send xoff +; +; First decide whice one applies + + mov a,b ; get ip ptr + sub c ; see if op ptr > ip ptr (case 2) + jm outp2 ; yup, so do case two + mvi a,szecyc ; else do buffer - ip + op + sub b + add c + jmp outpx ; do common test +outp2: mov a,c ; get op pointer + sub b ; less input pointer +outpx: ret ; with free space in a +; +; +; +; print - get a character from the buffer and print it if the printer +; is ready for it. If the buffer clears more than 3 spare characters +; and an xoff has been sent, then send an xon again. +print: push h ; save for rainy days + push d + push b + push psw ; .. as we may need flags etc.... + lda initflg ; First check if the system has initialised + ana a + jz printx ; If system not set up then skip +; nop +; nop +; nop ; debugging only... + call ckprtr ; check to see if printer is ready... + ana a ; not zero => ok + jz printx ; else skipit. +; nop +; nop +; nop ; skip the jump for debugging + lxi h,prnbuf + mov a,m ; get input pointer + inx h ; test against output pointer + cmp m ; if = then buffer empty + jz printx ; so quit + dcx h ;pointer to output pointer + call wrapt ; check for wrap around + sta prnbuf ; save new pointer + inx h + inx h ; + call inchl ; add output pointer to hl + mov c,m ; get byte + lda hosths ; have we told host to be quiet? + cpi xoff ; if = xoff then we have + jnz print1 ; nope, so just print it.. + push b ; save the character to print + call tstfree ; see how many free bytes in buffer + pop b + cpi 4 ; 3 characters left? + jz printx + push b + call sndxon ; send an xon to host and wake it up. + pop b +print1: mov a,c ; we are gonna print a character, so ... + call outprx ; get it to a (as required by outprx) and print it +printx: + pop psw + pop b + pop d + pop h ; restore regs. + ret + +; +; Utilities for the cyclical buffer. Returns a 0ffh if printer ready, +; else 0h. Called by outprn, print + +ckprtr: + call lptstat ; no registers saved +; mvi a,0 ; FOR DEBUGGING PURPOSES +; nop + ret +; + +inchl: push psw ; we do maths through this register + add l + mov l,a + mvi a,0 + adc h + mov h,a + pop psw ; hl = a + hl + ret + +; wrapt - checks the offset in a with the limits of the buffer. +; returns next address or if wrap around then 0 (start of buffer) +wrapt: push b + inr a + mov b,a ; save new a into b for now + mvi a,szecyc ; test for size of buffer + sub b + mov a,b + pop b ; restore bc regs again + rnz + xra a ; if wrap around, then reset pointer + ret ; return with next address pointer to in a + +; sndxoff - send an xoff to the host and save the xoff character in hosths +; saves all regs. is called by logwrt, outprn +sndxoff: + push psw + push b + push d + push h ; some calling routines may be sensitive... + lda floctl ; are we doing flow control? + ana a + jz sndxf ; no, so dont bother. + mvi a,xoff ;^S to stop the host while we write the buffer. + sta hosths ; save it so we know we have sent it + call setpar ; set correct parity... + mov e,a + call outmdm ; output it. + lxi d,ofsnt ; say we have sent an xoff + call prtstr +sndxf: pop h + pop d + pop b + pop psw ; some routines touchy + ret +ofsnt: db cr,lf,'[XOFF sent to host]',cr,lf,'$' + +; sndxon - send an xon to the host and clear the hosths flag. saves everything +; called by logwrt, print +sndxon: push psw + push b + push d + push h + lda floctl ; are we doing flow control? + ana a + jz sndxn + xra a + sta hosths ; no xoff to hos any more + mvi a,xon ;^Q to restart the host + call setpar ; set appropriate parity + mov e,a + call outmdm ; send it. + lxi d,onsnt + call prtstr ; say xon sent to host... +sndxn: pop h + pop d + pop b + pop psw + ret ; shame we dont do a pushall/popall subroutine... +onsnt: db cr,lf,'[XON sent to host]',cr,lf,'$' +; +; Routines to clear (or rather fill) TEMPnnn space with the data in A +; and to shift it all along one (filltmp an shiftmp respectively) +filltmp: + push b + push d + push h ; save all + lxi h,temp1 + mvi b,10 ; ten locations to fill +fillp: mov m,a + inx h + dcr b ; loop til all done + jnz fillp + pop h + pop d + pop b ; restore all + ret + +shiftmp: + push psw ; save all again + push b + push d + push h + lxi d,temp9 + lxi h,temp10 + mvi b,9 ; shift nine times +shiftl: ldax d ; from tempx + mov m,a ; to tempx+1 + dcx d + dcx h ; mover does not work as that increments + dcr b + jnz shiftl + pop h + pop d + pop b + pop psw + ret ; else all done + +; getun - get the user number to temp1 (lsd) and temp2 (msd) +; +getun: mvi a,0ffh ; tell nout to be quiet + sta nquiet + mvi c,usrcod + mvi e,0ffh ; get current user from bdos + call bdos + mov l,a ; put into hl + mvi h,0 + call nout ; decimalise it (decimalise???) + xra a + sta nquiet ; let nout print again + ret + +; ckcon - Do a direct console IO (read) to see if there is any input +; returns with a=0 (no input) or character (input received) +; Assume that all regs may be destroy. +ckcon: mvi e,0ffh ; direct console input + mvi c,dconio + call bdos + ret ; and return with wahtever returned in a + + + +; +; subbc - Subtract the unsigned number in bc from the unsigned number +; in HL with the answer in HL. Flags altered, all +; other registers left intact. +subbc: sta temp1 ; hl = hl - bc.. we need the accumulator + mov a,l + sub c + mov l,a + mov a,h + sbb b + mov h,a + lda temp1 ; restore loop counter but not flags + ret + +; P20LN - Routine to print a string at (DE) and count the number of +; line feeds. Pause after 20 lines printed. +p20ln: xra a ; clear the line counter + sta lincnt +p20ln1: ldax d ; get character to print + inx d + cpi '$' ; if a dollar we have done + rz + push d + push psw ; save pointer and character to print + mov e,a + call outcon ; send character + pop psw + pop d ; restore pointers etc + cpi lf ; was that last character a line feed? + jnz p20ln1 ; no, so carry on + lda lincnt ; yup, so update counter + inr a + sta lincnt + cpi 20 ; 20 lines printed? + jnz p20ln1 ; not yet + push d ; we need DE +; lxi d,anymes ; pause a while [MF]removed +; call prtstr ; write the message [MF] +;p20ln2: call ckcon ; wait for any input [MF] +; ana a ;[MF] +; jz p20ln2 ;[MF] + call pausit ;[MF] pause a while + pop d + jmp p20ln ; and continue + + +; Little code to allow some expansion of code without changing +; every futher address, only up to the end of this file. +; TO BE REMOVED FOR RELEASE! + +; org ($+100h) AND 0FF00H + +; link to the data area (was part of CPSUTL.ASM) + +IF lasm + LINK CPSDAT +ENDIF ;lasm diff --git a/cpswld.asm b/cpswld.asm index 8be6558..1accb42 100644 --- a/cpswld.asm +++ b/cpswld.asm @@ -1,222 +1,222 @@ -; CPSWLD.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; Multi-file access subroutine. Allows processing of multiple files -; (i.e., *.ASM) from disk. This routine builds the proper name in the -; FCB each time it is called. This command would be used in such pro- -; grams such as modem transfer, tape save, etc. in which you want to -; process single or multiple files. -; Note that it will fail if more than 256 entries match the wildcard. -; -; revision history: -; edit 4: June 20, 1986, by OBSchou. Added stuff at top and tail of routine -; to support multiple FCBs. If the routine get to mfn01 (Search for next) -; then the next file found gets its fcb added to the buffer. Once no -; more files have been found, the mfflg3 flag is set non-zero. -; The first thing to test on entry is whether a disk access -; is needed. Either way, the routine should return the next file name -; in the fcb, or return with the carry flag set if there are no more -; files to do. Once there is a carry flag set for the return, all -; temporary flags are reset. Get all that? -; -; edit 3: July 27, 1984 -; support LASM: remove exclamation points, link to CP4CMD. -; -; edit 2: June 7, 1984 (CJC) -; formatting and documentation; add module version string; redo movfcb, -; in preparation for moving DMA buffer (later...). -; -; edit 1: May, 1984 (CJC) -; extracted from CPMBASE.M80 version 3.9; modifications are described -; in the accompanying .UPD file. -; -wldver: db 'CPSWLD.ASM (4) 20-Jun-86$' - -; The FCB will be set up with the next name, ready to do normal -; processing (OPEN, READ, etc.) when routine is called. -; -; Carry is set if no more names can be found -; -; MFFLG1 is count/switch [0 for first time thru, pos for all others] -; MFFLG2 is counted down for each successive GETNEXT file call -; MFFLG3 is set to the last remaining FCBs buffered once Search for next -; file fails with files in the buffer. -; -; Technique used is to repeat SFIRST/SNEXT sequence N+1 times for each -; successive call, till sequence fails. CP/M does NOT allow disk-handling -; between SFIRST and SNEXT. -; called by: send, seof, dir - -mfname: ora a ; clear carry - push b ;Save registers - push d - push h - jmp mfnam0 ; skip over the next bit (which is entered from elsewhere) - -;[4] Get the FCB counter and see if we have any fcbs already. -mfnam1: lxi h,fcb0 - shld xfcbptr ; reset the pointer if we are to return an FCB - -mfnam0: lda fcbcnt - ana a ; if none, then we may have to get some from disk - jz mfn00 ; see later on - lhld xfcbptr ; we have some, so give the next one to the user - lxi d,fcb ; move from (hl) to (de) for length bc - lxi b,12 - call mover - xra a - sta fcbext ; clear fcb extents and such - sta fcbrno ; like record number - lhld xfcbptr ; point to next fcb - lxi d,fcblen - dad d ; yup - shld xfcbptr - lda fcbcnt - dcr a - sta fcbcnt ; decrease the number of fcbs we have - xra a ; clear carry - jmp mffix1 ; and exit as if were all done - -mfn00: lda mfflg3 ; no more FCBs for the user, any more on disk? - ana a - jnz mffix2 ; no, then set the carry flag to say so. - lxi h,fcb0 ; now reset the fcb pointers and counter - shld xfcbptr - xra a - sta fcbcnt -;[4] end of this addition. See below as well. - - - mvi c,setdma ;Init DMA addr, FCB - lxi d,80H - call bdos - xra a ;A = 0 - sta fcbext ;clear extension - lda mfflg1 ;find out if "second" call in row - ora a - jnz mfn01 ;Were here before - sta mfflg2 - lxi h,fcb - lxi d,mfreq - lxi b,12 - call mover ;.from FCB to MFREQ - mvi c,SFIRST ;Search first - lxi d,fcb - call bdos - jmp mfn02 ;and check results - -mfn01: dcr a - sta mfflg2 ;store down-counter - lxi h,mfreq ;SFIRST REQ name - lxi d,fcb - lxi b,12 - call mover ;.from MFREQ to FCB - mvi c,sfirst ;Search first old one,we got it before - lxi d,fcb - call bdos ;no error's expected -we got that before -mfn01a: - mvi c,snext ;Search next - call bdos -mfn02: push psw - lda mfflg2 ;get "repeat file counter" - ora a - jz mfn02a ;if zero, check if SNEXT had ERROR - dcr a ;count down - sta mfflg2 ;store back - pop psw ;no error-check, we got it before - jmp mfn01a ;next SNEXT - -mfn02a: pop psw - ora a - jm mffi2a ;No (more) found - call movfcb ;move data to fcb - lda mfreq ;the original disk-designator - sta fcb ;back into fcb - lda mfflg1 ;get file-flag - inr a ;increment - sta mfflg1 ;and store for next go-around - mvi a,0 ;Setup FCB - sta fcbext ;clean up FCB for OPEN etc - sta fcbrno - lhld xfcbptr ;[4] like here - xchg - lxi h,fcb ;[4] from fcb space - lxi b,12 - call mover - lhld xfcbptr ;[4] now lets update the pointers - lxi d,fcblen - dad d - shld xfcbptr ;[4] new pointer - lda fcbcnt ;[4] now the fcb counter - inr a - sta fcbcnt - cpi maxfcb ;[4] any more spare space? - jp mfnam1 ;[4] nope, so get first fcb and return - lxi d,fcb ; else restore the file to serach for - lxi h,mfreq - lxi b,12 ; copy the original fcb to fcb - call mover - jmp mfn01a ; and look for next match. - -mffix1: pop h ;restore registers - pop d - pop b - ret ;and return - -mffi2a: - sta mfflg3 ;[4] no more FCBs from disks to be had, but - lda fcbcnt ;[4]we have some in the buffer, havet we? - ana a - jnz mfnam1 ;[4] yes, so all's ok. Get an fcb and return, - -mffix2: xra a - sta mfflg3 ;[4] clear the new flag (=no more fcbs at all) - sta mfflg2 ;[4] may as well do the others, as we're not comming again - sta mfflg1 ;[4] - stc ;set carry - jmp mffix1 ;return with CARRY set - -; copy directory entry to FCB -; called with A/ entry number in directory (0-3) -; directory block in DMA buffer (buff) - -movfcb: add a - add a - add a - add a - add a ;* 32 - mov c,a ; copy offset to bc - mvi b,0 ; (high byte is zero) - lxi h,buff ; get start of disk buffer - dad b ; calculate start of directory entry - lxi d,fcb - lxi b,12 - call mover - ret - -; Data storage for MFNAME (multi-file access) -mfreq: DS 12 ;Requested name -mfflg1: DB 0 ;First time thru flag for MFNAME -mfflg2: DB 0 ;Down counter for MFNAME -mfflg3: DB 0 ;[4] Non zero if no more FCBs from disk, - ;[4] but we still have some in buffer -; -IF lasm - LINK CPSCMD -ENDIF;lasm - +; CPSWLD.ASM +; KERMIT - (Celtic for "FREE") +; +; This is the CP/M-80 implementation of the Columbia University +; KERMIT file transfer protocol. +; +; Version 4.0 +; +; Copyright June 1981,1982,1983,1984 +; Columbia University +; +; Originally written by Bill Catchings of the Columbia University Center for +; Computing Activities, 612 W. 115th St., New York, NY 10025. +; +; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, +; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many +; others. +; +; Multi-file access subroutine. Allows processing of multiple files +; (i.e., *.ASM) from disk. This routine builds the proper name in the +; FCB each time it is called. This command would be used in such pro- +; grams such as modem transfer, tape save, etc. in which you want to +; process single or multiple files. +; Note that it will fail if more than 256 entries match the wildcard. +; +; revision history: +; edit 4: June 20, 1986, by OBSchou. Added stuff at top and tail of routine +; to support multiple FCBs. If the routine get to mfn01 (Search for next) +; then the next file found gets its fcb added to the buffer. Once no +; more files have been found, the mfflg3 flag is set non-zero. +; The first thing to test on entry is whether a disk access +; is needed. Either way, the routine should return the next file name +; in the fcb, or return with the carry flag set if there are no more +; files to do. Once there is a carry flag set for the return, all +; temporary flags are reset. Get all that? +; +; edit 3: July 27, 1984 +; support LASM: remove exclamation points, link to CP4CMD. +; +; edit 2: June 7, 1984 (CJC) +; formatting and documentation; add module version string; redo movfcb, +; in preparation for moving DMA buffer (later...). +; +; edit 1: May, 1984 (CJC) +; extracted from CPMBASE.M80 version 3.9; modifications are described +; in the accompanying .UPD file. +; +wldver: db 'CPSWLD.ASM (4) 20-Jun-86$' + +; The FCB will be set up with the next name, ready to do normal +; processing (OPEN, READ, etc.) when routine is called. +; +; Carry is set if no more names can be found +; +; MFFLG1 is count/switch [0 for first time thru, pos for all others] +; MFFLG2 is counted down for each successive GETNEXT file call +; MFFLG3 is set to the last remaining FCBs buffered once Search for next +; file fails with files in the buffer. +; +; Technique used is to repeat SFIRST/SNEXT sequence N+1 times for each +; successive call, till sequence fails. CP/M does NOT allow disk-handling +; between SFIRST and SNEXT. +; called by: send, seof, dir + +mfname: ora a ; clear carry + push b ;Save registers + push d + push h + jmp mfnam0 ; skip over the next bit (which is entered from elsewhere) + +;[4] Get the FCB counter and see if we have any fcbs already. +mfnam1: lxi h,fcb0 + shld xfcbptr ; reset the pointer if we are to return an FCB + +mfnam0: lda fcbcnt + ana a ; if none, then we may have to get some from disk + jz mfn00 ; see later on + lhld xfcbptr ; we have some, so give the next one to the user + lxi d,fcb ; move from (hl) to (de) for length bc + lxi b,12 + call mover + xra a + sta fcbext ; clear fcb extents and such + sta fcbrno ; like record number + lhld xfcbptr ; point to next fcb + lxi d,fcblen + dad d ; yup + shld xfcbptr + lda fcbcnt + dcr a + sta fcbcnt ; decrease the number of fcbs we have + xra a ; clear carry + jmp mffix1 ; and exit as if were all done + +mfn00: lda mfflg3 ; no more FCBs for the user, any more on disk? + ana a + jnz mffix2 ; no, then set the carry flag to say so. + lxi h,fcb0 ; now reset the fcb pointers and counter + shld xfcbptr + xra a + sta fcbcnt +;[4] end of this addition. See below as well. + + + mvi c,setdma ;Init DMA addr, FCB + lxi d,80H + call bdos + xra a ;A = 0 + sta fcbext ;clear extension + lda mfflg1 ;find out if "second" call in row + ora a + jnz mfn01 ;Were here before + sta mfflg2 + lxi h,fcb + lxi d,mfreq + lxi b,12 + call mover ;.from FCB to MFREQ + mvi c,SFIRST ;Search first + lxi d,fcb + call bdos + jmp mfn02 ;and check results + +mfn01: dcr a + sta mfflg2 ;store down-counter + lxi h,mfreq ;SFIRST REQ name + lxi d,fcb + lxi b,12 + call mover ;.from MFREQ to FCB + mvi c,sfirst ;Search first old one,we got it before + lxi d,fcb + call bdos ;no error's expected -we got that before +mfn01a: + mvi c,snext ;Search next + call bdos +mfn02: push psw + lda mfflg2 ;get "repeat file counter" + ora a + jz mfn02a ;if zero, check if SNEXT had ERROR + dcr a ;count down + sta mfflg2 ;store back + pop psw ;no error-check, we got it before + jmp mfn01a ;next SNEXT + +mfn02a: pop psw + ora a + jm mffi2a ;No (more) found + call movfcb ;move data to fcb + lda mfreq ;the original disk-designator + sta fcb ;back into fcb + lda mfflg1 ;get file-flag + inr a ;increment + sta mfflg1 ;and store for next go-around + mvi a,0 ;Setup FCB + sta fcbext ;clean up FCB for OPEN etc + sta fcbrno + lhld xfcbptr ;[4] like here + xchg + lxi h,fcb ;[4] from fcb space + lxi b,12 + call mover + lhld xfcbptr ;[4] now lets update the pointers + lxi d,fcblen + dad d + shld xfcbptr ;[4] new pointer + lda fcbcnt ;[4] now the fcb counter + inr a + sta fcbcnt + cpi maxfcb ;[4] any more spare space? + jp mfnam1 ;[4] nope, so get first fcb and return + lxi d,fcb ; else restore the file to serach for + lxi h,mfreq + lxi b,12 ; copy the original fcb to fcb + call mover + jmp mfn01a ; and look for next match. + +mffix1: pop h ;restore registers + pop d + pop b + ret ;and return + +mffi2a: + sta mfflg3 ;[4] no more FCBs from disks to be had, but + lda fcbcnt ;[4]we have some in the buffer, havet we? + ana a + jnz mfnam1 ;[4] yes, so all's ok. Get an fcb and return, + +mffix2: xra a + sta mfflg3 ;[4] clear the new flag (=no more fcbs at all) + sta mfflg2 ;[4] may as well do the others, as we're not comming again + sta mfflg1 ;[4] + stc ;set carry + jmp mffix1 ;return with CARRY set + +; copy directory entry to FCB +; called with A/ entry number in directory (0-3) +; directory block in DMA buffer (buff) + +movfcb: add a + add a + add a + add a + add a ;* 32 + mov c,a ; copy offset to bc + mvi b,0 ; (high byte is zero) + lxi h,buff ; get start of disk buffer + dad b ; calculate start of directory entry + lxi d,fcb + lxi b,12 + call mover + ret + +; Data storage for MFNAME (multi-file access) +mfreq: DS 12 ;Requested name +mfflg1: DB 0 ;First time thru flag for MFNAME +mfflg2: DB 0 ;Down counter for MFNAME +mfflg3: DB 0 ;[4] Non zero if no more FCBs from disk, + ;[4] but we still have some in buffer +; +IF lasm + LINK CPSCMD +ENDIF;lasm + diff --git a/cpxapp.asm b/cpxapp.asm index be4abd5..434e440 100644 --- a/cpxapp.asm +++ b/cpxapp.asm @@ -1,749 +1,749 @@ -IF NOT lasm -.printx * CPXAPP.ASM * -ENDIF ;NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the system-dependent code and data for KERMIT. -; It will be probably be broken into independent files to generate -; overlays for the various systems, one or more overlay possible -; from each file. For now, we will leave it in one piece. -; -; revision history: -; edit 2, 22 July, 1987 by OBSchou. Massaged code to work with CPXCOM.ASM -; -; edit 1, 2nd June, 1987 by OBSchou. Extracted all Apple related code. -; -; -; Family is the string used in VERSION to say which of several -; smaller overlay files are used. These are (will be) derived from -; the juge CPXSYS.ASM file, in which case we will never get here. -; Just a Dollar, but put a sting in for a family of machines. -; -family: db 'CPXAPP.ASM (2) 22-jul-87$' ; Used for family versions.... -; - -IF apple -.printx * Assembling KERMIT-80 for the Apple ][ * -ENDIF;apple -IF apmmdm -.printx * with Z80 Softcard & Micromodem II * -ENDIF;apmmdm -IF ap6551 -.printx * with Z80 Softcard & 6551 ACIA * -ENDIF;ap6551 -IF ap6850;[32] -.printx * with Z80 Softcard & 6850 ACIA * -ENDIF;ap6850 [32] -IF apcps;[22] -.printx * with Softcard & CPS Multifunction card * -ENDIF;apcps - -; - -IF ap6551 OR ap6850 OR apcps;[9] [14] - ;jb eg. Apple SSC, Videx PSIO, Basis 108 -apslot EQU 2 ;jb set equal to slot containing serial card - ;jb set to 1 for Basis built-in port -ENDIF;jb ap6551 [9] apcps ap6850 [14] -IF ap6850 ;[14] offset in slot I/O space for ACIA registers - ;e.g. PACT=00,01: AIO-I=05,04: AIO-II=0D,0C: Aristocard=0B,0A -apdat EQU 0DH ;data reg.=0E080h+apslot*10h*apdat -apstat EQU 0CH ;comm/stat reg.=0E080h+apslot*10h+apstat -ENDIF;ap6850 - - -IF apmmdm -;APPLE Slot 2 contains Micromodem II. -MNPORT EQU 0E0A7H ;Communications Port. -mnprts EQU 0E0A6H ;Communications Port Status. -mnmodm EQU 0E0A5H ;Modem Control Port. -orgmod EQU 8EH ;Modem Originate Mode. -OUTPUT EQU 02H ;Output Buffer Empty. -INPUT EQU 01H ;Input Register Full. -apinc1 EQU 03H ;First Init Character for 6850 ACIA (Reset) -apinc2 EQU 11H ;Second Init Character for ACIA (8-bits) -apoffh EQU 80H ;Set if OFFHOOK -AP300 EQU 1 ;300 Baud -z80 EQU TRUE ;Z80 Softcard -ENDIF;apmmdm - -IF ap6551 ;jb -mnport EQU 0E088H+(10H*apslot) ;jb Communications Port. -mnprts EQU 0E089H+(10H*apslot) ;jb Communications Port Status. -mnprtc EQU 0E08BH+(10H*apslot) ;jb Communications Control -mnprtm EQU 0E08AH+(10H*apslot) ;jb Communications Master (command) -output EQU 10H ;jb Output Buffer Empty. -input EQU 08H ;jb Input Register Full. -mncinb EQU 18H ;jb Control Port Initialization Byte - ;jb (8-bit, no parity, 1-stop, 1200 baud) -mnminb EQU 0BH ;jb Master Port Initialization Byte - ;jb (DTR, RTS, no interrupts) -z80 EQU TRUE ;Z80 Softcard -ENDIF;ap6551 - -IF ap6850 ;[32] -mnport EQU 0E080H+(10H*apslot)+apdat ;Communications Port. -mnprts EQU 0E080H+(10H*apslot)+apstat ;Communications Port Status. -OUTPUT EQU 02H ;Output Buffer Empty. -INPUT EQU 01H ;Input Register Full. -apinc1 EQU 03H ;First Init Character for 6850 ACIA (Reset) -apinc2 EQU 15H ;Second Init Character for ACIA (8 data, 1 stop bit) -z80 EQU TRUE ;Z80 Softcard -ENDIF;[32] ap6850 - -IF apcps ;[22] -mnport EQU 0E0FAH+(100H*apslot) ; Communications Port. -mnprts EQU 0E0FBH+(100H*apslot) ; Communications Port Status. -mnprtc EQU 0E0FEH+(100H*apslot) ; Communications Control -output EQU 1 ; Output Buffer Empty. -input EQU 2 ; Input Register Full. -TxEmpty EQU 04h ; Transmitter empty flag -apmod1 EQU 4EH ; Mode Byte 1 (1 stop, no parity,8-bit, 16x) - ; Mode Byte 2 is speed control byte -apcmd EQU 37H ; Command Byte (RTS,Error reset,RxE,DTR,TxE) -z80 EQU TRUE ;Z80 Softcard -ENDIF;[22] apcps - -IF apple -defesc EQU ']'-100O ;The default escape character. -ENDIF;apple - - -; default to VT52-EMULATION ON. - -vtval EQU 1 - - - -sysxin: ; continuation of systemm dependent initialisation code - -IF ap6551 - lda mnprtc ; read control port - ani 0fH ; extract low order nybble - sta speed ; store as comm line speed - sta speed+1 ; (16 bits, to match speed table entries) - mvi a,mnminb ;jb initialization routine - sta mnprts ;jb - sta mnprtm ;jb initialize master (command) port - mvi a,mncinb ;jb - sta mnprtc ;jb initialize control port -ENDIF;ap6551 - -IF ap6850 ;[32] - mvi a,apinc1 ;Init ACIA - sta mnprts - mvi a,apinc2 ;Set ACIA bits per character - sta mnprts -ENDIF;[32] ap6850 - -IF apcps ;[22] - lxi h,3737h ;Default 1200 baud - shld speed ;Store as port speed - xchg - call sysspd ;Initialise the port -ENDIF;[22] apcps - - ret ; return from system-dependent routine - -; - -; -; system-dependent termination processing -; If we've changed anything, this is our last chance to put it back. -sysexit: - - ret - -; -; system-dependent processing for start of CONNECT command -; -syscon: -IF apmmdm - call ckdial ;See if dialing is required. - jmp kermit ;Go to command loop if aborted. -ENDIF;apmmdm - - ret - -conmsg: ; Messages printed when entering transparent (CONNECT) mode: -; - -IF apmmdm -;This code was mostly taken from -; APMODEM.ASM V2.1 -; Based on MODEM.ASM by Ward Christensen -; Modified for the Apple ][ by Gordon Banks 1-Jan-81 -; Micromodem ][ dialer option by Dav Holle 2-Feb-81 -; Code modified for KERMIT by Scott Robinson 14-Oct-82 -; -;Come here to see if we need to dial a number. -; -ckdial: lda mnport ;access the data port - lda mnprts ;check status - ani 4 ;do we already have carrier? - jz rskp ;Yes, just continue - xra a ;Hangup Phone for starters - sta mnmodm - lxi b,1000 ;Delay for a second - call delay - mvi a,8FH ;orgmod+ap300+apoffh - sta holdd ;storing mode for after dialing - mvi A,8DH ;Go Offhook to start dialing sequence - sta mnmodm - mvi a,apinc1 ;Init ACIA - sta mnport - mvi a,apinc2 ;Set ACIA bits per character - sta mnport - - lxi b,2500 ;wait 2.5 seconds for dial tone - call delay - lxi d,dialms ;Ask the user for the number - call prtstr -; -gtdial: mvi c,conin ;Get a character - call bdos - push psw ;save it - cpi 30H ;is it big enough to dial? - jc dialed ;no - cpi 3AH ;is it too big to dial? - jnc dialed ;yes - ani 0FH ;ok, it's a digit, get its value - jnz dialnz ;dial nonzero digits as-is - mvi A,10 ;dial zero as ten -; -dialnz: mov e,a ;count pulses in E-reg -dopuls: mvi a,0DH ;put it on-hook - sta mnmodm - lxi b,61 ;61-millisec pulse - call delay - mvi a,8DH ;take it off-hook again... - sta mnmodm - lxi b,39 ;39-millisec delay between pulses - call delay - dcr e ;any more pulses to do? - jnz dopuls ;yep, do 'em - lxi b,600 ;delay 600 msecs between digits - call delay -; -dialed: pop psw ;get back the char - cpi cr ;do we have a CR (done dialing)? - jnz gtdial ;no, keep on dialin' - lxi d,dialm2 - call prtstr - -tictoc: mvi c,dconio ;Direct console input. - mvi e,0FFH - call bdos - ora a ;Have a charcter? - jnz nodial ;If so we abort - lda mnport ;access the data port - lda mnprts ;get modem status - ani 4 ;carrier? - jnz tictoc ;No -; - lda holdd ;get the old modem control byte - sta mnmodm ;turn our carrier on - - lxi d,dialm3 - call prtstr - jmp rskp -nodial: xra a ;Hangup the modem. - sta mnmodm - ret ;Return to abort the command. -; -holdd: db 0 ;Modem setup code -dialms: DB 'Number to Dial: $' -dialm2: DB CR,LF,'Awaiting Carrier....(any key aborts)$' -dialm3: DB cr,lf,'Connected.',CR,LF,'$' -; -;DELAY wait for the number of millisecs in B,C -; -delay: push b ;save B,C - push d ;save D,E - inr b ;bump B for later DCR -; -delay1: mvi e,126 ;delay count for 1 millisec (Apple Z80 - ;clock=2.041MHz) -; -delay2: dcr e ;count - jnz delay2 ;down -; - dcr c ;more millisecs? - jnz delay1 ;yes - dcr b ;no - more in hi byte? - jnz delay1 ;yes - pop d ;no, restore D,E - pop b ; restore B,C - ret -ENDIF;apmmdm -; - -; -; syscls - system-dependent close routine -; called when exiting transparent session. -; -syscls: - ret -; - -; -; sysinh - help for system-dependent special functions. -; called in response to ?, 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: ,,, and 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 ?, 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: ,,, and are always discarded. +sysflt: + mov a,e ; get character for testing + + ret + +; mdmflt - modem filter [30] +; called with character to be sent to printer in E +; with parity set as appropriate. +; return with accumulator = 0 do do nothing, +; <> 0 to send char in E. +mdmflt: + mov a,e ;[30] get character to test + ret + + + +; prtflt - printer filter [30] +; called with character to be sent to printer in E +; returns with a = 0 to do nothing +; a <> 0 to print it. +; +; this routine for those printer that automatically insert +; a lf on cr, or cr for lf. Should this be shifted to +; the system indep. stuff, in say 4.06? +prtflt: + mov a,e ; [30] get character to test + + ret + + +; + +; +; system-dependent processing for BYE command. +; for apmmdm, heath, and lobo, hang up the phone. +sysbye: +IF apmmdm + xra a ;Hangup our end, too. + sta mnmodm +ENDIF;apmmdm + + ret +; + +; This is the system-dependent command to change the baud rate. +; DE contains the two-byte value from the baud rate table; this +; value is also stored in 'speed'. +sysspd: + +; Set the speed for Apple with 6551 ACIA +IF ap6551 + lda mnprtc ;jb read control port + ani 0F0H ;jb zap low order nybble + ora e ;jb put rate in low order nybble + sta mnprtc ;jb send to control port + ret +ENDIF;ap6551 + +; Set the speed for Apple with CPS Multifunction card +IF apcps ;[22] + mvi a,80h + sta mnprtc + lda mnprts ;read command register to reset 2651 + mvi a,apmod1 ;first mode byte + sta mnport + mvi a,4 ;waste some time before sending second byte +spdwt: dcr a ; 4 T-states + jnz spdwt ; 10 T-states + mov a,e ;second mode byte is speed byte + sta mnport + mvi a,apcmd ;command byte + sta mnprts + xra a + sta mnprtc + ret +ENDIF;[22] apcps + + +IF ap6551 ;jb +spdtbl: db 0DH ;jb 13 entries + db 03H,'110$', 03H,03H ;jb + db 04H,'1200$', 08H,08H ;jb + db 05H,'134.5$', 04H,04H ;jb + db 03H,'150$', 05H,05H ;jb + db 04H,'1800$', 09H,09H ;jb + db 05H,'19200$', 0FH,0FH ;jb + db 04H,'2400$', 0AH,0AH ;jb + db 03H,'300$', 06H,06H ;jb + db 04H,'3600$', 0BH,0BH ;jb + db 04H,'4800$', 0CH,0CH ;jb + db 03H,'600$', 07H,07H ;jb + db 04H,'7200$', 0DH,0DH ;jb + db 04H,'9600$', 0EH,0EH ;jb + +sphtbl: db cr,lf,' 110 134.5 150 300 600 1200 1800' + db cr,lf,' 2400 3600 4800 7200 9600 19200$' +ENDIF;ap6551 + +IF apcps ;[22] +spdtbl: db 10H ; 16 entries + db 03H,'110$', 32h,32h + db 04H,'1200$', 37h,37h + db 05H,'134.5$', 33h,33h + db 03H,'150$', 34h,34h + db 04H,'1800$', 38h,38h + db 05H,'19200$', 3fh,3fh + db 04H,'2000$', 39h,39h + db 04H,'2400$', 3ah,3ah + db 03H,'300$', 35h,35h + db 04H,'3600$', 3bh,3bh + db 04H,'4800$', 3ch,3ch + db 02H,'50$', 30h,30h + db 03H,'600$', 36h,36h + db 04H,'7200$', 3dh,3dh + db 02H,'75$', 31h,31h + db 04H,'9600$', 3eh,3eh + +sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200' + db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$' +ENDIF;[22] apcps + + + +; The following conditionals were once a huge if not statement. There +; wasn't enough room to add the lobo to the list, so it had to be broken +; into 2, which you can't do with an if not. I redid it as two ifs and +; applied them to those that wouldn't set baud. [Hal Hostetler] +IF apmmdm OR ap6850 ;[32] +spdtbl equ 0 ; SET BAUD not supported. +sphtbl equ 0 +ENDIF;appmdm OR ap6850 [32] +; +; +; no ports available for Apple +prttbl EQU 0 ;SET PORT not supported +prhtbl EQU 0 + +; +; + +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +sysprt: + + ret +; + +; +; selmdm - select modem port +; selcon - select console port +; selmdm is called before using inpmdm or outmdm; +; selcon is called before using inpcon or outcon. +; For iobyt systems, diddle the I/O byte to select console or comm port; +; For Decision I, switches Multi I/O board to console or modem serial +; port. [Toad Hall] +; For the rest, does nothing. +; preserves bc, de, hl. +selmdm: + ret + +selcon: + ret +; + +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: + mvi c,dconio ;Direct console I/O BDOS call. + mvi e,0FFH ;Input. + call BDOS + ret +; + +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: + + mvi c,dconio ;Console output bdos call. + call bdos ;Output the char to the console. + ret +; + +; +; outmdm - output a char from E to the modem. +; the parity bit has been set as necessary. +; returns nonskip; bc, de, hl preserved. +outmdm: +IF apple + push h +outmd1: lxi h,mnprts ;address of the port status register +outmd2: mov a,m ; get port status in A + ani output ;Loop till ready. + jz outmd2 +outmd3: lxi h,mnport ;address of port data register + mov m,e ; write the character + pop h + ret +ENDIF;apple + + + + +; + +; +; get character from modem; return zero if none available. +; for IOBYT systems, the modem port has already been selected. +; destroys bc, de, hl. +inpmdm: +IF apple +inpmd1: lda mnprts ;Get the port status into A. + ani input ;See if the input ready bit is on. + rz ;If not then return. +inpmd2: lda mnport ;If so, get the char. +ENDIF;apple + + +ret ; return with character in A + + +; +; flsmdm - flush comm line. +; Modem is selected. +; Currently, just gets characters until none are available. + +flsmdm: call inpmdm ; Try to get a character + ora a ; Got one? + jnz flsmdm ; If so, try for another + ret ; Receiver is drained. Return. +; + +; +; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not. +lptstat: + xra a + ret + +; +; outlpt - output character in E to printer +; console is selected. +; preserves de. +outlpt: + push d ; save DE in either case + call prtflt ; go through printer filter [30] + ana a ; if A = 0 do nothing, + jz outlp1 ; [30] if a=0 do nothing + + mvi c,lstout + call bdos ;Char to printer + +outlp1: pop d ; restore saved register pair + ret +; + +; +; Screen manipulation routines +; csrpos - move to row B, column C +; +; csrpos for terminals that use a leadin sequence followed +; by (row + 31.) and (column + 31.) +; +csrpos: push b ; save coordinates + lxi d,curldn ; get cursor leadin sequence + call prtstr ; print it + pop h ; restore coordinates + mov a,h ; get row + adi (' '-1) ; space is row one + mov e,a + push h + call outcon ; output row + pop h + mov a,l ; get column + adi (' '-1) ; space is column one + mov e,a + jmp outcon ; output it and return + +; +; delchr - make delete look like a backspace. Unless delete is a printing +; character, we just need to print a backspace. (we'll output clrspc +; afterwards) +; For Kaypro and Vector General, delete puts a blotch on the screen. +; For Apple and Osborne 1, delete moves but doesn't print. +delchr: + + lxi d,delstr + jmp prtstr + +; erase the character at the current cursor position +clrspc: mvi e,' ' + call outcon + mvi e,bs ;get a backspace + jmp outcon + +; erase the current line +clrlin: lxi d,eralin + jmp prtstr + +; erase the whole screen, and go home. preserves b (but not c) +clrtop: lxi d,erascr + jmp prtstr + +IF apple +sysver: db 'Apple II CP/M$' +outlin: db ('^'-100O),esc,'Y',cr,lf,' $' +erascr: db ('^'-100O),esc,'Y$' ;Clear screen and go home. +eralin: db cr,esc,'T$' ;Clear line. +delstr: db bs,bs,'$' ; Adjust for delete +curldn: db esc,'=$' ;Cursor lead-in +ttab: ;Table start location. +ta: db ('K'-100O),'$',0,0 ;Cursor up. +tb: db 12O,'$',0,0 ;Cursor down. +tc: db ('F'-100O),'$',0,0 ;Cursor right. +td: db '$',0,0,0 ;(can't) Cursor left +te: db '$',0,0,0 ;(can't) Clear display +tf: db '$',0,0,0 ;(can't) Enter graphics mode +tg: db '$',0,0,0 ;(can't) Exit graphics mode +th: db ('^'-100O),'$',0,0 ;Cursor home. +ti: db ('K'-100O),'$',0,0 ;Reverse linefeed. +tj: db esc,'Y$',0 ;Clear to end of screen. +tk: db esc,'T$',0 ;Clear to end of line. +ENDIF;apple + +ovlend equ $ ; End of overlay + + END diff --git a/cpxbbi.asm b/cpxbbi.asm index ffbdc14..47bd82d 100644 --- a/cpxbbi.asm +++ b/cpxbbi.asm @@ -1,618 +1,618 @@ -IF NOT lasm -.printx * CPXBBI.ASM * -ENDIF ;NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.08 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; -; -; revision history: -; -;edit 4, 7-Jan-1991 by MF. Added code to support the Ampro Little Board. -; The code was contributed by Jay S. Rouman; 913 North Drive; -; Mt. Pleasant, MI 48858 (voice (517)773-7887). -; edit 3, 23 July by OBSchou to massage file to suit CPXCOM.ASM -; -; edit 2 23 May 1987 by C.J.MILES@UMRCC. -; Reorganised file to be similar in structure to that -; of the Amstrad sys-dep file. Added hangup in clear -; screen options in CONNECT mode. -; -; edit 1 10 May 1987 by Chris Miles (C.J.MILES@UMRCC) -; Removed Kaypro, Xerox and Big Board from CPXSYS.ASM -; and grouped them into this file as CPXBBI.ASM. -; -; -; -; Original code broken off and modified by: -; -; Chris Miles -; 344, Claremont Road, -; Rusholme, -; MANCHESTER, -; M14 6WB. -; -; Tel: (061) 226 7839 -; - -; -; *** MAIN CODE START *** -; -; -; Keep module name, edit number, and last revision date in memory. - -sysedt: db 'CPXSYS.ASM (35) 01-Dec-86$' -family: db 'CPXBBI.ASM (4) 7-Jan-1991$' - - -; Assembly time message announcing which version we're building - -IF kpii -.printx * Assembling Kaypro II KERMIT-80 * -ENDIF - -IF xer820 -.printx * Assembling Xerox 820 KERMIT-80 * -ENDIF - -IF bbII -.printx * Assembling BigBoard II KERMIT-80 * -ENDIF - -IF ampro -.printx * Assembling Ampro Little Board KERMIT-80 * -ENDIF - -z80 EQU TRUE ; They all use Z80s - -IF xer820 -defesc EQU ']'-100O ;The default escape character for Xerox -ENDIF;xer820 - -IF kpII -defesc EQU '\'-100O ;The default escape character for Kaypro -ENDIF;kpII - -; If one of the above, default to VT52-EMULATION ON. -IF kpII OR xer820 -vtval EQU 1 -ENDIF;kpII OR xer820 - - -; -; Specific machine hardware information -; -IF bbI -mnport equ 04h ; Modem data port -mnprts equ 06h ; Modem status port -output equ 04h ; Transmit buffer empty -input equ 01h ; Receive data available -baudrt equ 00h ; Baud rate port for channel A -ENDIF;bbI - - -IF bbII -mnport equ 80h ; Modem data port (SIO channel A) -mnprts equ 81h ; Modem status port -output equ 04h ; Transmit buffer empty -input equ 01h ; Receive data available -baudrt equ 89h ; Baud rate port for channel A -ENDIF;bbII - -IF ampro -mnport equ 88h ; Modem data port (SIO channel B) -mnprts equ 8Ch ; Modem status port -output equ 04h ; Transmit buffer empty -input equ 01h ; Receive data available -baudrt equ 50h ; Baud rate port for channel B -ENDIF;ampro -; - -sysxin: ;continuation of system initialisation code - lxi d,siotbl ; Load the address of the status able - mvi c,siolen ; Length of status table -siolup: ; Loop back here for each command byte - ldax d ; Load the first byte into A - inx d ; Index the pointer - out mnprts ; Send it to the status port - dcr c ; Decrement the byte counter - jnz siolup ; Jump back for more commands - ret ; return from system-dependent routine - -; List of commands to set up SIO channel A for asynchronous operation. - -siotbl: DB 18H ; Channel reset - DB 18H ; another, in case register 0 wasn't selected - DB 04H ; Select register 4 - DB 44H ; 1 stop bit, clock*16 - DB 01H ; Select register 1 - DB 00H ; No interrupts enabled - DB 03H ; Select register 3 - DB 0C1H ; Rx enable, 8 bit Rx character - DB 05H ; Select register 5 - DB 0EAH ; Tx enable, 8 bit Tx character, - ; raise DTR and RTS -siolen equ $-siotbl ; length of command list - - -; -; sysexit - System-dependent termination processing -; if we've changed anything, this is our last -; chance to put it back. -; -sysexit: - ret - -; -; syscon - System-dependent processing for start -; of CONNECT command. -; -syscon: - lxi d,conmsg - call prtstr - ret - -conmsg: ; Messages printed when entering transparent (CONNECT) mode: - db cr,lf,'$' -; -; syscls - system-dependent close routine -; called when exiting transparent session. -; -syscls: - ret -; -; sysinh - help for system-dependent special functions. -; called in response to ?, 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: ,,, and 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 ?, 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: ,,, and are always discarded. +; +sysflt: + mov a,e ; get character for testing + ret + +; +; sysbye - system-dependent processing for BYE command. +; +sysbye: + ret +; +; This is the system-dependent command to change the baud rate. +; DE contains the two-byte value from the baud rate table; this +; value is also stored in 'speed'. +; +sysspd: + +; Set the speed for bigboard II +IF bbII + di ; don't let anything between the data bytes + mvi a,01000111b ; get the command byte (load time constant) + out baudrt ; output it to CTC + mov a,e ; Get the parsed value. + out baudrt ; Tell the baud rate generator. + ei ; end of critical section + ret +ENDIF;bbII + + +; Set the speed for bigboard I +IF bbI + mov a,e ; get the parsed value + out baudrt ; Tell the baud rate generator. + ret +ENDIF;bbI + +; set the speed for the Ampro Little Board +if ampro + mvi e,3fh ; offset to port b ctc 3f hex bytes + call getbios + mvi a,47h ; counter mode,ctc reset,value follows + mov m,a ; store value + lda speed+1 ; get ctc divisor + inx h ; location of ctc divisor + mov m,a ; store new divisor +; +; set up wr4 clock divisor according to mspeed +; + mvi e,50h ; offset to dart wr4 + call getbios + mvi a,3fh ; mask for wr4 clock bits + ana m ; mask off bits + mov m,a ; and save to wr4 + lda speed ; get clock flag + ora a ; set flags, zero = 300 bps + mvi a,80h ; x32 clock bit + jz lbps ; setup wr4 for 300 bps x32 clock +; +; set up wr4 value for 1200 bps x16 clock 'hl' has wr4 loc +; +hbps: mvi a,40h ; x16 clock +; +; setup wr4 value for 300 bps x32 clock 'hl' has wr4 loc +; +lbps: ora m ; set clock bits saving parity + mov m,a ; store new clock divisor to wr4 value +; +; initialize sio/dart +; +intsio: lxi h,intend + push h ; set up for return + mvi e,36h ; offset to ioinit + call getbios + pchl ; we pushed return address +intend: ret + +; +; return bios location in 'hl' called with offset in 'e' +; +getbios: + lhld 1 ; get bios location + mvi d,0 ; clear 'd' + dad d + ret +; +ENDIF;ampro + +; +; Speed tables +; (Note that speed tables MUST be in alphabetical order for later +; lookup procedures, and must begin with a value showing the total +; number of entries. The speed help tables are just for us poor +; humans. + +; db string length,string,divisor (2 identical bytes or 1 word) +; [Toad Hall] + +IF bbI +spdtbl: db 10h ;16 entries + db 03h,'110$', 02h,02h + db 04h,'1200$', 07h,07h + db 05h,'134.5$', 03h,03h + db 03h,'150$', 04h,04h + db 04h,'1800$', 08h,08h + db 05h,'19200$', 0fh,0fh + db 04h,'2000$', 09h,09h + db 04h,'2400$', 0ah,0ah + db 03h,'300$', 05h,05h + db 04h,'3600$', 0bh,0bh + db 04h,'4800$', 0ch,0ch + db 02h,'50$', 00h,00h + db 03h,'600$', 06h,06h + db 04h,'7200$', 0dh,0dh + db 02h,'75$', 01h,01h + db 04h,'9600$', 0eh,0eh + +sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200' + db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$' +ENDIF;bbI + +IF bbII +spdtbl: db 8 ; 8 entries + db 04h,'1200$', 20h,20h + db 05h,'19200$', 02h,02h + db 04h,'2400$', 10h,10h + db 03h,'300$', 80h,80h + db 05h,'38400$', 01h,01h + db 04h,'4800$', 08h,08h + db 03h,'600$', 40h,40h + db 04h,'9600$', 04h,04h + +sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600 19200 38400$' +ENDIF;bbII + + +IF ampro +spdtbl: db 6 ; 6 entries + db 04h,'1200$', 1,104 + db 04h,'2400$', 1,52 + db 03h,'300$', 0,208 + db 04h,'4800$', 1,26 + db 03h,'600$', 1,208 + db 04h,'9600$', 1,13 + +sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$' +ENDIF;ampro + +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +; +sysprt: + ret +; + +prttbl equ 0 ; SET PORT is not supported +prhtbl equ 0 + +; +; selmdm - select modem port +; selcon - select console port +; selmdm is called before using inpmdm or outmdm; +; selcon is called before using inpcon or outcon. +; preserves BC, DE, HL. +; +selmdm: +selcon: + ret +; +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: + mvi c,dconio ;Direct console I/O BDOS call. + mvi e,0FFH ;Input. + call BDOS + ret +; +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: + + mvi c,dconio ;Console output bdos call. + call bdos ;Output the char to the console. + + ret +; +; +; outmdm - output a char from E to the modem. +; the parity bit has been set as necessary. +; returns nonskip; bc, de, hl preserved. +outmdm: + in mnprts ;Get the output done flag. + ani output ;Is it set? + jz outmdm ;If not, loop until it is. + mov a,e + out mnport ;Output it. + ret + + +; +; get character from modem; return zero if none available. +; destroys bc, de, hl. +inpmdm: + in mnprts ;Get the port status into A. + ani input ;See if the input ready bit is on. + rz ;If not then return. + in mnport ;If so, get the char. + + ret ; return with character in A + + +; +; flsmdm - flush comm line. +; Modem is selected. +; Currently, just gets characters until none are available. + +flsmdm: call inpmdm ; Try to get a character + ora a ; Got one? + jnz flsmdm ; If so, try for another + ret ; Receiver is drained. Return. +; +; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not. +lptstat: + xra a ; assume it is ok.. this may not be necessary + ret + +; +; outlpt - output character in E to printer +; console is selected. +; preserves de. +outlpt: + push d ; save DE in either case + ana a ; if A = 0 do nothing, + jz outlp1 ; [30] if a=0 do nothing + mvi c,lstout + call bdos ;Char to printer +outlp1: pop d ; restore saved register pair + ret +; + +; +; Screen manipulation routines +; csrpos - move to row B, column C +; +; csrpos for terminals that use a leadin sequence followed +; by (row + 31.) and (column + 31.) +; +IF NOT (bbII OR ampro) ;[obs I think ] +csrpos: push b ; save coordinates + lxi d,curldn ; get cursor leadin sequence + call prtstr ; print it + pop h ; restore coordinates + mov a,h ; get row + adi (' '-1) ; space is row one + mov e,a + push h + call outcon ; output row + pop h + mov a,l ; get column + adi (' '-1) ; space is column one + mov e,a + jmp outcon ; output it and return +ENDIF ; NOT bbII OR ampro + +; +; delchr - make delete look like a backspace. Unless delete is a +; printing character, we just need to print a backspace +; (we'll output clrsp afterwards) +delchr: + +IF bbI + lxi d,delstr + jmp prtstr +ENDIF;bbI + + +IF NOT bbI + mvi e,bs ;get a backspace + jmp outcon +ENDIF;NOT bbI + +; erase the character at the current cursor position +clrspc: mvi e,' ' + call outcon + mvi e,bs ;get a backspace + jmp outcon + +; erase the current line +clrlin: lxi d,eralin + jmp prtstr + +; erase the whole screen, and go home. preserves b (but not c) +clrtop: lxi d,erascr + jmp prtstr + +; If its a BigBoard or Ampro, we need a terminal, so link to CPXVDU.ASM +IF bbII +sysver: db 'Big Board II$' +ENDIF;bbII + +IF ampro +sysver: db 'Ampro Little Board$' +ENDIF;ampro + +IF (bbII AND lasm) ; we need a terminal as well +LINK CPXVDU.ASM +ENDIF ;(bbII AND lasm) + +IF (ampro AND lasm) ; we need a terminal as well +LINK CPXVDU.ASM +ENDIF ;(ampro AND lasm) + +;If here, we are Kaypro or Xerox 820, or if from M80, we should skip +; a few lines if Bigboard. + +IF kpii +sysver: +ttytyp: db 'Kaypro II$' +outlin: db subt,cr,lf,tab,tab,'$' +erascr: db subt,'$' ;Clear screen and home. +eralin: db cr,18H,'$' ;Clear line. +curldn: db esc,'=$' ;Cursor lead-in +delstr: db bs,' ',bs,bs,'$' ; adjust for echoing delete character +ttab: ;Table start location. +ta: db 0BH,'$',0,0 ;Cursor up. +tb: db 0AH,'$',0,0 ;Cursor down. +tc: db 0CH,'$',0,0 ;Cursor right. +td: db bs,'$',0,0 ;Cursor left +te: db subt,'$',0,0 ;Clear display +tf: db esc,'G$',0 ; Enter Graphics Mode (select Greek) +tg: db esc,'A$',0 ; Exit Graphics mode (select ASCII) +th: db 1EH,'$',0,0 ; Cursor home. [UTK016] +ti: db esc,'E','$',0 ; Reverse linefeed. (insert line) +tj: db 'W'-100O,'$',0,0 ; Clear to end of screen. +tk: db 'X'-100O,'$',0,0 ; Clear to end of line. +ENDIF ; kpii +; + +IF xer820 +ttytyp: +sysver: db 'Xerox 820$' +outlin: db subt,cr,lf,tab,tab,'$' +erascr: db subt,'$' ;Clear screen and home. +eralin: db cr,18H,'$' ;Clear line. +curldn: db esc,'=$' ;Cursor lead-in +delstr: db bs,' ',bs,bs,'$' ; adjust for echoing delete character +ttab: ;Table start location. +ta: db 0BH,'$',0,0 ;Cursor up. +tb: db 0AH,'$',0,0 ;Cursor down. +tc: db 0CH,'$',0,0 ;Cursor right. +td: db bs,'$',0,0 ;Cursor left +te: db subt,'$',0,0 ;Clear display +tf: db '$',0,0,0 ; Enter Graphics Mode (can't) +tg: db '$',0,0,0 ; Exit Graphics mode (can't) +th: db 1EH,'$',0,0 ; Cursor home. [UTK016] +ti: db 0BH,'$',0,0 ; Reverse linefeed. (cursor up) +tj: db 11H,'$',0,0 ; Clear to end of screen. +tk: db 18H,'$',0,0 ; Clear to end of line. +ENDIF ; xer820 +ovlend equ $ ; End of overlay + + END diff --git a/cpxbee.asm b/cpxbee.asm index 7333c2a..883bce2 100644 --- a/cpxbee.asm +++ b/cpxbee.asm @@ -1,996 +1,996 @@ -IF NOT lasm -.printx * CPXBEE.ASM * -ENDIF ;NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.09 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; -; -; revision history: -; -; edit 1, 1st September 1990 -; Original version by Russell Lang -; 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 ?, 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: ,,, and 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 +; 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 ?, 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: ,,, and are always discarded. +; +sysflt: + mov a,e ; get character for testing + ret + +; +; sysbye - system-dependent processing for BYE command. +; +sysbye: + ret + +; +; This is the system-dependent command to change the baud rate. +; DE contains the two-byte value from the baud rate table; this +; value is also stored in 'speed'. +; +sysspd: + call setbaud + ret + +; +; Speed tables +; (Note that speed tables MUST be in alphabetical order for later +; lookup procedures, and must begin with a value showing the total +; number of entries. The speed help tables are just for us poor +; humans. + +; db string length,string,divisor (2 identical bytes or 1 word) +; [Toad Hall] + +spdtbl: db 11 ;11 entries + db 03h,'110$' + dw t110 + db 04h,'1200$' + dw t1200 + db 07h,'1200/75$' + dw t1275 + db 03h,'150$' + dw t150 + db 04h,'2400$' + dw t2400 + db 03h,'300$' + dw t300 + db 04h,'4800$' + dw t4800 + db 03h,'600$' + dw t600 + db 02h,'75$' + dw t75 + db 07h,'75/1200$' + dw t7512 + db 04h,'9600$' + dw t9600 + +sphtbl: db cr,lf,'75 75/1200 110 150 300 600 1200 1200/75' + db ' 2400 4800 9600$' + + +; +; This is the system-dependent SET PORT command. +sysprt: + ret + +prttbl equ 0 ; SET PORT is not supported +prhtbl equ 0 + + +; +; selmdm - select modem port +; selcon - select console port +; selmdm is called before using inpmdm or outmdm; +; selcon is called before using inpcon or outcon. +; preserves BC, DE, HL. +; +selmdm: +selcon: + ret +; +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: + mvi c,dconio ;Direct console I/O BDOS call. + mvi e,0FFH ;Input. + call BDOS + ret +; +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: + + mvi c,dconio ;Console output bdos call. + call bdos ;Output the char to the console. + ret + + + +; +; +; outmdm - output a char from E to the modem. +; the parity bit has been set as necessary. +; returns nonskip; bc, de, hl preserved. +outmdm: +; + push psw + push b + push d + push h + mov a,e + lxi h,outm2 ; return address + push h + lhld txcall + pchl ; send to rs232 port +outm2: pop h + pop d + pop b + pop psw + ret + + +; +; get character from modem; return zero if none available. +; bc, de, hl preserved. +inpmdm: + call rsin ; get char if available + ret ; return with character in A + + +; +; flsmdm - flush comm line. +; Modem is selected. +; Currently, just gets characters until none are available. +flsmdm: call inpmdm ; Try to get a character + ora a ; Got one? + jnz flsmdm ; If so, try for another + ret ; Receiver is drained. Return. + +; +; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not. +lptstat: + lda pflag + ret + +; +; outlpt - output character in E to printer +; console is selected. +; preserves de. +outlpt: + push d ; save DE in either case + ana a ; if A = 0 do nothing, + jz outlp1 ; [30] if a=0 do nothing + mov a,e + call parout +outlp1: pop d ; restore saved register pair + ret + + +; +; +; Screen manipulation routines +; csrpos - move to row B, column C +; +; csrpos for terminals that use a leadin sequence followed +; by (row + 31.) and (column + 31.) +; +csrpos: push b ; save coordinates + lxi d,curldn ; get cursor leadin sequence + call prtstr ; print it + pop h ; restore coordinates + mov a,h ; get row + adi (' '-1) ; space is row one + mov e,a + push h + call outcon ; output row + pop h + mov a,l ; get column + adi (' '-1) ; space is column one + mov e,a + jmp outcon ; output it and return + +; +; delchr - make delete look like a backspace. Unless delete is a +; printing character, we just need to print a backspace +; (we'll output clrsp afterwards) +delchr: + lxi d,delstr + jmp prtstr + + +; erase the character at the current cursor position +clrspc: mvi e,' ' + call outcon + mvi e,bs ;get a backspace + jmp outcon + +; erase the current line +clrlin: lxi d,eralin + jmp prtstr + +; erase the whole screen, and go home +clrtop: lxi d,erascr + jmp prtstr + + +sysver: db 'Microbee$' +outlin: db 1AH,cr,lf,tab,'$' ;(Clear screen, home cursor) +erascr: db 1AH,'$' ;Clear screen and go home. +eralin: db cr,esc,'T$' ;Clear line. +delstr: db bs,'$' ; Adjust for delete +curldn: db esc,'=$' ;Cursor lead-in +ttab: ;Table start location. +ta: db ('K'-100O),'$',0,0 ;Cursor up. +tb: db 12O,'$',0,0 ;Cursor down. +tc: db ('L'-100O),'$',0,0 ;Cursor right. +td: db bs,'$',0,0 ;Cursor left. +te: db subt,'$',0,0 ;Clear screen. +tf: db '$',0,0,0 ;(can't) Enter graphics mode +tg: db '$',0,0,0 ;(can't) Exit graphics mode +th: db ('^'-100O),'$',0,0 ;Cursor home. +ti: db ('K'-100O),'$',0,0 ;Reverse linefeed. +tj: db esc,'Y$',0 ;Clear to end of screen. +tk: db esc,'T$',0 ;Clear to end of line. + + +;Microbee software serial port routines +porta equ 0 +portb equ 2 + + +; interrupt vectors +; We change the Z80 Interrupt register to point to these vectors. +; Instead of trying to identify a particular Microbee system, +; we just put vectors here for all systems. +; +; known vectors are: +; 48h : 56k (64k apc) - tested 19-Jun-1990 +; 48k : 64k - tested 01-Sep-1990 +; 50h : dreamdisk (3rd party disk for Microbee) +; e0h : 128k - tested 19-Jun-1990 +; e0h : 256k - tested 01-Sep-1990 + + org ($ and 0ff00h) + 100h +int equ $/256 ; byte for interrupt register + + dw inta ; printer vector + dw intb ; rs232 vector + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + dw inta + dw intb + + +; tables for baud rates +t75: db 124,13 ; full delay + db 55,7 ; semi delay + db 168,255 ; txrx delay + dw trout ; address of subroutine to transmit char +t7512: db 124,13 ; 75R/1200T + db 55,7 + db 194,1 ; txout delay + dw txout +t110: db 129,9 + db 55,5 + db 5,217 + dw trout +t150: db 59,7 + db 23,4 + db 2,158 + dw trout +t300: db 26,4 + db 134,2 + db 3,75 + dw trout +t600: db 139,2 + db 191,1 + db 2,34 + dw trout +t1200: db 195,1 + db 90,1 + db 3,13 + dw trout +t1275: db 195,1 ; 1200R/75T + db 90,1 + db 124,13 + dw txout +t2400: db 94,1 + db 40,1 + db 2,3 + dw trout +t4800: db 44,1 + db 15,1 + db 44,1 + dw txout +t9600: db 19,1 + db 1,1 + db 19,1 + dw txout + + +; copy table entries to locations used by serial routines +setbaud: + lxi h,fulldel + mvi b,8 +setb2: ldax d + mov m,a + inx h + inx d + dcr b + jnz setb2 + ret + + +;transmit character in E +; destroys all regs +txout: mvi b,ntotal ;total number of bits to send + di + in portb ;c = portb with tx bit zeroed + ani 0dfh + mov c,a + ora a ;carry=0 (start bit) +txout2: mov a,c ; 4T + jnc txout4 ;10T skip if space + ori 20h ; 3T (average) set mark +txout4: out portb ;11T + lhld txrxdel ;16T +txout6: dcr l ;delay + jnz txout6 + dcr h + jnz txout6 ; 14*L + 14*H + 3584*(H-1) + stc ; 4T carry=1 (stop bit) + mov a,e ; 4T shift next bit to carry + rar ; 4T + mov e,a ; 4T + dcr b ; 4T + jnz txout2 ;10T + ;loop = 74T + (delay loop) + ei + ret + + +; +;transmit character in E +;simultaneous receive char if necessary +trout: mov a,e + mvi b,ndata + lxi h,0 +tro2: rrc ;shift tx char to hl + mov c,a + mov a,l + ral + mov l,a + mov a,h + ral + mov h,a + mov a,c ;recover + dcr b + jnz tro2 +tro10: mvi b,tqfudge ;adjust char in hl to align with + ;tx bit of portb +tro12: stc ; pad out + mov a,l + ral + mov l,a + mov a,h + ral + mov h,a + dcr b + jnz tro12 + mvi a,0ffh ;flag to say we are not receiving + sta trtemp ;save it + mvi d,tqbit ;total number of qtr bits to send + in portb ;b = portb with tx bit zeroed + ani 0dfh + mov b,a + mvi e,0 ;we are not receiving yet +tro14: in portb + ori 8h ;test CTS + jz tro14 ;loop till Clear To Send + out 09h ;Color Wait OFF + di + call qbit + lda trtemp ;are we receiving + ora a + jnz tro22 ;skip if not + in portb ;is last bit a mark? + ori 10h + jz tro18 ;skip if mark (don't wait for stop) + lhld fulldel ;delay to stop bit +tro16: dcr l + jnz tro16 + dcr h + jnz tro16 +tro18: lhld wptr ; check buffer + xchg + lhld rptr + dcx d ; decrement queue pointer + mov a,d + ora e + jnz tro20 ; skip if no queue wrap around + lxi d,maxque-1 ; wrap around +tro20: mov a,l ; sub hl,de + sub e + mov l,a + mov a,h + sbb d + mov h,a + ora l ; check for zero + jz tro22 ; skip if buffer full + xchg + shld wptr ; update queue + lxi d,rqueue + dad d + mov m,c ; put char in queue +tro22: ei + ret ;ret + + +; routine for quarter bit timing +; for transmit and simultaneous receive +; total execution time is 223T + L*14T + H*34T +qbit: call txrx ;17T + 162T + lda txrxdel ;13T +qbit2: dcr a ; 4T + jnz qbit2 ;10T + lda txrxdel+1 ;13T +qbit4: dcr a ; 4T + nop ; 4T + nop ; 4T + nop ; 4T + nop ; 4T + nop ; 4T + jnz qbit4 ;10T + mov a,d ; 4T Check if still sending or receiving + ora e ; 4T + jnz qbit ;10T + ret + + +;simultaneous transmit/receive +;do next quarter bit +; regs: b = portb with tx bit zeroed +; c = character being received +; d = number of qtr bits remaining to send +; e = number of qtr bits remaining to receive (0 if not receiving) +; hl = character being transmitted +;this subroutine always executes in 162T (or 163T) +txrx: mov a,d ; 4T qtr bits remaining to send + ora a ; 4T + jz txrx12 ;10T skip if no bits remaining (may be receiving) + ani 03h ; 7T a complete bit? + jnz txrx10 ;10T skip if not + dad h ;11T shift tx bit to bit 5 of h + mov a,h ; 4T + ani 20h ; 7T extract tx bit + ora b ; 4T combine with portb + out portb ;11T send it +txrx2: dcr d ; 4T one less qtr bit to send + ;76T total +;now receive part +txrx4: mov a,e ; 4T qtr bits remaining to receive + ora a ; 4T + jz txrx16 ;10T skip if not receiving + ani 3h ; 7T a complete bit? + jnz txrx14 ;10T skip if not + in portb ;11T get input + ani 10h ; 7T extract rx bit + sui 1 ; 7T bit to carry + mov a,c ; 4T bit to c + rar ; 4T + mov c,a ; 4T +txrx6: dcr e ; 4T one less qtr bit to receive +txrx8: ret ;10T + ;86T total + +;come here if transmitting, but not a complete bit +;delay to match up execution times +txrx10: + ora a ; 4T + ora a ; 4T + ora a ; 4T + ora a ; 4T + ora a ; 4T + ori 00h ; 7T + jmp txrx2 ;10T + +;come here if not sending (but still receiving) +;delay to match up execution times +txrx12: ora a ; 4T + ora a ; 4T + ora a ; 4T + ora a ; 4T + ora a ; 4T + ora a ; 4T + ora a ; 4T + ora a ; 4T + ora a ; 4T + ora a ; 4T + ora a ; 4T + ora a ; 4T + jmp txrx4 ;10T + +;come here if receiving (but not a complete bit) +;delay to match up execution time +txrx14: ora a ; 4T + ora a ; 4T + ora a ; 4T + ora a ; 4T + ora a ; 4T + ori 00h ; 7T + jmp txrx6 ;10T + +;come here if not receiving +txrx16: in portb ;11T check if start bit + ani 10h ; 7T + jz txrx18 ;10T skip if mark + mvi e,rqbit ; 7T get quarter bit count for receive + xra a ; 4T + sta trtemp ;13T store flag to say we are receiving + ori a ; 7T delay (should be 6T) + ret ;10T + +txrx18: ora a ; 4T + ora a ; 4T + ora a ; 4T + ora a ; 4T + ora a ; 4T + jmp txrx8 ;10T + + + + +; RS232 input interrupt routine +; stores received character in queue +; ;semi delay starts here +intb: ;20T (approx.) for interrupt + push psw ;11T + push b ;11T + push d ;11T + push h ;11T + in portb ;11T + ani 10h ; 7T test input for start bit + jz intb16 ;10T skip if no start bit. + out 09h ;11T + lhld semidel ;16T half bit delay +intb2: dcr l ; 4T + jnz intb2 ;10T inner loop 14T*L + dcr h ; 4T + jnz intb2 ;10T outer loop (14*H + 256*14*(H-1))T + mvi e,8 ; 6T number of data bits + ;semi delay ends here (125T + delay loop) + ;full delay starts here +intb4: lhld fulldel ;16T full bit delay +intb6: dcr l + jnz intb6 + dcr h + jnz intb6 ; 14*L + 14*H + 3584*(H-1) + in portb ;11T test input + ani 10h ; 7T + sui 1 ; 7T input bit to carry + mov a,c ; 4T + rar ; 4T + mov c,a ; 4T and then to C + dcr e ; 4T bit count + jnz intb4 ;10T loop till all data bits collected + ;full delay ends here (67T + delay loop) + in portb + ani 10h + jz intb12 ; skip if mark + lhld fulldel ; wait for stop bit +intb10: dcr l + jnz intb10 + dcr h + jnz intb10 +intb12: lhld wptr ; check buffer + xchg + lhld rptr + dcx d ; decrement queue pointer + mov a,d + ora e + jnz intb14 ; skip if no queue wrap around + lxi d,maxque-1 ; wrap around +intb14: mov a,l ; sub hl,de + sub e + mov l,a + mov a,h + sbb d + mov h,a + ora l ; check for zero + jz intb16 ; skip if buffer full + xchg + shld wptr ; update queue + lxi d,rqueue + dad d + mov m,c ; put char in queue +intb16: pop h + pop d + pop b + pop psw + ei + db 0EDh,4Dh ;reti + +; +; get char from serial port buffer. +; exit: A=char or Z if no char +rsin: push d + push h + lhld rptr + xchg + lhld wptr + mov a,l ;sub hl,de + sub e + mov l,a + mov a,h + sbb d + mov h,a + ora l ;check for zero + jnz rsi4 ;get char +rsi2: pop h + pop d + ret + +rsi4: push psw + dcx d ; decrement queue pointer + mov a,d + ora e + jnz rsi6 ; skip if no queue wrap around + lxi d,maxque-1 ; wrap around +rsi6: pop psw + xchg + shld rptr + lxi d,rqueue + dad d + mov e,m ;get char from queue + ori 0ffh ;set NZ + mov a,e + jmp rsi2 + +; printer routines + +inta: sta ptemp + mvi a,0 + sta pflag + lda ptemp + ei + db 0EDh,4Dh ;reti + +parout: push h + lxi h,pflag +par2: db 0CBh,46h ;bit 0,(hl) + jnz par2 + mvi m,0ffh + out porta + pop h + ret + +; data storage + +oldint: db 0 ; storage for old i reg +trtemp: db 0 +ptemp: db 0 ;temp storage used by inta interrupt +pflag: db 0 ;0ffh if waiting for printer. 00h if ready + +;receive queue pointers +maxque equ 2048 ; receiver queue size +rptr: dw maxque-1 +wptr: dw maxque-1 + +;transmit +ndata equ 8 ; 8 data bits +nstrt equ 1 ; 1 start bit +nstop equ 1 ; 1 stop bit +ntotal equ nstrt+ndata+nstop +rqbit equ 4*(nstrt+ndata) ;number of quarter bits to receive +tqbit equ 4*(nstrt+ndata+nstop) ;number of quarter bits to transmit +tqfudge equ 13-nstrt-ndata + +;H=0 or L=0 behave as 256 +;receive delays. +fulldel: dw 0 ; 3584(H-1) + 14H + 14L + 67 cycles +semidel: dw 0 ; 3584(H-1) + 14H + 14L + 125 cycles +;1/4 bit transmit and simultaneous tx/rx delay 34H + 14L + 223 cycles +;or full bit delay 3584(H-1) + 14H + 14L + 74 cycles +txrxdel: dw 0 ; +txcall: dw trout ; address of subroutine to transmit char + +; receiver queue +rqueue: ds maxque + + +ovlend equ $ ; End of overlay + +IF lasm + END +ENDIF diff --git a/cpxcif.asm b/cpxcif.asm index d4568c4..f6ce1e8 100644 --- a/cpxcif.asm +++ b/cpxcif.asm @@ -1,746 +1,746 @@ -IF NOT lasm -.printx * CPXCIF.ASM * -ENDIF ;NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the system dependent part for Cifer systems, and -; is based on code contributed by John Shearwood of Birmingham -; University. This file was originally CPXTOR.ASM but now an -; FAMILY file on its own. -; -; This file has code that supports Cifer 1886/2886 systems, running -; either CP/M Version 2.2 or 3.0, and driving the VL or AUX port. -; xxx is a three letter abbrev. for the system you are adding. -; -; revision history: -; -; edit 2, 21 July, 1987 by OBSchou to bring it into line for use with -; CPXCOM.ASM. -; -; edit 1, 14 July by OBSchou for John Shearwood of Birmingham University, UK. -; His edits ar based on the former CPXTOR.ASM family file. -; -; edit 4, Apr 7 1987, JA Shearwood. Add support for Cifer Aux port. -; edit 2, Mar 17 1987, JA Shearwood Add support for Cifer CP/M Plus -; -; Keep module name, edit number, and last revision date in memory. -family: db 'CPXCIF.ASM (2) 14-Jul-87 $' -; -; Assembly time message to let me know I'm building the right version. -; LASM generates an 'S' error along with the message, which is messy, but -; better than trying to put everything inside a IF m80 OR mac80 conditional, -; because LASM doesn't like nested IF's, either. - -IF cifer -.printx * Assembling Kermit-80 for Cifer 1886 * -ENDIF - -IF cifer3 -.printx * with CP/M Plus -ENDIF - -IF cifaux -.printx * with AUX port -ENDIF - -; -;========================================================================= -; I/O Byte assignments (2-bit fields for 4 devices at loc 3) -; -;bits 6+7 LIST field -; 0 LIST is Teletype device (TTY:) -; 1 LIST is CRT device (CRT:) -; 2 LIST is Lineprinter (LPT:) -; 3 LIST is user defined (UL1:) -; -;bits 4+5 PUNCH field -; 0 PUNCH is Teletype device (TTY:) -; 1 PUNCH is high speed punch (PUN:) -; 2 PUNCH is user defined #1 (UP1:) -; 3 PUNCH is user defined #2 (UP2:) -; -;bits 2+3 READER field -; 0 READER is Teletype device (TTY:) -; 1 READER is high speed reader (RDR:) -; 2 READER is user defined #1 (UR1:) -; 3 READER is user defined #2 (UR2:) -; -;bits 0+1 CONSOLE field -; 0 CONSOLE is console printer (TTY:) -; 1 CONSOLE is CRT device (CRT:) -; 2 CONSOLE is in Batch-mode (BAT:);READER = Input, -; LIST = Output -; 3 CONSOLE is user defined (UC1:) -; -;========================================================================= - -iobyte EQU 03H ;Location of I/O byte - -IF cifer ;[13] -batio equ 80h ; tty: as console -defio equ 81h ; crt: as console -z80 SET TRUE ; although it really is... -ENDIF;cifer [13] - -defesc EQU ']'-100O ;The default escape character. - -; Select initial setting for VT-52 emulation flag. -vtval EQU 1 - -IF iobyt ; only CP/M 2.2 and VL port use coniob in CPXCOM - ; rest use this one -coniob: db 0 ; default console bit pattern -ENDIF ;iobyt - - - -sysxin: ;system initialisation not covered by sysinit - mvi a,defio - sta coniob - -IF cifer AND NOT cifaux ; [JAS] Not if AUX port - lxi d,ciferi - call prtstr -ENDIF ;cifer AND NOT cifaux - -IF cifaux ; [JAS] Only Aux Port - lhld 00047h ; Get address of CIOPS table - lxi d,6fh - dad d ; Calculate address of SETLNSPD - shld cifiop - inx h - inx h - inx h - shld ciflod ; Next entry LODEF - lxi d,81h-72h - dad d ; Calculate address of LIDEF - shld ciflid - lhld 00045h ; Get address of SYSPTRS table - lxi d,12h ; Offset for LIDEF pointer - dad d ; Add to table address - mov e,m ; Get low byte LIDEF pointer - inx h - mov d,m ; Get high byte LIDEF pointer - push d - inx h ; LIPARM pointer next - mov a,m ; Get low byte of LIPARM pointer - sta ciptbl ; Keep - inx h - mov a,m ; Get high byte - sta ciptbl+1 ; Keep - lxi d,1eh-15h ; Offset to LODEF - dad d - mov e,m ; Low byte - inx h - mov d,m ; High byte - inx h ; LOPARM is next entry - mov a,m - sta coptbl ; Keep low byte LOPARM - inx h - mov a,m - sta coptbl+1 ; Keep high byte -; Now set up port for no parity 8 bits xon/xoff protocol both ways - xchg ; LODEF into hl register - push h ; Needed later - mvi a,0 - mov m,a ; Clear byte 0 - inx h - mov m,a ; Clear byte 1 - inx h - mvi a,099h ; XON/XOFF protocol, 8bits, no parity - mov m,a ; Flag into byte 2 - pop h ; Restore address of LODEF -ciflod equ $+1 - call $ ; LODEF routine (poked above) - pop h ; LIDEF (PUSHed from de earlier) - push h ; Needed later - mvi a,0 - mov m,a ; Clear byte 0 - inx h - mov m,a ; Clear byte 1 - inx h - mvi a,099h ; XON/XOFF protocol, 8bits, no parity - mov m,a ; Flag into byte 2 - pop h ; Restore address of LIDEF -ciflid equ $+1 - call $ ; LIDEF routine (poked above) - lhld ciptbl ; Get current input speed - mov a,m - sta speed - sta speed+1 - mov e,a - mov d,a - call sysspd ; Make sure ip and op are the same -ENDIF; cifer AND cifaux - - ret ; return from system-dependent routine - -; -; -; system-dependent termination processing -; If we've changed anything, this is our last chance to put it back. -sysexit: - -IF cifer AND NOT cifaux - lxi d,cifero - call prtstr -ENDIF;cifer AND NOT cifaux - - ret - -; -; system-dependent processing for start of CONNECT command -; -syscon: - ret - -conmsg: ; Messages printed when entering transparent (CONNECT) mode: -; -; -; syscls - system-dependent close routine -; called when exiting transparent session. -; -syscls: - ret -; -; -; sysinh - help for system-dependent special functions. -; called in response to ?, 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: ,,, and 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 ?, 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: ,,, and are always discarded. +sysflt: + mov a,e ; get character for testing + ret + +; mdmflt - modem filter [30] +; called with character to be sent to printer in E +; with parity set as appropriate. +; return with accumulator = 0 do do nothing, +; <> 0 to send char in E. +mdmflt: + mov a,e ;[30] get character to test + ret + + + +; prtflt - printer filter [30] +; called with character to be sent to printer in E +; returns with a = 0 to do nothing +; a <> 0 to print it. +; +; this routine for those printer that automatically insert +; a lf on cr, or cr for lf. Should this be shifted to +; the system indep. stuff, in say 4.06? +prtflt: + mov a,e ; [30] get character to test + ret + + +; +; +; system-dependent processing for BYE command. +; for apmmdm, heath, and lobo, hang up the phone. +sysbye: + ret +; +; This is the system-dependent command to change the baud rate. +; DE contains the two-byte value from the baud rate table; this +; value is also stored in 'speed'. +sysspd: + +IF (cifer AND NOT cifaux); This one is wierd.. + ; send an escape string to the screen to set rate. + push d ; Save the data returned + lxi d,cifbrt ; send the start of the escape string (esc ?) + call prtstr ; + pop psw ; get data into a (and flags>..) + inr a ; need to send (a+1-1) 'N' to screen + push psw ; we will need the data again + call cifnos ; send a set of Ns to the screen + pop psw ; (which then sets the VL line on the screen + call cifnos ; processor card) + call prcrlf ; cr will terminate.. a crlf is handy + ret + +cifnos: dcr a ; if result = 0 then done + jz cifno1 ; if done then say 'Y' for yes. + push psw + mvi e,'N' ; else send a string of Ns to screen processor + mvi c,dconio + call bdos + pop psw + jmp cifnos +cifno1: mvi e,'Y' + mvi c,dconio + call bdos + ret ; sent a sring of 0 or more N then a Y + +cifbrt: db esc,'?$' ; start setting baud rate string +ENDIF ;cifer AND NOT cifaux + +IF cifaux; [JAS] Set baud rate by massaging LIPARM/LOPARM and calling + ;CIOPS routine +; Set up speed byte in first location of tables + lhld coptbl ; Now sort out baud rate + mov a,e ; That's output speed + mov m,a + xchg + lhld ciptbl + mov m,a ; Input speed +; Call CIOPS routine SETLNSPD with tables in appropriate rp's +cifiop equ $+1 + call $ ; Poked by sysinit + ret + +coptbl: dw 0 +ciptbl: dw 0 +ENDIF; cifaux + +; +; Speed tables +; (Note that speed tables MUST be in alphabetical order for later +; lookup procedures, and must begin with a value showing the total +; number of entries. The speed help tables are just for us poor +; humans. + +; db string length,string,divisor (2 identical bytes or 1 word) +; [Toad Hall] + +IF cifer +spdtbl: db 10h ;16 entries + db 03h,'110$', 02h,02h + db 04h,'1200$', 07h,07h + db 05h,'134.5$', 03h,03h + db 03h,'150$', 04h,04h + db 04h,'1800$', 08h,08h + db 05h,'19200$', 0fh,0fh + db 04h,'2000$', 09h,09h + db 04h,'2400$', 0ah,0ah + db 03h,'300$', 05h,05h + db 04h,'3600$', 0bh,0bh + db 04h,'4800$', 0ch,0ch + db 02h,'50$', 00h,00h + db 03h,'600$', 06h,06h + db 04h,'7200$', 0dh,0dh + db 02h,'75$', 01h,01h + db 04h,'9600$', 0eh,0eh + +sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200' + db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$' +ENDIF;cifer + +; The following conditionals were once a huge if not statement. There +; wasn't enough room to add the lobo to the list, so it had to be broken +; into 2, which you can't do with an if not. I redid it as two ifs and +; applied them to those that wouldn't set baud. [Hal Hostetler] +; +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +sysprt: +IF iobyt + mov a,m ;Get the I/O byte + sta prtiob ;Save the desired IO byte for this port + inx h ;Point at next entry + mov a,m ;Get the output function + sta prtfun ;Save it +ENDIF;iobyt + + ret +; +; +; +; Port tables for GENERIC CPM 2.2 +IF gener +; help text +prhtbl: db cr,lf,'CRT device' + db cr,lf,'PTR device' + db cr,lf,'TTY device' + db cr,lf,'UC1 device' + db cr,lf,'UR1 device' + db cr,lf,'UR2 device$' + +; command table +prttbl: db 06H ;Six devices to choose from + db 03H,'CRT$' + dw crtptb + db 03H,'PTR$' + dw ptrptb + db 03H,'TTY$' + dw ttyptb + db 03H,'UC1$' + dw uc1ptb + db 03H,'UR1$' + dw ur1ptb + db 03H,'UR2$' + dw ur2ptb + +; port entry table +; table entries are: +; db iobyte-value, BDOS output function, reserved +crtptb: db crtio,conout,0 +ptrptb: db ptrio,punout,0 +ttyptb: db ttyio,conout,0 +uc1ptb: db uc1io,conout,0 +ur1ptb: db ur1io,punout,0 +ur2ptb: db ur2io,punout,0 +ENDIF;gener + +; +; +IF cifer ; no ports yet... +prttbl EQU 0 +prhtbl EQU 0 ; +ENDIF; cifer + +IF iobyt +prtfun: db punout ;Function to use for output to comm port +prtiob: db batio ;I/O byte to use for communicating +ENDIF;iobyt + +IF NOT (iobyt OR lobo OR cifer) ;[hh] +prttbl equ 0 ; SET PORT is not supported +prhtbl equ 0 +ENDIF;NOT (iobyt OR lobo OR cifer) + +; +; +; selmdm - select modem port +; selcon - select console port +; selmdm is called before using inpmdm or outmdm; +; selcon is called before using inpcon or outcon. +; For iobyt systems, diddle the I/O byte to select console or comm port; +; For Decision I, switches Multi I/O board to console or modem serial +; port. [Toad Hall] +; For the rest, does nothing. +; preserves bc, de, hl. +selmdm: +IF iobyt + lda prtiob ;Set up for output to go to the comm port + sta iobyte ;Switch byte directly +ENDIF;iobyt + + ret + +selcon: +IF iobyt + lda coniob ;Set up for output to go to the console port + sta iobyte ;Switch directly +ENDIF;iobyt + + ret +; +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: +IF NOT iobyt + mvi c,dconio ;Direct console I/O BDOS call. + mvi e,0FFH ;Input. + call BDOS +ENDIF;NOT iobyt + +IF iobyt + call bconst ;Get the status + ora a ;Anything there? + rz ;No, forget it + call bconin ;Yes, get the character +ENDIF;iobyt + ret +; +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: + +IF NOT iobyt + mvi c,dconio ;Console output bdos call. + call bdos ;Output the char to the console. +ENDIF;NOT iobyt + +IF iobyt + mov c,e ;Character + call bcnout ;to Console +ENDIF;iobyt + ret +; +; +; outmdm - output a char from E to the modem. +; the parity bit has been set as necessary. +; returns nonskip; bc, de, hl preserved. +outmdm: +IF inout + in mnprts ;Get the output done flag. + ani output ;Is it set? + jz outmdm ;If not, loop until it is. + mov a,e + out mnport ;Output it. + ret +ENDIF;inout + +IF iobyt +;**** Note that we enter from outpkt with the I/O byte already set up for +; output to go to the comm port + push h + push b + lda prtfun ;Get the output function + mov c,a ;Into C + call bdos ;And output the character + pop b + pop h + ret +ENDIF;iobyt + +IF cifer3 ; [JAS] + push h + push b + mvi c,auxout ;Output to the aux output device + call bdos + pop b + pop h + ret +ENDIF;cifer3 + + +; +; +; get character from modem; return zero if none available. +; for IOBYT systems, the modem port has already been selected. +; destroys bc, de, hl. +inpmdm: +IF iobyt + call bconst ;Is Char at COMM-Port? + ora a ;something there? + rz ; return if nothing there + call bconin ; data present. read data. +ENDIF;iobyt + +IF inout +;Note: modem port should already be selected for mdI. [Toad Hall] + in mnprts ;Get the port status into A. + ani input ;See if the input ready bit is on. + rz ;If not then return. + in mnport ;If so, get the char. +ENDIF;inout + +IF cifer3 ; [JAS] + mvi c,auxist + call bdos ;is char at auxin? + ora a ;something there? + rz ;no + mvi c,auxin + call bdos ;read char from auxin +ENDIF;cifer3 + +ret ; return with character in A + + +; +; flsmdm - flush comm line. +; Modem is selected. +; Currently, just gets characters until none are available. + +flsmdm: call inpmdm ; Try to get a character + ora a ; Got one? + jnz flsmdm ; If so, try for another + ret ; Receiver is drained. Return. + + +; +; +; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not. +lptstat: +IF iobyte ;[33] + call bprtst ; get status +ENDIF ;iobyte[33] +IF NOT iobyte ;[33] + xra a ; assume it is ok.. this may not be necessary +ENDIF ;iobyte [33] + ret +; +; +; outlpt - output character in E to printer +; console is selected. +; preserves de. +outlpt: + push d ; save DE in either case + call prtflt ; go through printer filter [30] + ana a ; if A = 0 do nothing, + jz outlp1 ; [30] if a=0 do nothing + +IF NOT iobyte + mvi c,lstout + call bdos ;Char to printer +ENDIF;NOT iobyt +IF iobyt + mov c,e + call blsout +ENDIF;iobyt + +outlp1: pop d ; restore saved register pair + ret +; +; +; Screen manipulation routines +; csrpos - move to row B, column C +; +; csrpos for terminals that use a leadin sequence followed +; by (row + 31.) and (column + 31.) +; +IF cifer ; [14] cifer does it colums then rows.. swap b and c +csrpos: push b ; save coordinates + lxi d,curldn ; get cursor leadin sequence + call prtstr ; print it + pop h ; restore coordinates + mov a,l ; [obs] get column + adi (' '-1) ; space is column one + mov e,a + push h + call outcon ; output row + pop h + mov a,h ; [obs] get row + adi (' '-1) ; space is row one + mov e,a + jmp outcon ; output it and return +ENDIF; cifer + +; +; +; delchr - make delete look like a backspace. Unless delete is a printing +; character, we just need to print a backspace. (we'll output clrspc +; afterwards) +; For Kaypro and Vector General, delete puts a blotch on the screen. +; For Apple and Osborne 1, delete moves but doesn't print. +delchr: + mvi e,bs + call outcon + +; erase the character at the current cursor position +clrspc: mvi e,' ' + call outcon + mvi e,bs ;get a backspace + jmp outcon + +; erase the current line +clrlin: lxi d,eralin + jmp prtstr + +; erase the whole screen, and go home. preserves b (but not c) +clrtop: lxi d,erascr + jmp prtstr + + +IF cifer AND NOT cifaux ;[13] +ttytyp: db 'Cifer 1886 (Parity set to space only)$' +ENDIF; cifer AND NOT cifaux + +IF cifaux ;JAS +ttytyp: db ' Cifer 1886 $' +ENDIF; cifaux + +IF cifer ;[JAS] +sysver: db ' Cifer 1886 $' ; +outlin: db esc,'J',cr,lf,tab,tab,'$' +eralin: db esc,'^K$' ;Clear to end of line. +erascr: db esc,'J$' ;Clear screen and go home. +curldn: db esc,'P$' ;Cursor lead-in +ttab: ;Table start location. +ta: db esc,'A$',0 ;Cursor up. +tb: db esc,'@$',0 ;Cursor down. +tc: db esc,'C$',0 ;Cursor right. +td: db esc,'D$',0 ;Cursor left. +te: db esc,'J',0,0 ;Clear screen and home cursor +tf: db '$',0,0,0 ;(can't) Enter Graphics mode +tg: db '$',0,0,0 ;(can't) Exit Graphics mode +th: db esc,'H$',0 ;Cursor home. +ti: db esc,'@$',0 ;reverse linfeed +tj: db esc,'B$',0 ;Clear to end of screen +tk: db esc,'K$',0 ;Clear to end of line. +ENDIF;cifer +; +IF cifer AND NOT cifaux ;[JAS] +; Setup string for the Cifer.. called as a prtstr param. from sysinit +ciferi: db esc,'/' ;Setup cifer for on line + db esc,'*[' ; direct mode on + db esc,'%' ; protocol on host line on + db esc,'*~x' ; protocol is xon/xoff + db esc,'*(' ; protocol out on host is xon/xoff + db esc,'? NNNY',cr ; set VL port to space parity + ; It cannot do NONE.. Thanks a lot + db '$' ; all done +; Finish string for the Cifer.. called as a prtstr param. from sysexit +cifero: db esc,'&' ; Host input protocol off + db esc,'*)' ; Host output protocol off + db esc,'*]' ; Direct mode off + db esc,'\' ; Setup cifer for off line + db '$' +; Break string for cifer VL port. +brkmes: db esc,'*"$' ;Send a break command string +ENDIF;cifer AND NOT cifaux [13] + +ovlend equ $ ; End of overlay + + END + diff --git a/cpxcom.asm b/cpxcom.asm index 7c3034e..6123f64 100644 --- a/cpxcom.asm +++ b/cpxcom.asm @@ -1,486 +1,486 @@ -IF NOT lasm -.printx * CPXCOM.ASM * -ENDIF ; NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains part common code required for most if not all -; systems. Specifiacally, SYSINIT, INIADR, MOVER, and DELAY to name -; the most important ones. -; -; revision history: -; -; edit 1, 21st July 1987 by OBSchou. Regretably, I have had to include -; some system dependent IFs, mainly for CRT, TORCH and OSI. Inclusion -; here means simpler family files later on. (Regrettably, the delay -; loop for APMMDM differs too.) -; -; Set the fuzzy timeout value. Range is 1 (VERY short) through 0ffffH to zero -; (maximum). The actual duration is a function of the loop length and the -; processor speed. For now, we'll make it zero for everybody, but feel free -; to change it for your system. -; [OBS] make it a little less than max, say 1000H. More useful. -fuzval EQU 1000H - -; -; System-dependent initialization -; Called once at program start. -sysinit: -; -; [13] Had to move this call to here, as the prtstr routine needs this -; before the config message is sent out. It has only been moved. -; - call iniadr ;Initialize the BIOS addresses - mvi c,gtiob ;Get current I/O byte - call bdos ;From CP/M - sta coniob ;Remember where console is - mvi c,getvnm ; get the BDOS version number (e.g. 22H, 31H) - call bdos - mov a,l - sta bdosvr ; and store it away for future reference - lxi d,cfgmsg ; "configured for " - call prtstr - lxi d,sysver ; get configuration we're configured for - call prtstr ; print it. -; -; If we're set up to do special terminal handling, say what kind -; of terminal we expect... (unless it's the generic 'crt') -IF termin - lxi d,witmsg ; " with " - call prtstr - lxi d,ttytyp ; terminal type - call prtstr -ENDIF;termin - call prcrlf ; print CR/LF -; -; now, to work... -; -; locate large buffer for multi-sector I/O -; What we want to do here is find the ccp. Space between ovlend and the ccp -; is available for buffering, except we don't want to use more than maxsec -; buffers (if we use too many, the remote end could time out while we're -; writing to disk). maxsec is system-dependent, but for now we'll just -; use 8Kbytes. If you get retransmissions and other protocol errors after -; transferring the first maxsec sectors, lower maxsec. - -maxsec EQU (8*1024)/bufsiz ; 8K / number of bytes per sector - - lxi h,ovlend ; get start of buffer - shld bufadr ; store in linkage section - mvi a,maxsec ; get size of buffer, in sectors - sta bufsec ; store that, too. - - call sysxin ; call system specific init code - - ret ; return from system-dependent routine - -bdosvr: ds 1 ; space to save the BDOS version number -IF NOT iobyt -coniob: ds 1 ; space to save copy of IO byte -ENDIF ;NOT iobyt -; -; This one is hopefully the last "improvement" in view of GENERIC -;Kermit. It uses for Character-I/O the BIOS-routines ( instead of the -;"normal" BDOS routines. What does it give us (hopefully) : More speed, -;higher chance of success ( I/O byte implemented in BIOS [if at all]), -;but no "extra" device handling - that's done by BDOS. -; -; How do we "get" the call-adresses? Location 0 has a JMP Warm-Boot -;in CP/M which points into the second location of the BIOS JMP-Vector. The -;next three locations of the JMP-Vector point to the CONSTAT,CONIN,CONOUT -;BIOS-routines. CONOUT wants the character in C. -; -;- Bernie Eiben - -iniadr: lhld 1 ;get BIOS Warmstart-address - lxi d,3 ;next adress is CONSTAT in BIOS - dad d - shld bconst+1 ;stuff it into the call-instruction - lxi d,3 ;next adress is CONIN in BIOS - dad d - shld bconin+1 ; - lxi d,3 ;next adress is CONOUT in BIOS - dad d - shld bcnout+1 - lxi d,3 ;next address is LIST in BIOS - dad d - shld blsout+1 - lxi d,10*3 ; get printer status routine - dad d - shld bprtst - ret ;And return - -bconst: jmp $-$ ;Call BIOS directly (filled in by iniadr) - -bconin: jmp $-$ ;Call BIOS directly (filled in by iniadr) - -bcnout: jmp $-$ ;Call BIOS directly (filled in by iniadr) - -blsout: jmp $-$ ; .... - -bprtst: jmp $-$ ; Call BIOS directly for printer status - -IF NOT apmmdm ; Shame about this, but the Apple needs a different delay -; -;[cjc] Delay routine. Called with time (hundredths of seconds) in A. -; The inner loop delays 1001 T-states, assuming no wait states are -; inserted; this is repeated CPUSPD times, for a total delay of just -; over 0.01 second. (CPUSPD should be set to the system clock rate, -; in units of 100KHz: for an unmodified Kaypro II, that's 25 for -; 2.5 MHz. Some enterprising soul could determine whether or not the -; Kaypro actually inserts a wait state on instruction fetch (a common -; practice); if so, the magic number at delay2 needs to be decreased. -; (We also neglect to consider time spent at interrupt level). -; -; called by: sendbr -; destroys BC - -delay: mvi c,cpuspd ; Number of times to wait 1000 T-states to - ; make .01 second delay -delay2: mvi b,70 ; Number of times to execute inner loop to - ; make 1000 T-state delay -delay3: dcr b ; 4 T-states (* 70 * cpuspd) - jnz delay3 ; 10 T-states (* 70 * cpuspd) - dcr c ; 4 T-states (* cpuspd) - jnz delay2 ; 10 T-states (* cpuspd) - ; total delay: ((14 * 70) + 14) * cpuspd - ; = 1001 * cpuspd - dcr a ; 4 T-states - jnz delay ; 10 T-states - ret ; grand total: ((1001 * cpuspd) + 14) * a -ENDIF ; NOT apmmdm -; -; -; Set up screen display for file transfer -; called with kermit version in DE -; -sysscr: push d ; save version for a bit - lxi d,outlin ; clear screen, position cursor - call prtstr ; do it - pop d ; get Kermit's version -IF NOT (osi OR crt) ; got cursor control? - call prtstr ; print it - mvi e,'[' ; open bracket - call outcon ; print it (close bracket is in outln2) - lxi d,sysver ; get name and version of system module - call prtstr - lxi d,outln2 ; yes, print field names - call prtstr - lda dbgflg ; is debugging enabled? - ora a - rz ; finished if no debugging - lxi d,outln3 ; set up debugging fields - call prtstr -ENDIF;NOT (osi OR crt) - ret -; -; Calculate free space for current drive -; returns value in HL -sysspc: - lda bdosvr ;cpm3's alloc vect may be in another bank - cpi 30H ;cpm3 or later? - jm cp2spc ;no: use cp/m 2 algorithm - lda fcb ;If no drive, get - ora a ; logged in drive - jz dir180 - dcr a ;FCB drive A=1 normalize to be A=0 - jmp dir18a - -dir180: mvi c,rddrv - call bdos -dir18a: mov e,a ;drive in e - mvi c,getfs ;get free space BDOS funct - call bdos ;returns free recs (3 bytes in buff..buff+2) - mvi b,3 ;conv recs to K by 3 bit shift -dir18b: xra a ;clear carry - mvi c,3 ;for 3 bytes - lxi h,buff+3 ;point to addr + 1 -dir18c: dcx h ;point to less sig. byte - mov a,m ;get byte - rar ;carry -> A -> carry - mov m,a ;put back byte - dcr c ;for all bytes (carry not mod) - jnz dir18c - dcr b ;shift 1 bit 3 times - jnz dir18b - mov e,m ;get least sig byte - inx h - mov d,m ;get most sig byte - xchg ;get K free in HL - ret - -; the rest are CP/M 2.2 systems, so use the alloc vector -cp2spc: mvi c,getalv ;Address of CP/M Allocation Vector - call bdos - xchg ;Get its length - lhld bmax - inx h - lxi b,0 ;Initialize Block count to zero -dir19: push d ;Save allocation address - ldax d - mvi e,8 ;set to process 8 blocks -dir20: ral ;Test bit - jc dir20a - inx b -dir20a: mov d,a ;Save bits - dcx h - mov a,l - ora h - jz dir21 ;Quit if out of blocks - mov a,d ;Restore bits - dcr e ;count down 8 bits - jnz dir20 ;do another bit - pop d ;Bump to next count of Allocation Vector - inx d - jmp dir19 ;process it - -dir21: pop d ;Clear Allocation vector from stack - mov l,c ;Copy block to 'HL' - mov h,b - lda bshiftf ;Get Block Shift Factor - sui 3 ;Convert from records to thousands - rz ;Skip shifts if 1K blocks -dir22: dad h ;Multiply blocks by 'K per Block' - dcr a - jnz dir22 - ret - -; +----|----|----|----|----|----|----|... -; 1 | -; 2 | Kermit-80 v4.0 [system] -; 3 | -; 4 |Number of packets: ____ -; 5 |Number of retries: ____ -; 6 |File name: ____________ -; 7 |... -; 8 |... -; 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 |... -; 4 |... -; 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 |... +; 8 |... +; 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 |... +; 4 |... +; 5 |RPack: ___ (if debugging)... +; 6 | +; 7 |SPack: ___ (if debugging)... +; 8 | +; 9 |Kermit-80 A:> (when finished) +; + +IF NOT px8 ; [29] +nppos EQU 4*100h+20 +rtpos EQU 5*100h+20 +fnpos EQU 6*100h+12 +errlin EQU 7 +stlin EQU 8 +rplin EQU 9 +splin EQU 11 +prplin EQU 13 +ENDIF ; NOT px8 + +IF px8 +nppos EQU 2*100h+20 +rtpos EQU 1*100h+59 +fnpos EQU 2*100h+51 +errlin EQU 3 +stlin EQU 4 +rplin EQU 5 +splin EQU 7 +prplin EQU 9 +ENDIF ; px8 [29] + + +IF NOT (osi OR crt );[26] +scrnp: lxi b,nppos + jmp csrpos + +scrnrt: lxi b,rtpos + jmp csrpos + +scrfln: lxi b,fnpos + call csrpos +clreol: + lxi d,tk + jmp prtstr + +screrr: lxi b,errlin*100H+1 + call csrpos + jmp clreol + +scrst: lxi b,stlin*100H+1 + call csrpos + jmp clreol + +rppos: lxi b,rplin*100H+8 + call csrpos + jmp clreol + +sppos: lxi b,splin*100H+8 + call csrpos + jmp clreol + +; [29] Modify scrend to make the cursor line conditional on use of debugging +; This means that in most cases the entire file transfer will fit on PX-8 lcd +scrend: lda dbgflg + ora a + jz scr1nd + lxi b,prplin*100H+1 ; debugging in use [29] + jmp scr2nd +scr1nd: lxi b,rplin*100H+1 ; no debugging +scr2nd: call csrpos +clreos: lxi d,tj + jmp prtstr +; [29] and nop out the rest for now... +; +;scrend: lxi b,prplin*100H+1 +; call csrpos +;clreos: lxi d,tj +; jmp prtstr +ENDIF;NOT (osi OR crt ) [26] + + +IF osi OR crt ; no cursor control +scrnp: mvi e,' ' + jmp outcon + +scrnrt: mvi e,' ' + call outcon + mvi e,'%' + jmp outcon + +scrfln: +screrr: +scrst: +scrend: jmp prcrlf ;Print CR/LF [Toad Hall] + +rppos: lxi d,prpack + jmp prtstr + +sppos: lxi d,pspack + jmp prtstr +ENDIF;osi OR crt + +; Some frequently-used routines (duplicates of those in CPSMIT): +; prcrlf - output a CR/LF +; prtstr - output string in DE +; rskp - return, skipping over error return +prcrlf: lxi d,crlf +prtstr: +; [17] added this to avoid prtstr.. emulate function 9 call. +; Works on most machines. +IF (torch OR px8 OR z80mu) +; +; Modified print string as the CP/N (for Nut) system traps control +; characters in a function 9 call.. rot its cotton socks. + push h + push d + push b +prtst1: + ldax d + inx d + cpi '$' ; if a dollar then end of string + jz prtst2 + push d + mov e,a + mov c,a ; also to c if its via conout in BIOS + call outcon ; send it to the screen + pop d + jmp prtst1 + +prtst2: pop b + pop d + pop h + ret ; regs restored.. just in case +ENDIF ;(torch OR px8 OR z80mu) + +IF NOT (torch OR px8 or z80mu) ;ie any machine that can send ctrl chrs via dos call 9 + PUSH H + PUSH D + push b + mvi c,9 ; Dos call 9 (print a string) + call bdos + pop b + POP D + POP H + ret ; all done for good machines +ENDIF ;NOT (torch OR px8 OR z80mu) + +; +; rskp - return to calling address + 3. +rskp: pop h ; Get the return address + inx h ; Increment by three + inx h + inx h + pchl + +; Copy block of data +; source in HL, destination in DE, byte count in BC +; called by: cpxsys, mfname +; +mover: +;IF NOT z80 ; 8080's have to do it the hard way +;OBS assume its an 8080 for now - this will work on Z80s anyway. + mov a,m + stax d + inx h + inx d + dcx b + mov a,b + ora c + jnz mover +;ENDIF;NOT z80 +;IF z80 +; db 0EDh,0B0h ; Z80 LDIR instruction +;ENDIF;z80 + ret + +; +; Miscellaneous messages +; +crlf: db cr,lf,'$' +cfgmsg: db 'configured for $' +witmsg: db ' with $' ; Its included if we get here ('with terminal') + +IF NOT (osi OR crt OR px8) ; [29] got cursor control? +outln2: db ']',cr,lf,cr,lf,'Number of packets:' + db cr,lf,'Number of retries:' + db cr,lf,'File name:$' +ENDIF;NOT (osi OR crt OR px8) + +IF px8 ; [29] +outln2: db '] Number of retries:', cr, lf + db 'Number of packets: File name:$' +ENDIF ; px8 [29] + +IF NOT (osi OR crt) ; [29] +outln3: db cr,lf,cr,lf ; debugging messages + db cr,lf,'Rpack:' + db cr,lf ; Blank line in case of long packet + db cr,lf,'Spack:$' +ENDIF ; NOT (osi OR crt) [29] + +IF lasm +LINK CPXSWT.ASM +ENDIF ;lasm + diff --git a/cpxgni.asm b/cpxgni.asm index 615103f..51561b0 100644 --- a/cpxgni.asm +++ b/cpxgni.asm @@ -1,440 +1,440 @@ -; CPXGNI.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the system-dependent code and data for various -; Genie 3 CPM kermit -; -; This has the Family name of CPXGNI.ASM. -; -; revision history (last edit first) -; edit 3: 27 October, a987 by OBSchou. Massaged file to suit V4.09 structure. -; -; Edit 2: Aug 27 1987 GDS Put in code for BREAK and fillited out -; a lot of unnecessary IF's -; -;Edit 1: Nov. 28, 1986 Geof Smith Clinical Research centre Harrow UK. - -.printx * Assembling for Eaca Genie 3 * -; -drtime EQU 05H ;Default receive time out interval. -; -; the basics... -; -mnport EQU 0E8H -mnprts EQU 0EDH -output EQU 20H -input EQU 01H -lctrl EQU 0EBH -divlsb EQU 0E8H -divmsb EQU 0E9H -z80 EQU TRUE -brkval EQU 40H - -defesc EQU ']'-100O ;The default escape character. - - -;Select initial setting for VT-52 emulation flag. - -; default to VT52-EMULATION ON. -; -vtval EQU 1 -; -; - -; Family is the string used in VERSION to say which of several -; smaller overlay files are used. These are (will be) derived from -; the huge CP4SYS.ASM file, in which case we will never get here. -; Just a Dollar, but put a sting in for a family of machines. -; -family:db 'CPXGNI.ASM (3) 27-Oct-87$' ; Used for family versions.... - - - -; -; System-dependent initialization -; Called once at program start. -sysxin: -; - ;Set up 9600 bd, 8bit words, no parity 1stop bit - - mvi a,83H ;enable DLAB by setting bit 7 - out lctrl ;and outputting to control port - mvi a,14H ;get word = 20 decimal - out divlsb ;and put it out - mvi a,00H ;as two separate - out divmsb ;bytes - lda pstore ;get parity etc - out lctrl ;do it resetting DLAB at same time - - ret ; return from system-dependent routine - - -; -; system-dependent termination processing -; If we've changed anything, this is our last chance to put it back. -sysexit: - - ret - -; -; system-dependent processing for start of CONNECT command -; -syscon: - ret - -conmsg: ; Messages printed when entering transparent (CONNECT) mode: -; - - -; -; syscls - system-dependent close routine -; called when exiting transparent session. -; -syscls: - ret -; - - -; -; sysinh - help for system-dependent special functions. -; called in response to ?, 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: ,,, and 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 ?, 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: ,,, and are always discarded. +sysflt: + mov a,e ; get character for testing + ret + +; mdmflt - modem filter [30] +; called with character to be sent to modem in E +; with parity set as appropriate. +; return with accumulator = 0 do do nothing, +; <> 0 to send char in E. +mdmflt: mov a,e ; get character to a + ret + + + +; prtflt - printer filter [30] +; called with character to be sent to printer in E +; returns with a = 0 to do nothing +; a <> 0 to print it. +; +; this routine for those printer that automatically insert +; a lf on cr, or cr for lf. Should this be shifted to +; the system indep. stuff, in say 4.06? +prtflt: + mov a,e ; [30] get character to test + ret + + +; + + +; +; system-dependent processing for BYE command. +; for apmmdm, heath, and lobo, hang up the phone. +sysbye: + ret +; + + +; This is the system-dependent command to change the baud rate. +; DE contains the two-byte value from the baud rate table; this +; value is also stored in 'speed'. +sysspd: + + ;Set up baud rate 8bit words, no parity 1stop bit + mvi a,83H ;enable DLAB by setting bit 7 + out lctrl ;and outputting to control port + mov a,d ;get LSB + out divlsb ;and put it out + mov a,e ;get MSB + out divmsb ;output it as well + lda pstore ;get parity etc + out lctrl ;do it resetting DLAB at same time + ret + +pstore: db 03H ;Default value for parity word length and stop bits + +spdtbl: db 11h ;17 entries + db 03h,'110$', 06H,0D1H + db 04h,'1200$', 00H,0A0H + db 05h,'134.5$', 05H,94H + db 03h,'150$', 05H,00H + db 04h,'1800$', 00H,6BH + db 05h,'19200$', 00H,0AH + db 04h,'2000$', 00H,60H + db 04h,'2400$', 00H,50H + db 03h,'300$', 02H,80H + db 04h,'3600$', 00H,35H + db 05h,'38400$', 00H,05H + db 04h,'4800$', 00H,28H + db 02h,'50$', 0FH,00H + db 03h,'600$', 01H,40H + db 04h,'7200$', 00H,1BH + db 02h,'75$', 0AH,00H + db 04h,'9600$', 00H,14H + +sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200' + db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200 38400$' + +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +sysprt: + + ret +; +prttbl equ 0 ; SET PORT not supported +prhtbl equ 0 + +; + +; +; selmdm - select modem port +; selcon - select console port +; selmdm is called before using inpmdm or outmdm; +; selcon is called before using inpcon or outcon. +; For iobyt systems, diddle the I/O byte to select console or comm port; +; For Decision I, switches Multi I/O board to console or modem serial +; port. [Toad Hall] +; For the rest, does nothing. +; preserves bc, de, hl. +selmdm: + ret + +selcon: + ret +; + + +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: + mvi c,dconio ;Direct console I/O BDOS call. + mvi e,0FFH ;Input. + call BDOS + + ret +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: + + mvi c,dconio ;Console output bdos call. + call bdos ;Output the char to the console. + + ret +; +; +; outmdm - output a char from E to the modem. +; the parity bit has been set as necessary. +; returns nonskip; bc, de, hl preserved. +outmdm: + + in mnprts ;Get the output done flag. + ani output ;Is it set? + jz outmdm ;If not, loop until it is. + mov a,e + out mnport ;Output it. + ret + +;-------------------------------------------------------------------------- +; +; get character from modem; return zero if none available. +; for IOBYT systems, the modem port has already been selected. +; destroys bc, de, hl. +inpmdm: +;Note: modem port should already be selected for mdI. [Toad Hall] + in mnprts ;Get the port status into A. + ani input ;See if the input ready bit is on. + rz ;If not then return. + in mnport ;If so, get the char. + ret ; return with character in A + + +; +; flsmdm - flush comm line. +; Modem is selected. +; Currently, just gets characters until none are available. + +flsmdm: call inpmdm ; Try to get a character + ora a ; Got one? + jnz flsmdm ; If so, try for another + ret ; Receiver is drained. Return. +;----------------------------------------------------------------------------- +; +; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not. +lptstat: + xra a ; assume it is ok.. this may not be necessary + ret + +; +; outlpt - output character in E to printer +; console is selected. +; preserves de. +outlpt: + push d ; save DE in either case + call prtflt ; go through printer filter [30] + ana a ; if A = 0 do nothing, + jz outlp1 ; [30] if a=0 do nothing + + mvi c,lstout + call bdos ;Char to printer +outlp1: pop d ; restore saved register pair + ret +;------------------------------------------------------------------------------ +; +; Screen manipulation routines +; csrpos - move to row B, column C +; +; csrpos for terminals that use a leadin sequence followed +; by (row + 31.) and (column + 31.) +; +csrpos: push b ; save coordinates + lxi d,curldn ; get cursor leadin sequence + call prtstr ; print it + pop h ; restore coordinates + mov a,h ; get row + adi (' '-1) ; space is row one + mov e,a + push h + call outcon ; output row + pop h + mov a,l ; get column + adi (' '-1) ; space is column one + mov e,a + jmp outcon ; output it and return + +; +; delchr - make delete look like a backspace. Unless delete is a printing +; character, we just need to print a backspace. (we'll output clrspc +; afterwards) +; For Kaypro and Vector General, delete puts a blotch on the screen. +; For Apple and Osborne 1, delete moves but doesn't print. +delchr: + + mvi e,bs ;get a backspace + jmp outcon + +; erase the character at the current cursor position +clrspc: mvi e,' ' + call outcon + mvi e,bs ;get a backspace + jmp outcon + +; erase the current line +clrlin: lxi d,eralin + jmp prtstr + +; erase the whole screen, and go home. preserves b (but not c) +clrtop: lxi d,erascr + jmp prtstr + +;[2] I see no real saving in having all screens in separate file and +;therefore have included screen definition here and commented out +;the link to VDU file +; +;Specific definitions for the Genie III screen +; +sysver: db 'Eaca Genie III$' +outlin: db 1aH,cr,lf,' $' +erascr: db 1AH,'$' +eralin: db cr,18H,'$' +curldn: db esc,'=$' +ttab: +ta: db 0BH,'$',0,0 ;Cursor up +tb: db 0AH,'$',0,0 ;Cursor down +tc: db 0CH,'$',0,0 ;Cursor right +td: db 08H,'$',0,0 ;Cursor left +te: db 1AH,'$',0,0 ;Clear display +tf: db esc,'R$',0 ;Reverse on +tg: db esc,'S$',0 ;Reverse off +th: db 1EH,'$',0,0 ;Cursor home +ti: db 0BH,'$',0,0 ;Reverse linefeed +tj: db 19H,'$',0,0 ;Clear to end of screen +tk: db 18H,'$',0,0 ;Clear to end of line + +ovlend equ $ ;End of overlay + +END + + + + + diff --git a/cpxhea.asm b/cpxhea.asm index e78d9df..32e6b4e 100644 --- a/cpxhea.asm +++ b/cpxhea.asm @@ -1,921 +1,921 @@ -IF NOT lasm -.printx * CPXHEA.ASM * -ENDIF ;NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the system-dependent code and data for KERMIT -; specific to the Heath/Zenith H89 and Z100, the Telcon Zorba, -; and the OEM ScreenTyper. All but the latter use VT52 (or a -; replica thereof) for screen output; the ScreenTyper uses the -; same serial port chip as the H89 (an Intel 8250). -; -; revision history: -; -; Edit 4, 31-Aug-1989 by Mike Freeman, 301 N.E. 107th Street; Vancouver wa -; 98685 USA; Telephone (206)574-8221: Added Baud-rate Selection and -; Break-sending ability for the Telcon Zorba portable. -; -; edit 3, 22 July, 1987 by OBSchou to massage code to conform to new set -; of overlay files (stripping out common code to CPXCOM.ASM) -; -; edit 2 by OBSchou to add in old Kermit-80 V3.5 heath-8 code, formerly -; in CPM directory. Entry from CP/M file: -; -; This file contains an upgrade to the CPMBASE.M80 KERMIT -; to allow setting and display of baud rates, a bug fix in -; telnet, and an extension of the HELP to show GET (which works -; in this release, on the H8). Look for the new symbol "h8quad" -; (for the heath quad i/o board that it uses) in the conditionals. -; Note that the Heath H8 is NOT the same machine as the H89. The H89 -; code does not run 'as is' on the H8, and does NOT initialize the -; UART. Also there was a bug in the telnet section that is fixed -; here, though I expect that it has already been found and fixed -; by now - this is from the DECUS FALL 83 tape. The comments were -; stripped out of this file to make it small enough for my H8 to -; assemble, however, I have put the first section back in to make -; it easier for you to identify. Thanks for a nice product to use -; and work on. Major insertions are heavily commented, edit as needed. -; -; This modification done by John Mealing, InteCom Inc, 601 Intecom Dr., -; Allen, TX 75002 (214)797-9141, x-2493, 5 Nov 84. -; -; [OBSchou notes: This is the header, and the bugs in telnet are -; unknown. telnet routine has been substantially changed anyway with -; 4.08-4.09 revision. As for the major insertions: they probably went -; with the 4.xx re-write. I am unable to test this version: can -; anyone else do so??] -; -; -; edit 01 5th Mar 1987 by M J Carter, Nottingham Uni [majoc] -; Split off from CPXSYS.ASM, in order to install support for -; the OEM ScreenTyper. I can't test anything other than the -; ScreenTyper as I haven't the hardware. Any offers? -; Thanks are due to Paul Bartlett of John Elmer -; Electronics Ltd, who provided me with his modified sources -; for (a slightly antiquated) CP/M 4.05 Kermit on which this -; is based. -; -; Keep module name, edit number, and last revision date in memory. -;sysedt: db 'CPXSYS.ASM (35) 01-Dec-86 $' -; [majoc 870305] Now in CPXFRK. I'll have to consult on this ... -; -; -; -; Assembly time message to let me know I'm building the right version. -; LASM generates an 'S' error along with the message, which is messy, but -; better than trying to put everything inside a IF m80 OR mac80 conditional, -; because LASM doesn't like nested IF's, either. - -IF heath -.printx * Assembling KERMIT-80 for the Heath/Zenith 89 * -ENDIF - -IF h8quad -.printx * Assembling KERMIT-80 for the Heath-8 with Quad IO board * -ENDIF - -IF z100 -.printx * Assembling KERMIT-80 for the Heath/Zenith Z100 * -ENDIF - -IF telcon -.printx * Assembling KERMIT-80 for the Telcon Zorba * -ENDIF - -IF scntpr -.printx * Assembling KERMIT-80 for the OEM ScreenTyper * -ENDIF -; - -; - -IF heath -mnport EQU 330O ;Modem data port -ENDIF ; heath - -IF h8quad -mnport EQU 330O ;all port addresses can be set by user - -mnprts EQU mnport + 05 ; in octal cause heath wrote documents that -output EQU 20H ; way -- relative addressing on the UART -input EQU 01H ; registers, just to be nice -baudls EQU mnport ;ls baud divisor latch when DALB set -baudms EQU mnport + 1 ;ms baud divisor latch when DALB set -linctl EQU mnport + 3 ;line control register -modctl EQU mnport + 4 ;MODEM control register -dalbon EQU 80H ;enables speed selection -linset EQU 03H ;force hardware 8 bit, even parity -; -; The line control register (linctl) is bit mapped as follows: -; bit # function value -; 0,1 select word size 00 -> 5 bit, 10 -> 7 bit -; 01 -> 6 bit, 11 -> 8 bit -; 2 select stop bits 0 -> 1 stop bit, 1 -> 1 1/2 for 5 bit, -; 1 -> 2 for 6 bit words -; 3 parity enable 0 -> no parity, 1 -> parity as set by 4 -; 4 Even parity select 0 -> Odd parity, 1 -> Even parity -; 5 Stick parity 1 -> Parity of bit 4 is inverted -; 6 Break control 1 -> output forced to spacing (break) -; 7 DALB 1 -> access divisor latches to set baud rate -; -; The value in linset is loaded into linctl when KERMIT comes up. -; -ms300 EQU 001O ;set for 300 baud as default -ls300 EQU 200O -rtsoff EQU 20O ;direct control of modem lines -rtson EQU 11O -z80 EQU FALSE ;[2] or is it? -ENDIF ;h8quad - -IF scntpr -mnport EQU 8 ;Modem data port -ENDIF ; scntpr -IF heath OR scntpr - -; Definitions for the 8250 ACE - -acerbr EQU 0 ; ACE Receiver Buffer Register offset (R/O) (DLAB = 0) -acethr EQU 0 ; ACE Transmitter Holding Register offset (W/O) -acedll EQU 0 ; ACE Divisor Latch (Low) (DLAB = 1) -acedlh EQU 1 ; ACE Divisor Latch (High) (DLAB = 1) -aceier EQU 1 ; ACE Interrupt Enable Register (DLAB = 0) -aceiir EQU 2 ; ACE Interrupt Identification Register -acelcr EQU 3 ; ACE Line Control Register -acemcr EQU 4 ; ACE Modem Control Register -acelsr EQU 5 ; ACE Line Status Register offset -acemsr EQU 6 ; ACE Modem Status Register - -ace8bw EQU 00000011b ; 8 bit words -acesb EQU 01000000b ; set break -acedla EQU 10000000b ; divisor latch access -acedtr EQU 00000001b ; data terminal ready -aceloo EQU 00010000b ; loopback mode -acedr EQU 00000001b ; data ready -acethe EQU 00100000b ; transmitter holding register empty - -;mnport EQU 330O ;Modem data port -; [35a: majoc 870305] Shifted up above joint IF, to save nesting. -mnprts EQU mnport+acelsr ;Modem status port -output EQU acethe ;Transmitter empty -input EQU acedr ;Input data available -z80 EQU TRUE ;H89 uses the Z80 -ENDIF;heath OR scntpr - -IF z100 -mnport EQU 0ECH ;Modem data port -mnprts EQU 0EDH ;Modem status port -output EQU 01H ;Transmitter empty -input EQU 02H ;Input data available -z80 EQU FALSE ;[hh] this one's an 8085. -ENDIF;z100 - - -IF telcon -MNPORT EQU 20H ;Modem data port -MNPRTS EQU 21H ;Modem status port -OUTPUT EQU 01H ;Transmitter empty -INPUT EQU 02H ;Input data available -BRPORT EQU 00H ;8254-2 Baud Rate Generator Timer for Port A -COMMND EQU 03H ;8254-2 Timer Control Port -z80 EQU TRUE ;[MF]A real Z80 -ENDIF;telcon -; - -IF telcon -defesc EQU ']'-100O ;The default escape character. -ENDIF;telcon - -IF heath OR h8quad OR z100 OR scntpr -defesc EQU '\'-100O ;The default is Control \ -- it's easier B.E. -ENDIF;heath OR h8quad OR z100 OR scntpr - -; Select initial setting for VT-52 emulation flag. -IF (heath OR h8quad OR z100 OR telcon) -vtval EQU 0 ; we don't need VT52 emulation -ENDIF;heath OR h8quad OR z100 OR telcon OR vt52 [OBS question - ok for h8quad?] -; If none of the above, default to VT52-EMULATION ON. -IF scntpr -vtval EQU 1 ; we do VT52 emulation -ENDIF;scntpr - - -; -; Family is the string used in VERSION to say which of several -; smaller overlay files are used. These are (will be) derived from -; the juge CPXSYS.ASM file, in which case we will never get here. -; Just a Dollar, but put a sting in for a family of machines. -; -family: db 'CPXHEA.ASM (4) 31-Aug-1989$' ; Used for family versions.... - -; -sysxin: ; continuation of initialisation code -IF heath OR scntpr -; -; System dependent startup for H89 and OEM ScreenTyper -; - - call mdmofl ; keep the line safe from garbage - -; First, tell Kermit the modem port's current speed - in mnport+acelcr - ori acedla - out mnport+acelcr ; access the ACE's divisor latch - in mnport+acedll ; get the low byte - sta speed - in mnport+acedlh ; and the high byte - sta speed+1 - -; Now set up the port for Kermit - mvi a,ace8bw ; 8 data bits, 1 stop bit, no parity - out mnport+acelcr - in mnport+acemcr - ori acedtr ; raise DTR (just in case) - out mnport+acemcr - call mdmonl ; and put the ACE back on line - ret - -; Take the ACE off line before modifying its state -mdmofl: - in mnport+aceier ; save the ACE's interrupt state - sta iersav - xra a - out mnport+aceier ; and disable ACE interrupts - in mnport+acemcr ; now put the ACE in loopback mode - ori aceloo - out mnport+acemcr - ret - -; Put the ACE back on line -mdmonl: - in mnport ; flush left-over garbage in the receive buffer - mvi a,7 ; wait about 2 300-baud character times - call delay - in mnport ; and flush more garbage - in mnport+acemcr ; take the ACE out of loopback mode - ani 0FFH-aceloo - out mnport+acemcr - lda iersav - out mnport+aceier ; and restore the ACE's interrupt state - ret - -iersav: ds 1 -ENDIF;heath OR scntpr - -IF h8quad -h8init: lxi d,180h ; [2] set up for 300 baud -h8baud: mvi a,rtsoff ;disable modem for now - out modctl - mvi a,dalbon ;set for UART speed programming - out linctl - mov a,d ; [2] get ms bits for rate - out baudms - mov a,e ; [2] get ls bits for rate - out baudls - mvi a,linset ;force 8 bit, no parity and clear dalb - out linctl - in mnport ;clear the recieve side - mvi a,rtson ;get ready - out modctl ;modem is on and ready to go -ENDIF ;h8quad - - ret ; return from system-dependent routine - -; -; -; system-dependent termination processing -; If we've changed anything, this is our last chance to put it back. -sysexit: - ret - -; -; system-dependent processing for start of CONNECT command -; -syscon: - ret - -conmsg: ; Messages printed when entering transparent (CONNECT) mode: -; -; -; syscls - system-dependent close routine -; called when exiting transparent session. -; -syscls: - ret -; -; -; sysinh - help for system-dependent special functions. -; called in response to ?, 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: ,,, and 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 ?, 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: ,,, and are always discarded. +sysflt: + mov a,e ; get character for testing + ret + +; mdmflt - modem filter [30] +; called with character to be sent to printer in E +; with parity set as appropriate. +; return with accumulator = 0 do do nothing, +; <> 0 to send char in E. +mdmflt: + mov a,e ;[30] get character to test + ret + + + +; prtflt - printer filter [30] +; called with character to be sent to printer in E +; returns with a = 0 to do nothing +; a <> 0 to print it. +; +; this routine for those printer that automatically insert +; a lf on cr, or cr for lf. Should this be shifted to +; the system indep. stuff, in say 4.06? +prtflt: + mov a,e ; [30] get character to test + ret + + +; +; +; system-dependent processing for BYE command. +; for apmmdm, heath, scntpr, and lobo, hang up the phone. +sysbye: +IF heath OR scntpr + call mdmdrp ; Sleazy but effective +ENDIF;heath OR scntpr + + ret +; +; This is the system-dependent command to change the baud rate. +; DE contains the two-byte value from the baud rate table; this +; value is also stored in 'speed'. +sysspd: + +IF heath OR scntpr +; +; Set speed for H89 +; + call mdmofl ; keep the line safe from garbage + in mnport+acelcr + ori acedla + out mnport+acelcr ; access the ACE's divisor latch + mov a,e ; low byte of speed is in E + out mnport+acedll ; set the low byte + mov a,d ; high byte of speed is in D + out mnport+acedlh ; set the high byte + in mnport+acelcr + ani 0FFH-acedla + out mnport+acelcr ; de-access the ACE's divisor latch + call mdmonl ; and put the ACE back on line +ENDIF;heath OR scntpr + +IF h8quad ;[2][obs] A bit of guesswork this. Enter with date in de + call h8baud ; [2] routine is in initialisation bit +ENDIF ; h8quad[2] +; +IF telcon ;[4] + MVI A,36H ;Set square wave + OUT COMMND ;... + MOV A,E ;Get LSB of Baud rate + OUT BRPORT ;Send to generator + MOV A,D ;Get msb of baud rate + OUT BRPORT ;Send to Baud rate generator +ENDIF ;telcon +; + ret + +; +; +; Speed tables +; (Note that speed tables MUST be in alphabetical order for later +; lookup procedures, and must begin with a value showing the total +; number of entries. The speed help tables are just for us poor +; humans. +; +; db string length,string,divisor (2 identical bytes or 1 word) +; [Toad Hall] + +IF heath +; +; Speed selection table for H89 (OK, so I got a little carried away...) +; + +spdtbl: db 19 ; 19 entries + db 3,'110$' + dw 1047 + db 4,'1200$' + dw 96 + db 5,'134.5$' + dw 857 + db 4,'1800$' + dw 64 + db 5,'19200$' + dw 6 + db 3,'200$' + dw 576 + db 4,'2400$' + dw 48 + db 3,'300$' + dw 384 + db 4,'3600$' + dw 32 + db 5,'38400$' + dw 3 + db 3,'450$' + dw 256 + db 4,'4800$' + dw 24 + db 2,'50$' + dw 2304 + db 5,'56000$' + dw 2 + db 3,'600$' + dw 192 + db 4,'7200$' + dw 16 + db 2,'75$' + dw 1536 + db 3,'900$' + dw 128 + db 4,'9600$' + dw 12 + +sphtbl: db cr,lf + db ' 50 75 110 134.5 200 300 450 600 900 1200' + db cr,lf,' 1800 2400 3600 4800 7200 9600 19200 38400 56000$' +ENDIF;heath + +IF h8quad +spdtbl: db 6 ;[2] 6 entries + db 3,'300$', 1,80h ; divisor for 300 baud + db 3,'600$', 0,0c0h + db 4,'1200$', 0,60h + db 4,'2400$', 0,30h + db 4,'4800$', 0,18h + db 4,'9600$', 0,0ch +; +; The strings to display the speed selected from the table above +; +sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$' +ENDIF ;h8quad + +IF scntpr +; [35a: majoc 870305] +; +; Speed selection table for ScreenTyper +; + +spdtbl: db 14 ; 14 entries + db 3,'110$' + dw 470H + db 4,'1200$' + dw 68H + db 5,'134.5$' + dw 3a1H + db 4,'1800$' + dw 45H + db 5,'19200$' ; This was in PB's table, but not in the + dw 7H ; accompanying text string. Oversight? +; db 3,'200$' +; dw 576 + db 4,'2400$' + dw 34H + db 3,'300$' + dw 1a1H + db 4,'3600$' + dw 23H +; db 5,'38400$' +; dw 3 +; db 3,'450$' +; dw 256 + db 4,'4800$' + dw 1aH + db 2,'50$' + dw 964H +; db 5,'56000$' +; dw 2 + db 3,'600$' + dw 0d0H + db 4,'7200$' + dw 11H + db 2,'75$' + dw 683H +; db 3,'900$' +; dw 128 + db 4,'9600$' + dw 0dH + +sphtbl: db cr,lf,' 50 75 110 134.5 300 600 1200' + db cr,lf,' 1800 2400 3600 4800 7200 9600 (19200?)$' +ENDIF;scntpr +; +IF telcon ;[4] +; +; Speed selection tables for the Telcon Zorba (I overdid it, also) +; +; **NOTE** that when Kermit is first executed, the baud rate is +; unknown to Kermit, having been set by CP/M upon cold-boot, SETUP.COM, +; another communications program, etc. The easiest way to insure that +; the baud rate is known upon Kermit start-up is to set it +; in KERMIT.INI. +; +spdtbl: db 20 ;[4]Number of entries (some of these + ;speeds are *weird* but the Zorba + ;supports them so I'll put them in + db 3,'110$' + dw 4545 + db 4,'1200$' + dw 417 + db 5,'134.5$' + dw 3717 + db 3,'150$' + dw 3333 + db 4,'1760$' + dw 284 + db 4,'1800$' + dw 278 + db 5,'19200$' + dw 26 + db 3,'200$' + dw 2500 + db 4,'2000$' + dw 250 + db 4,'2400$' + dw 208 + db 3,'300$' + dw 1667 + db 4,'3520$' + dw 142 + db 4,'3600$' + dw 139 + db 4,'4800$' + dw 104 + db 2,'50$' + dw 10000 + db 3,'600$' + dw 833 + db 4,'62.5$' + dw 8000 + db 4,'7200$' + dw 69 + db 2,'75$' + dw 6667 + db 4,'9600$' + dw 52 +; +; Help table +; +sphtbl: db cr,lf + db ' 50 62.5 75 110 134.5 150 200 300 600 1200' + db cr,lf,' 1760 1800 2000 2400 3520 3600 4800 7200' + db cr,lf,' 9600 19200$' +; +ENDIF ;Telcon + +; The following conditionals were once a huge if not statement. There +; wasn't enough room to add the lobo to the list, so it had to be broken +; into 2, which you can't do with an if not. I redid it as two ifs and +; applied them to those that wouldn't set baud. [Hal Hostetler] +IF z100 +spdtbl equ 0 ; SET BAUD not supported. +sphtbl equ 0 +ENDIF;z100 +; +; +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +sysprt: + ret +; +prttbl equ 0 ; SET PORT is not supported +prhtbl equ 0 +; +; +; +; selmdm - select modem port +; selcon - select console port +; selmdm is called before using inpmdm or outmdm; +; selcon is called before using inpcon or outcon. +; For iobyt systems, diddle the I/O byte to select console or comm port; +; For Decision I, switches Multi I/O board to console or modem serial +; port. [Toad Hall] +; For the rest, does nothing. +; preserves bc, de, hl. +selmdm: + ret + +selcon: + ret + +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: +IF NOT iobyt + mvi c,dconio ;Direct console I/O BDOS call. + mvi e,0FFH ;Input. + call BDOS +ENDIF;NOT iobyt + + ret +; +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: +IF NOT iobyt + mvi c,dconio ;Console output bdos call. + call bdos ;Output the char to the console. +ENDIF;NOT iobyt + ret +; +; +; outmdm - output a char from E to the modem. +; the parity bit has been set as necessary. +; returns nonskip; bc, de, hl preserved. +outmdm: +IF inout + in mnprts ;Get the output done flag. + ani output ;Is it set? + jz outmdm ;If not, loop until it is. + mov a,e + out mnport ;Output it. + ret +ENDIF;inout + +IF iobyt +;**** Note that we enter from outpkt with the I/O byte already set up for +; output to go to the comm port + push h + push b + lda prtfun ;Get the output function + mov c,a ;Into C + call bdos ;And output the character + pop b + pop h + ret +ENDIF;iobyt + +; +; +; get character from modem; return zero if none available. +; for IOBYT systems, the modem port has already been selected. +; destroys bc, de, hl. +inpmdm: +IF NOT iobyt ;[2] this routine not in submitted file, so I guess + ; guess this is what it is supposed to do. + in mnprts ; input status port + ani input ; anything t read in? + rz ; nope + in mnport ; else read in the data + ret ; return with character in A +ENDIF ; NOT iobyte [2] + +; +; flsmdm - flush comm line. +; Modem is selected. +; Currently, just gets characters until none are available. + +flsmdm: call inpmdm ; Try to get a character + ora a ; Got one? + jnz flsmdm ; If so, try for another + ret ; Receiver is drained. Return. +; +; +; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not. +lptstat: + call bprtst ; assume it is ok.. this may not be necessary + ret + +; +; outlpt - output character in E to printer +; console is selected. +; preserves de. +outlpt: + push d ; save DE in either case + call prtflt ; go through printer filter [30] + ana a ; if A = 0 do nothing, + jz outlp1 ; [30] if a=0 do nothing + +IF NOT iobyt + mvi c,lstout + call bdos ;Char to printer +ENDIF;NOT iobyt +outlp1: pop d ; restore saved register pair + ret +; +; +; Screen manipulation routines +; csrpos - move to row B, column C +; +; csrpos for terminals that use a leadin sequence followed +; by (row + 31.) and (column + 31.) +; +csrpos: push b ; save coordinates + lxi d,curldn ; get cursor leadin sequence + call prtstr ; print it + pop h ; restore coordinates + mov a,h ; get row + adi (' '-1) ; space is row one + mov e,a + push h + call outcon ; output row + pop h + mov a,l ; get column + adi (' '-1) ; space is column one + mov e,a + jmp outcon ; output it and return + +; +; delchr - make delete look like a backspace. Unless delete is a printing +; character, we just need to print a backspace. (we'll output clrspc +; afterwards) +; For Kaypro and Vector General, delete puts a blotch on the screen. +; For Apple and Osborne 1, delete moves but doesn't print. +delchr: + mvi e,bs ;get a backspace + jmp outcon + +; erase the character at the current cursor position +clrspc: mvi e,' ' + call outcon + mvi e,bs ;get a backspace + jmp outcon + +; erase the current line +clrlin: lxi d,eralin + jmp prtstr + +; erase the whole screen, and go home. preserves b (but not c) +clrtop: lxi d,erascr + jmp prtstr + +IF telcon +sysver: db 'Telcon Zorba$' +ENDIF;telcon + +IF heath +sysver: db 'Heath/Zenith 89$' +ENDIF;heath + +IF h8quad +sysver: db 'Heath H8 with quad I/O card$' +ENDIF + +IF z100 +sysver: db 'Heath/Zenith Z-100 CP/M$' +ENDIF;z100 + +IF scntpr +; [35a: majoc 870305] +sysver: db 'OEM ScreenTyper: 4MHz Z80 running OS/M$' +ENDIF;scntpr + +IF heath OR h8quad OR z100 OR telcon +outlin: db esc,'H',esc,'J',cr,lf,tab,tab,'$' +erascr: db esc,'H',esc,'J$' ;Clear screen and go home. +eralin: db cr,esc,'K$' ;Clear line. +curldn: db esc,'Y$' ;cursor leadin +ttab: ;Table start location. +ta: db esc,'A$',0 ;Cursor up. +tb: db esc,'B$',0 ;Cursor down. +tc: db esc,'C$',0 ;Cursor right. +td: db esc,'D$',0 ;Cursor left +te: db esc,'E$',0 ;Clear display +tf: db esc,'F$',0 ;Enter Graphics Mode +tg: db esc,'G$',0 ;Exit Graphics mode +th: db esc,'H$',0 ;Cursor home. +ti: db esc,'I$',0 ;Reverse linefeed. +tj: db esc,'J$',0 ;Clear to end of screen. +tk: db esc,'K$',0 ;Clear to end of line. +ENDIF;heath OR h8quad OR z100 OR telcon +; + +IF scntpr ; [35a: majoc 870305] +outlin: db 1aH, cr, lf, '$' +erascr: db 1aH, '$' ;Clear screen and go home. +eralin: db cr,esc,'*$' ;Clear line. +curldn: db esc,'=$' ;cursor leadin +ttab: ;Table start location. +ta: db 1eH,'$',0,0 ;Cursor up. +tb: db 1fH,'$',0,0 ;Cursor down. +tc: db 1cH,'$',0,0 ;Cursor right. +td: db 1dH,'$',0,0 ;Cursor left +te: db 1aH,'$',0,0 ;Clear display +tf: db 0,0,0,0 ;(Can't)Enter Graphics Mode +tg: db 0,0,0,0 ;(Can't)Exit Graphics mode +th: db 15H,'$',0,0 ;Cursor home. +ti: db 1eH,'$',0,0 ;Reverse linefeed. +tj: db esc,'%$',0 ;Clear to end of screen. +tk: db esc,'*$',0 ;Clear to end of line. +ENDIF;scntpr + +ovlend EQU $ ; End of overlay + END ; Phew ... [majoc 870305] diff --git a/cpxlnk.asm b/cpxlnk.asm index 30dd080..83ac991 100644 --- a/cpxlnk.asm +++ b/cpxlnk.asm @@ -1,206 +1,206 @@ -; CPXLNK.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file describes the areas used to communicate between KERMIT -; and the customizing overlay. It is included by the overlay. -; This file should be changed only to reflect changes in the -; system-independent portion of Kermit (enhancements, I hope). -; -; revision history: -;edit 8, 14-Sep-1990 by MF. Added variable "incflg" to hold incomplete- -; file status for SET INCOMPLETE-FILES command. -; edit 7: 8 April, 1987 by OBSchou. Added a new entry EXTERN to leap off to -; code written by the user to emulate any terminal they want. All -; characters are sent here in stead of conout during connect state. -; In due course, Ill trap all prtstrs and dconio as well. -; -; edit 6: May 30, 1986 by OBSchou. Added two more entries to the link area: -; first to point to a "family" string giving the family name of the -; system. If the older CP4SYS.ASM still has the code, then the -; string is null. Secondly, a JMP to give printer status (should be -; a BIOS function). If 0 then printer is ready, if 0ffh then printer -; busy. This makes version 4.07 incompatable with 4.05 -; -; edit 5: February 6, 1985 -; Added a storage variable, "PORT", for the port-in-use value -; required for the port status routine (same purpose as SPEED). -; Also moved the printer copy flag (PRNFLG:) into the commun- -; ications storage area so machine dependant overlay can access it. -; [Hal Hostetler] -; Also, replace assembly-time conditional "ffussy" with run-time -; switch (CJC). -; -; edit 4: August 21, 1984 (CJC) -; Define a use for the third word of the linkage section: it points -; to the version string for CP4SYS.ASM. Add flsmdm, to flush comm line -; on startup. Add bufadr and bufsec for multiple-sector buffer support. -; Shift the entry section up two bytes so we can exit cleanly from DDT. -; -; edit 3: August 3, 1984 (CJC) -; put "mover" in CP4SYS, so we can do a Z80 block move if so inclined. -; -; edit 2: July 10, 1984 (CJC) -; integrate Toad Hall changes for LASM compatibility: CP4LNK is linked -; by CP4DEF, and links CP4SYS. -; -; edit 1: May, 1984 (CJC) -; extracted from CPMBASE.M80 version 3.9; modifications are described -; in the accompanying .UPD file. -; - -; Define the entry section. These addresses contain jumps to -; useful routines in KERMIT. To show we know what we're doing, -; we store the length of this section (entsiz) in our linkage -; section. I didn't use ORG and DS because I don't want zeroes -; generated for all the space between here and the actual start -; of cp4sys. -entry equ 105H ; start of entry section -kermit equ entry+0 ; reentry address -nout equ entry+3 ; output HL in decimal -entsiz equ 2*3 ; 2 entries, so far. -; -; End of entry section. -; -; Linkage section. This block (through the definition of lnksiz) -; is used by Kermit to reach the routines and data in the overlay. -; The section length is stored at the beginning of the overlay -; area so Kermit can verify that the overlay section is (a) present, -; (b) in the right place, and (c) the same size as (and therefore -; presumably the same as) the linkage section Kermit is expecting. -; - ASEG - ORG OVLADR -; -lnkflg: dw lnksiz ; linkage information for consistency check. - dw entsiz ; length of entry table, for same. - dw swtver ; address of switcher. CPXSYS now a family - dw family ;*NEW* for V4.08. Address of the family string -; -; hooks for system-dependent routines: -; -; Input/output routines. -; - jmp selmdm ; select modem for I/O - jmp outmdm ; output character in E to modem - jmp inpmdm ; read character from modem. return character or 0 in A. - jmp flsmdm ; flush pending input from modem - jmp selcon ; select console for I/O - jmp outcon ; output character in E to console - jmp inpcon ; read char from console. return character or 0 in A - jmp outlpt ; output character in E to printer - jmp lptstat ;*NEW* get the status for the printer. - ; 0=>ok, 0ffh=> not ok - jmp 0 ;*NEW for 4.09* Terminal Emulation code (optional) - ; If terminal is set to EXTERNAL and this address - ; has been filled, then user uses their own code. -xbdos: jmp 0 ;*NEW* Address of the BDOS trap in the independent - ; code. Use this enty for BDOS calls if you want - ; the printer handler to work properly. - -; screen formatting routines - jmp clrlin ; erase current line - jmp clrspc ; erase current position (after backspace) - jmp delchr ; make delete look like backspace - jmp clrtop ; erase screen and go home -; -; these routines are called to display a field on the screen. - jmp scrend ; move to prompt field - jmp screrr ; move to error message field - jmp scrfln ; move to filename field - jmp scrnp ; move to packet count field - jmp scrnrt ; move to retry count field - jmp scrst ; move to status field - jmp rppos ; move to receive packet field (debug) - jmp sppos ; move to send packet field (debug) -; - jmp sysinit ; program initialization - jmp sysexit ; program termination - jmp syscon ; remote session initialization - jmp syscls ; return to local command level - jmp sysinh ; help text for interrupt (escape) extensions - jmp sysint ; interrupt (escape) extensions, including break - jmp sysflt ; filter for incoming characters. - ; called with character in E. - jmp sysbye ; terminate remote session - jmp sysspd ; baud rate change routine. - ; called with value from table in DE - jmp sysprt ; port change routine. - ; called with value from table in HL - jmp sysscr ; screen setup for file transfer - ; called with Kermit's version string in DE - jmp csrpos ; move cursor to row B, column C - jmp sysspc ; calculate free space for current drive - jmp mover ; do block move - jmp prtstr ; *** NEW *** Link from system indep equivalent -; -; Local parameter values -; -pttab: dw ttab ; points to local equivalents to VT52 escape sequences -spdtab: dw spdtbl ; address of baud rate command table, or zero -spdhlp: dw sphtbl ; address of baud rate help table, or zero -prttab: dw prttbl ; address of port command table, or zero -prthlp: dw prhtbl ; address of port help table, or zero -timout: dw fuzval ; Fuzzy timeout. -vtflg: db vtval ; VT52 emulation flag -escchr: db defesc ; Storage for the escape character. -speed: dw 0FFFFH ; storage for the baud rate (initially unknown) -port: dw 0FFFFH ; storage for port value (initially unknown) [hh] -prnflg: db 0 ; printer copy flag [hh] -dbgflg: db 0 ; debugging flag -ecoflg: db 0 ; Local echo flag (default off). -flwflg: db 1 ; File warning flag (default on). -ibmflg: db 0 ; IBM flag (default off). -cpmflg: db 0 ;[bt] file-mode flag (default is DEFAULT) -incflg: db 0 ;[MF]incomplete-file flag (default is DISCARD) -parity: db defpar ; Parity. -spsiz: db dspsiz ; Send packet size. -rpsiz: db drpsiz ; Receive packet size. -stime: db dstime ; Send time out. -rtime: db drtime ; Receive time out. -spad: db dspad ; Send padding. -rpad: db drpad ; Receive padding. -spadch: db dspadc ; Send padding char. -rpadch: db drpadc ; Receive padding char. -seol: db dseol ; Send EOL char. -reol: db dreol ; Receive EOL char. -squote: db dsquot ; Send quote char. -rquote: db drquot ; Receive quote char. -chktyp: db dschkt ; Checksum type desired -tacflg: ; TACtrap status: -IF tac - db tacval ; when non-zero, is current TAC intercept character; -ENDIF;tac -IF NOT tac - db 0 ; when zero, TACtrap is off. -ENDIF;tac -tacchr: db tacval ; Desired TAC intercept character (even when off) -bufadr: dw buff ; Address of possibly multi-sector buffer for I/O -bufsec: db 1 ; Number of sectors big buffer can hold (0 means 256) -ffussy: db 1 ; if nonzero, don't permit <>.,;?*[] in CP/M filespec. -; space used by directory command; here because space calculation is -; (operating) system-dependent -bmax: ds 2 ; highest block number on drive -bmask: ds 1 ; (records/block)-1 -bshiftf: ds 1 ; number of shifts to multiply by rec/block -nnams: ds 1 ; counter for filenames per line - -lnksiz equ $-lnkflg ; length of linkage section, for consistency check. - -IF lasm ; If we're assembling with LASM, - LINK CPXCOM ; get the next section. -ENDIF;lasm +; CPXLNK.ASM +; KERMIT - (Celtic for "FREE") +; +; This is the CP/M-80 implementation of the Columbia University +; KERMIT file transfer protocol. +; +; Version 4.0 +; +; Copyright June 1981,1982,1983,1984 +; Columbia University +; +; Originally written by Bill Catchings of the Columbia University Center for +; Computing Activities, 612 W. 115th St., New York, NY 10025. +; +; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, +; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many +; others. +; +; This file describes the areas used to communicate between KERMIT +; and the customizing overlay. It is included by the overlay. +; This file should be changed only to reflect changes in the +; system-independent portion of Kermit (enhancements, I hope). +; +; revision history: +;edit 8, 14-Sep-1990 by MF. Added variable "incflg" to hold incomplete- +; file status for SET INCOMPLETE-FILES command. +; edit 7: 8 April, 1987 by OBSchou. Added a new entry EXTERN to leap off to +; code written by the user to emulate any terminal they want. All +; characters are sent here in stead of conout during connect state. +; In due course, Ill trap all prtstrs and dconio as well. +; +; edit 6: May 30, 1986 by OBSchou. Added two more entries to the link area: +; first to point to a "family" string giving the family name of the +; system. If the older CP4SYS.ASM still has the code, then the +; string is null. Secondly, a JMP to give printer status (should be +; a BIOS function). If 0 then printer is ready, if 0ffh then printer +; busy. This makes version 4.07 incompatable with 4.05 +; +; edit 5: February 6, 1985 +; Added a storage variable, "PORT", for the port-in-use value +; required for the port status routine (same purpose as SPEED). +; Also moved the printer copy flag (PRNFLG:) into the commun- +; ications storage area so machine dependant overlay can access it. +; [Hal Hostetler] +; Also, replace assembly-time conditional "ffussy" with run-time +; switch (CJC). +; +; edit 4: August 21, 1984 (CJC) +; Define a use for the third word of the linkage section: it points +; to the version string for CP4SYS.ASM. Add flsmdm, to flush comm line +; on startup. Add bufadr and bufsec for multiple-sector buffer support. +; Shift the entry section up two bytes so we can exit cleanly from DDT. +; +; edit 3: August 3, 1984 (CJC) +; put "mover" in CP4SYS, so we can do a Z80 block move if so inclined. +; +; edit 2: July 10, 1984 (CJC) +; integrate Toad Hall changes for LASM compatibility: CP4LNK is linked +; by CP4DEF, and links CP4SYS. +; +; edit 1: May, 1984 (CJC) +; extracted from CPMBASE.M80 version 3.9; modifications are described +; in the accompanying .UPD file. +; + +; Define the entry section. These addresses contain jumps to +; useful routines in KERMIT. To show we know what we're doing, +; we store the length of this section (entsiz) in our linkage +; section. I didn't use ORG and DS because I don't want zeroes +; generated for all the space between here and the actual start +; of cp4sys. +entry equ 105H ; start of entry section +kermit equ entry+0 ; reentry address +nout equ entry+3 ; output HL in decimal +entsiz equ 2*3 ; 2 entries, so far. +; +; End of entry section. +; +; Linkage section. This block (through the definition of lnksiz) +; is used by Kermit to reach the routines and data in the overlay. +; The section length is stored at the beginning of the overlay +; area so Kermit can verify that the overlay section is (a) present, +; (b) in the right place, and (c) the same size as (and therefore +; presumably the same as) the linkage section Kermit is expecting. +; + ASEG + ORG OVLADR +; +lnkflg: dw lnksiz ; linkage information for consistency check. + dw entsiz ; length of entry table, for same. + dw swtver ; address of switcher. CPXSYS now a family + dw family ;*NEW* for V4.08. Address of the family string +; +; hooks for system-dependent routines: +; +; Input/output routines. +; + jmp selmdm ; select modem for I/O + jmp outmdm ; output character in E to modem + jmp inpmdm ; read character from modem. return character or 0 in A. + jmp flsmdm ; flush pending input from modem + jmp selcon ; select console for I/O + jmp outcon ; output character in E to console + jmp inpcon ; read char from console. return character or 0 in A + jmp outlpt ; output character in E to printer + jmp lptstat ;*NEW* get the status for the printer. + ; 0=>ok, 0ffh=> not ok + jmp 0 ;*NEW for 4.09* Terminal Emulation code (optional) + ; If terminal is set to EXTERNAL and this address + ; has been filled, then user uses their own code. +xbdos: jmp 0 ;*NEW* Address of the BDOS trap in the independent + ; code. Use this enty for BDOS calls if you want + ; the printer handler to work properly. + +; screen formatting routines + jmp clrlin ; erase current line + jmp clrspc ; erase current position (after backspace) + jmp delchr ; make delete look like backspace + jmp clrtop ; erase screen and go home +; +; these routines are called to display a field on the screen. + jmp scrend ; move to prompt field + jmp screrr ; move to error message field + jmp scrfln ; move to filename field + jmp scrnp ; move to packet count field + jmp scrnrt ; move to retry count field + jmp scrst ; move to status field + jmp rppos ; move to receive packet field (debug) + jmp sppos ; move to send packet field (debug) +; + jmp sysinit ; program initialization + jmp sysexit ; program termination + jmp syscon ; remote session initialization + jmp syscls ; return to local command level + jmp sysinh ; help text for interrupt (escape) extensions + jmp sysint ; interrupt (escape) extensions, including break + jmp sysflt ; filter for incoming characters. + ; called with character in E. + jmp sysbye ; terminate remote session + jmp sysspd ; baud rate change routine. + ; called with value from table in DE + jmp sysprt ; port change routine. + ; called with value from table in HL + jmp sysscr ; screen setup for file transfer + ; called with Kermit's version string in DE + jmp csrpos ; move cursor to row B, column C + jmp sysspc ; calculate free space for current drive + jmp mover ; do block move + jmp prtstr ; *** NEW *** Link from system indep equivalent +; +; Local parameter values +; +pttab: dw ttab ; points to local equivalents to VT52 escape sequences +spdtab: dw spdtbl ; address of baud rate command table, or zero +spdhlp: dw sphtbl ; address of baud rate help table, or zero +prttab: dw prttbl ; address of port command table, or zero +prthlp: dw prhtbl ; address of port help table, or zero +timout: dw fuzval ; Fuzzy timeout. +vtflg: db vtval ; VT52 emulation flag +escchr: db defesc ; Storage for the escape character. +speed: dw 0FFFFH ; storage for the baud rate (initially unknown) +port: dw 0FFFFH ; storage for port value (initially unknown) [hh] +prnflg: db 0 ; printer copy flag [hh] +dbgflg: db 0 ; debugging flag +ecoflg: db 0 ; Local echo flag (default off). +flwflg: db 1 ; File warning flag (default on). +ibmflg: db 0 ; IBM flag (default off). +cpmflg: db 0 ;[bt] file-mode flag (default is DEFAULT) +incflg: db 0 ;[MF]incomplete-file flag (default is DISCARD) +parity: db defpar ; Parity. +spsiz: db dspsiz ; Send packet size. +rpsiz: db drpsiz ; Receive packet size. +stime: db dstime ; Send time out. +rtime: db drtime ; Receive time out. +spad: db dspad ; Send padding. +rpad: db drpad ; Receive padding. +spadch: db dspadc ; Send padding char. +rpadch: db drpadc ; Receive padding char. +seol: db dseol ; Send EOL char. +reol: db dreol ; Receive EOL char. +squote: db dsquot ; Send quote char. +rquote: db drquot ; Receive quote char. +chktyp: db dschkt ; Checksum type desired +tacflg: ; TACtrap status: +IF tac + db tacval ; when non-zero, is current TAC intercept character; +ENDIF;tac +IF NOT tac + db 0 ; when zero, TACtrap is off. +ENDIF;tac +tacchr: db tacval ; Desired TAC intercept character (even when off) +bufadr: dw buff ; Address of possibly multi-sector buffer for I/O +bufsec: db 1 ; Number of sectors big buffer can hold (0 means 256) +ffussy: db 1 ; if nonzero, don't permit <>.,;?*[] in CP/M filespec. +; space used by directory command; here because space calculation is +; (operating) system-dependent +bmax: ds 2 ; highest block number on drive +bmask: ds 1 ; (records/block)-1 +bshiftf: ds 1 ; number of shifts to multiply by rec/block +nnams: ds 1 ; counter for filenames per line + +lnksiz equ $-lnkflg ; length of linkage section, for consistency check. + +IF lasm ; If we're assembling with LASM, + LINK CPXCOM ; get the next section. +ENDIF;lasm diff --git a/cpxmrl.asm b/cpxmrl.asm index 31d6849..fb32692 100644 --- a/cpxmrl.asm +++ b/cpxmrl.asm @@ -1,454 +1,454 @@ -IF NOT lasm -.printx * CPXMRL.ASM * -ENDIF ; NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; CPXMRL.ASM created 16 July, 1987 from submitted code by William Rose. -; -; Kermit system dependent file for Rair Black Box (British Telecom -; Merlin, ICL PC etc) originally submitted by William Rose, and -; modified by OBSchou to work with the Kermit-80 V4.08 and later -; files. Wills original overlay file a stripped down CPXSYS.ASM -; file. -; -; KERSYS.ASM - version 0.6A dated 17 Jun 87. -; -; Cutdown CP4SYS.ASM for Telecom Merlin M2215 only. (ICL PC, Rair Black Box) -; -; This uses TTY1: only, and cannot alter it's parameters. It resets the -; interrupt flag to prevent use of the buffer, and is generally a kludge. -; However it runs at 4800 baud, and tidying the code might get 9600. -; -; Revision History (Last entry first) -; -; edit 2, 22 July by OBSchou to massage frile to fit with CPXCOM.ASM -; -; edit 1, 17 July by OBSchou for Will Rose, to make file suitable for V4.08 -; overlay etc. -; -; Keep module name, edit number, and last revision date in memory. -; -family: db 'CPXMRL.ASM (2) 22-Jun-87 $' ; Telecom Merlin added - -; -; Assembly time message to let me know I'm building the right version. -; - -IF m2215 - .printx * Assembling Kermit-80 for Merlin M2215 * -ENDIF - -IF m2215 ;equates removed because interrupts stopped port access -;iobase equ 14h ; base address of TTY1 -;mnport equ iobase ; rx and tx data ports -;mnprts equ iobase+1 ; status port -;mnmode equ iobase+2 ; mode port -;mncmd equ iobase+3 ; PCI command port -;txrdy equ 1 ; tx ready bit set if free -;output equ txrdy -;rxrdy equ 2 ; RX ready bit -;input equ rxrdy -z80 equ false ; For Merlin M2215 -ENDIF - - -sysxin: ; Continue system initialisation fro sysinit - -IF FALSE ; unable to penetrate the 8085 interrupts - in mncmd ; clear command register counter - mvi a,4eh ; 0100$1110 - 1 stop bit, 8 data bits, - ; / by 16 counter - out mnmode - mvi a,30h+7 ; 0011$0000 - select internal rate generator - ; use 1200 baud by default - out mnmode - mvi a,27h ; 0010$0111 - enable tx and rx, RTS and DTR low - out mncmd - mvi h, 12 - mvi l, 12 - shld speed ; to show its been set up - -ENDIF - - ret - -porbuf: ds 3 ; original port settings - -; -; system-dependent KERMIT termination processing -; If we've changed anything, this is our last chance to put it back. -; -sysexit: - ret - -; -; system-dependent processing for start of CONNECT command -; -syscon: - ret - -conmsg: ; Messages printed when entering transparent (CONNECT) mode: - - db '$' - -; -; syscls - system-dependent close routine -; called when exiting transparent session. -; -syscls: - ret - -; -; sysinh - help for system-dependent special functions. -; called in response to ?, 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: ,,, and 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 ?, 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: ,,, and are always discarded. +; +sysflt: + mov a,e ; get character for testing + ret + +; +; mdmflt - modem filter +; called with character to be sent to printer in E +; with parity set as appropriate. +; return with accumulator = 0 do do nothing, +; <> 0 to send char in E. +mdmflt: + mov a,e ; get character to test + ret + +; +; prtflt - printer filter +; called with character to be sent to printer in E +; returns with a = 0 to do nothing +; a <> 0 to print it. +; +; this routine for those printer that automatically insert +; a lf on cr, or cr for lf. Should this be shifted to +; the system indep. stuff, in say 4.06? +; +prtflt: + mov a,e ; get character to test + +IF FALSE ; strip out lf from printer stream + ani 7fh ; make sure it is parity less + cpi lf ; is it a line feed? + rnz ; no, print it +; xra a ; yes, don't. + +ENDIF + + ret + +; +; system-dependent processing for BYE command. +; +sysbye: + ret + +; +; This is the system-dependent command to change the baud rate. +; DE contains the two-byte value from the baud rate table; both +; bytes of this value are also stored in 'speed'. +; +sysspd: + +IF FALSE ; as always + in mncmd ; clear register counter + mvi a,4eh ; set for 1 stop, 8 data bits + out mnmode ; save in mode 1 port + mvi a,30h ; set bits for rate etc.. + add e ; add baud rate (bits 0 - 3) + out mnmode ; set mode port 2 + mvi a,27h ; set tx/rx ready, RTS CTS active + out mncmd + ret +ENDIF + ret ; if routine not supported +; +; Speed tables +; (Note that speed tables MUST be in alphabetical order for later +; lookup procedures, and must begin with a value showing the total +; number of entries. The speed help tables are just for us poor +; humans. +; +; db string length, string, divisor (2 bytes or 1 word, ab) +; the data byte a is return in A and E, and b in D +; only byte 'a' is the key for the table + +IF FALSE ; as always +spdtbl: db 16 ; sixteen entries for PCI + db 3,'110$', 2,2 + db 4,'1200$', 7,7 + db 3,'134$', 3,3 + db 3,'150$', 4,4 + db 4,'1800$', 8,8 + db 5,'19200$', 15,15 + db 4,'2000$', 9,9 + db 4,'2400$', 10,10 + db 3,'300$', 5,5 + db 4,'3600$', 11,11 + db 4,'4800$', 12,12 + db 2,'50$', 0,0 + db 3,'600$', 6,6 + db 4,'7200$', 13,13 + db 2,'75$', 1,1 + db 4,'9600$', 14,14 + +sphtbl: db ' 50 75 110 134 150 300 600 1200 ' + db cr,lf,'1800 2000 2400 3600 4800 7200 9600 19200$' +ENDIF + +IF m2215 +spdtbl equ 0 ; routine unsupported +sphtbl equ 0 +ENDIF + +; +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +; +sysprt: + +IF m2215 +prttbl equ 0 ; SET PORT is not supported +prhtbl equ 0 ; Merlin M2215 could, I suppose +ENDIF + +; +; selmdm - select modem port +; selcon - select console port +; selmdm is called before using inpmdm or outmdm; +; selcon is called before using inpcon or outcon. +; For iobyt systems, diddle the I/O byte to select console or comm port; +; For the rest, does nothing. +; preserves bc, de, hl. +; +selmdm: + ret + +selcon: + ret + +; +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: + call 0f55dh ;CONST BIOS vector + ora a ;set flags + rz + call 0f56eh ;CONIN BIOS vector + ret + +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: + mov c, e + call 0f57fh ;CONOUT BIOS vector + ret + +; +; outmdm - output a char from E to the modem. +; the parity bit has been set as necessary. +; returns nonskip; bc, de, hl preserved. +; +outmdm: + +IF m2215 + push psw + push h + push d + push b + + mov c, e + mvi a, 1 ; ie: tty1: + mov d, a + call 0f6a2h ;PUN BIOS vector + + pop b + pop d + pop h + pop psw +ENDIF + + ret + +; +; for IOBYT systems, the modem port has already been selected. +; destroys bc, de, hl. +; +inpmdm: + +IF m2215 + ; check status + lda 0fa32h ; ie. tty1: + ora a + rz + + mvi a, 1 ; RDR BIOS vector + mov d, a + call 0f651h +; ani 7fh + + push a + di + mvi a, 0 + sta 0fa32h ; remove interrupt flag + sta 0f2d3h ; zero buffer counter + lda 0f2d4h + sta 0f2d5h + ei + nop + pop a + + ret +ENDIF + +; +; flsmdm - flush comm line. +; Modem is selected. +; Currently, just gets characters until none are available. +; +flsmdm: + + call inpmdm ; Try to get a character + ora a ; Got one? + jnz flsmdm ; If so, try for another + ret ; Receiver is drained. Return. + + +; + +; +; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not. +lptstat: +IF iobyte ;[33] + call bprtst ; get status +ENDIF ;iobyte[33] + +IF NOT iobyte ;[33] + xra a ; assume it is ok.. this may not be necessary +ENDIF ;iobyte [33] + ret +; +; outlpt - output character in E to printer +; console is selected. +; preserves de. +; +outlpt: + push d ; save DE in either case + call prtflt ; go through printer filter [30] + ana a ; if A = 0 do nothing, + jz outlp1 ; if a=0 do nothing + +outlp1: pop d ; restore saved register pair + ret + +; delchr - make delete look like a backspace. Unless delete is a printing +; character, we just need to print a backspace. (we'll output clrspc +; afterwards) +delchr: + + mvi e,bs ;get a backspace + jmp outcon + +; erase the character at the current cursor position +clrspc: mvi e,' ' + call outcon + mvi e,bs ;get a backspace + jmp outcon + +; erase the current line +clrlin: lxi d,eralin + jmp prtstr + +; erase the whole screen, and go home. preserves b (but not c) +clrtop: lxi d,erascr + jmp prtstr + + +IF m2215 +sysver: db 'BT Merlin M2215, port TTY1:, settings unchanged.$' +ENDIF + +tstmsg: db 'Test message',cr,lf,'$' + +IF lasm +LINK CPXVDU.ASM ; link to the Terminal definition tables +ENDIF ;lasm diff --git a/cpxnor.asm b/cpxnor.asm index 2648060..4600bb3 100644 --- a/cpxnor.asm +++ b/cpxnor.asm @@ -1,587 +1,587 @@ -IF NOT LASM -.printx * CPXNOR.ASM * -ENDIF ;NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the system-dependent code and data for various -; NorthStar KERMITs. This has the Family name of CPXNOR.ASM. -; -; revision history (last edit first) -; -;edit 4, 16-Jan-1991 by MF. Fixed a bug in OUTCON wherein the final RET -; was missing (bug reported by David P. Arnot of Scottish -; Agricultural College). -;edit 3, 12-Oct-1990 by MF. Added a semicolon before the comment -; beginning "Family is the string so we don't get errors -; edit 2, 23 July, 1987 by OBSchou to massage file to suit CPXCOM.ASM. -; -; edit 1: 1 June, 1986 by OBSchou, Loughborogh University, UK. -; Hived off northstar and Comart system dependent modules from -; CPXSYS.ASM. This assembles ok, but I cannot test it. Any comments? - - -IF norths -.printx * Assembling for NorthStar Horizon with HSIO-4 board * -ENDIF;norths - -IF horizon ;[25] -.printx * Assembling KERMIT-80 for the NorthStar Horizon * -ENDIF;horizon - -IF advant ;[22] -.printx * Assembling kermit-80 for North Star Advantage * -ENDIF ;[22] - -IF basicns ;[29] -.printx * Assembling KERMIT-80 for the Northstar Horizon using printer port * -ENDIF ;basicns [29] - -IF comart -.printx * Assembling KERMIT-80 for Comart Communicator * -ENDIF ; comart - -; the basics... -IF norths ;The basic Northstar Horizon BIOS does not access ports 2-5 -port0d equ 02h ;Port 0 data (console) -port0s equ 03h ;Port 0 status -port1d equ 04h ;Port 1 data (printer) -port1s equ 05h ;Port 1 status - -port2b equ 10h ;Port 2 baud -port2i equ 11h ;Port 2 interrupt mask -port2d equ 12h ;Port 2 data -port2s equ 13h ;Port 2 status - -port3b equ 14h ;Port 3 baud -port3i equ 15h ;Port 3 interrupt mask -port3d equ 16h ;Port 3 data -port3s equ 17h ;Port 3 status - -port4b equ 18h ;Port 4 baud -port4i equ 19h ;Port 4 interrupt mask -port4d equ 1Ah ;Port 4 data -port4s equ 1Bh ;Port 4 status - -port5b equ 1Ch ;Port 5 baud -port5i equ 1Dh ;Port 5 interrupt mask -port5d equ 1Eh ;Port 5 data -port5s equ 1Fh ;Port 5 status - -NS19K2 EQU 00H ;19.2 kilobaud -NS9600 EQU 01H ;9600 baud -NS4800 EQU 02H ;4800 baud -NS2400 EQU 03H ;2400 baud -NS1200 EQU 04H ;1200 baud -NS0600 EQU 05H ; 600 baud -NS0300 EQU 06H ; 300 baud -NS0110 EQU 07H ; 110 baud -;; Set to use port 5 at 1200 baud -mnport equ port5d ;Data port -mnprts equ port5s ;Status port -baudrt equ port5b ;Baud rate port -baudini equ ns1200 ;Initial baud rate -output EQU 1 ;Bit of UART status for transmitter ready -input EQU 2 ;Bit of UART status for receiver ready -z80 EQU TRUE ;This one's a Z80. -ENDIF;norths - -IF basicns ;[29] -mnport equ 04h ;printer port data -mnprts equ 05h ; printer port status -output equ 1 ;transmitter ready -input equ 2 ;receiver ready -z80 equ FALSE ; not important -ENDIF ;basicns [29] - -IF horizon ;[25] -mnport EQU 004H ;Modem data port -mnprts EQU 005H ;Modem status port -output EQU 01H ;Transmitter empty -input EQU 02H ;Input data available -TxEmpty EQU 04h ;Transmitter empty -;Note: Needs terminal definition (vt100, vt52, tvi925, adm3a or crt above) -z80 EQU TRUE ;This one's a Z80. -ENDIF;horizon - -IF advant ;[22] -vtval EQU 1 ; we do emulation of VT52s -slot EQU 1 ;SIO card slot -mnport EQU (6-slot)*16 ;Modem data port -mnprts EQU mnport+1 ;Modem status port -baudrt EQU mnport+8 ;Baud rate register -output EQU 01H ;Transmitter buffer empty -input EQU 02H ;Input data available -TxEmpty EQU 04h ;Transmitter empty flag -z80 EQU TRUE -ENDIF;[22] advant - -IF comart ;[25] -mnport EQU 002H ;Modem data port -mnprts EQU 003H ;Modem status port -output EQU 01H ;Transmitter empty -input EQU 02H ;Input data available -TxEmpty EQU 04h ;Transmitter empty -;Note: Needs terminal definition (vt100, vt52, tvi925, adm3a or crt above) -z80 EQU TRUE ;This one's a Z80. -ENDIF;comart - - -IF advant -defesc EQU '\'-100O -ENDIF;advant - -; -; Family is the string used in VERSION to say which of several -; smaller overlay files are used. These are (will be) derived from -; the juge CP4SYS.ASM file, in which case we will never get here. -; Just a Dollar, but put a sting in for a family of machines. -; -family: db 'CPXNOR.ASM (4) 16-Jan-1991$' ; Used for family versions.... - - - -sysxin: ; continuation of system dependent initialisation code -IF advant ;[22] - mvi a,40h - out mnprts ; Reset USART - lxi h,7070h ; Default to 1200 baud - shld speed ; store current speed - xchg - call sysspd ; set default baud rate - mvi a,4Eh ; Set UART mode to async 16x clock, 8 data - out mnprts ; bits, no parity, and 1 stop bit - mvi a,37h ; Set command to Tx enable, DTR on, Rx enable, - out mnprts ; break off, error reset, and RTS on -ENDIF;[22] advant - -IF norths - mvi a,baudini ;Get initial speed - out baudrt - sta speed ;save for status display - sta speed+1 -ENDIF;norths - -IF comart OR horizon ;[25] -; The PD8251/PD8251A is reset by three successive 00 Hex or two -; successive 80 Hex command instructions followed by a software -; reset command instruction (40 Hex). - mvi a,80h ; Send UART reset - out mnprts - mvi a,80h - out mnprts - mvi a,40h - out mnprts - mvi a,4Eh ; Set UART mode to async 16x clock, 8 data - out mnprts ; bits, no parity, and 1 stop bit - mvi a,37h ; Set command to Tx enable, DTR on, Rx enable, - out mnprts ; break off, error reset, and RTS on -ENDIF;comart OR horizon - - - ret ; return from system-dependent routine -; - -; -; system-dependent termination processing -; If we've changed anything, this is our last chance to put it back. -sysexit: - - ret - -; -; system-dependent processing for start of CONNECT command -; -syscon: - ret - -conmsg: ; Messages printed when entering transparent (CONNECT) mode: -; - -; -; syscls - system-dependent close routine -; called when exiting transparent session. -; -syscls: - ret -; - -; -; sysinh - help for system-dependent special functions. -; called in response to ?, 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: ,,, and 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 ?, 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: ,,, and are always discarded. +sysflt: + mov a,e ; get character for testing +IF advant ;[22] + cpi 'D'-100O ;Control-D's reset video + rnz ; if not control-D, it's ok. + xra a ; don't allow control-D out. +ENDIF;[22] advant + ret + +; mdmflt - modem filter [30] +; called with character to be sent to printer in E +; with parity set as appropriate. +; return with accumulator = 0 do do nothing, +; <> 0 to send char in E. +mdmflt: + mov a,e ;[30] get character to test + ret + + + +; prtflt - printer filter [30] +; called with character to be sent to printer in E +; returns with a = 0 to do nothing +; a <> 0 to print it. +; +; this routine for those printer that automatically insert +; a lf on cr, or cr for lf. Should this be shifted to +; the system indep. stuff, in say 4.06? +prtflt: + mov a,e ; [30] get character to test + ret + + +; + +; +; system-dependent processing for BYE command. +; for apmmdm, heath, and lobo, hang up the phone. +sysbye: + ret +; + +; This is the system-dependent command to change the baud rate. +; DE contains the two-byte value from the baud rate table; this +; value is also stored in 'speed'. +sysspd: +IF norths OR advant ; + mov a,e ; get the parsed value + out baudrt ; Tell the baud rate generator. + ret +ENDIF;norths OR advant + +IF advant ;[22] +spdtbl: db 6 ; 6 entries + db 04,'1200$', 70h,70h + db 04,'2400$', 78h,78h + db 03,'300$', 40h,40h + db 04,'4800$', 7Ch,7Ch + db 03,'600$', 60h,60h + db 04,'9600$', 7Eh,7Eh + +sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$' +ENDIF;[22] advant + + +IF norths +spdtbl: db 8 ; 8 entries + db 3,'110$', 07H,07H + db 4,'1200$', 04H,04H + db 5,'19200$', 00H,00H + db 4,'2400$', 03H,03H + db 3,'300$', 06H,06H + db 4,'4800$', 02H,02H + db 3,'600$', 05H,05H + db 4,'9600$', 01H,01H + + +sphtbl: db cr,lf + db ' 110 300 600 12000 2400 4800 9600 19200$' +ENDIF;norths + +; The following conditionals were once a huge if not statement. There +; wasn't enough room to add the lobo to the list, so it had to be broken +; into 2, which you can't do with an if not. I redid it as two ifs and +; applied them to those that wouldn't set baud. [Hal Hostetler] +IF NOT (advant OR norths) +spdtbl EQU 0 ;[hh] SET BAUD not supported. +sphtbl EQU 0 ;[hh] ran out of room above... +ENDIF ;NOT (advant OR norths) +; +; + +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +sysprt: + ret + +prttbl equ 0 ; SET PORT not supported +prhtbl equ 0 +; + +; +; selmdm - select modem port +; selcon - select console port +; selmdm is called before using inpmdm or outmdm; +; selcon is called before using inpcon or outcon. +; For iobyt systems, diddle the I/O byte to select console or comm port; +; For Decision I, switches Multi I/O board to console or modem serial +; port. [Toad Hall] +; For the rest, does nothing. +; preserves bc, de, hl. +selmdm: +selcon: + ret +; + +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: + mvi c,dconio ;Direct console I/O BDOS call. + mvi e,0FFH ;Input. + call BDOS + ret +; + +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: + mvi c,dconio ;Console output bdos call. + call bdos ;Output the char to the console. + ret ;[MF]per David P. Arnot +; + +; +; outmdm - output a char from E to the modem. +; the parity bit has been set as necessary. +; returns nonskip; bc, de, hl preserved. +outmdm: + in mnprts ;Get the output done flag. + ani output ;Is it set? + jz outmdm ;If not, loop until it is. + mov a,e + out mnport ;Output it. + ret +; + +; +; get character from modem; return zero if none available. +; for IOBYT systems, the modem port has already been selected. +; destroys bc, de, hl. +inpmdm: +;Note: modem port should already be selected for mdI. [Toad Hall] + in mnprts ;Get the port status into A. + ani input ;See if the input ready bit is on. + rz ;If not then return. + in mnport ;If so, get the char. + ret ; return with character in A + + +; +; flsmdm - flush comm line. +; Modem is selected. +; Currently, just gets characters until none are available. + +flsmdm: call inpmdm ; Try to get a character + ora a ; Got one? + jnz flsmdm ; If so, try for another + ret ; Receiver is drained. Return. +; + +; +; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not. +lptstat: + xra a ; assume it is ok.. this may not be necessary + ret + +; +; outlpt - output character in E to printer +; console is selected. +; preserves de. +outlpt: + push d ; save DE in either case + call prtflt ; go through printer filter [30] + ana a ; if A = 0 do nothing, + jz outlp1 ; [30] if a=0 do nothing + mvi c,lstout + call bdos ;Char to printer +outlp1: pop d ; restore saved register pair + ret +IF advant ; all others require terminals +; + +; +; Screen manipulation routines +; csrpos - move to row B, column C +; +; csrpos for terminals that use a leadin sequence followed +; by (row + 31.) and (column + 31.) +; +csrpos: push b ; save coordinates + lxi d,curldn ; get cursor leadin sequence + call prtstr ; print it + pop h ; restore coordinates + mov a,h ; get row + adi (' '-1) ; space is row one + mov e,a + push h + call outcon ; output row + pop h + mov a,l ; get column + adi (' '-1) ; space is column one + mov e,a + jmp outcon ; output it and return +ENDIF ;advant + +; +; delchr - make delete look like a backspace. Unless delete is a printing +; character, we just need to print a backspace. (we'll output clrspc +; afterwards) +; For Kaypro and Vector General, delete puts a blotch on the screen. +; For Apple and Osborne 1, delete moves but doesn't print. +delchr: +IF advant ;[22] + ret +ENDIF;advant +IF NOT (advant );[22] + mvi e,bs ;get a backspace + jmp outcon +ENDIF;NOT (advant) [22] + +; erase the character at the current cursor position +clrspc: mvi e,' ' + call outcon + mvi e,bs ;get a backspace + jmp outcon + +; erase the current line +clrlin: lxi d,eralin + jmp prtstr + +; erase the whole screen, and go home. preserves b (but not c) +clrtop: lxi d,erascr + jmp prtstr + + +IF norths +sysver: db 'Northstar Horizon$' +ENDIF;norths + +IF basicns ;[29] +sysver: db 'Northstar using printer port$' +ENDIF ;basicns [29] + +IF comart ;[25] +sysver: db 'Comart Communicator$' +ENDIF;comart + +IF horizon ;[25] +sysver: db 'Northstar Horizon$' +ENDIF;horizon + +IF advant ;[22] +sysver: db 'North Star Advantage$' +outlin: db 04H,cr,lf,tab,'$' +erascr: db 04H,'$' ;Clear screen and go home. +eralin: db cr,0EH,'$' ;Clear line. +curldn: db esc,'=$' ;cursor leadin +ttab: ;Table start location. +ta: db 0BH,'$',0,0 ;Cursor up. +tb: db 0AH,'$',0,0 ;Cursor down. +tc: db 0CH,'$',0,0 ;Cursor right. +td: db bs,'$',0,0 ;Cursor left +te: db 04H,'$',0,0 ;Clear display +tf: db 12H,'$',0,0 ;Enter Graphics Mode +tg: db 13H,'$',0,0 ;Exit Graphics mode +th: db 1EH,'$',0,0 ;Cursor home. +ti: db 0BH,'$',0,0 ;Reverse linefeed. +tj: db 0FH,'$',0,0 ;Clear to end of screen. +tk: db 0EH,'$',0,0 ;Clear to end of line. +ENDIF;[22] advant +IF lasm AND (NOT advant) +LINK CPXVDU.ASM +ENDIF ;lasm - m80 will INCLUDE CPXVDU.ASM + +IF lasm ; here if not a terminal selected and in LASM +ovlend equ $ + END +ENDIF ;lasm diff --git a/cpxpcw.asm b/cpxpcw.asm index 554fd61..5bb76c1 100644 --- a/cpxpcw.asm +++ b/cpxpcw.asm @@ -1,912 +1,912 @@ -IF NOT lasm -.printx * CPXPCW.ASM * -ENDIF ;NOT lasm -; -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.08 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; This file contains the system-dependent code and data for KERMIT -; on the Amstrad range of personal computers. -; -; -; Revision history: -; -;edit 9, 22-Jan-1991 by MF. Added "sysinit" code at "init04" from Kermit -; version 4.08 which had been left out of version 4.09 to reserve -; space for the Amstrad's I/O buffers. Amstrad Kermit now stores -; files correctly (version 4.09 had garbled files). Again, -; this fix comes from Mr. D. P. Arnot of the Scottish Agricultural -; College in the UK. -;edit 8, 16-Jan-1991 by MF. Added a "bs" left out of "delstr" per -; instruction from David P. Arnot of Scottish Agricultural -; College, Auchincruive, Ayr, UK. -; E-mail: -; 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 ?, 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: ,,, and 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: +; 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 ?, 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: ,,, and are always discarded. +; +sysflt: + mov a,e ; get character for testing + ret +; +; system-dependent processing for BYE command. +; +sysbye: + ret + +; +; This is the system-dependent command to change the baud rate. +; DE contains the two-byte value from the baud rate table; this +; value is also stored in 'speed'. +; +sysspd: + push d ; move to HL for firmware + pop h + mov a,h ; if h=0 then Prestel rates + ora a + jnz spd01 ; if not 1200/75 then skip + lxi h,0802H ; else set 1200/75 into HL + jmp spd03 ; jump to normal setup + +spd01: cpi 11h ; if h=11h then reverse Prestel + jnz spd02 ; if not 75/1200 then skip + lxi h,0208h ; else set 75/1200 into HL + jmp spd03 ; jump to normal setup + +spd02: cpi 10h ; if h=10h then 31250 baud + jnz spd03 ; if not 31250 then skip to normal setup + mvi a,36h ; set 8253 for mode 2 binary count + lxi b,ctcmod ; output to CTC mode register + dw outc + lxi b,ctc0 ; select transmit clock + mov a,4 ; timer value for 31250 (04h) + dw outc + mov a,0 ; timer value for 31250 (04h) + dw outc + lxi b,ctc0 ; select receive clock + mov a,4 ; timer value for 31250 (04h) + dw outc + mov a,0 ; timer value for 31250 (04h) + dw outc + ret + +spd03: call userf ; set whatever we have now... + dw sabaud ; using BIOS routine + ret + +; +; Speed tables +; (Note that speed tables MUST be in alphabetical order for later +; lookup procedures, and must begin with a value showing the total +; number of entries. The speed help tables are just for us poor +; humans. +; +; db string length,string,divisor (2 identical bytes or 1 word) +; +spdtbl: db 12h ;18 entries + db 03h,'110$', 03h,03h + db 04h,'1200$', 08h,08h + db 07h,'1200/75$', 00h,00h ; real values faked up when required + db 05h,'134.5$', 04h,04h + db 03h,'150$', 05h,05h + db 04h,'1800$', 09h,09h + db 05h,'19200$', 0fh,0fh + db 04h,'2400$', 0ah,0ah + db 03h,'300$', 06h,06h + db 05h,'31250$',10h,10h ; flag to direct setup routine + db 04h,'3600$', 0bh,0bh + db 04h,'4800$', 0ch,0ch + db 02h,'50$', 01h,01h + db 03h,'600$', 07h,07h + db 04h,'7200$', 0dh,0dh + db 02h,'75$', 02h,02h + db 07h,'75/1200$',11h,11h ; real values faked up when required + db 04h,'9600$', 0eh,0eh + +sphtbl: db cr,lf,lf + db 'Normal rates: 50 75 110 134.5 150 300 600' + db cr,lf + db ' 1200 1800 2400 3600 4800 7200 9600 19200' + db cr,lf,lf + db 'High speed : 31250 (only between Amstrads)' + db cr,lf,lf + db 'Split rates : 1200/75 (Rx=1200, Tx= 75)' + db cr,lf + db ' 75/1200 (Rx= 75, Tx=1200)' + db cr,lf,'$' + +; +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +; +sysprt: + ret + +prttbl equ 0 ; SET PORT is not supported +prhtbl equ 0 + +; +; selmdm - select modem port +; selcon - select console port +; selmdm is called before using inpmdm or outmdm; +; selcon is called before using inpcon or outcon. +; preserves bc, de, hl. +; +selmdm: +selcon: + ret + +; +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: + call bcnst ; get console status + ora a ; anything there? + rz ; no, forget it + jmp bcnin ; yes, get the character + +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: + mov a,e ; TAB? + cpi tab + jz out001 + mov c,e ; set correct arg register + jmp bcnot ; output to console via BIOS [obs was bcnout] + +; +; perform tab expansion ourselves +; +out001: call userf ; get column in L + dw teask + mov a,l ; a <- column 0..n + ani 7 ; column 0..7 + xri 0FFh ; not(col 0..7) + adi 9 ; a is 8-(colf7) +out002: ora a ; any left? + rz ; return if not + dcr a ; one less now, anyhow + push psw ; save over BIOS call (just in case) + mvi c,' ' ; print one space + call bcnot ;[obs was bcnout] + call suck ; in case any stuff coming in + pop psw ; fetch count back + jmp out002 ; and go round again + +; +; outmdm - output a char from E to the modem. +; the parity bit has been set as necessary. +; returns nonskip; bc, de, hl preserved. +outmdm: +IF cpc + push b ; save BC for CPC 16 bit I/O +ENDIF +outmd1: + call xsuck ; keep checking for incoming characters +IF pcw + in mnprts ; get the output done flag. +ENDIF +IF cpc + lxi b,mnprts + dw inpc ; IN A,(C) +ENDIF + ani output ; is it set? + jz outmd1 ; if not, loop until it is. + mov a,e +IF pcw + out mnport ; output it. +ENDIF +IF cpc + lxi b,mnport + dw outc ; OUT (C),A + pop b ; restore BC +ENDIF + ret + +; +; get character from modem; return zero if none available. +; destroys bc, de, hl. +; +inpmdm: + call suck ; get any characters pending + lhld sioct ; count of chars in buffer + mov a,h ; or together to get result + ora l + rz ; not got any, return now + + dcx h ; down count + shld sioct + + lhld siord ; read pointer + mov c,m ; fetch character ** NB TO C FOR NOW ** + + lxi d,1-ovlend ; bump pointer, subtract base + dad d + mov a,h ; mask high byte of offset + ani siomsk/256 + mov h,a + lxi d,ovlend ; add in base again + dad d + shld siord + + mov a,c ; get to proper register + ret + +; +; flsmdm - flush comm line. +; Modem is selected. +; Currently, just gets characters until none are available. + +flsmdm: call inpmdm ; Try to get a character + ora a ; Got one? + jnz flsmdm ; If so, try for another + ret ; Receiver is drained. Return. + +; +; SIO input buffer handling. The buffer pointers are held as pointers into +; the buffer. The read pointer +; is to the next unused character, the write pointer to the next unused space. +; +siord: dw ovlend ; next char to read +siowr: dw ovlend ; next char to write +sioct: dw 0 ; number in buffer + +xsuck: push d ; save regs version of suck + push b + push h + call suck + pop h + pop b + pop d + ret + +; +; suck +; +; this routine is called whenever it would be possible that some +; characters might be available in the SIO device; they are all +; transferred (there may be up to 4 pending) to the buffer. +; +; all registers are destroyed +; +suck: +IF pcw + call baxist ; check input status via BDOS + ora a ; check if zero +ENDIF +IF cpc + lxi b,mnprts ; get input status directly + dw inpc ; IN A,(C) + ani input ; mask for Rx ready +ENDIF + rz ; return if no + +IF pcw + call baxin ; fetch character via BDOS +ENDIF +IF cpc + lxi b,mnport ; fetch character directly from SIO + dw inpc ; IN A,(C) +ENDIF + + lhld siowr ; write pointer + mov m,a ; put character + + lxi d,1-ovlend ; take off base, bump pointer + dad d + mov a,h ; top byte of offset + ani siomsk/256 ; masked off + mov h,a + lxi d,ovlend ; add on base again + dad d + shld siowr ; replace pointer + + lhld sioct ; bump count in buffer + inx h + shld sioct + + jmp suck ; go round in case any more + +; +; outlpt - output character in E to printer +; console is selected. +; preserves de. +outlpt: + push d ; save DE in either case + mov c,e ; correct arg register + call blist + pop d ; restore saved register pair + ret + +; +; Screen manipulation routines +; csrpos - move to row B, column C +; +; csrpos for terminals that use a leadin sequence followed +; by (row + 31.) and (column + 31.) +; or (row) and (column) +; +csrpos: push b ; save coordinates + lxi d,curldn ; get cursor leadin sequence + call prtstr ; print it + pop h ; restore coordinates + mov a,h ; get row + adi (' '-1) ; space is row one + mov e,a + push h + call outcon ; output row + pop h + mov a,l ; get column + adi (' '-1) ; space is column one + mov e,a + jmp outcon ; output it and return + +; +; delchr - make delete look like a backspace. Unless delete is a printing +; character, we just need to print a backspace. (we'll output clrspc +; afterwards) +; For Kaypro and Vector General, delete puts a blotch on the screen. +; For Apple and Osborne 1, delete moves but doesn't print. +delchr: +IF pcw ;[6] OBS for Phillip Wade + lxi d,delstr ;[5] send a string rather than a single character + call prtstr + +delstr: db bs,' ',bs,'$' ;[OBS] Was bs,space,bs,bs +ENDIF ;pcw + + mvi e,bs ;get a backspace + jmp outcon + +; erase the character at the current cursor position +clrspc: mvi e,' ' + call outcon + mvi e,bs ;get a backspace + jmp outcon + +; erase the current line +clrlin: lxi d,eralin + jmp prtstr + +; erase the whole screen, and go home. preserves b (but not c) +clrtop: lxi d,erascr + jmp prtstr + + +IF pcw +sysver: db 'Amstrad PCW with SIO option$' +ENDIF +IF cpc +sysver: db 'Amstrad CPC with CP/M Plus$' +ENDIF + +outlin: db esc,'H',esc,'J',cr,lf,' $' + +erascr: db esc,'H',esc,'J$' ;Clear screen and go home. +eralin: db cr,esc,'K$' ;Clear line. +curldn: db esc,'Y$' ;cursor leadin +ttab: ;Table start location. +ta: db esc,'A$',0 ;Cursor up. +tb: db esc,'B$',0 ;Cursor down. +tc: db esc,'C$',0 ;Cursor right. +td: db esc,'D$',0 ;Cursor left +te: db esc,'E$',0 ;Clear display +tf: db '$',0,0,0 ;Enter Graphics Mode +tg: db '$',0,0,0 ;Exit Graphics mode +th: db esc,'H$',0 ;Cursor home. +ti: db esc,'I$',0 ;Reverse linefeed. +tj: db esc,'J$',0 ;Clear to end of screen. +tk: db esc,'K$',0 ;Clear to end of line. + +ovlend equ $ ; End of overlay + + END diff --git a/cpxpro.asm b/cpxpro.asm index 9099b04..015ba05 100644 --- a/cpxpro.asm +++ b/cpxpro.asm @@ -1,561 +1,561 @@ -IF NOT lasm -.printx * CPXPRO.ASM * -ENDIF ;NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; revision history: -; -;edit 2, 16-Oct-1990 by MF. Reformatted speed tables according to -; current usage and reworked sysspd routine accordingly. -; Also eliminated cursor-positioning routines as we now link to -; cpxvdu.asm. Reworked version message according to current usage. -;edit 1, 17 November, 1987, by OBSchou. Extracted Compupro code -; from CPMPRO.ASM and massaged fort CP/M kermit V4.09 -; -; Modifications to KERMIT-80 for use with Compupro Interfacer 3/4 "[gv]" -; -; Guy Valiquette, M.D. -; Black Bldg. Rm 322 -; Dept. of Neurology -; College of Physicians & Surgeons -; Columbia University -; 630 W. 168th Street -; New York, NY 10032 -; (212) 694-3965 -; -; I/O routines for Interfacer 3/4 board -; Allow sending break with 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 ?, 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: ,,, and 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 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 ?, 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: ,,, and are always discarded. +sysflt: + mov a,e ; get character for testing + ret + +; mdmflt - modem filter [30] +; called with character to be sent to printer in E +; with parity set as appropriate. +; return with accumulator = 0 do do nothing, +; <> 0 to send char in E. +mdmflt: + mov a,e ;[30] get character to test + ret + + +; prtflt - printer filter [30] +; called with character to be sent to printer in E +; returns with a = 0 to do nothing +; a <> 0 to print it. +; +; this routine for those printer that automatically insert +; a lf on cr, or cr for lf. Should this be shifted to +; the system indep. stuff, in say 4.06? +prtflt: + mov a,e ; [30] get character to test + ret + + +; +; +; system-dependent processing for BYE command. +; for apmmdm, heath, and lobo, hang up the phone. +sysbye: + + call hangup + ret +; +; This is the system-dependent command to change the baud rate. +; DE contains the two-byte value from the baud rate table; this +; value is also stored in 'speed'. +sysspd: + + +IF compro + lda speed ;[MF]Get requested baud-rate + mov b,a ;Save the number. + lxi h,baudrt ;point to current baud rate + mov a,m ;get it + ani 0f0h ;keep high nibble + ora b ;merge back baud rate + mov m,a ;store back + xra a ;clear A + sta ckdialf ;put up flag to force reinitialization + ret ;...at next connect + +ENDIF;compro + + +; + +; Speed tables +; (Note that speed tables MUST be in alphabetical order for later +; lookup procedures, and must begin with a value showing the total +; number of entries. The speed help tables are just for us poor +; humans. + +; db string length,string,divisor (2 identical bytes or 1 word) +; [Toad Hall] + +spdtbl: db 8 ;[MF]8 entries in speed table + db 3,'110$' + db 02h,02h ;[MF]110 baud + db 4,'1200$' + db 07h,07h ;[MF]1200 baud + db 5,'134.5$' + db 03h,03h ;[MF]134.5 baud + db 3,'150$' + db 04h,04h ;[MF]150 baud + db 4,'1800$' + db 08h,08h ;[MF]1800 baud + db 5,'19200$' + db 0fh,0fh ;[MF]19200 baud + db 4,'2000$' + db 09h,09h ;[MF]2000 baud + db 4,'2400$' + db 0ah,0ah ;[MF]2400 baud + db 3,'300$' + db 05h,05h ;[MF]300 baud + db 4,'3600$' + db 0bh,0bh ;[MF]3600 baud + db 4,'4800$' + db 0ch,0ch ;[MF]4800 baud + db 2,'50$' + db 00h,00h ;[MF]50 baud + db 3,'600$' + db 06h,06h ;[MF]600 baud + db 4,'7200$' + db 0dh,0dh ;[MF]7200 baud + db 2,'75$' + db 01h,01h ;[MF]75 baud + db 4,'9600$' + db 0eh,0eh ;[MF]9600 baud + +sphtbl: db cr,lf,'50 75 110 134 150 300 600 1200' + db cr,lf,'1800 2000 2400 3600 4800 7200 9600 19200$' + +ckdialf:db 0 ;force UART initialization on entry +baudrt: db 0011$0111b ;default baud rate: 1200 baud +moderg1:db 0100$1110b ;default mode register 1: + ; -asynch, 8 data bits, 1 stop bit, + ; -parity odd, disabled +moderg2 EQU baudrt +ENDIF;compro +; + +; +; The following conditionals were once a huge if not statement. There +; wasn't enough room to add the lobo to the list, so it had to be broken +; into 2, which you can't do with an if not. I redid it as two ifs and +; applied them to those that wouldn't set baud. [Hal Hostetler] +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +sysprt: + ret +; +; +; Port table not applicable +prttbl EQU 0 +prhtbl EQU 0 ; + +; +; +; selmdm - select modem port +; selcon - select console port +; selmdm is called before using inpmdm or outmdm; +; selcon is called before using inpcon or outcon. +; For iobyt systems, diddle the I/O byte to select console or comm port; +; For Decision I, switches Multi I/O board to console or modem serial +; port. [Toad Hall] +; For the rest, does nothing. +; preserves bc, de, hl. +selmdm: + ret + +selcon: + ret +; +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: + mvi c,dconio ;Direct console I/O BDOS call. + mvi e,0FFH ;Input. + call BDOS + ret +; +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: + mvi c,dconio ;Console output bdos call. + call bdos ;Output the char to the console. + ret +; +; +; outmdm - output a char from E to the modem. +; the parity bit has been set as necessary. +; returns nonskip; bc, de, hl preserved. +outmdm: +;************************System Dependent**************************** +; +; Addition by [gv], 16/7/84 +; Return the status of the modem port: +; Z flag set if NO input available +; C flag set in NOT output ready +; Destroys A and flags, preserves all other registers +; +stchr: + di + mvi a,user + out usersel + in stat + ani output + in stat + ei + jz outmdm ;not output ready, try again +; else... + di ;no interrupts + mvi a,user + out usersel + mov a,e ;get back character + out datap + ei + ret + +; + +; +; +; get character from modem; return zero if none available. +; for IOBYT systems, the modem port has already been selected. +; destroys bc, de, hl. +inpmdm: +; + di + mvi a,user + out usersel + in stat + ei + ani input ;test for input status (C flag reset by ANI n) + rz ; no input available +; +;************************System Dependent**************************** +; +; Addition by [gv], 16/7/84 +; get a character "raw" (i.e. just get it in A) +; +; Note: MUST have character ready before call, use stchr + mvi a,user + di + out usersel + in datap + ei + ret +; +; + +; +; flsmdm - flush comm line. +; Modem is selected. +; Currently, just gets characters until none are available. + +flsmdm: call inpmdm ; Try to get a character + ora a ; Got one? + jnz flsmdm ; If so, try for another + ret ; Receiver is drained. Return. + + +; +; +; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not. +lptstat: + xra a ; assume it is ok.. this may not be necessary + ret +; +; +; outlpt - output character in E to printer +; console is selected. +; preserves de. +outlpt: + push d ; save DE in either case + call prtflt ; go through printer filter [30] + ana a ; if A = 0 do nothing, + jz outlp1 ; [30] if a=0 do nothing + mvi c,lstout + call bdos ;Char to printer +outlp1: pop d ; restore saved register pair + + + +IF inout +prtout: +ENDIF ;inout +IF compro AND inout + di + mvi a,user + out usersel + in stat + ei +ENDIF;compro AND inout +IF (NOT compro) AND inout + in mnprts ;Get the output ready flag. +ENDIF;(NOT compro) AND inout +IF inout + ani output ;Is it set? + jz prtout ;If so, loop until it isn't. +ENDIF ;inout +IF compro AND inout + di + mvi a,user + out usersel + mov a,e + out datap + ei +ENDIF;compro AND inout +IF (NOT compro) AND inout + mov a,e ;Get the char to output. +prtou2: out mnport ;Output it. +ENDIF;(NOT compro) AND inout + ret + + +; + +; +; Screen manipulation routines +; +; delchr - make delete look like a backspace. Unless delete is a printing +; character, we just need to print a backspace. (we'll output clrspc +; afterwards) +; For Kaypro and Vector General, delete puts a blotch on the screen. +; For Apple and Osborne 1, delete moves but doesn't print. +delchr: + mvi e,bs + call outcon + +; erase the character at the current cursor position +clrspc: mvi e,' ' + call outcon + mvi e,bs ;get a backspace + jmp outcon + +; erase the current line +clrlin: lxi d,eralin + jmp prtstr + +; erase the whole screen, and go home. preserves b (but not c) +clrtop: lxi d,erascr + jmp prtstr + + +IF compro; [gv] +sysver: db '[Compupro IF4-',user+'0',']$' +ENDIF;compro + +IF lasm +LINK CPXVDU.ASM +ENDIF ;lasm diff --git a/cpxsb.asm b/cpxsb.asm index 3beefe7..18056d4 100644 --- a/cpxsb.asm +++ b/cpxsb.asm @@ -1,696 +1,696 @@ -IF NOT lasm -.printx * CPXSB.ASM * -ENDIF ;NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file created 16 July, 1987 by OBSchou from code submitted -; by William Rose for the Micromint SB180 systems (as featured in -; BYTE magazine, 1986). This file has been modified to fit in with -; Kermit-80 V4.08 etc. His file KERSYS.ASM is a stripped down version -; of CPXSYS.ASM (formerly CP4SYS.ASM). -; -; revision history: -; KERSYS.ASM - version 0.8 dated 13 Jul 87. -; -; Cutdown CP4SYS.ASM for SB-180/Ampro 230. -; -; -; While this is a single CPU version (to ease editing) the assembler -; conditionals have been kept to identify machine specific code. -; -; Note that the baud setting routine also sets parity, but this does not -; change the parity given by Kermit's 'stat' command. I assume that the -; main body of the program does its own parity check. -; -; Revision history (last entry first) -; -; edit 2, 22 July by OBSchou to massage file to fit with CPXCOM.ASM. -; -; edit 1, 15 July, 1987 by OBSchou for William Rose who submitted -; the code for Kermit-80 V 4.05. Modified code as appropriate -; for 4.08 compatability. -; - -delfac EQU 150 ; Delay factor in SB-180 input loop - a fudge - -; -; Keep module name, edit number, and last revision date in memory. -; -;sysedt: db 'KERSYS.ASM (03) 12-FEB-87 $' ; last SB-180 revision -;sysedt: db 'KERSYS.ASM (04) 12-APR-87 $' ; Telecom Merlin added -;sysedt: db 'KERSYS.ASM (5) 9-May-87 $' ; Minor tidying -;sysedt: db 'KERSYS.ASM (6A) 17-Jun-87 $' ; BT Merlin M2215 only -;sysedt: db 'KERSYS.ASM (7) 19-Jun-87 $' ; SB-180 only -;sysedt: db 'KERSYS.ASM (8) 13-Jul-87 $' ; 6/9 MHz version -family: db 'CPXSB.ASM (2) 22-Jul-87$' ; First entry for V4.08/9 - -; -; Assembly time message to let me know I'm building the right version. -; - -IF sb180 -.printx * Assembling Kermit-80 for Micromint SB-180 * -ENDIF - - -IF sb180 -mnctrla EQU 000H ;Modem control port - CNTLA0 -mnctrlb EQU 002H ;Modem control port - CNTLB0 -mnstat EQU 004H ;Modem status port - STAT0 -mntxdat EQU 006H ;Modem output port - TDR0 -mnrddat EQU 008H ;Modem input port - RDR0 -output EQU 002H ;Transmit data register empty mask - TDRE -input EQU 080H ;Receive data register full mask - RDRF -z80 EQU TRUE ;This one's an HD64180, but Z80 will do -ENDIF - - -sysxin: ; continuation of system initialisation from sysinit - -IF sb180 - lxi h, porbuf ; park the original settings - db 0EDh, 038h, mnctrla ; HD64180 code IN0 g,(m) - mov m, a - inx h - db 0EDh, 038h, mnctrlb - mov m, a - inx h - db 0EDh, 038h, mnstat - mov m, a -ENDIF - ; re-initialise for KERMIT -IF sb6 - mvi h, 08h ; 0000$1001 - 9600 baud, (even) parity - mvi l, 08h ; 'speed' is two bytes -ENDIF - -IF sb9 - mvi h, 21h ; 0010$0001 - 9600 baud, (even) parity - mvi l, 21h ; 'speed' is two bytes -ENDIF - -IF sb180 - shld speed - lxi h, parind - mvi m, 8 ; index for 8 bits, no parity, 2 stop - call setpor -ENDIF - - ret - -porbuf: ds 3 ; original port settings - -; -; system-dependent KERMIT termination processing -; If we've changed anything, this is our last chance to put it back. -; -sysexit: - -IF sb180 - lxi h, porbuf - mov a, m ; output parity - db 0EDh, 039h, mnctrla ; HD64180 code OUT0 (m),g - inx h - mov a, m ; output baud rate - db 0EDh, 039h, mnctrlb - inx h - mov a, m ; output to clear error flags - db 0EDh, 039h, mnstat - ; read twice to reset DCD0 ? - db 0EDh, 038h, mnstat - db 0EDh, 038h, mnstat -ENDIF - - ret - -; -; system-dependent processing for start of CONNECT command -; -syscon: - ret - -conmsg: ; Messages printed when entering transparent (CONNECT) mode: - - db '$' - -; -; syscls - system-dependent close routine -; called when exiting transparent session. -; -syscls: - ret - -; -; sysinh - help for system-dependent special functions. -; called in response to ?, 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: ,,, and 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 ?, 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: ,,, and are always discarded. +; +sysflt: + mov a,e ; get character for testing + ret + +; +; mdmflt - modem filter +; called with character to be sent to printer in E +; with parity set as appropriate. +; return with accumulator = 0 do do nothing, +; <> 0 to send char in E. +mdmflt: + mov a,e ; get character to test + ret + +; +; prtflt - printer filter +; called with character to be sent to printer in E +; returns with a = 0 to do nothing +; a <> 0 to print it. +; +; this routine for those printer that automatically insert +; a lf on cr, or cr for lf. Should this be shifted to +; the system indep. stuff, in say 4.06? +; +prtflt: + mov a,e ; get character to test + +IF FALSE ; strip out lf from printer stream + ani 7fh ; make sure it is parity less + cpi lf ; is it a line feed? + rnz ; no, print it +; xra a ; yes, don't. + +ENDIF + + ret + +; +; system-dependent processing for BYE command. +; +sysbye: + ret + +; +; This is the system-dependent command to change the baud rate. +; DE contains the two-byte value from the baud rate table; both +; bytes of this value are also stored in 'speed'. +; +sysspd: + +IF sb180 + lxi d, prtmsg ; ask for variables + call prtstr + + lxi d, tbuf ; get suitable string + mvi c, 10 + call bdos + + lxi h, tbuf1 + mov a, m + ora a + jz setpor ; leave unchanged if string zero length + + cpi 3 ; check given length + jnz spd1 ; error - wrong length + inx h + inx h + mov a, m + ani 137O ; convert parity code to upper case + mov m, a + + lxi d, tbuf1 ; get index of given parameter + lxi h, parstr + call sposn + ora a + jnz spd2 ; or fall through if error +spd1: lxi d, invmsg ; invalid input - try again + call prtstr + jmp sysspd + +spd2: adi 3 ; get index to parval table + rrc ; by dividing by 4 + rrc + ani 15 ; mask out high bits + lxi h, parind + mov m, a ; and store it + call setpor ; set up port iaw index and speed bytes + + ret + +prtmsg: db cr,lf,'Enter bit/char, parity, and stop bits required.' + db cr,lf,'(Bit 7/8 Parity N/O/E Stop 1/2 - CR same) : $' +invmsg: db cr,lf,'Invalid parameters$' + +parind: db 8 ; default <8N2> index +parstr: db 48,'7N1$7N2$7O1$7O2$7E1$7E2$' + db '8N1$8N2$8O1$8O2$8E1$8E2$' +parval: db 0,1,16+2,16+3,2,3 + db 4,5,16+6,16+7,6,7 +tbuf db 6 +tbuf1 db 3,'8N2','$$$$' + +; +; Set up the port using the table index in parind and the speed byte +; +setpor: + lxi h, parind + mov a, m + dcr a + lxi h, parval ; table base + mvi b, 0 + mov c, a + dad b ; HL points at parameter value + mov a, m + mov b, a ; park parval + + ani 16 ; the parity switch bit + lxi h, speed + add m ; this is now the baud rate byte + mov c, a ; park it + + mov a, b ; sort out the parameter byte + ani 7 ; b/p/s only wanted + adi 96 ; RE, TE enable + db 0EDh,039h,mnctrla ; output parity etc. + mov a, c + db 0EDh,039h,mnctrlb ; output baud rate + mvi a, 0 + db 0EDh,039h,mnstat ; clear status + db 0EDh,038h,mnstat ; read twice to reset DCD0 + db 0EDh,038h,mnstat + ret + +; +; Find substring position - Leventhal page 293, modified +; enter with subtring in DE and string in HL +; returns index in A or 0 for failure +; +sposn: + mov a, m ; exit if either string length zero + ora a + jz notfnd + sta slen + mov b, a + inx h + shld string + xchg + mov a, m + ora a + jz notfnd + sta sublen + mov c, a + inx h + shld substg + mov a, b + +; no of searches = stringlen - substrlen + 1 +; if substr longer than string quit immediately + + sub c + jc notfnd + inr a + mov c, a + xra a + sta index + +; search until remaining string shorter than substring + +slp1: lxi h, index + inr m + lda sublen + mov b, a + lhld substg + xchg + lhld string + +; try to match substring starting at index + +cmplp: ldax d + cmp m + jnz slp2 + dcr b + jz found + inx h + inx d + jmp cmplp + +; arrive here if match fails + +slp2: dcr c + jz notfnd + lhld string + inx h + shld string + jmp slp1 + +; found, return index + +found: lda index + ret + +; not found, return zero + +notfnd: sub a + ret + +string: ds 2 +substg: ds 2 +slen: ds 1 +sublen: ds 1 +index: ds 1 +ENDIF + + ret + +; +; Speed tables +; (Note that speed tables MUST be in alphabetical order for later +; lookup procedures, and must begin with a value showing the total +; number of entries. The speed help tables are just for us poor +; humans. +; +; db string length, string, divisor (2 bytes or 1 word, ab) +; the data byte a is return in A and E, and b in D +; only byte 'a' is the key for the table + +IF sb6 +spdtbl: db 9 ; 9 entries + db 04h,'1200$', 0Bh,0Bh + db 03h,'150$', 0Eh,0Eh + db 05h,'19200$', 01h,01h + db 04h,'2400$', 0Ah,0Ah + db 03h,'300$', 0Dh,0Dh + db 05h,'38400$', 00h,00h + db 04h,'4800$', 09h,09h + db 03h,'600$', 0Ch,0Ch + db 04h,'9600$', 08h,08h + +sphtbl: db cr,lf + db ' 150 300 600 1200 2400 4800 9600 19200 38400$' +ENDIF + +IF sb9 +spdtbl: db 7 ; 7 entries + db 04h,'1200$', 24h,24h + db 05h,'19200$', 20h,20h + db 04h,'2400$', 23h,23h + db 03h,'300$', 26h,26h + db 04h,'4800$', 22h,22h + db 03h,'600$', 25h,25h + db 04h,'9600$', 21h,21h + +sphtbl: db cr,lf + db ' 300 600 1200 2400 4800 9600 19200$' +ENDIF + + +; +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +; +sysprt: + ret + +IF sb180 +prttbl EQU 0 ; SET PORT is not supported +prhtbl EQU 0 +ENDIF + +; +; selmdm - select modem port +; selcon - select console port +; selmdm is called before using inpmdm or outmdm; +; selcon is called before using inpcon or outcon. +; For iobyt systems, diddle the I/O byte to select console or comm port; +; For the rest, does nothing. +; preserves bc, de, hl. +; +selmdm: + ret + +selcon: + ret + +; +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: + mvi c,dconio ;Direct console I/O BDOS call. + mvi e,0FFH ;Input. + call BDOS + + ret + +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: + mvi c,dconio ;Console output bdos call. + call bdos ;Output the char to the console. + + ret + +; +; outmdm - output a char from E to the modem. +; the parity bit has been set as necessary. +; returns nonskip; bc, de, hl preserved. +; +outmdm: + +IF sb180 + db 0EDh,038h,mnstat + ani output ; check status + jz outmdm ; wait until port is available + mov a, e + db 0EDh,039h,mntxdat ; transmit +ENDIF + + ret + +; +; get character from modem; return zero if none available. +; for IOBYT systems, the modem port has already been selected. +; destroys bc, de, hl. +; +inpmdm: + +IF sb180 + lxi h, delfac ; loops to give delay +inpm1: db 0EDh,038h,mnstat + ani input ; check status + jz inpm2 + db 0EDh,038h,mnrddat ; get a byte + ret + +inpm2: dcx h ; no data + mov h, a + ora l + jnz inpm1 ; still tries left + ret ; with zero in A +ENDIF + + ret + +; +; flsmdm - flush comm line. +; Modem is selected. +; Currently, just gets characters until none are available. +; +flsmdm: + call inpmdm ; Try to get a character + ora a ; Got one? + jnz flsmdm ; If so, try for another + ret ; Receiver is drained. Return. + +; + +; +; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not. +lptstat: +IF iobyte ;[33] + call bprtst ; get status +ENDIF ;iobyte[33] +IF NOT iobyte ;[33] + xra a ; assume it is ok.. this may not be necessary +ENDIF ;iobyte [33] + ret +; +; outlpt - output character in E to printer +; console is selected. +; preserves de. +; +outlpt: + push d ; save DE in either case + call prtflt ; go through printer filter [30] + ana a ; if A = 0 do nothing, + jz outlp1 ; if a=0 do nothing + +outlp1: pop d ; restore saved register pair + ret + +; delchr - make delete look like a backspace. Unless delete is a printing +; character, we just need to print a backspace. (we'll output clrspc +; afterwards) +delchr: + + mvi e,bs ;get a backspace + jmp outcon + +; erase the character at the current cursor position +clrspc: mvi e,' ' + call outcon + mvi e,bs ;get a backspace + jmp outcon + +; erase the current line +clrlin: lxi d,eralin + jmp prtstr + +; erase the whole screen, and go home. preserves b (but not c) +clrtop: lxi d,erascr + jmp prtstr + +IF sb180 +sysver: db 'MicroMint SB 180 ' +ENDIF + +IF sb6 + db ' (6 MHz)' +ENDIF + +IF sb9 + db ' (9 MHz)' +ENDIF + db '$' + +IF lasm +LINK CPXVDU.ASM ; get terminal defs etc +ENDIF ;lasm diff --git a/cpxswt.asm b/cpxswt.asm index 32b0d11..1942c41 100644 --- a/cpxswt.asm +++ b/cpxswt.asm @@ -1,294 +1,294 @@ -IF NOT lasm -.printx * CPXSWT.ASM * -ENDIF ; NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file is a simple family or system file switcher, selecting -; one of several family files, or selectin CPXSYS.ASM (now modified) -; if a family file does not exist. -; -; -; revision history: -; -;edit 10, 7-Jan-1991 by MF. Added code by Jay S. Rouman to support the -; Ampro Little Board (see CPXBBI.ASM) and PRINTX for the HP-125. -; edit 9, 1st September 1990 by Russell Lang, rjl@monu1.cc.monash.edu.au. -; Added Microbee support. -; edit 8, 2 December by OBSchou. Added Z80MU "system" to allow kermit-80 -; debugging on a PC! -; -; edit 7, 27 October, 1987 by OBSchou. Added bits for Sanyo, Compupro, -; Genie and TRS-80 M4. -; -; edit 6, 16 July, 1987 for Will Rose, who has submitted code for -; Micromint SB180 (6 and 9 Mhz) and a BT Merlin (alias RAIR) -; -; edit 5, 15 July, 1987 by OBSchou for David Moore, who has submitted -; code for a Teletek SYSTEMASTER and for ADM22 terminals. -; -; edit 4, 14 July 1987 by OBSchou for JA Shearwood of Birmingham University, -; Chris Miles of Manchester University. Added a Cifer family file -; for John, and added a BigBoard-Kaypro-Xerox family file for Chris -; Finally, added in new family file for Heath, telcon, z100 and scntpr -; systems for Martin Carter of Nottingham University. -; -; edit 3, 6 April, 1986 by OBSchou. -; Added in switching for NCR Desision Mate V and Amstrad CPC 664/6128 -; systems. -; -; edit 2, March 16, 1987 by OBSchou. -; added in support for m80 macro assembler. -; -; edit 1 28 January, 1987 by OBSchou. -; Take out the series of printx etx and selection of systems and -; leave this with only the system dep. code for systems without -; a family file. Hopefully, this file will go alltogether in time. -; -; Keep module name, edit number, and last revision date in memory. -swtver: db 'CPXSWT.ASM (10) 7-Jan-1991 $' -; -; Assembly time message to let me know I'm building the right version. -; LASM generates an 'S' error along with the message, which is messy, but -; better than trying to put everything inside a IF m80 OR mac80 conditional, -; because LASM doesn't like nested IF's, either. - - -IF (torfam AND lasm) -;Link to the module with the code for Superbrains, Torch, Cifer and pci2651 -LINK CPXTOR.ASM ; also NCR DMV systems -ENDIF;(torfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM - -IF (ciffam AND LASM) -; Link to the Cifer family file. (Cifer code previously on CPXTOR.ASM) -LINK CPXCIF.ASM ; Cifer family file -ENDIF ;(ciffam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM - -IF (appfam AND lasm) ;[33] apple frogs as a separate family.. -; Link to the APPLE family... -LINK CPXAPP.ASM -ENDIF ;(appfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM - -IF (norfam AND lasm); Link to the Northstar family (and Comart) -; Link to the NorthStar family file -LINK CPXNOR.ASM -ENDIF; (norfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM - -IF (pcwfam AND lasm) ;[35] Amstrad PCW 8256/8512 or CPC systems -; Link to the Amstrad PCW family -LINK CPXPCW.ASM -ENDIF ;(cpwfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM - -IF (bbifam AND lasm) ;Bigboard, Kaypro and Xerox 820 file -; Link to the Bigboard family -.printx * Linking to the BigBoard family * -LINK CPXBBI.ASM -ENDIF ;(bbifam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM - -IF (heafam AND lasm) ; heath, z100, telcon, and scntpr systems -; Link to the Heath-telcon-screentyper family -.printx * Linking to the Heath-telcon-screentyper family * -LINK CPXHEA.ASM -ENDIF ;(heafam) - m80 use: INCLUDE from CPXTYP.ASM - -IF (sbfam AND lasm) -; Link to the SB180 Family file -,printx * Linking to the SB180 Family file * -LINK CPXSB.ASM -ENDIF ; (sbfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM - -IF (m2215 AND lasm) -; Link to the RAIR/ BT Merlin code -.printx * Linking to the Merlin/Rair code * -LINK CPXMRL.ASM -ENDIF ; (m2215 AND lasm) - m80 use: INCLUDE from CPXTYP.ASM - -IF (sanfam AND lasm) -; Link to the Sanyo code -.printx * linking to the sanyo code * -LINK CPXSYO.ASM -ENDIF ; (sanfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM - -IF (comfam AND lasm) -; Link to the compupro code -.printx * linking to the Compupro code * -LINK CPXPRO.ASM -ENDIF ; (comfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM - -IF (genfam AND lasm) -; Link to the Genie family code -.printx * linking to the Genie code * -LINK CPXGNI.ASM -ENDIF ; (genfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM - -IF (trsfam AND lasm) -; Link to the TRS-80 family file -.printx * linking to the TRS family file* -LINK CPXTM4.ASM -ENDIF ; (trsfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM - -IF (z80fam AND lasm) -; Link to the Z80MU family file -.printx * linking to the Z80MU family file* -LINK CPXZ80.ASM -ENDIF ; (z80fam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM - -IF (beefam AND lasm) -; Link to the Microbee family file -.printx * linking to the Microbee family file * -LINK CPXBEE.ASM -ENDIF ; (beefam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM - - -; If we have come here, we are assembling the CPXSYS.ASM file - -IF robin -.printx * Assembling KERMIT-80 for the DEC VT180 * -ENDIF - -IF vector -.printx * Assembling KERMIT-80 for the Vector Graphics * -ENDIF - -IF osi -.printx * Assembling KERMIT-80 for the Ohio Scientific * -ENDIF - -IF heath -.printx * Assembling KERMIT-80 for the Heath/Zenith 89 * -ENDIF - -IF z100 -.printx * Assembling KERMIT-80 for the Heath/Zenith Z100 * -ENDIF - -IF trs80 -.printx * Assembling KERMIT-80 for the TRS-80 II * -ENDIF - -IF osbrn1 -.printx * Assembling KERMIT-80 for the Osborne 1 * -ENDIF - -IF telcon -.printx * Assembling KERMIT-80 for the Telcon Zorba * -ENDIF - -IF dmII -.printx * Assembling KERMIT-80 for the DECmate II * -ENDIF - -IF gener -.printx * Assembling Generic KERMIT-80 * -ENDIF - -IF cpm3 -.printx * Assembling Generic KERMIT-80 for CP/M 3.0 * -ENDIF - -IF hp125 -.printx * Assembling Kermit-80 for the HP-125 Series 100 * -ENDIF ;hp125 - -IF kpii -.printx * Assembling Kaypro II KERMIT-80 * -ENDIF - -IF xer820 ;[pcc001] -.printx * Assembling Xerox 820 KERMIT-80 * -ENDIF ;[pcc001] - -IF bbII -.printx * Assembling BigBoard II KERMIT-80 * -ENDIF - -IF ampro -.printx * Assembling Ampro Little Board KERMIT-80 * -ENDIF - -IF mdI -.printx * Assembling for Morrow Decision I * -ENDIF ;mdI [Toad Hall] - -IF mmdI -.printx * Assembling for Morrow Micro Decision I * -ENDIF ;mmdI - -IF mikko -.printx * Assembling MikroMikko Kermit-80 * -ENDIF - -IF delphi ;[7] -.printx * Assembling Digicomp Delphi 100 Kermit-80 * -ENDIF ;[7] - -IF cpt85xx -.printx * Assembling CPT-85xx (under CompuPak CP/M) Kermit-80 * -ENDIF - -IF cmemco ;[25] -.printx * Assembling KERMIT-80 for the Cromemco (TU-ART) * -ENDIF;cmemco - -IF bbc ;[22] -.printx * Assembling Kermit-80 for BBC with Z80 co-processor * -ENDIF ;[22] - -IF rm380z ;[22] -.printx * Assembling Kermit-80 for Research Machines 380Z * -ENDIF ;[22] - -IF px8 ;[29] -.printx * Assembling Kermit-80 for Epson PX-8 * -ENDIF ;px8 [29] - -IF mmate ;[29] -.printx * Assembling KERMIT-80 for the PMC MicroMate * -ENDIF ;mmate [29] - -IF disc ;[29] -.printx * Assembling KERMIT-80 for the A. C. E. Discovery * -ENDIF ;disc [29] - -IF s1008 ;[29] -.printx * Assembling KERMIT-80 for the MicroSales s1008 * -ENDIF ;s1008 [29] - -IF access ;[29] -.printx * Assembling Kermit-80 for the ACCESS-MATRIX computer * -ENDIF ;access [29] - -IF lobo ;[hh] -.printx * Assembling Kermit-80 for the Lobo MAX-80 * -ENDIF;lobo [hh] - -IF teletek -.printx * Assembling Kermit-80 for the Teletek * -ENDIF ;teletek - -; -; -; If here, we have not linked to a family, so link to CPXSYS.ASM -IF lasm - LINK CPXSYS.ASM -ENDIF ;lasm -; -; If we are using m80, then the CPXSYS.ASM file will be INCLUDED from CPXTYP -; - - - +IF NOT lasm +.printx * CPXSWT.ASM * +ENDIF ; NOT lasm +; KERMIT - (Celtic for "FREE") +; +; This is the CP/M-80 implementation of the Columbia University +; KERMIT file transfer protocol. +; +; Version 4.0 +; +; Copyright June 1981,1982,1983,1984,1985 +; Columbia University +; +; Originally written by Bill Catchings of the Columbia University Center for +; Computing Activities, 612 W. 115th St., New York, NY 10025. +; +; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, +; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many +; others. +; +; This file is a simple family or system file switcher, selecting +; one of several family files, or selectin CPXSYS.ASM (now modified) +; if a family file does not exist. +; +; +; revision history: +; +;edit 10, 7-Jan-1991 by MF. Added code by Jay S. Rouman to support the +; Ampro Little Board (see CPXBBI.ASM) and PRINTX for the HP-125. +; edit 9, 1st September 1990 by Russell Lang, rjl@monu1.cc.monash.edu.au. +; Added Microbee support. +; edit 8, 2 December by OBSchou. Added Z80MU "system" to allow kermit-80 +; debugging on a PC! +; +; edit 7, 27 October, 1987 by OBSchou. Added bits for Sanyo, Compupro, +; Genie and TRS-80 M4. +; +; edit 6, 16 July, 1987 for Will Rose, who has submitted code for +; Micromint SB180 (6 and 9 Mhz) and a BT Merlin (alias RAIR) +; +; edit 5, 15 July, 1987 by OBSchou for David Moore, who has submitted +; code for a Teletek SYSTEMASTER and for ADM22 terminals. +; +; edit 4, 14 July 1987 by OBSchou for JA Shearwood of Birmingham University, +; Chris Miles of Manchester University. Added a Cifer family file +; for John, and added a BigBoard-Kaypro-Xerox family file for Chris +; Finally, added in new family file for Heath, telcon, z100 and scntpr +; systems for Martin Carter of Nottingham University. +; +; edit 3, 6 April, 1986 by OBSchou. +; Added in switching for NCR Desision Mate V and Amstrad CPC 664/6128 +; systems. +; +; edit 2, March 16, 1987 by OBSchou. +; added in support for m80 macro assembler. +; +; edit 1 28 January, 1987 by OBSchou. +; Take out the series of printx etx and selection of systems and +; leave this with only the system dep. code for systems without +; a family file. Hopefully, this file will go alltogether in time. +; +; Keep module name, edit number, and last revision date in memory. +swtver: db 'CPXSWT.ASM (10) 7-Jan-1991 $' +; +; Assembly time message to let me know I'm building the right version. +; LASM generates an 'S' error along with the message, which is messy, but +; better than trying to put everything inside a IF m80 OR mac80 conditional, +; because LASM doesn't like nested IF's, either. + + +IF (torfam AND lasm) +;Link to the module with the code for Superbrains, Torch, Cifer and pci2651 +LINK CPXTOR.ASM ; also NCR DMV systems +ENDIF;(torfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM + +IF (ciffam AND LASM) +; Link to the Cifer family file. (Cifer code previously on CPXTOR.ASM) +LINK CPXCIF.ASM ; Cifer family file +ENDIF ;(ciffam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM + +IF (appfam AND lasm) ;[33] apple frogs as a separate family.. +; Link to the APPLE family... +LINK CPXAPP.ASM +ENDIF ;(appfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM + +IF (norfam AND lasm); Link to the Northstar family (and Comart) +; Link to the NorthStar family file +LINK CPXNOR.ASM +ENDIF; (norfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM + +IF (pcwfam AND lasm) ;[35] Amstrad PCW 8256/8512 or CPC systems +; Link to the Amstrad PCW family +LINK CPXPCW.ASM +ENDIF ;(cpwfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM + +IF (bbifam AND lasm) ;Bigboard, Kaypro and Xerox 820 file +; Link to the Bigboard family +.printx * Linking to the BigBoard family * +LINK CPXBBI.ASM +ENDIF ;(bbifam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM + +IF (heafam AND lasm) ; heath, z100, telcon, and scntpr systems +; Link to the Heath-telcon-screentyper family +.printx * Linking to the Heath-telcon-screentyper family * +LINK CPXHEA.ASM +ENDIF ;(heafam) - m80 use: INCLUDE from CPXTYP.ASM + +IF (sbfam AND lasm) +; Link to the SB180 Family file +,printx * Linking to the SB180 Family file * +LINK CPXSB.ASM +ENDIF ; (sbfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM + +IF (m2215 AND lasm) +; Link to the RAIR/ BT Merlin code +.printx * Linking to the Merlin/Rair code * +LINK CPXMRL.ASM +ENDIF ; (m2215 AND lasm) - m80 use: INCLUDE from CPXTYP.ASM + +IF (sanfam AND lasm) +; Link to the Sanyo code +.printx * linking to the sanyo code * +LINK CPXSYO.ASM +ENDIF ; (sanfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM + +IF (comfam AND lasm) +; Link to the compupro code +.printx * linking to the Compupro code * +LINK CPXPRO.ASM +ENDIF ; (comfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM + +IF (genfam AND lasm) +; Link to the Genie family code +.printx * linking to the Genie code * +LINK CPXGNI.ASM +ENDIF ; (genfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM + +IF (trsfam AND lasm) +; Link to the TRS-80 family file +.printx * linking to the TRS family file* +LINK CPXTM4.ASM +ENDIF ; (trsfam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM + +IF (z80fam AND lasm) +; Link to the Z80MU family file +.printx * linking to the Z80MU family file* +LINK CPXZ80.ASM +ENDIF ; (z80fam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM + +IF (beefam AND lasm) +; Link to the Microbee family file +.printx * linking to the Microbee family file * +LINK CPXBEE.ASM +ENDIF ; (beefam AND lasm) - m80 use: INCLUDE from CPXTYP.ASM + + +; If we have come here, we are assembling the CPXSYS.ASM file + +IF robin +.printx * Assembling KERMIT-80 for the DEC VT180 * +ENDIF + +IF vector +.printx * Assembling KERMIT-80 for the Vector Graphics * +ENDIF + +IF osi +.printx * Assembling KERMIT-80 for the Ohio Scientific * +ENDIF + +IF heath +.printx * Assembling KERMIT-80 for the Heath/Zenith 89 * +ENDIF + +IF z100 +.printx * Assembling KERMIT-80 for the Heath/Zenith Z100 * +ENDIF + +IF trs80 +.printx * Assembling KERMIT-80 for the TRS-80 II * +ENDIF + +IF osbrn1 +.printx * Assembling KERMIT-80 for the Osborne 1 * +ENDIF + +IF telcon +.printx * Assembling KERMIT-80 for the Telcon Zorba * +ENDIF + +IF dmII +.printx * Assembling KERMIT-80 for the DECmate II * +ENDIF + +IF gener +.printx * Assembling Generic KERMIT-80 * +ENDIF + +IF cpm3 +.printx * Assembling Generic KERMIT-80 for CP/M 3.0 * +ENDIF + +IF hp125 +.printx * Assembling Kermit-80 for the HP-125 Series 100 * +ENDIF ;hp125 + +IF kpii +.printx * Assembling Kaypro II KERMIT-80 * +ENDIF + +IF xer820 ;[pcc001] +.printx * Assembling Xerox 820 KERMIT-80 * +ENDIF ;[pcc001] + +IF bbII +.printx * Assembling BigBoard II KERMIT-80 * +ENDIF + +IF ampro +.printx * Assembling Ampro Little Board KERMIT-80 * +ENDIF + +IF mdI +.printx * Assembling for Morrow Decision I * +ENDIF ;mdI [Toad Hall] + +IF mmdI +.printx * Assembling for Morrow Micro Decision I * +ENDIF ;mmdI + +IF mikko +.printx * Assembling MikroMikko Kermit-80 * +ENDIF + +IF delphi ;[7] +.printx * Assembling Digicomp Delphi 100 Kermit-80 * +ENDIF ;[7] + +IF cpt85xx +.printx * Assembling CPT-85xx (under CompuPak CP/M) Kermit-80 * +ENDIF + +IF cmemco ;[25] +.printx * Assembling KERMIT-80 for the Cromemco (TU-ART) * +ENDIF;cmemco + +IF bbc ;[22] +.printx * Assembling Kermit-80 for BBC with Z80 co-processor * +ENDIF ;[22] + +IF rm380z ;[22] +.printx * Assembling Kermit-80 for Research Machines 380Z * +ENDIF ;[22] + +IF px8 ;[29] +.printx * Assembling Kermit-80 for Epson PX-8 * +ENDIF ;px8 [29] + +IF mmate ;[29] +.printx * Assembling KERMIT-80 for the PMC MicroMate * +ENDIF ;mmate [29] + +IF disc ;[29] +.printx * Assembling KERMIT-80 for the A. C. E. Discovery * +ENDIF ;disc [29] + +IF s1008 ;[29] +.printx * Assembling KERMIT-80 for the MicroSales s1008 * +ENDIF ;s1008 [29] + +IF access ;[29] +.printx * Assembling Kermit-80 for the ACCESS-MATRIX computer * +ENDIF ;access [29] + +IF lobo ;[hh] +.printx * Assembling Kermit-80 for the Lobo MAX-80 * +ENDIF;lobo [hh] + +IF teletek +.printx * Assembling Kermit-80 for the Teletek * +ENDIF ;teletek + +; +; +; If here, we have not linked to a family, so link to CPXSYS.ASM +IF lasm + LINK CPXSYS.ASM +ENDIF ;lasm +; +; If we are using m80, then the CPXSYS.ASM file will be INCLUDED from CPXTYP +; + + + diff --git a/cpxsy2.asm b/cpxsy2.asm index a420d37..999f084 100644 --- a/cpxsy2.asm +++ b/cpxsy2.asm @@ -1,1364 +1,1364 @@ -IF NOT lasm -.printx * CPXSY2.ASM * -ENDIF ;NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the system-dependent code and data for KERMIT. -; It will be probably be broken into independent files to generate -; overlays for the various systems, one or more overlay possible -; from each file. For now, we will leave it in one piece. -; -; revision history: -; -; -; This is the system-dependent command to change the baud rate. -; DE contains the two-byte value from the baud rate table; this -; value is also stored in 'speed'. -sysspd: - - -IF px8 ; [29] - push d - call rsclose ; baud rate can only be set on opening rs232 - pop d - mov a, e - sta px8blk+4 ; set param block - call rsopen ; to set rate - ret -ENDIF ; px8 [29] - -; Set the speed for the Osborne I -IF osbrn1 - mvi a,osbin1 ;Reset the ACIA - call osstst ;Write the control port -osbs1: inr c ;Waiting loop - jnz osbs1 - mov a,e ; get the specified speed - jmp osstst ;Write the control reg. -ENDIF;osbrn1 - -;[hh] set the speed for a lobo MAX-80 -IF lobo - mov a,e ;[hh] get the parsed value -setbd: sta baudrt ;[hh] and send it to the baud rate port - ret ;[hh] -ENDIF;lobo - -; Set the speed for bigboard I or the delphi or the CPT-85xx -; or Cromemco (TU-ART) -IF delphi OR cpt85xx OR cmemco OR mmate ;[22] [29] - mov a,e ; get the parsed value - out baudrt ; Tell the baud rate generator. - ret -ENDIF;delphi OR cpt85xx OR cmemco OR mmate [22] [29] - -;[22] Set the speed for Acorn BBC -IF bbc - mov l,e - mvi a,7 ;Set receive baud rate - call osbyte ;*FX7,?e - mov l,e - mvi a,8 ;Set transmit baud rate - call osbyte ;*FX8,?e - ret -ENDIF;[22] bbc - -;[22] Set speed for RM 380Z -IF rm380z - mvi a,4 ;device type (SI/O4) in A - rst 6 ; EMT - db 29h ; SETLST - ret -ENDIF;[22] rm380z - -; Set the speed for MicroMikko. DE is baud rate multiplier -IF mikko - di - lxi h,txclk - mov m,d ;LSB first (swapped in memory) - mov m,e ;MSB last - lxi h,rxclk - mov m,d - mov m,e - mvi b,0 ;"modifier" for 1 stop bit - mvi a,2 ;Test MSB of speed >2 (110 bps or less) - cmp e - jp miksp1 - mvi b,00001000B ;"modifier" for 2 stop bits -miksp1: mvi a,4 ;Select SIO Reg 4 - lxi h,sioac - mov m,a - mvi a,sion4 ;Get values - ora b ;Add modifier - mov m,a ;Set value (stop bits) - ei - ret -ENDIF;mikko - - -; Set the speed for the Decision I -IF mdI - call selmdm ;Let's be absolutely sure, huh? - mvi a,dlab+wls1+wls0+stb ;Set data latch access bit - out lcr ;Out to Line Control Register - lhld speed ;Load baudrate multiplier - xchg - mov a,d ;Get low order byte for baud rate - out dlm ;Out to the MSB divisor port - mov a,e ;...and the high order byte - out dll ;Out to the LSB divisor port - mvi a,wls1+wls0+stb ;Enable Divisor Access Latch - out lcr ;Out to ACE Line Control Register - xra a ;Clear A - out ier ;Set no interrupts - out lsr ;Clear status - in msr ;Clear Modem Status Register - in lsr ;Clear Line Status Register - in rbr ;Clear Receiver Buffers - in rbr - ret -ENDIF ;mdI [Toad Hall] - -IF teletek - di - mov a,e ; first speed byte - out baudrt - mov a,d ; second speed byte - out baudrt - ei - ret -ENDIF ;teletek - -IF access ;[29] - mov a,e ;Get the parsed time constant -;The following code is derived from the Access initialization code - sta savspd ;Save the time constant - mvi a,14h ;Code for 'monitor' to set channel A baudrate - call monitor - lda savspd ;Get the time constant - call monitor ; and send it to the CRT - ret -savspd: ds 1 -monitor: ;Routine to do CRT functions - out 90h ;Output the data to the CRT - mvi a,1 ;Set DRDY true - out 23h -mon1: in 0a0h ;Wait for CACK* true - rlc - jc mon1 - in 80h ;Read the input data latch - push psw ;Save the input data - xra a ;Set DRDY false - out 23h -mon2: in 0a0h ;Wait for CACK* false - rlc - jc mon2 - pop psw - sta 0ee02h ;Save the input data - ret -ENDIF;access [29] - - -IF disc ;[29] -; Assuming that parsing of value from speed table puts low order -; byte of time constant in the e register and high byte in d. - mvi a,12 ;Register 12 - out mnprts - mov a,e ;Low order byte of time constant - out mnprts - mvi a,13 ;Register 13 - out mnprts - mov a,d ;High order byte of time constant - out mnprts - mvi a,14 ;Register 14 - out mnprts - mvi a,3 ;Enable baud rate generator - out mnprts - mvi a,11 ;Register 11 - out mnprts - mvi a,52h ;no Xtal, tclk=rclk=/trxc out=br gen - out mnprts - ret -ENDIF;disc [29] -; Speed tables -; (Note that speed tables MUST be in alphabetical order for later -; lookup procedures, and must begin with a value showing the total -; number of entries. The speed help tables are just for us poor -; humans. - -; db string length,string,divisor (2 identical bytes or 1 word) -; [Toad Hall] - -IF delphi OR lobo ;[hh] -spdtbl: db 10h ;16 entries - db 03h,'110$', 02h,02h - db 04h,'1200$', 07h,07h - db 05h,'134.5$', 03h,03h - db 03h,'150$', 04h,04h - db 04h,'1800$', 08h,08h - db 05h,'19200$', 0fh,0fh - db 04h,'2000$', 09h,09h - db 04h,'2400$', 0ah,0ah - db 03h,'300$', 05h,05h - db 04h,'3600$', 0bh,0bh - db 04h,'4800$', 0ch,0ch - db 02h,'50$', 00h,00h - db 03h,'600$', 06h,06h - db 04h,'7200$', 0dh,0dh - db 02h,'75$', 01h,01h - db 04h,'9600$', 0eh,0eh - -sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200' - db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$' -ENDIF;delphi OR lobo ;[hh] - -IF cpt85xx -spdtbl: db 15 ; 15 entries - db 03,'110$', 03h,03h - db 04,'1200$', 09h,09h - db 05,'134.5$', 04h,04h - db 03,'150$', 05h,05h - db 04,'1800$', 0Ah,0Ah - db 04,'2400$', 0Bh,0Bh - db 03,'300$', 06h,06h - db 04,'3600$', 0Ch,0Ch - db 04,'4800$', 0Dh,0Dh - db 02,'50$', 01h,01h - db 03,'600$', 07h,07h - db 04,'7200$', 0Eh,0Eh - db 02,'75$', 02h,02h - db 03,'900$', 08h,08h - db 04,'9600$', 0Fh,0Fh - -sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 900' - db cr,lf,' 1200 1800 2400 3600 4800 7200 9600$' -ENDIF;cpt85xx - -IF bbc ;[22] -spdtbl: db 8 ; 8 entries - db 04,'1200$', 04h,04h - db 03,'150$', 02h,02h - db 05,'19200$', 08h,08h - db 04,'2400$', 05h,05h - db 03,'300$', 03h,03h - db 04,'4800$', 06h,06h - db 02,'75$', 01h,01h - db 04,'9600$', 07h,07h - -sphtbl: db cr,lf,' 75 150 300 1200 2400 4800 9600 19200$' -ENDIF;[22] bbc - -IF rm380z ;[22] -spdtbl: db 7 ; 7 entries - db 03,'110$', 00h,00h - db 04,'1200$', 03h,03h - db 04,'2400$', 04h,04h - db 03,'300$', 01h,01h - db 04,'4800$', 05h,05h - db 03,'600$', 02h,02h - db 04,'9600$', 06h,06h - -sphtbl: db cr,lf,' 110 300 600 1200 2400 4800 9600$' -ENDIF;[22] rm380z - -IF px8 ; [29] -spdtbl: db 9 ; 9 entries - db 03,'110$', 02h,02h - db 04,'1200$', 0ah,0ah - db 03,'150$', 04h,04h - db 05,'19200$', 0fh,0fh - db 04,'2400$', 0ch,0ch - db 03,'300$', 06h,06h - db 04,'4800$', 0dh,0dh - db 03,'600$', 08h,08h - db 04,'9600$', 0eh,0eh -sphtbl: db cr, lf - db ' 100 150 300 600 1200 2400 4800 9600 19200$' -ENDIF ; px8 [29] - -IF mikko -spdtbl: db 9h ;9 entries - db 03h,'110$' - dw 0369h - db 04h,'1200$' - dw 0050h - db 03h,'150$' - dw 0280h - db 04h,'2400$' - dw 0028h - db 03h,'300$' - dw 0140h - db 04h,'4800$' - dw 0014h - db 03h,'600$' - dw 00A0H - db 02h,'75$' - dw 0500h - db 04h,'9600$' - dw 000ah - -sphtbl: db cr,lf,' 75 110 150 300 600 1200 2400 4800 9600$' -ENDIF;mikko - -IF osbrn1 -spdtbl: db 02h ;2 entries - db 04h,'1200$', OSBI12,OSBI12 - db 03h,'300$', OSBI03,OSBI03 - -sphtbl: db cr,lf,' 300',cr,lf,' 1200$' -ENDIF;osbrn1 - - -IF mdI -spdtbl: db 0dh ; 13 entries - db 03h, '110$' - dw 1047 - db 04h, '1200$' - dw 96 - db 03h, '150$' - dw 768 - db 05h,'19200$' - dw 6 - db 04h, '2400$' - dw 48 - db 03h, '300$' - dw 384 - db 05h,'38400$' - dw 3 - db 03h, '450$' - dw 288 - db 04h, '4800$' - dw 24 - db 05h,'56000$' - dw 2 - db 03h, '600$' - dw 192 - db 02h, '75$' - dw 1536 - db 04h, '9600$' - dw 12 - -sphtbl: db cr,lf,' 75 110 150 300 450 600 1200' - db cr,lf,' 2400 4800 9600 19200 38400 56000$' - -;(Lord knows what you'll be communicating with at 56000 baud, but the -;Multi-I/O board literature says it'll do it, so what the heck.... -;might as well throw it in here just to show off...sure hope the -;port don't melt...) - -ENDIF ;mdI [Toad Hall] - -IF cmemco ;[25] -spdtbl: db 7 ; 7 entries - db 3,'110$', 01H,01H - db 4,'1200$', 88H,88H - db 3,'150$', 82H,82H - db 4,'2400$', 90H,90H - db 3,'300$', 84H,84H - db 4,'4800$', 0A0H,0A0H - db 4,'9600$', 0C0H,0C0H - -sphtbl: db cr,lf - db ' 110 150 300 1200 2400 4800 9600$' -ENDIF;cmemco - -IF access ;Similar to bbI with different values [29] -spdtbl: db 6h ;6 entries - db 04h,'1200$', 28h,28h - db 04h,'2400$', 14h,14h - db 03h,'300$', 0a0h,0a0h - db 04h,'4800$', 0ah,0ah - db 03h,'600$', 50h,50h - db 04h,'9600$', 5,5 - -sphtbl: db cr,lf,' 300 600 1200 2400 4800 9600$' -ENDIF;access [29] - -IF mmate ;[29] -spdtbl: db 10h ;16 entries - db 03h,'110$', 0e2h,0e2h - db 04h,'1200$', 0e7h,0e7h - db 05h,'134.5$', 0e3h,0e3h - db 03h,'150$', 0e4h,0e4h - db 04h,'1800$', 0e8h,0e8h - db 05h,'19200$', 0efh,0efh - db 04h,'2000$', 0e9h,0e9h - db 04h,'2400$', 0eah,0eah - db 03h,'300$', 0e5h,0e5h - db 04h,'3600$', 0ebh,0ebh - db 04h,'4800$', 0ech,0ech - db 02h,'50$', 0e0h,0e0h - db 03h,'600$', 0e6h,0e6h - db 04h,'7200$', 0edh,0edh - db 02h,'75$', 0e1h,0e1h - db 04h,'9600$', 0eeh,0eeh - -sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200' - db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$' -ENDIF;mmate [29] - -IF disc ;[29] -; Similar to mikko table but with different time constant values -spdtbl: db 9h ;9 entries - db 03h,'110$' - dw 1134 - db 04h,'1200$' - dw 102h - db 03h,'150$' - dw 831 - db 04h,'2400$' - dw 50 - db 03h,'300$' - dw 415 - db 04h,'4800$' - dw 24 - db 03h,'600$' - dw 206 - db 02h,'75$' - dw 1665 - db 04h,'9600$' - dw 11 - -sphtbl: db cr,lf,' 75 110 150 300 600 1200 2400 4800 9600$' -ENDIF;disc [29] - -IF teletek -spdtbl: db 7 ; 7 entries - db 4, '1200$', 47h,40h - db 5,'19200$', 47h,04h - db 4, '2400$', 47h,20h - db 3, '300$', 47h,00h - db 4, '4800$', 47h,10h - db 3, '600$', 47h,80h - db 4, '9600$', 47h,08h - -sphtbl: db cr,lf - db ' 300 600 1200 2400 4800 9600 19200$' -ENDIF ;teletk - - -; The following conditionals were once a huge if not statement. There -; wasn't enough room to add the lobo to the list, so it had to be broken -; into 2, which you can't do with an if not. I redid it as two ifs and -; applied them to those that wouldn't set baud. [Hal Hostetler] -IF robin OR gener OR dmII OR vector OR trs80;[32] -spdtbl equ 0 ; SET BAUD not supported. -sphtbl equ 0 -ENDIF;robin OR gener OR dmII OR vector OR trs80 -; -IF mmdI OR osi OR cpm3 OR S1008 ; [29] -spdtbl EQU 0 ;[hh] SET BAUD not supported. -sphtbl EQU 0 ;[hh] ran out of room above... -ENDIF;mmdI OR osi OR cpm3 OR S1008 [29] -; -IF hp125 ;[MF] -spdtbl equ 0 ; SET BAUD not supported. -sphtbl equ 0 -ENDIF;hp125 [MF] -; -; This is the system-dependent SET PORT command. -; HL contains the argument from the command table. -sysprt: -IF lobo ;[hh] - mov a,l ;[hh] get the data port value and store at - sta outmd3+1 ;[hh] the two places we use... - sta inpmd2+1 ;[hh] MNPORT in the overlay - sta port ;[hh] inform program of the change in ports - inr a ;[hh] status port = data port + 1 in the Lobo - sta outmd1+1 ;[hh] store it at the three places... - sta inpmd1+1 ;[hh] we use MNPRTS... - sta outctl+1 ;[hh] in the overlay - mov a,h ;[hh] now get the baud rate port value - sta getbd+1 ;[hh] store it in the two places we use... - sta setbd+1 ;[hh] BAUDRT in the overlay - sta port+1 ;[hh] don't need to, but keeps it consistant -getbd: lda baudrt ;[hh] get baud rate value from port - sta speed ;[hh] tell STAT. baud rate for each port - ;[hh] is independant of the other -ENDIF ;lobo - -IF iobyt - mov a,m ;Get the I/O byte - sta prtiob ;Save the desired IO byte for this port - inx h ;Point at next entry - mov a,m ;Get the output function - sta prtfun ;Save it -ENDIF;iobyt - -IF iobyt AND robin - inx h ;Point at next entry - mov a,m ;Get the hardware address for the port - sta prtadr ;Store it -ENDIF;iobyt AND robin -; -IF hp125 ;[MF] - push psw - push b - push d - push h - xchg ;Put port connect sequence address in DE - call prtstr ;Connect proper port - pop h - pop d - pop b - pop psw -ENDIF;hp125 [MF] -; - ret -; -; Port tables for Lobo MAX-80 -IF lobo ;[hh] -; help text -prhtbl: db cr,lf,'RS-232 port A or B$' -; -; command table -prttbl: db 02H ;[hh] two entries - db 01H,'A$',0E4H,0D0H - db 01H,'B$',0E6H,0D4H -ENDIF ;lobo -; -; Port tables for GENERIC CPM 2.2 -IF gener -; help text -prhtbl: db cr,lf,'CRT device' - db cr,lf,'PTR device' - db cr,lf,'TTY device' - db cr,lf,'UC1 device' - db cr,lf,'UR1 device' - db cr,lf,'UR2 device$' - -; command table -prttbl: db 06H ;Six devices to choose from - db 03H,'CRT$' - dw crtptb - db 03H,'PTR$' - dw ptrptb - db 03H,'TTY$' - dw ttyptb - db 03H,'UC1$' - dw uc1ptb - db 03H,'UR1$' - dw ur1ptb - db 03H,'UR2$' - dw ur2ptb - -; port entry table -; table entries are: -; db iobyte-value, BDOS output function, reserved -crtptb: db crtio,conout,0 -ptrptb: db ptrio,punout,0 -ttyptb: db ttyio,conout,0 -uc1ptb: db uc1io,conout,0 -ur1ptb: db ur1io,punout,0 -ur2ptb: db ur2io,punout,0 -ENDIF;gener - -; -; Port tables for DECmate II or MicroMikko or Acorn BBC -; -IF dmII OR mikko OR bbc ;[22] -; help text -prhtbl: db cr,lf,'COMMUNICATIONS port$' - -; command table -prttbl: db 01H ;Only one port known at this point - db 0EH,'COMMUNICATIONS$' - dw comptb ;address of info - -; port entry table -; table entries are: -; db iobyte-value, BDOS output function, reserved -comptb: db batio,punout,0 - -ENDIF;[22] dmII OR mikko OR bbc -; -; Port tables for Robin -; -IF robin -; help text -prhtbl: db cr,lf,'COMMUNICATIONS port' - db cr,lf,'GENERAL purpose port' - db cr,lf,'PRINTER port$' - -; command table -prttbl: db 03H ;Three entries - db 0EH,'COMMUNICATIONS$' - dw comptb - db 07H,'GENERAL$' - dw gppptb - db 07H,'PRINTER$' - dw prnptb - -; port entry table -; table entries are: -; db iobyte-value, BDOS output function, hardware port address -; (control/status) -; -;At present, the hardware port address is only used for sending a break. -comptb: db batio,punout,comtst -gppptb: db gppio,conout,gentst -prnptb: db lptio,conout,prntst - -prtadr: db comtst ;space for current hardware port address -ENDIF;robin - -IF iobyt -prtfun: db punout ;Function to use for output to comm port -prtiob: db batio ;I/O byte to use for communicating -coniob: db defio ;I/O byte to use for console -ENDIF;iobyt -; -IF hp125 ;[MF] -; Help table -prhtbl: db cr,lf,'Communications port' - db cr,lf,'Printer port$' -; command table -prttbl: db 02H ;2 entries - db 0eH,'COMMUNICATIONS$' - dw mapon1 - db 07H,'PRINTER$' - dw mapon2 -;Port table entries are the addresses of the escape sequences to connect -;the ports. -; -ENDIF;hp125 [MF] - -IF NOT (iobyt OR lobo OR hp125) ;[hh] [MF] -prttbl equ 0 ; SET PORT is not supported -prhtbl equ 0 -ENDIF;NOT iobyt OR lobo OR hp125 [MF] -; -; selmdm - select modem port -; selcon - select console port -; selmdm is called before using inpmdm or outmdm; -; selcon is called before using inpcon or outcon. -; For iobyt systems, diddle the I/O byte to select console or comm port; -; For Decision I, switches Multi I/O board to console or modem serial -; port. [Toad Hall] -; For the rest, does nothing. -; preserves bc, de, hl. -selmdm: -IF iobyt - lda prtiob ;Set up for output to go to the comm port - sta iobyte ;Switch byte directly -ENDIF;iobyt - -IF mdI - lda group - ori mdmgrp ;Mask modem serial port - out grpsel -ENDIF;mdI [Toad Hall] - - ret - -selcon: -IF iobyt - lda coniob ;Set up for output to go to the console port - sta iobyte ;Switch directly -ENDIF;iobyt - -IF mdI - lda group - ori congrp ;Mask console serial port (1) - out grpsel -ENDIF;mdI [Toad Hall] - - ret -; Get character from console, or return zero. -; result is returned in A. destroys bc, de, hl. -; -inpcon: -IF NOT iobyt - mvi c,dconio ;Direct console I/O BDOS call. - mvi e,0FFH ;Input. - call BDOS -ENDIF;NOT iobyt - -IF iobyt - call bconst ;Get the status - ora a ;Anything there? - rz ;No, forget it - call bconin ;Yes, get the character -ENDIF;iobyt - ret -; -; Output character in E to the console. -; destroys bc, de, hl -; -outcon: - -IF rm380z ;[22] - mov a,e - cpi cr ;cr produces cr + lf - jnz outcn1 - mvi e,'N'-100O ;Control-N produces cr only -outcn1: ;continue -ENDIF;[22] rm380z - -IF NOT iobyt - mvi c,dconio ;Console output bdos call. - call bdos ;Output the char to the console. -ENDIF;NOT iobyt - -IF iobyt - mov c,e ;Character - call bcnout ;to Console -ENDIF;iobyt - ret -; -; outmdm - output a char from E to the modem. -; the parity bit has been set as necessary. -; returns nonskip; bc, de, hl preserved. -outmdm: -IF osi OR lobo ;[hh] - push h -outmd1: lxi h,mnprts ;address of the port status register -outmd2: mov a,m ; get port status in A - ani output ;Loop till ready. - jz outmd2 -outmd3: lxi h,mnport ;address of port data register - mov m,e ; write the character - pop h - ret -ENDIF;osi OR lobo - -IF osbrn1 - call osldst ;Read the status port - ani output ;Loop till ready. - jz outmdm - mov a,e - jmp osstda ;Write to the data port -ENDIF;osbrn1 - -IF px8 ; [29] - push h - push b - push d -outmd1: call rsoutst ; get the output status - ora a - jz outmd1 ; check if output enabled - pop d - mov c, e ; char in C - push d - call rsput - pop d - pop b - pop h - ret -ENDIF; px8 [29] - -IF inout - in mnprts ;Get the output done flag. - ani output ;Is it set? - jz outmdm ;If not, loop until it is. - mov a,e - out mnport ;Output it. - ret -ENDIF;inout - -IF iobyt -;**** Note that we enter from outpkt with the I/O byte already set up for -; output to go to the comm port - push h - push b - lda prtfun ;Get the output function - mov c,a ;Into C - call bdos ;And output the character - pop b - pop h - ret -ENDIF;iobyt - -IF cpm3 OR hp125 ;[MF] - push h - push b - mvi c,auxout ;Output to the aux output device - call bdos - pop b - pop h - ret -ENDIF;cpm3 OR hp125 [MF] - -; org $+100h AND 0FF00h ; get rid of phase error - -; -; get character from modem; return zero if none available. -; for IOBYT systems, the modem port has already been selected. -; destroys bc, de, hl. -inpmdm: -IF iobyt - call bconst ;Is Char at COMM-Port? - ora a ;something there? - rz ; return if nothing there - call bconin ; data present. read data. -ENDIF;iobyt - -IF cpm3 - mvi c,auxist - call bdos ;is char at auxin? - ora a ;something there? - rz ;no - mvi c,auxin - call bdos ;read char from auxin -ENDIF;cpm3 -; -IF hp125 ;[MF] - lxi b,70ffh ;SEt subfunction to get RDR (auxin) status - call bdos ;is char at RDR? - ora a ;something there? - rz ;no - mvi c,auxin - call bdos ;read char from RDR -ENDIF;hp125 [MF] - -IF osi OR lobo ;[hh] -inpmd1: lda mnprts ;Get the port status into A. - ani input ;See if the input ready bit is on. - rz ;If not then return. -inpmd2: lda mnport ;If so, get the char. -ENDIF;osi OR lobo - -IF osbrn1 - call osldst ;Read the status port - ani input ;Something there? - rz ;Nope - call osldda ;Read the data port -ENDIF;osbrn1 - -IF inout -;Note: modem port should already be selected for mdI. [Toad Hall] - in mnprts ;Get the port status into A. - ani input ;See if the input ready bit is on. - rz ;If not then return. - in mnport ;If so, get the char. -ENDIF;inout - -IF px8 ; [29] - call rserst ; check error status - ani 64h ; this assumes 'not open' cannot occur - jnz inpmd1 ; error has occurred! - call rsinst ; any chars outstanding? - ora a - rz ; exit if none - call rsget ; get char in A - ret -; return the 'no char outstanding' indication on error -inpmd1: mvi a, 0 -ENDIF; px8 [29] - - ret ; return with character in A - - -; -; flsmdm - flush comm line. -; Modem is selected. -; Currently, just gets characters until none are available. - -flsmdm: call inpmdm ; Try to get a character - ora a ; Got one? - jnz flsmdm ; If so, try for another - ret ; Receiver is drained. Return. -; -; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not. -lptstat: -IF iobyt ;[33] - call bprtst ; -call bprtst ; get status -ENDIF ;iobyt[33] -IF NOT iobyt ;[33] - xra a ; assume it is ok.. this may not be necessary -ENDIF ;iobyt [33] - ret - -; -; outlpt - output character in E to printer -; console is selected. -; preserves de. -outlpt: - push d ; save DE in either case - call prtflt ; go through printer filter [30] - ana a ; if A = 0 do nothing, - jz outlp1 ; [30] if a=0 do nothing - -IF NOT iobyt - mvi c,lstout - call bdos ;Char to printer -ENDIF;NOT iobyt -IF iobyt - mov c,e - call blsout -ENDIF;iobyt - -outlp1: pop d ; restore saved register pair - ret -; -; Screen manipulation routines -; csrpos - move to row B, column C -; -; csrpos for terminals that use a leadin sequence followed -; by (row + 31.) and (column + 31.) -; -IF NOT (robin OR dmII OR osi OR vector OR termin OR hp125) - ;[MF] Terminals code in CPXVDU -csrpos: push b ; save coordinates - lxi d,curldn ; get cursor leadin sequence - call prtstr ; print it - pop h ; restore coordinates - mov a,h ; get row - adi (' '-1) ; space is row one - mov e,a - push h - call outcon ; output row - pop h - mov a,l ; get column - adi (' '-1) ; space is column one - mov e,a - jmp outcon ; output it and return -ENDIF;NOT (robin OR dmII OR osi OR vector OR termin OR hp125)[MF] -; -; -; -; csrpos for ANSI terminals -; -IF robin OR dmII -csrpos: push b ; save coordinates - lxi d,curldn ; get cursor leadin sequence - call prtstr ; print it - pop h ; peek at coordinates - push h ; then save away again - mov l,h ; l = row - mvi h,0 ; hl = row - call nout ; output in decimal - mvi e,';' ; follow with semicolon - call outcon ; print it - pop h ; restore column - mvi h,0 ; hl = column - call nout - mvi e,'H' ; terminate with 'move cursor' command - jmp outcon ; output it and return -ENDIF;robin OR dmII -; -; csrpos for the HP-125 [MF] -; -IF hp125 ;[MF] -csrpos: dcr b ;HP-125 uses zero-based addressing - dcr c ;... - push b ; save coordinates - lxi d,curldn ; get cursor leadin sequence - call prtstr ; print it - pop h ; peek at coordinates - push h ; then save away again - mov l,h ; l = row - mvi h,0 ; hl = row - call nout ; output in decimal - mvi e,'R'+20h ;Say it was a row - call outcon ; print it - pop h ; restore column - mvi h,0 ; hl = column - call nout - mvi e,'C' ; terminate with 'move cursor' command - jmp outcon ; output it and return -ENDIF;hp125 [MF] -; -; csrpos for the Vector General. It's weird. -; -IF vector -csrpos: dcr b ; vector uses zero-based addressing? - dcr c - push b ; save coordinates - mvi e,esc ; print an escape - call outcon - pop d ; peek at coordinates - push d - call outcon ; output column - pop d - mov e,d ; get row - jmp outcon ; output and return -ENDIF;vector - -IF osi ; systems without cursor positioning -csrpos: ret ; dummy routine referenced by linkage section -ENDIF;osi - - -; -; delchr - make delete look like a backspace. Unless delete is a printing -; character, we just need to print a backspace. (we'll output clrspc -; afterwards) -; For Kaypro and Vector General, delete puts a blotch on the screen. -; For Apple and Osborne 1, delete moves but doesn't print. -delchr: - -IF vector OR osbrn1 OR lobo - lxi d,delstr - jmp prtstr -ENDIF ;vector OR osbrn1 OR lobo - -IF bbc OR rm380z ;[22] - ret -ENDIF;bbc OR rm380z - -IF NOT (vector OR osbrn1 OR bbc OR rm380z);[22] - mvi e,bs ;get a backspace - jmp outcon -ENDIF;NOT (vector OR osbrn1 OR bbc OR rm380z [22] - -; erase the character at the current cursor position -clrspc: mvi e,' ' - call outcon - mvi e,bs ;get a backspace - jmp outcon - -; erase the current line -clrlin: lxi d,eralin - jmp prtstr - -; erase the whole screen, and go home. preserves b (but not c) -clrtop: lxi d,erascr - jmp prtstr - - -IF robin -sysver: db 'VT180 Robin$' -ENDIF;robin - -IF dmII -sysver: db 'DECmate II CP/M-80$' -ENDIF;dmII - -IF delphi ; [7] new system -sysver: db 'Digicomp Delphi 100$' -endif;delphi - -IF access -sysver: db 'Actrix CP/M$' -endif; - -IF teletek -sysver: db 'Teletek SYSTEMASTER CP/M-80$' -ENDIF ;teletek - -IF cpt85xx -sysver: db 'CPT-85xx under CompuPak CP/M$' -ENDIF;cpt85xx - -IF mdI -sysver: db 'Morrow Decision I$' -ENDIF;mdI [Toad Hall] - -IF mmdI -sysver: db 'MicroDecision I$' -ENDIF;mmdI - -IF osi -sysver: db 'Ohio Scientific$' -ENDIF;osi - -IF mmate ;[29] -sysver: db 'PMC Micromate using port I/O$' -ENDIF;mmate [29] - -IF disc ;[29] -sysver: db 'Discovery using 83U board port B$' -ENDIF ;disc [29] - -IF s1008 ;[29] -sysver: db 'U. S. MicroSales using printer port$' -ENDIF ;s1008 [29] - -IF cmemco ;[25] -sysver: db 'Cromemco (TU-ART)$' -ENDIF;cmemco -; -IF robin OR dmII -; Note that we cannot support Graphics Mode or the H19 erase-screen command -; (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 +; (E), because the sequences are more than three bytes. +defesc EQU '\'-100O ;Still Control-\ (just ran out of room...) +vtval EQU 0 ; we probably don't want VT52 emulation +outlin: db esc,3CH,esc,'[H',esc,'[J',cr,lf,tab,tab,'$' +erascr: db esc,'[H',esc,'[J$' ;Clear screen and go home. +eralin: db cr,esc,'[K$' ;Clear line. +curldn: db esc,'[$' ; Cursor leadin +ttab: +ta: db esc,'[A$' ; Cursor up. +tb: db esc,'[B$' ; Cursor down. +tc: db esc,'[C$' ; Cursor right. +td: db esc,'[D$' ; Cursor left +te: db '$',0,0,0 ; (can't) Clear display +tf: db '$',0,0,0 ; (don't) Enter Graphics Mode +tg: db '$',0,0,0 ; (don't) Exit Graphics mode +th: db esc,'[H$' ; Cursor home. +ti: db esc,'M$',0 ; Reverse linefeed. +tj: db esc,'[J$' ; Clear to end of screen. +tk: db esc,'[K$' ; Clear to end of line. +ENDIF;robin OR dmII + +IF mikko +sysver: db 'MikroMikko$' +outlin: db subt,cr,lf,tab,'$' +erascr: db subt,'$' ;Clear screen and go home. +eralin: db cr,1CH,'$' ;Clear line. +curldn: db esc,'=$' ;cursor leadin +ttab: ;Table start location. +ta: db 0BH,'$',0,0 ;Cursor up. +tb: db 0AH,'$',0,0 ;Cursor down. +tc: db 0CH,'$',0,0 ;Cursor right. +td: db bs,'$',0,0 ;Cursor left +te: db subt,'$',0,0 ;Clear display +tf: db '$',0,0,0 ;(can't) Enter Graphics Mode +tg: db '$',0,0,0 ;(can't) Exit Graphics mode +th: db 1EH,'$',0,0 ;Cursor home. +ti: db '$',0,0,0 ;(can't) Reverse linefeed. +tj: db 1cH,'$',0,0 ;Clear to end of screen. +tk: db 1cH,'$',0,0 ;Clear to end of line. +ENDIF;mikko +; +IF bbc ;[22] +sysver: db 'BBC (Z80)$' +outlin: db 0CH,esc,'=',21H,30H,'$' +erascr: db 0CH,'$' ;Clear screen and go home. +eralin: db cr,esc,'@$' ;Clear line. +curldn: db esc,'=$' ;cursor leadin +ttab: ;Table start location. +ta: db 0BH,'$',0,0 ;Cursor up. +tb: db 0AH,'$',0,0 ;Cursor down. +tc: db tab,'$',0,0 ;Cursor right. +td: db bs,'$',0,0 ;Cursor left +te: db 0CH,'$',0,0 ;Clear display +tf: db '$',0,0,0 ;(can't) Enter Graphics Mode +tg: db '$',0,0,0 ;(can't) Exit Graphics mode +th: db 1EH,'$',0,0 ;Cursor home. +ti: db '$',0,0,0 ;(can't) Reverse linefeed. +tj: db esc,'?$',0,0 ;Clear to end of screen. +tk: db esc,'@$',0,0 ;Clear to end of line. +ENDIF;[22] bbc +; +IF rm380z ;[22] +sysver: db 'Research Machines 380Z$' +outlin: db 1FH,cr,tab,'$' +erascr: db 1FH,'$' ;Clear screen and go home. +eralin: db 0EH,19H,'$' ;Clear line. +curldn: db 16H,'$' ;cursor leadin +ttab: ;Table start location. +ta: db 0BH,'$',0,0 ;Cursor up. +tb: db 0AH,'$',0,0 ;Cursor down. +tc: db 18H,'$',0,0 ;Cursor right. +td: db bs,'$',0,0 ;Cursor left +te: db 1FH,'$',0,0 ;Clear display +tf: db '$',0,0,0 ;(can't) Enter Graphics Mode +tg: db '$',0,0,0 ;(can't) Exit Graphics mode +th: db 1DH,'$',0,0 ;Cursor home. +ti: db '$',0,0,0 ;(can't) Reverse linefeed. +tj: db 1EH,'$',0,0 ;Clear to end of screen. +tk: db 19H,'$',0,0 ;Clear to end of line. +ENDIF;[22] rm380z + +IF lobo ;[hh] +sysver: db 'Lobo MAX-80$' +outlin: db esc,'*',cr,lf,tab,tab,'$' +erascr: db esc,'*$' ;[hh] clear screen and home cursor +eralin: db cr,esc,'R$' ;[hh] clear line +curldn: db esc,'=$' ;[hh] cursor lead-in string +delstr: db bs,' ',bs,bs,'$' ;[hh] ??adjust for echoing delete +ttab: ;[hh] table start location +ta: db 0BH,'$',0,0 ;[hh] cursor up +tb: db 0AH,'$',0,0 ;[hh] cursor down +tc: db 0CH,'$',0,0 ;[hh] cursor right +td: db 08H,'$',0,0 ;[hh] cursor left +te: db esc,'*$',0 ;[hh] clear display (homes cursor) +tf: db '$',0,0,0 ;[hh] (can't) enter graphics mode +tg: db '$',0,0,0 ;[hh] (can't) exit graphics mode +th: db 01EH,'$',0,0 ;[hh] home cursor +ti: db esc,'E$',0 ;[hh] reverse linefeed (insert line) +tj: db esc,'Y$',0 ;[hh] clear to end of screen +tk: db esc,'T$',0 ;[hh] clear to end of line +ENDIF ;lobo + +IF px8 ; [29] +sysver: db 'Epson PX-8$' +outlin: db esc,'*$' +erascr: db esc,'*$' ; clear screen and home +eralin: db cr,esc,'T$' ; clear line +curldn: db esc,'=$' ; cursor lead in +ttab: ; table start location +ta: db 30,'$',0,0 ; cursor up +tb: db 31,'$',0,0 ; cursor down +tc: db 28,'$',0,0 ; cursor right +td: db 29,'$',0,0 ; cursor left +te: db esc,'*$',0 ; clear display +tf: db '$',0,0,0 ; can't enter graphics graphics mode +tg: db '$',0,0,0 ; can't exit graphics mode +th: db 11,'$',0,0 ; home cursor +ti: db 30,'$',0,0 ; reverse linefeed +tj: db esc,'Y$',0 ; erase to end of screen +tk: db esc,'T$',0 ; erase to end of line +ENDIF ; px8 [29] + +; +IF osbrn1 +sysver: db 'Osborne 1$' +outlin: db 1AH,cr,lf,tab,'$' ;(Clear screen, home cursor) +erascr: db 1AH,'$' ;Clear screen and go home. +eralin: db cr,esc,'T$' ;Clear line. +delstr: db bs,bs,'$' ; Adjust for delete +curldn: db esc,'=$' ;Cursor lead-in +ttab: ;Table start location. +ta: db ('K'-100O),'$',0,0 ;Cursor up. +tb: db 12O,'$',0,0 ;Cursor down. +tc: db ('L'-100O),'$',0,0 ;Cursor right. +td: db bs,'$',0,0 ;Cursor left. +te: db subt,'$',0,0 ;Clear screen. +tf: db '$',0,0,0 ;(can't) Enter graphics mode +tg: db '$',0,0,0 ;(can't) Exit graphics mode +th: db ('^'-100O),'$',0,0 ;Cursor home. +ti: db ('K'-100O),'$',0,0 ;Reverse linefeed. +tj: db esc,'T$',0 ;(can't) Clear to end of screen. +tk: db esc,'T$',0 ;Clear to end of line. +ENDIF;osbrn1 +; +IF vector +sysver: db 'Vector Graphics$' +outlin: db ('D'-100O),cr,lf,tab,tab,'$' +erascr: db ('D'-100O),'$' ;Clear screen and go home. +eralin: db cr,('Q'-100O),'$' ;Clear line. +delstr: db bs,' ',bs,bs,'$' ; adjust for echoing delete character +ttab: ;Table start location. +ta: db ('U'-100O),'$',0,0 ;Cursor up. +tb: db 12O,'$',0,0 ;Cursor down. +tc: db ('Z'-100O),'$',0,0 ;Cursor right. +td: db '$',0,0,0 ;(can't) Cursor left +te: db '$',0,0,0 ;(can't) Clear display +tf: db '$',0,0,0 ;(can't) Enter graphics mode +tg: db '$',0,0,0 ;(can't) Exit graphics mode +th: db ('B'-100O),'$',0,0 ;Cursor home. +ti: db ('U'-100O),'$',0,0 ;Reverse linefeed. +tj: db ('P'-100O),'$',0,0 ;Clear to end of screen. +tk: db ('Q'-100O),'$',0,0 ;Clear to end of line. +ENDIF;vector + +IF trs80lb +sysver: db 'TRS-80 II Lifeboat CP/M$' +outlin: db esc,':',cr,lf,tab,tab,'$' +erascr: db esc,':$' ;Clear screen and go home. +eralin: db cr,esc,'T$' ;Clear line. +curldn: db esc,'=$' ;Cursor lead-in +ttab: ;Table start location. +ta: db 0BH,'$',0,0 ;Cursor up. +tb: db 0AH,'$',0,0 ;Cursor down. +tc: db 0CH,'$',0,0 ;Cursor right. +td: db bs,'$',0,0 ;Cursor left +te: db esc,':$',0 ;Clear display +tf: db '$',0,0,0 ;(can't) Enter Graphics Mode +tg: db '$',0,0,0 ;(can't) Exit Graphics mode +th: db 1EH,'$',0,0 ;Cursor home. +ti: db 0BH,'$',0,0 ;Reverse linefeed. +tj: db esc,'Y$',0 ;Clear to end of screen. +tk: db esc,'T$',0 ;Clear to end of line. +ENDIF;trs80lb +; +IF trs80pt +sysver: db 'TRS-80 II P+T CP/M$' +outlin: db 0CH,cr,lf,tab,tab,'$' +erascr: db 0CH,'$' ;Clear screen and go home. +eralin: db cr,01H,'$' ;Clear line. +curldn: db esc,'Y$' ;Cursor lead-in +ttab: ;Table start location ;Must be 4 bytes each +ta: db 1EH,'$',0,0 ;Cursor up. +tb: db 1FH,'$',0,0 ;Cursor down. +tc: db 1DH,'$',0,0 ;Cursor right. +td: db 1CH,'$',0,0 ;Cursor left +te: db 0CH,'$',0,0 ;Clear display +tf: db 11H,'$',0,0 ;Enter Graphics Mode +tg: db 14H,'$',0,0 ;Exit Graphics mode +th: db 06H,'$',0,0 ;Cursor home. +ti: db 1EH,'$',0,0 ;Reverse linefeed. +tj: db 02H,'$',0,0 ;Clear to end of screen. +tk: db 01H,'$',0,0 ;Clear to end of line. +ENDIF;trs80pt + +IF osi +outlin: db cr,lf,'Starting ...$' +erascr equ crlf ;"Home & clear" (best we can do). +eralin: db '^U',cr,lf,'$' ;Clear line. +prpack: db cr,lf,'RPack: $' +pspack: db cr,lf,'SPack: $' +ttab equ 0 ; no VT52 table +ENDIF;osi +; +IF hp125 ;[MF] +defesc EQU '\'-100O ;Still Control-\ (just ran out of room...) +vtval EQU 0 ; we probably don't want VT52 emulation +; +sysver: db 'HP-125 Series 100$' +; +outlin: db esc,'H',esc,'J',cr,lf,tab,tab,'$' +erascr: db esc,'H',esc,'J$' ;Clear screen and go home. +eralin: db cr,esc,'K$' ;Clear line. +curldn: db esc,'&a$' ;Cursor leadin +ttab: ;Table start location. +ta: db esc,'A$',0 ;Cursor up. +tb: db esc,'B$',0 ;Cursor down. +tc: db esc,'C$',0 ;Cursor right. +td: db esc,'D$',0 ;Cursor left +te: db esc,'J$',0 ;Clear display +tf: db '$',0,0,0 ;[hh] (can't) enter graphics mode +tg: db '$',0,0,0 ;[hh] (can't) exit graphics mode +th: db esc,'H$',0 ;Cursor home. +ti: db esc,'M$',0 ;Reverse linefeed. +tj: db esc,'J$',0 ;Clear to end of screen. +tk: db esc,'K$',0 ;Clear to end of line. +; +; +; Escape sequences to map CP/M Reader/Punch to Data Comm input/output, +; respectively and to turn off these mappings +; +mapon1: db esc,'&i10s18d9M' + db esc,'&i2s25d9M' + db esc,'&i10s16d2M' + db esc,'&i0s25d2M$';Esc. sequences to turn off DAtacomm2/turn + ;on Data Comm 1 +mapon2: db esc,'&i10s16d9M' + db esc,'&i0s25d9M' + db esc,'&i10s18d2M' + db esc,'&i2s25d2M$';Esc. sequences to turn off Datacomm1/turn + ;on Datacomm 2 +mapoff: db esc,'&i0s25d9M' + db esc,'&i10s16d9M' + db esc,'&i2s25d9M' + db esc,'&i10s18d9M$' +; +readin: call $-$ ;Read character into b + mov a,b ;Get 8-bit character + ret ;and return +; +jbuf: db 7 ;bios dispatch table vector argument block + db 0 ;to read RDR routine address + db 0c3h ;... + dw 0 ;... +; +ENDIF;hp125 ;[MF] + +IF lasm and termin ; if no terminal, no need to link +LINK CPXVDU.ASM +ENDIF ; lasm and termin + +ovlend EQU $ + +IF lasm + END ; If m80 then this ignored +ENDIF ; lasm diff --git a/cpxsyo.asm b/cpxsyo.asm index 5b1cb0e..aaba2bb 100644 --- a/cpxsyo.asm +++ b/cpxsyo.asm @@ -1,389 +1,389 @@ -IF NOT lasm -.printx * CPXSYO.ASM * -ENDIF ;NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the system dependent part for Sanyo MBC 1100 -; systems, and has been extracted from the CPMSYO.ASM code (kermit -; version 3.5) -; -; revision history: -; -; edit 1, 27 October, 1987, by OBSchou. Extracted Sanyo code from CPMSYO.ASM -; and massaged fort CP/M kermit V4.09 -; -; Keep module name, edit number, and last revision date in memory. -family: db 'CPXSYO.ASM (1) 27-Oct-87 $' -; - -; Assembly time message to let me know I'm building the right version. -; LASM generates an 'S' error along with the message, which is messy, but -; better than trying to put everything inside a IF m80 OR mac80 conditional, -; because LASM doesn't like nested IF's, either. - -IF sanyo -.printx * Assembling Kermit-80 for Sanyo MBC 1100 * -ENDIF - -iobyte EQU 03H ;Location of I/O byte - -if sanyo -baudrt EQU 0DAH ;BAUD RATE MEMORY LOCATION -MNPORT EQU 0DCH ;COMMUNICATIONS PORT -MNPRTS EQU 0DDH ;COMMUNICATIONS PORT STATUS -OUTPUT EQU 01H ;OUTPUT READY BIT -INPUT EQU 02H ;INPUT READY BIT -ENDIF;SANYO - -defesc EQU '\'-100O ;The default escape character. - -; Select initial setting for VT-52 emulation flag. -vtval EQU 1 - - -sysxin: ;system initialisation not covered by sysinit - ret ; return from system-dependent routine - -; - -; -; system-dependent termination processing -; If we've changed anything, this is our last chance to put it back. -sysexit: - ret - -; -; system-dependent processing for start of CONNECT command -; -syscon: - ret - -; - -; -; syscls - system-dependent close routine -; called when exiting transparent session. -; -syscls: - ret -; - -; -; sysinh - help for system-dependent special functions. -; called in response to ?, 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: ,,, and 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 ?, 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: ,,, and are always discarded. +sysflt: + mov a,e ; get character for testing + ret + +; mdmflt - modem filter [30] +; called with character to be sent to printer in E +; with parity set as appropriate. +; return with accumulator = 0 do do nothing, +; <> 0 to send char in E. +mdmflt: + mov a,e ;[30] get character to test + ret + + +; prtflt - printer filter [30] +; called with character to be sent to printer in E +; returns with a = 0 to do nothing +; a <> 0 to print it. +; +; this routine for those printer that automatically insert +; a lf on cr, or cr for lf. Should this be shifted to +; the system indep. stuff, in say 4.06? +prtflt: + mov a,e ; [30] get character to test + ret + + +; + +; +; system-dependent processing for BYE command. +; for apmmdm, heath, and lobo, hang up the phone. +sysbye: + ret +; + +; This is the system-dependent command to change the baud rate. +; DE contains the two-byte value from the baud rate table; this +; value is also stored in 'speed'. +sysspd: + ret + +; + +; Speed tables +; (Note that speed tables MUST be in alphabetical order for later +; lookup procedures, and must begin with a value showing the total +; number of entries. The speed help tables are just for us poor +; humans. + +; db string length,string,divisor (2 identical bytes or 1 word) +; [Toad Hall] + +IF sanyo +spdtbl EQU 0 ; No speed table for the Sanyo +sphtbl EQU 0 ; ditto help for speed. + +; The following conditionals were once a huge if not statement. There +; wasn't enough room to add the lobo to the list, so it had to be broken +; into 2, which you can't do with an if not. I redid it as two ifs and +; applied them to those that wouldn't set baud. [Hal Hostetler] +; + +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +sysprt: + ret +; + +; +; Port table not applicable tot he Sanyo... +prttbl EQU 0 +prhtbl EQU 0 ; + +; + +; +; selmdm - select modem port +; selcon - select console port +; selmdm is called before using inpmdm or outmdm; +; selcon is called before using inpcon or outcon. +; For iobyt systems, diddle the I/O byte to select console or comm port; +; For Decision I, switches Multi I/O board to console or modem serial +; port. [Toad Hall] +; For the rest, does nothing. +; preserves bc, de, hl. +selmdm: + ret + +selcon: + ret +; + +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: + mvi c,dconio ;Direct console I/O BDOS call. + mvi e,0FFH ;Input. + call BDOS + ret +; + +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: + mvi c,dconio ;Console output bdos call. + call bdos ;Output the char to the console. + ret +; + +; +; outmdm - output a char from E to the modem. +; the parity bit has been set as necessary. +; returns nonskip; bc, de, hl preserved. +outmdm: +IF inout + in mnprts ;Get the output done flag. + ani output ;Is it set? + jz outmdm ;If not, loop until it is. + mov a,e + out mnport ;Output it. + ret +ENDIF;inout + +; + +; +; get character from modem; return zero if none available. +; for IOBYT systems, the modem port has already been selected. +; destroys bc, de, hl. +inpmdm: +IF inout +;Note: modem port should already be selected for mdI. [Toad Hall] + in mnprts ;Get the port status into A. + ani input ;See if the input ready bit is on. + rz ;If not then return. + in mnport ;If so, get the char. +ENDIF;inout + ret ; return with character in A + + +; +; flsmdm - flush comm line. +; Modem is selected. +; Currently, just gets characters until none are available. + +flsmdm: call inpmdm ; Try to get a character + ora a ; Got one? + jnz flsmdm ; If so, try for another + ret ; Receiver is drained. Return. + + +; + +; +; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not. +lptstat: + xra a ; assume it is ok.. this may not be necessary + ret +; + +; +; outlpt - output character in E to printer +; console is selected. +; preserves de. +outlpt: + push d ; save DE in either case + call prtflt ; go through printer filter [30] + ana a ; if A = 0 do nothing, + jz outlp1 ; [30] if a=0 do nothing + mvi c,lstout + call bdos ;Char to printer +outlp1: pop d ; restore saved register pair + ret +; + +; +; Screen manipulation routines +; csrpos - move to row B, column C +; +; csrpos for terminals that use a leadin sequence followed +; by (row + 31.) and (column + 31.) +; +csrpos: push b ; save coordinates + lxi d,curldn ; get cursor leadin sequence + call prtstr ; print it + pop h ; restore coordinates + mov a,h ; get row + adi (' '-1) ; space is row one + mov e,a + push h + call outcon ; output row + pop h + mov a,l ; get column + adi (' '-1) ; space is column one + mov e,a + jmp outcon ; output it and return +ENDIF;NOT (robin OR dmII OR osi OR vector OR termin) + + ret ; Can the Sany do cursor opsitioning?? + +; +; +; delchr - make delete look like a backspace. Unless delete is a printing +; character, we just need to print a backspace. (we'll output clrspc +; afterwards) +; For Kaypro and Vector General, delete puts a blotch on the screen. +; For Apple and Osborne 1, delete moves but doesn't print. +delchr: + mvi e,bs + call outcon + +; erase the character at the current cursor position +clrspc: mvi e,' ' + call outcon + mvi e,bs ;get a backspace + jmp outcon + +; erase the current line +clrlin: lxi d,eralin + jmp prtstr + +; erase the whole screen, and go home. preserves b (but not c) +clrtop: lxi d,erascr + jmp prtstr + + + +IF SANYO +outlin: DB ESC,'E',ESC,'H',CR,LF,TAB ;WHATEVER +sysver: DB 'KERMIT-80 V3.9 [SANYO MBC-1100]',CR,LF,'$' ;VERSION HEADING +DELSTR: DB ESC,'K','$' ;WHATS A STRING? +eralin: DB ESC,'P','$' ;CLEAR SPACE +;CLRLIN: DB ESC,'K','$' ;CLEAR LINE +erascr: DB ESC,'E',ESC,'H','$' ;CLEAR SCREEN AND CURSOR HOME +curldn: db esc,'=','$',0 ;cursor lead in +;SCRNP: DB ESC,'=',24H,25H,'$' ;SPOT FOR SCREEN PACKETS +;SCRNRT: DB ESC,'=',25H,25H,'$' ;SPOT FOR # OF RETRIES +;SCRFLN: DB ESC,'=',26H,25H,'$' ;SPOT FOR FILE NAME +;SCRST: DB ESC,'=',28H,25H,'$' ;SPOT FOR STATUS +;SCREND: DB ESC,'=',2AH,25H,'$' ;SPOT FOR PROMPT +;SCRERR: DB ESC,'=',2DH,25H,'$' ;SPOT FOR ERRORS +ttab: ;NO TRANSLATION TABLE +ta: DB ESC,'A',0,0 ;CURSOR UP +tb: DB ESC,'B',0,0 ;CURSOR DOWN +tc: DB ESC,'D',0,0 ;CURSOR RIGHT +td: DB ESC,'C',0,0 ;CURSOR LEFT +te: DB ESC,'E',0,0 ;CLEAR SCREEN +tf: DB 0,0,0,0 ;WHAT??? +tg: DB 0,0,0,0 ;WHAT??? +th: DB ESC,'H',0,0 ;CURSOR HOME +ti: DB ESC,'A',ESC,'C',0,0 ;REVERSE LINEFEED?? +tj: DB ESC,'J',0,0 ;CLEAR TO END OF SCREEN +tk: DB ESC,'K',0,0 ;CLEAR TO END OF LINE +ENDIF;SANYO + +ovlend equ $ ; End of overlay + + END + + + + + + + + + + + + + + + diff --git a/cpxsys.asm b/cpxsys.asm index 0b179b9..93b5c1f 100644 --- a/cpxsys.asm +++ b/cpxsys.asm @@ -1,1386 +1,1386 @@ -IF NOT lasm -.printx * CPXSYS.ASM * -ENDIF ;NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the system-dependent code and data for KERMIT. -; It will be probably be broken into independent files to generate -; overlays for the various systems, one or more overlay possible -; from each file. For now, we will leave it in one piece. -; -; revision history: -; -; -; Edit 40, 28-Aug-89 by Mike Freeman of Bonneville Power Administration, -; P.O. Box 491, Vancouver WA 98666 USA, Telephone (206)690-2307: -; Home address: 301 N.E. 107th Street; Vancouver, WA 98685 USA -; Home telephone: (206)574-8221 -; added support for Hewlett-Packard HP-125 Business Assistant computer -; running a HP-modified CP/M Version 2.2; communications on -; DAta Comm 1 or Data Comm 2 (8th-bit quoting must be used on -; Data Comm 2 to transfer binary files as Data Comm 2 only supports -; a 7-bit data path); printer cannot be used with communications on -; Data Comm 2 (the printer port). -; edit 39, 4 August, 1987b by OBSchou for Charles Lasner re. DECMATE II -; fixes to set xon/off control off for the duration of Kermit-80. -; -; His header reads: -; -; IBM mode restore program -; -; This routine must be run after using CP4DMF (and KERMIT-80) to restore -; the normal handling of XON/XOFF; the user may also elect to cold-boot -; the DECMATE instead. -; -; acknowledgments and limitations. -; -; This program is based on DECMATE specific implementation details -; provided by Walt Lamia of DEC. It is of course, specific to DECMATE -; implementations of CP/M-80 for DECMATE II, III, III-plus, etc. -; -; usage consists of merely: -; -; CP4DMF run xon/xoff disable program -; KERMIT80 then run kermit -; -; 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 -; -; 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 -; -; 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 ?, 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: ,,, and 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 +; +; 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 +; +; 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 +; +; 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 ?, 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: ,,, and are always discarded. +sysflt: + mov a,e ; get character for testing +IF mikko + cpi 'O'-100O ;Control-O's lock keyboard + rnz ; if not control-O, it's ok. + xra a ; don't allow control-O out. +ENDIF;mikko + + ret + +; mdmflt - modem filter [30] +; called with character to be sent to printer in E +; with parity set as appropriate. +; return with accumulator = 0 do do nothing, +; <> 0 to send char in E. +mdmflt: + mov a,e ;[30] get character to test + ret + + + +; prtflt - printer filter [30] +; called with character to be sent to printer in E +; returns with a = 0 to do nothing +; a <> 0 to print it. +; +; this routine for those printer that automatically insert +; a lf on cr, or cr for lf. Should this be shifted to +; the system indep. stuff, in say 4.06? +prtflt: + mov a,e ; [30] get character to test + ret + + +; +; system-dependent processing for BYE command. +; for lobo, hang up the phone. +sysbye: +IF lobo ;[hh] + call discon ;[hh] force modem to hang up +ENDIF;lobo + ret + +IF lasm + LINK CPXSY2.ASM ; If m80 then this ignored +ENDIF ; lasm diff --git a/cpxtm4.asm b/cpxtm4.asm index bb933ee..b2faa7f 100644 --- a/cpxtm4.asm +++ b/cpxtm4.asm @@ -1,490 +1,490 @@ -;CPXTM4.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the system-dependent code and data for various -; Tandy Model 4 running under Montezuma Micro CPM -; -; This has the Family name of CPXTM4.ASM. -; -; revision history (last edit first) -; -; edit 5, 8-Feb-1991 by Lance Tagliapietra of the University of Wisconsin- -; Platteville. Corrected error in the VT52 translation table for -; clearing from the cursor to the end of the line. -; -; edit 4, 27 October, 1987 by OBSchou. Massaged into format suitable -; for overlay version 4.09 -; -; Edit 3: Sept 5 1987 GDS Transformed code from Genie III to Tandy Model 4 -; -; Edit 2: Aug 27 1987 GDS Put in code for BREAK and fillited out -; a lot of unnecessary IF's -; -;Edit 1: Nov. 28, 1986 Geof Smith Clinical Research centre Harrow UK. - - -.printx * Assembling for Tandy Model 4* -; -drtime EQU 05H ;Default receive time out interval. -; -; the basics... -; -mnport EQU 0EBH -mnprts EQU 0EAH -output EQU 40H -input EQU 80H -lctrl EQU 0E8H -baudpt EQU 0E9H -z80 EQU TRUE -brkval EQU 0H -inout EQU TRUE - -defesc EQU 'X'-100O ;The default escape character. - - -;Select initial setting for VT-52 emulation flag. - -; default to VT52-EMULATION ON. -; -vtval EQU 1 -; -; - - - - - - - - - -; Family is the string used in VERSION to say which of several -; smaller overlay files are used. These are (will be) derived from -; the huge CP4SYS.ASM file, in which case we will never get here. -; Just a Dollar, but put a sting in for a family of machines. -; -family: db 'CPXTM4.ASM (5) 8-Feb-91$' ; Used for family versions.... - - -; -; System-dependent initialization -; Called once at program start. -sysxin: -; - ;Set up 9600 bd, 8bit words, no parity 1stop bit - - mvi a,0EEH ;Get byte for desired baud (9600 = CC) and - out baudpt ;and put it out of baud port - out lctrl ;latch control port with anything - lda pstore ;get parity etc and put it out of - out mnprts ;port - ret ; return from system-dependent routine - -; - - - - - - - - - -; -; system-dependent termination processing -; If we've changed anything, this is our last chance to put it back. -sysexit: - ret -; -; system-dependent processing for start of CONNECT command -; -syscon: - ret - -conmsg: ; Messages printed when entering transparent (CONNECT) mode: -;------------------------------------------------------------------------------- -; -- -; -; syscls - system-dependent close routine -; called when exiting transparent session. -; -syscls: - ret -;------------------------------------------------------------------------------- -; --- -; -; sysinh - help for system-dependent special functions. -; called in response to ?, 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: ,,, and 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 ?, 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: ,,, and are always discarded. +sysflt: + mov a,e ; get character for testing + ret + +; mdmflt - modem filter [30] +; called with character to be sent to modem in E +; with parity set as appropriate. +; return with accumulator = 0 do do nothing, +; <> 0 to send char in E. +mdmflt: mov a,e + ret + + + +; prtflt - printer filter [30] +; called with character to be sent to printer in E +; returns with a = 0 to do nothing +; a <> 0 to print it. +; +; this routine for those printer that automatically insert +; a lf on cr, or cr for lf. Should this be shifted to +; the system indep. stuff, in say 4.06? +prtflt: + mov a,e ; [30] get character to test + ret + + +; + + + + + + + + + + +; +; system-dependent processing for BYE command. +; for apmmdm, heath, and lobo, hang up the phone. +sysbye: + ret +; + + + + + + + + + + +; This is the system-dependent command to change the baud rate. +; DE contains the two-byte value from the baud rate table; this +; value is also stored in 'speed'. +sysspd: + ;Set up baud rate 8bit words, no parity 1stop bit + + mov a,e ;get get speed into a + out baudpt ;output it as well + lda pstore ;get parity etc + out lctrl ;do it resetting DLAB at same time + out mnprts + ret + +pstore: db 6CH ;Default value for parity word length and stop bits + +spdtbl: db 10h ;17 entries + db 03h,'110$', 22H,22H + db 04h,'1200$', 77H,77H + db 05h,'134.5$', 33H,33H + db 03h,'150$', 44H,44H + db 04h,'1800$', 88H,88H + db 05h,'19200$', 0FFH,0FFH + db 04h,'2000$', 99H,99H + db 04h,'2400$', 0AAH,0AAH + db 03h,'300$', 55H,55H + db 04h,'3600$', 0BBH,0BBH + db 04h,'4800$', 0CCH,0CCH + db 02h,'50$', 00H,00H + db 03h,'600$', 66H,66H + db 04h,'7200$', 0DDH,0DDH + db 02h,'75$', 11H,11H + db 04h,'9600$', 0EEH,0EEH + +sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200' + db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200 $' + +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +sysprt: + ret +; +prttbl equ 0 ; SET PORT not supported +prhtbl equ 0 + +; + + + + + + + + + +; +; selmdm - select modem port +; selcon - select console port +; selmdm is called before using inpmdm or outmdm; +; selcon is called before using inpcon or outcon. +; For iobyt systems, diddle the I/O byte to select console or comm port; +; For Decision I, switches Multi I/O board to console or modem serial +; port. [Toad Hall] +; For the rest, does nothing. +; preserves bc, de, hl. +selmdm: + ret + +selcon: + ret +; + + + + + + + + + +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: + mvi c,dconio ;Direct console I/O BDOS call. + mvi e,0FFH ;Input. + call BDOS + + ret +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: + + mvi c,dconio ;Console output bdos call. + call bdos ;Output the char to the console. + + ret +; +; +; outmdm - output a char from E to the modem. +; the parity bit has been set as necessary. +; returns nonskip; bc, de, hl preserved. +outmdm: + + in mnprts ;Get the output done flag. + ani output ;Is it set? + jz outmdm ;If not, loop until it is. + mov a,e + out mnport ;Output it. + ret + +;-------------------------------------------------------------------------- +; +; get character from modem; return zero if none available. +; for IOBYT systems, the modem port has already been selected. +; destroys bc, de, hl. +inpmdm: +;Note: modem port should already be selected for mdI. [Toad Hall] + in mnprts ;Get the port status into A. + ani input ;See if the input ready bit is on. + rz ;If not then return. + in mnport ;If so, get the char. + ret ; return with character in A + + +; +; flsmdm - flush comm line. +; Modem is selected. +; Currently, just gets characters until none are available. + +flsmdm: call inpmdm ; Try to get a character + ora a ; Got one? + jnz flsmdm ; If so, try for another + ret ; Receiver is drained. Return. +;----------------------------------------------------------------------------- +; +; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not. +lptstat: + xra a ; assume it is ok.. this may not be necessary + ret + +; +; outlpt - output character in E to printer +; console is selected. +; preserves de. +outlpt: + push d ; save DE in either case + call prtflt ; go through printer filter [30] + ana a ; if A = 0 do nothing, + jz outlp1 ; [30] if a=0 do nothing + + mvi c,lstout + call bdos ;Char to printer +outlp1: pop d ; restore saved register pair + ret +;------------------------------------------------------------------------------ +; +; Screen manipulation routines +; csrpos - move to row B, column C +; +; csrpos for terminals that use a leadin sequence followed +; by (row + 31.) and (column + 31.) +; +csrpos: push b ; save coordinates + lxi d,curldn ; get cursor leadin sequence + call prtstr ; print it + pop h ; restore coordinates + mov a,h ; get row + adi (' '-1) ; space is row one + mov e,a + push h + call outcon ; output row + pop h + mov a,l ; get column + adi (' '-1) ; space is column one + mov e,a + jmp outcon ; output it and return + +; +; delchr - make delete look like a backspace. Unless delete is a printing +; character, we just need to print a backspace. (we'll output clrspc +; afterwards) +; For Kaypro and Vector General, delete puts a blotch on the screen. +; For Apple and Osborne 1, delete moves but doesn't print. +delchr: + + mvi e,bs ;get a backspace + jmp outcon + +; erase the character at the current cursor position +clrspc: mvi e,' ' + call outcon + mvi e,bs ;get a backspace + jmp outcon + +; erase the current line +clrlin: lxi d,eralin + jmp prtstr + +; erase the whole screen, and go home. preserves b (but not c) +clrtop: lxi d,erascr + jmp prtstr + +;[2] I see no real saving in having all screens in separate file and +;therefore have included screen definition here and commented out +;the link to VDU file +; +; +;Specific definitions for the Model IV screen +; +sysver: db 'Tandy Model IV$' +outlin: db 1aH,cr,lf,' $' +erascr: db 1AH,'$' +eralin: db cr,15H,'$' +curldn: db esc,'=$' +ttab: +ta: db 0BH,'$',0,0 ;Cursor up +tb: db 0AH,'$',0,0 ;Cursor down +tc: db 0CH,'$',0,0 ;Cursor right +td: db 08H,'$',0,0 ;Cursor left +te: db 1AH,'$',0,0 ;Clear display +tf: db 0FH,'$',0,0 ;Reverse on +tg: db 0EH,'$',0,0 ;Reverse off +th: db 1EH,'$',0,0 ;Cursor home +ti: db 0BH,'$',0,0 ;Reverse linefeed +tj: db 19H,'$',0,0 ;Clear to end of screen +tk: db 15H,'$',0,0 ;Clear to end of line + +ovlend equ $ ;End of overlay + + END diff --git a/cpxtor.asm b/cpxtor.asm index 51b653a..9f574ad 100644 --- a/cpxtor.asm +++ b/cpxtor.asm @@ -1,1229 +1,1229 @@ -IF NOT lasm -.printx * CPXTOR.ASM * -ENDIF ;NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the system dependent part for Torch, Superbrains, -; PCI2651 (Loughborough 8" Standard CP/M system) and Cifer computers. -; -; This is the first attempt to break the huge CPXSYS.ASM file -; into smaller system dependent files. To start with I will bunch -; several micros to one class. -; -; Please name system dependent files in the form CPXxxx.ASM where -; xxx is a three letter abbrev. for the system you are adding. -; -; revision history: -; -;edit 5, 10-Jan-1991 by MF. Removed references to assembly switch ker09. -; edit 4, 21 July, 1987 by OBSchou. Removed routines no in CPXCOM.ASM -; -; edit 3, 8 April, 1987 by OBSchou. Moved the VDU declarations for the -; Torch, superbrain and Cifer from CPXVDU.ASM. Also added code to -; see if the MCP/CCCP ROM versions on the Torch is less or grater than -; 1. Less than 1 => poor screen control. Finally adjusted the -; positioning of the filename to cope with a user number and drive -; in the filename field -; -; -; edit 2, 20 March, 1987 by C.J.MILES@UK.AC.UMRCC. Added support for -; NCR Decision Mate V (2651 USART) -; -; edit 1, 22 April, 1986, OBSchou. Start on splitting off individual -; systems from this huge file. It is done using the LINK facility -; LASM. We link to a collection of systems under CPXxxx.ASM. -; I have started with the systems I know, the Torch, Cifer and -; pci2651. These will all be held under CPXTOR.ASM -; -; -; Keep module name, edit number, and last revision date in memory. -family: db 'CPXTOR.ASM (5) 10-Jan-1991 $' -; -; Assembly time message to let me know I'm building the right version. -; LASM generates an 'S' error along with the message, which is messy, but -; better than trying to put everything inside a IF m80 OR mac80 conditional, -; because LASM doesn't like nested IF's, either. - -IF ncrdmv -.printx * Assembling KERMIT-80 for the N.C.R. Decision Mate V * -ENDIF - -IF brain -.printx * Assembling KERMIT-80 for the Intertec Superbrain * -ENDIF - -IF brainm -.printx * With main port selected -ENDIF -IF braina -.printx * With Aux port -ENDIF - -IF pci2651 ; -.printx * assembling Kermit-80 for 2651 PCI as comms device * -ENDIF - -IF torch -.printx * Assembling Kermit-80 for Torch Unicorn 5 * -ENDIF -; *******This should be in the original CPXSYS.ASM file -; -;========================================================================= -; I/O Byte assignments (2-bit fields for 4 devices at loc 3) -; -;bits 6+7 LIST field -; 0 LIST is Teletype device (TTY:) -; 1 LIST is CRT device (CRT:) -; 2 LIST is Lineprinter (LPT:) -; 3 LIST is user defined (UL1:) -; -;bits 4+5 PUNCH field -; 0 PUNCH is Teletype device (TTY:) -; 1 PUNCH is high speed punch (PUN:) -; 2 PUNCH is user defined #1 (UP1:) -; 3 PUNCH is user defined #2 (UP2:) -; -;bits 2+3 READER field -; 0 READER is Teletype device (TTY:) -; 1 READER is high speed reader (RDR:) -; 2 READER is user defined #1 (UR1:) -; 3 READER is user defined #2 (UR2:) -; -;bits 0+1 CONSOLE field -; 0 CONSOLE is console printer (TTY:) -; 1 CONSOLE is CRT device (CRT:) -; 2 CONSOLE is in Batch-mode (BAT:);READER = Input, -; LIST = Output -; 3 CONSOLE is user defined (UC1:) -; -;========================================================================= - -iobyte EQU 03H ;Location of I/O byte - - -; [13] modifed to use either main or aux port. Should really -; be selected by set port, but this is urgent, so no frills -IF brain -baudst EQU 60H ; -baudrt EQU 0EF00H ;Memory location where baud rates are stored. -output EQU 01H ;Transmitter ready -input EQU 02H ;Input data available -TxEmpty EQU 04h ;Transmitter empty -z80 SET TRUE ;I don't know... -ENDIF;brain -IF brainm ; Superbrain and main ports -mnport EQU 58H ;Modem data port -mnprts EQU 59H ;Modem status port -ENDIF ;brainm -IF braina ; Superbrain and aux port -mnport EQU 40H ;Modem data port -mnprts EQU 41H ;Modem status port -ENDIF ;braina [13] - -IF ncrdmv -iobase equ 70h ; base address of PCI device -modrx equ 70h ; Rx data port -mnprts equ 71h ; status port -mnmodr equ 72h ; mode register read -mncmdr equ 73h ; command register read -modtx equ 74h ; Tx data port -mnmodw equ 76h ; mode register write -mncmdw equ 77h ; command register write -txrdy equ 1 -output equ txrdy -rxrdy equ 2 -input equ rxrdy -baudini equ 0ah ; initial baud to 2400 -z80 SET true -cpuspd SET 40 -ENDIF - -IF pci2651 ;[28] -iobase equ 04h ; base address of PCI device -mnport equ iobase ; rx and tx data ports -mnprts equ iobase+1 ; status port -mnmode equ iobase+2 ; mode port -mncmd equ iobase+3 ; PCI command port - -txrdy equ 1 ; tx ready bit set if free -output equ txrdy -rxrdy equ 2 ; RX ready bit -input equ rxrdy -baudini equ 7 ; 7 => 1200 baud by default -z80 SET true ; For Ithica intersystems it is -cpuspd SET 40 ; and running at four megs -ENDIF ;[28] - -IF torch ;[13] -z80 SET TRUE -; [32] baudini removed as now read current baud rate -; settings from base processor. - -;baudini equ 707h ; Initial Baud rate = 1200 baud - ; Entry to be of form x0xh where x is - ; the value x in the FX 7,x and FX 8,x - ; funtion calls. 4= 1200 baud, 7 = 9600 - ; 2 = 300 baud. -ENDIF - -IF brain OR torch -defesc EQU ']'-100O ;The default escape character. -ENDIF;brain OR torch - -; If none of the above, default to VT52-EMULATION ON. -IF NOT crt -vtval EQU 1 -ENDIF;NOT crt - - -sysxin: - -IF brainm ;[25] - lda baudrt ; fetch current baud rate - ani 0F0H ; extract left nibble - rrc ; shift right 4 places - rrc - rrc - rrc - sta speed ; store as comm port speed - sta speed+1 ; (16 bits, to match speed table entries) -ENDIF;brainm - -IF braina ;[25] - lda baudrt ; fetch current baud rate - ani 00FH ; extract right nibble - sta speed ; store as comm port speed - sta speed+1 ; (16 bits, to match speed table entries) -ENDIF;braina - -IF torch ; [13] [32] - push h - mvi a,0f2h ; nick code from BBC initialisation - lxi h,0ff00h - call osbyte ; Read current speed setting - mov a,l - ani 7 - xri 7 ; Store as two's complement - inr a - sta speed - sta speed+1 - mov e,a - call sysspd ; Make sure they are both the same! - mvi a,15 ; Flush all internal buffers [32] - mvi l,0 -; call osbyte - mvi a,3 - lxi h,0100h ; *FX 3,0,1 Enable RS423 - call osbyte - mvi a,2 ; Select keyboard, Enable RS423 input - mvi l,2 - call osbyte - mvi a,5 ; Select serial printer [32] - mvi l,2 - call osbyte ; [30] - mvi a,6 ; Must be able to send LF [30] - mvi l,0 - call osbyte ; [30] - mvi a,202 ; FX 202,255 set lower case on - mvi l,255 - call osbyte - pop h - -; Now see what version of MCP CCP roms. Assume >1, else copy a few of the -; older Torch VDU declares over the new ones. -; -; lda 0ffffh ; Address 0ffffh has single byte Version no. -; push psw ; save for a rainy day -; ani 0F0h ; get ms digit of MCP version -; rra ; move right 4 places -; rra -; rra -; rra -; ani 0fh -; adi 30h ; make it a number -; sta mcpver -; pop psw ; its raining... -; push psw ; ... its pouring... -; ani 0fh ; get ls digit -; adi 30h ; make it ascii number -; sta mcpver+2 -; pop psw ; restore psw -; cpi 10h ; Version 1.00 or less? -; jp init2 ; yes, so skip next bit -; lxi h,ooutli ; from old string table -; lxi d,ttab ; to new ttab -; lxi b,60 ; 60 bytes to move -; call mover -init2: - -IF ncrdmv - mvi a,00 ; clear out command register - out mncmdw - mvi a,4eh ; 1 stop bit, 8 data bits, / by 16 counter - out mnmodw - mvi a,70h+baudini ; baud rate and select internal rate gen. - out mnmodw - mvi a,27h ; enable tx and rx, RTS and DTR low - out mncmdw -ENDIF ; ncrdmv - -IF pci2651 ;[28] - in mncmd ; clearw command reg counter - mvi a,4eh ; 1 stop bit, 8 data bits, / by 16 counter - out mnmode - mvi a,30h+baudini ; baud rate and select internal rate gen. - out mnmode - mvi a,27h ; enable tx and rx, RTS and DTR low - out mncmd -ENDIF ; pci2651 [28] - - ret ; return from system-dependent routine - -; -; -; system-dependent termination processing -; If we've changed anything, this is our last chance to put it back. -sysexit: - ret - -; -; system-dependent processing for start of CONNECT command -; -syscon: - ret - -conmsg: ; Messages printed when entering transparent (CONNECT) mode: -; -; -; syscls - system-dependent close routine -; called when exiting transparent session. -; -syscls: - ret -; -; -; sysinh - help for system-dependent special functions. -; called in response to ?, 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: ,,, and 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 ?, 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: ,,, and are always discarded. +sysflt: + mov a,e ; get character for testing + ret + +; mdmflt - modem filter [30] +; called with character to be sent to printer in E +; with parity set as appropriate. +; return with accumulator = 0 do do nothing, +; <> 0 to send char in E. +mdmflt: + mov a,e ;[30] get character to test +IF torch ;[30] map del to bs,space,bs + ani 7fh ; strip parity + cpi 7fh ; is it the delete character + rnz ; no, then a <> 0 so print it + mvi e,bs ; else load a backspace + call outmdm ; little recursion... + mvi e,' ' ; then a space + call outmdm ; backspace, space, now another... + mvi e,bs ; backspace + call outmdm ; + xra a ; clear a => on return do nowt. +ENDIF ;torch [30] + ret + + + +; prtflt - printer filter [30] +; called with character to be sent to printer in E +; returns with a = 0 to do nothing +; a <> 0 to print it. +; +; this routine for those printer that automatically insert +; a lf on cr, or cr for lf. Should this be shifted to +; the system indep. stuff, in say 4.06? +prtflt: + mov a,e ; [30] get character to test +IF torch ; strip out lf from printer stream + ani 7fh ; make sure it is parity less + cpi lf ; is it a line feed? + rnz ; no, print it +; xra a ; yes, don't. + +ENDIF ;torch [30] + ret + + +; +; +; system-dependent processing for BYE command. +; for apmmdm, heath, and lobo, hang up the phone. +sysbye: + ret +; +; This is the system-dependent command to change the baud rate. +; DE contains the two-byte value from the baud rate table; this +; value is also stored in 'speed'. +sysspd: + +; Set the speed for the Brain (Main Port) +IF brainm ;[25] + lda baudrt ;Get the present baud rates. + ani 0fH ;turn off the left + mov d,a ;Set it aside. + mov a,e ;Get the new baud rate. + rlc ;Shift left 4 places. + rlc + rlc + rlc + ora d ; combine with the old baud rate + sta baudrt ;Store the new baud rates. + out baudst ;Set the baud rates. + ret +ENDIF;brainm + +; Set the speed for the Brain (Aux Port) +IF braina ;[25] + lda baudrt ;Get the present baud rates. + ani 0f0H ;turn off the right + ora e ; combine with the new baud rate + sta baudrt ;Store the new baud rates. + out baudst ;Set the baud rates. + ret +ENDIF;braina + +If torch ; Set speed for Torch [14] [32] + mvi a,7 ; Osbyte call to set rx rate + mov l,e + call osbyte ; + mvi a,8 ; set up for tx rate to be set + mov l,e + call osbyte + ret ; and now, all rates should be different + +ENDIF ;torch [14] [32] + +IF ncrdmv ; Set baud rate for NCR Decision Mate V + mvi a,00 ; clear command register + out mncmdw + mvi a,4eh ; set for 1 stop, 8 data bits + out mnmodw ; save in mode 1 port + mvi a,70h ; set bits for rate etc.. + add e ; add baud rate (bits 0 - 3) + out mnmodw ; set mode port 2 + mvi a,27h ; set tx/rx ready, RTS CTS active + out mncmdw + ret +ENDIF ; ncrdmv + + +IF pci2651 ; Set baud for PCI [28] + in mncmd ; Clear register counter + mvi a,4eh ; set for 1 stop, 8 data bits + out mnmode ; save in mode 1 port + mvi a,30h ; set bits for rate etc.. + add e ; add baud rate (bits 0 - 3) + out mnmode ; set mode port 2 + mvi a,27h ; set tx/rx ready, RTS CTS active + out mncmd + ret +ENDIF ;pci2651 [28] + +; +; Speed tables +; (Note that speed tables MUST be in alphabetical order for later +; lookup procedures, and must begin with a value showing the total +; number of entries. The speed help tables are just for us poor +; humans. + +; db string length,string,divisor (2 identical bytes or 1 word) +; [Toad Hall] + +IF brain OR pci2651 OR ncrdmv +spdtbl: db 10h ;16 entries + db 03h,'110$', 02h,02h + db 04h,'1200$', 07h,07h + db 05h,'134.5$', 03h,03h + db 03h,'150$', 04h,04h + db 04h,'1800$', 08h,08h + db 05h,'19200$', 0fh,0fh + db 04h,'2000$', 09h,09h + db 04h,'2400$', 0ah,0ah + db 03h,'300$', 05h,05h + db 04h,'3600$', 0bh,0bh + db 04h,'4800$', 0ch,0ch + db 02h,'50$', 00h,00h + db 03h,'600$', 06h,06h + db 04h,'7200$', 0dh,0dh + db 02h,'75$', 01h,01h + db 04h,'9600$', 0eh,0eh + +sphtbl: db cr,lf,' 50 75 110 134.5 150 300 600 1200' + db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$' +ENDIF;brain OR pci2651 OR ncrdmv + +IF torch ;[17] +spdtbl: db 8 ; 8 entries + db 4,'1200$', 4,4 + db 3,'150$', 2,2 + db 5,'19200$', 8,8 + db 4,'2400$', 5,5 + db 3,'300$', 3,3 + db 4,'4800$', 6,6 + db 2,'75$', 1,1 + db 4,'9600$', 7,7 + +sphtbl: db cr,lf,' 75 150 300 1200 2400 4800 9600 19200$' +ENDIF;torch [17] + + +; The following conditionals were once a huge if not statement. There +; wasn't enough room to add the lobo to the list, so it had to be broken +; into 2, which you can't do with an if not. I redid it as two ifs and +; applied them to those that wouldn't set baud. [Hal Hostetler] +; +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +sysprt: +IF iobyt + mov a,m ;Get the I/O byte + sta prtiob ;Save the desired IO byte for this port + inx h ;Point at next entry + mov a,m ;Get the output function + sta prtfun ;Save it +ENDIF;iobyt + + ret +; +; +; +; Port tables for GENERIC CPM 2.2 +IF gener +; help text +prhtbl: db cr,lf,'CRT device' + db cr,lf,'PTR device' + db cr,lf,'TTY device' + db cr,lf,'UC1 device' + db cr,lf,'UR1 device' + db cr,lf,'UR2 device$' + +; command table +prttbl: db 06H ;Six devices to choose from + db 03H,'CRT$' + dw crtptb + db 03H,'PTR$' + dw ptrptb + db 03H,'TTY$' + dw ttyptb + db 03H,'UC1$' + dw uc1ptb + db 03H,'UR1$' + dw ur1ptb + db 03H,'UR2$' + dw ur2ptb + +; port entry table +; table entries are: +; db iobyte-value, BDOS output function, reserved +crtptb: db crtio,conout,0 +ptrptb: db ptrio,punout,0 +ttyptb: db ttyio,conout,0 +uc1ptb: db uc1io,conout,0 +ur1ptb: db ur1io,punout,0 +ur2ptb: db ur2io,punout,0 +ENDIF;gener + +; +; +IF iobyt +prtfun: db punout ;Function to use for output to comm port +prtiob: db batio ;I/O byte to use for communicating +coniob: db defio ;I/O byte to use for console +ENDIF;iobyt + +IF NOT iobyt +prttbl equ 0 ; SET PORT is not supported +prhtbl equ 0 +ENDIF;NOT iobyt +; +; +; selmdm - select modem port +; selcon - select console port +; selmdm is called before using inpmdm or outmdm; +; selcon is called before using inpcon or outcon. +; For iobyt systems, diddle the I/O byte to select console or comm port; +; For Decision I, switches Multi I/O board to console or modem serial +; port. [Toad Hall] +; For the rest, does nothing. +; preserves bc, de, hl. +selmdm: +IF iobyt + lda prtiob ;Set up for output to go to the comm port + sta iobyte ;Switch byte directly +ENDIF;iobyt + ret + +selcon: +IF iobyt + lda coniob ;Set up for output to go to the console port + sta iobyte ;Switch directly +ENDIF;iobyt + + ret +; +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: +IF NOT iobyt + mvi c,dconio ;Direct console I/O BDOS call. + mvi e,0FFH ;Input. + call BDOS +ENDIF;NOT iobyt + +IF iobyt + call bconst ;Get the status + ora a ;Anything there? + rz ;No, forget it + call bconin ;Yes, get the character +ENDIF;iobyt + ret +; +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: + +IF NOT iobyt + mvi c,dconio ;Console output bdos call. + call bdos ;Output the char to the console. +ENDIF;NOT iobyt + +IF iobyt + mov c,e ;Character + call bcnout ;to Console +ENDIF;iobyt + ret +; +; +; outmdm - output a char from E to the modem. +; the parity bit has been set as necessary. +; returns nonskip; bc, de, hl preserved. +outmdm: +IF inout AND NOT ncrdmv + in mnprts ;Get the output done flag. + ani output ;Is it set? + jz outmdm ;If not, loop until it is. + mov a,e + out mnport ;Output it. + ret +ENDIF;inout AND NOT ncrdmv + +IF inout AND ncrdmv + in mnprts ;Get the output done flag + ani output ;Set ? + jz outmdm ;Loop until it is + mov a,e + out modtx ;output char + ret +ENDIF;inout AND ncrdmv + +IF iobyt +;**** Note that we enter from outpkt with the I/O byte already set up for +; output to go to the comm port + push h + push b + lda prtfun ;Get the output function + mov c,a ;Into C + call bdos ;And output the character + pop b + pop h + ret +ENDIF;iobyt + + +IF torch ; [32] [13] Torch stuff. Requires some bit bashing + ; via the BBC host computer (io computer) + ; see also decription of osbyte later on +outdat: + lda prinuse ; get the printer in use flag + ana a ; if set, then must use traditional osbyte, + jnz outda2 ; else... + push b + push h ; Preserve registers [32] + call tx + db 1 ; MCP send to printer command + mov c,e ; Byte to send is in E [32] + call txbyte + pop h + pop b + ret + +outda2: ; Preserve registers [32] + push h + mvi a,138 ; Osbyte insert byte into buffer + mvi l,2 + mov h,e ; get the byte to be sent s-l-o-w-l-y + call osbyte + pop h ; Restore registers and exit + ret + +ENDIF ;[13] + +; +; +; get character from modem; return zero if none available. +; for IOBYT systems, the modem port has already been selected. +; destroys bc, de, hl. +inpmdm: +IF iobyt + call bconst ;Is Char at COMM-Port? + ora a ;something there? + rz ; return if nothing there + call bconin ; data present. read data. +ENDIF;iobyt + +IF inout AND NOT ncrdmv +;Note: modem port should already be selected for mdI. [Toad Hall] + in mnprts ;Get the port status into A. + ani input ;See if the input ready bit is on. + rz ;If not then return. + in mnport ;If so, get the char. +ENDIF;inout AND NOT ncrdmv + +IF inout AND ncrdmv + in mnprts ;Get input port status + ani input ;Mask input RDY bit + rz ;return if no char + in modrx ;get the char +ENDIF;inout AND ncrdmv +IF torch ; [32] [13] torch input +indat: + push h + mvi a,128 + lxi h,0fffeh ; Read buffer status + call osbyte + mov a,h ; HL has number of characters + ora l ; in the buffer + jz indatq ; None, so skip fetch + mvi a,145 ; Get character from input buffer [32] + lxi h,1 + call osbyte ; Result returned in 'Y', rather H + mov a,h +indatq: + pop h + ani 7fh + ret ; rx data in A +ENDIF ;torch [13] [32] + +ret ; return with character in A + + +; +; flsmdm - flush comm line. +; Modem is selected. +; Currently, just gets characters until none are available. + +flsmdm: call inpmdm ; Try to get a character + ora a ; Got one? + jnz flsmdm ; If so, try for another + ret ; Receiver is drained. Return. + + +; +; +; lptstat - get the printer status. Return a=0 if ok, or 0ffh if not. +lptstat: +IF torch + mvi a,80h ; read chars remaining in printer buffer + mvi l,252 ; do osbyte 80H, X=252 (printer buffer) + mvi h,0ffh + call osbyte + mov a,h + cpi 10 ; 10 characters left? + mvi a,0 ; if pos, yes r better + rp + mvi a,0ffh + ret +ENDIF ;torch + +IF torch + mvi a,5 ; got to select the real printer (par. port) + mvi l,1 ; ie FX 5,1 + call osbyte +ENDIF ;torch + +IF iobyte ;[33] + call bprtst ; get status +ENDIF ;iobyte[33] + +IF torch + push psw + mvi a,5 ; restore serial line = printer + mvi l,2 ; ie FX 5,2 + call osbyte + pop psw ; return with code in a +ENDIF ;torch + + +IF NOT iobyte ;[33] + xra a ; assume it is ok.. this may not be necessary +ENDIF ;iobyte [33] + ret +; +; +; outlpt - output character in E to printer +; console is selected. +; preserves de. +outlpt: + push d ; save DE in either case + call prtflt ; go through printer filter [30] + ana a ; if A = 0 do nothing, + jz outlp1 ; [30] if a=0 do nothing + +IF torch ;[30] Must set printer routed to par port + mvi a,5 ; fx 5,1 (parallel port selected for printer) + mvi l,1 ; Modified for new osbyte form [32] + call osbyte +ENDIF ;torch [30] + +IF NOT iobyt + mvi c,lstout + call bdos ;Char to printer +ENDIF;NOT iobyt +IF iobyt + mov c,e + call blsout +ENDIF;iobyt +IF torch ; re-route printer to serial port => faster tx bytes to line [30] + mvi a,5 ; Modified for new Osbyte form [32] + mvi l,2 ;fx 5,2 + call osbyte + mvi a,6 + mvi l,0 ;fx 6,0 + call osbyte +ENDIF ;torch [30] + +outlp1: pop d ; restore saved register pair + ret +; +; +; Screen manipulation routines +; csrpos - move to row B, column C +; +; csrpos for terminals that use a leadin sequence followed +; by (row + 31.) and (column + 31.) +; +IF brain +csrpos: push b ; save coordinates + lxi d,curldn ; get cursor leadin sequence + call prtstr ; print it + pop h ; restore coordinates + mov a,h ; get row + adi (' '-1) ; space is row one + mov e,a + push h + call outcon ; output row + pop h + mov a,l ; get column + adi (' '-1) ; space is column one + mov e,a + jmp outcon ; output it and return +ENDIF;brain +; +; +IF torch +csrpos: push b ; save coordinates + lxi d,curldn ; get cursor leadin sequence + call prtstr ; print it + pop h ; restore coordinates + mov a,l ; [obs] get column + adi 0ffh ; NULL is column one + mov e,a + push h + call outcon ; output row + pop h + mov a,h ; [obs] get row + adi 0ffh ; NULL (ie decrement) is row one + mov e,a + jmp outcon ; output it and return +ENDIF;torch +; +; +; delchr - make delete look like a backspace. Unless delete is a printing +; character, we just need to print a backspace. (we'll output clrspc +; afterwards) +; For Kaypro and Vector General, delete puts a blotch on the screen. +; For Apple and Osborne 1, delete moves but doesn't print. +delchr: + + +IF NOT torch ;[22] + mvi e,bs ;get a backspace + jmp outcon +ENDIF;NOT torch + +; erase the character at the current cursor position +clrspc: mvi e,' ' + call outcon + mvi e,bs ;get a backspace + jmp outcon + +; erase the current line +clrlin: lxi d,eralin + jmp prtstr + +; erase the whole screen, and go home. preserves b (but not c) +clrtop: lxi d,erascr + jmp prtstr + + +IF torch ;[13] +; +; OSBYTE call from Torch to BBC Base Processor. +; +; A register has osbyte type +; H register has equivalent Y register of 6502 +; L register has equivalent X register of 6502 +; +; Results (X and Y) are returned in HL respectively +; +; + +usrimm equ 0ffc0h ; MCP user function [32] +tx equ 0ffc3h ; tx routine to talk to base board proc. +rx equ 0ffc6h ; rx ditto +txbyte equ 0ffc9h ; send C to base processor [32] + +osbyte: ; Osbyte rewritten [32] + push b ; Keep these + mov b,a ; Local copy - use in a moment + call usrimm ; MCP osbyte function + db 15 + mov c,b ; Osbyte function + call txbyte + mov c,l ; 6502 X register + call txbyte + mov c,h ; 6502 Y register + call txbyte + call rx ; fetch results + mov l,a ; X returned + sta xx ; save just in case... + call rx + mov h,a ; Y returned + sta yy + mov a,b ; return A as called + pop b + ret + +xx: db 0 +yy: db 0 ; temporary space + +prinuse:db 0 ; 0=> fast tx, <>0 => slow tx to serial pt. [30] + +ENDIF ;torch [13] + +IF pci2651 ; whatever version +sysver: db 'Ithaca Intersystems S100$' +ENDIF ;pci2651 + +IF ncrdmv ; whatever version +sysver: db 'NCR DecisionMate V$' +ENDIF ;ncrdmv + +IF torch ; whatever version +ttytyp: +sysver: db 'Torch Unicorn 5 ' + db '$' ; stop here for now, otherwise say.. + db ' MCP version ' + db '1.00 $' ; or whatever... +ENDIF ;torch + +; Assume MCP - CCCP ROMS greater than 1 +;mcpver: db 'x.x $' +;outlin: db esc,'*',cr,lf,tab,'$' +;eralin: db cr,esc,'&$' ;Clear to end of line. +;erascr: db esc,'*$' ;Clear screen and go home. +;curldn: db esc,'=$' ;Cursor lead-in +;ttab: ;Table start location. +;ta: + db esc,'!$',0 ;Cursor up. +;tb: db 0ah,'$',0,0 ;Cursor down. +;tc: db esc,'+$',0 ;Cursor right. +;td: db 08h,'$',0,0 ;Cursor left. +;te: db esc,'*$',0 ;Clear screen and home cursor +;tf: db '$',0,0,0 ;(can't) Enter Graphics mode +;tg: db '$',0,0,0 ;(can't) Exit Graphics mode +;th: db esc,'>$',0 ;Cursor home. +;ti: db '$',0,0,0 ;(Can't) reverse linefeed +;tj: db esc,'%$',0 ; Clear to end of screen +;tk: db esc,'&$',0 ; Clear to end of line. + + +;Older message for MCP - CCCP verstion less than 1 +;ooutli: db 0ch,cr,lf,tab,tab,'$'; +;oerali: db '$',0,0,0 ;Clear to end of line. +;oerasc: db 0ch,'$',0 ;Clear screen and go home. +;ocurld: db 1fh,'$',0 ;Cursor lead-in +;ottab: ;Table start location. +; db 0bh,'$',0,0 ;Cursor up. +; db 0ah,'$',0,0 ;Cursor down. +; db 09h,'$',0,0 ;Cursor right. +; db 08h,'$',0,0 ;Cursor left. +; db 0ch,'$',0,0 ;Clear screen and home cursor +; db '$',0,0,0 ;(can't) Enter Graphics mode +; db '$',0,0,0 ;(can't) Exit Graphics mode +; db 1eh,'$',0,0 ;Cursor home. +; db 0bh,'$',0,0 ;reverse linfeed +; db '$',0,0,0 ;(Can't) Clear to end of screen +; db '$',0,0,0 ;(Can't) Clear to end of line. +; +;Specials +;spac15: db ' ' +; db bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,'$'; +;spac80: db cr +; db ' ' +; db ' ' +; db bs,cr,'$' ;80 spaces, bs and then back to line start +; + +IF torch ; Should be IF ker08 AND torch... + db '$' ; to terminate the ID string +outlin: db 0ch,cr,lf,tab,tab,'$' +eralin: db '$',0,0,0 ;Clear to end of line. +erascr: db 0ch,'$',0 ;Clear screen and go home. +curldn: db 1fh,'$',0 ;Cursor lead-in +ttab: ;Table start location. +ta: db 0bh,'$',0,0 ;Cursor up. +tb: db 0ah,'$',0,0 ;Cursor down. +tc: db 09h,'$',0,0 ;Cursor right. +td: db 08h,'$',0,0 ;Cursor left. +te: db 0ch,'$',0,0 ;Clear screen and home cursor +tf: db '$',0,0,0 ;(can't) Enter Graphics mode +tg: db '$',0,0,0 ;(can't) Exit Graphics mode +th: db 1eh,'$',0,0 ;Cursor home. +ti: db 0bh,'$',0,0 ;reverse linfeed +tj: db '$',0,0,0 ;(Can't) Clear to end of screen +tk: db '$',0,0,0 ;(Can't) Clear to end of line. + +;Specials +spac15: db ' ' + db bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,bs,'$'; +spac80: db cr + db ' ' + db ' ' + db bs,cr,'$' ;80 spaces, bs and then back to line start + +ENDIF;ker08 AND torch [13] + +IF brain +sysver: db 'Intertec SuperBrain$' +outlin: db ('A'-100O),esc,'~k',cr,lf,tab,tab,'$' +erascr: db ('A'-100O),esc,'~k$' ;Clear screen and go home. +eralin: db cr,esc,'~K$' ;Clear line. +curldn: db esc,'Y$' ; leadin for cursor positioning +ttab: ;Table start location. +ta: db ('K'-100O),'$',0,0 ;Cursor up. +tb: db 12O,'$',0,0 ;Cursor down. +tc: db ('F'-100O),'$',0,0 ;Cursor right. +td: db '$',0,0,0 ;(can't) Cursor left +te: db '$',0,0,0 ;(can't) Clear display +tf: db '$',0,0,0 ;(can't) Enter graphics mode +tg: db '$',0,0,0 ;(can't) Exit graphics mode +th: db ('A'-100O),'$',0,0 ;Cursor home. +ti: db ('K'-100O),'$',0,0 ;Reverse linefeed. +tj: db esc,'~k$',0 ;Clear to end of screen. +tk: db esc,'~K$',0 ;Clear to end of line. +ENDIF;brain + +IF lasm and not termin ; we dont want CPXVDU +ovlend equ $ ;Overlay end - start buffer + end +ENDIF ;lasm and not termin + +IF lasm; we want a terminal +LINK CPXVDU.ASM +ENDIF ;lasm + diff --git a/cpxtyp.asm b/cpxtyp.asm index 28b65b3..83528a9 100644 --- a/cpxtyp.asm +++ b/cpxtyp.asm @@ -1,722 +1,722 @@ -; CPXTYP.ASM -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This is the header file for building the system-dependent overlay -; for KERMIT. It contains the definitions used to select the target -; system, and collects (via INCLUDE or LINK directives) the remaining -; code. If the target system is one of the supported systems -; described below, then this is the only file that needs to be -; edited. -; -; revision history: -; -;edit 34, 10-Jan-1991 by MF. Put in "terminal required" notation for -; more machines that need terminals. -;edit 33, 9-Jan-1991 by MF. Put in "terminal required" notation for Access -; Matrix and eliminated an extra "sysfam set FALSE" when torfam set TRUE -;edit 32, 7-Jan-1991 by MF. Added code by Jay. S. Rouman to support the -; Ampro Little Board (see CPXBBI.ASM). -; Also put in a couple of missing .printx's -;edit 31, 2-Nov-1990 by MF. Moved overlay address to 7000H. -;edit 30, 14-Sep-1990 by MF. Added INCOMPLETE-FILE flag for SET -; INCOMPLETE-FILE -;edit 29, 11-Sep-1990 by MF. Moved overlay address for version 4.10. -; to 6C00H. -; edit 28, 1st September 1990 by Russell Lang, rjl@monu1.cc.monash.edu.au -; Added support for MicroBee (CPXBEE.ASM). -; -; edit 27, 28-Aug-89 by Mike Freeman, Bonneville Power Administration, -; P.O. Box 491, Vancouver WA 98666 USA: add support for Hewlett- -; Packard HP-125 "Business Assistant" computer using a HP-modified - ;CP/M Version 2.2. -; -; edit 26, 2 December, by OBSchou. Added code for CP/M-80 Kermit to -; run on an IBM-PC under Z80MU. Perverse?? No, its to allow testing -; of independent code on a PC running CP/M kermit. -; -; edit 25, 27 October, 1987 by OBSchou. Merged in Sanyo, CompuPro, Genie -; and TRS Model 4 code, and added four new families. -; CPXSYO.ASM for the Sanyo, CPXPRO.ASM for the Compupro, -; CPXTRS.ASM for the TRS-80 Model 4, CPXGNI.ASM for the Genie. -; Many thanks to G. Smith for these latter two systems. Also -; added the WYSE 100 Terminal type to the VDU table. -; -; edit 24, 17 July, 1987 by OBSchou. Added (hopefully) code from -; CP/M Kermit 3.5 (WOW) for the Heath 8. (h8quad) The actual code -; has been put into the CPXHEA.ASM family file, but I do not actually -; *KNOW* if this new version works. Anyone willing to test it out?? -; -; edit 23 16 July, 1987 for for Will Rose: -; edit of 15 Jan 1987 by C W Rose -; Added code for Micromint SB180 and Ampro 230 terminal. -; -; edit of 10 Apr 87 by C W Rose -; Amended code for pci2651 to handle Telecom Merlin M2215. -; (8085 at 5 MHz, 2651 USART, port TTY1:, Ampro 230 terminal equivalent). -; -; edit of 13 Jul 1987 by C W Rose -; Added Micromint SB180 with 6/9 MHz. option. -; -; edit 22, 15th July, 1987 by OBSchou for David Moore. -; David submitted a paper copy of Kermit 4.05 overlay for a Teletek -; system: I have (hopefully) correctly appended his code. He also -; send in the code for ADM 22 terminals. -; -; edit 21, 14 July, 1986 by OBSchou for John Shearwood of Birmingham -; University. His edits: -; edit of Apr 7th, 1987 by JA Shearwood. Added entry for Cifer Aux port -; edit of Mar 24 1987 by JA Shearwood, Birmingham. Added code for Cifer -; 1886 with CP/M Plus -; -; Also added in code from Chris Miles: -; edit of 19 May 26, 1987 by C.J.MILES@UMRCC. -; Kaypro II, Xerox 820 and Big Board II code seperated -; from CPXSYS.ASM and put in a new family file called -; CPXBBI.ASM. -; -; Finally added code from MJ Carter of Nottingham University: -; edit 16a of 5th Mar 1987 by M J Carter, Nottingham Uni [majoc], to add -; entry for OEM ScreenTyper (scntpr). See also CPXFRK.ASM ("fork"), -; the tail end of CPXLNK.ASM, and the Heath-Zenith family file -; CPXHEA.ASM (heath, z100, telcon, and scntpr). -; -; [Note: Martins CPXFRK is another version of CPXSWT.ASM] -; -; -; edit 20, 21 May 1987 by OBSchou for Colin Burns of the Institute -; of Neurological Sciences, Glasgow. Added flag for Hazeltine 1500 -; VDU (h1500) -; -; edit 19, 6th April, 1987 by OBSchou. -; Added in EQUs for Amstrad 664 and 6128 machines (CPC) and NCR -; Decsision mate V, bot sets of code submitted by Chris Miles of -; Manchester University. NCR code is similar to the PCI2651 code, so -; NCRDMV chains to CPXTOR.ASM. CPC cahins to the modified CPXPCW file -; as submitted by Chris. *** NOTE *** All Amstrad versions require -; CP/M 3, so the 664 version must both have the system upgraded to -; CP/M 3 and have an aditional RAM pack. All Amstrad systems require -; a serial interface. -; -; edit 18, 30 March, 1986. OBSchou. -; * * * Here Begineth kermit-80 Version 4.09 * * * -; -; Biggest change is the overlay address has been moved (again) to 6000h -; and the files have all been diced into families. M80 (almost) back -; in, though I have found some bugs. Will worry about those later. -; CPXSYS.ASM (CP4SYS.ASM in V4.05) now is a family file as well. -; -; Comments and all that would be much appreciated. -; -; Bertil Schou, -; The Computer Centre, -; Loughborough University of Technology, -; Loughborough -; Leicestershire, LE11 3TU -; Great Britain -; -; tel (0509) 222313 -; E-Mail (Janet) OBSchou at LOUGHBOROUGH.MULTICS -; -; -; edit 17, March 15, by OBSchou to add in support for M80 Macro Assembler. -; Now its a little messy using the M80 Assembler,asn we have family files -; and how are we gonna tell M80 what files to use? -; Sort of Simple: we generate a set of EQUs that only INCLUDE the family -; file being assembled. I hope. -; -; edit 16 Dec 1st, 1986 by OBSchou. Added entry for Amstrad PCW range (PCW) -; Code in Family file CPXPCW.ASM, submitted by Ian Young of Lattice -; Logic Systems. -; -; Edit 15 June 20 1986. Had to chand org address to 5000h to give room for -; multi-fcb space for DIR command and other additions in the system -; indepentent part. This starts Kermit-80 version 4.08... -; -; Edit 14: March 20, 1986 by OBSchou Loughborough University for -; B Robertson, Aberdeen Univ. Computing Centre. -; Add support for APPLE II with serial cards based on the 6850 ACIA. -; Mod 380Z support to allow both MDS (5 1/4" discs) and FDS (8" discs) -; configurations. Any mistakes on this merge all my fault (OBSchou) -; -; edit 13 22 April, 1986 by OBSchou Loughborough University -; Changed org address to 4000h to allow for mods to the system -; independent part for kermit version 4.06 -; -; edit 12 5 Febuary, 1986 by OBSchou -; merged in conditionals for Epson PX8 (px8). Code from Tony Addyman -; Salford University, England. -; Added code from other contibutors for Basic Northstar (basicns), -; Access-Matrix (access), US Micro Sales s1008 (s1008), -; Micro Mate (mmate), A.C.E. Discovery (disc). -; These I cannot test: please send comments back if these are buggy. -; -; edit 11 29 January 1985 by OBSchou @ multics.lut.ac.uk -; added in code for 2651 USART for use with CP/M and a VDU -; -; edit 10: 21 November, 1985 by ajcole @ leeds.ai -; Merged in support for the following: -; North Star Horizon without SIO-4 (horizon) -; Comart Communicator (comart) -; Cromemco TU-ART interface (cmemco) -; TVI912/920 VDUs (tvi912) -; -; edit 9 24 October by OBSchou. Merged code from B Robertson from -; Aberdeen University. He writes: -; September 20, 1985 by B Robertson, Aberdeen Univ. Computing Centre. -; Add support for Research Machines 380Z, North Star Advantage, Acorn -; BBC with Z80 co-processor and APPLE II with Mountain Computers CPS -; Multifunction card. -; -; edit 8: 11 October, 1985 by OBSchou -; tidied up code around Superbrain main/aux port business -; -; edit 7: 11 June, 1985 by O B Schou, Loughborough University of Tech. -; Loughborough, Leics, England. -; Added code for Torch (Second processor to BBC-B) and Cifer 1886 -; Hopefully this code will work with Torchpacks, and Cifer 26xx -; and 28xx series computers. Edits marked by OBS -; -; edit 6: 9-Feb-85 by CJC -; Merge Northstar Horizon, Lobo MAX, and Xerox 820 changes: -; 13-Dec-84 Add Northstar Horizon with SIO-4 board, port 5 at 1200 [CSM] -; 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809 -; -;pcc001 27-Dec-84 vjc modules: cp4sys,cp4typ -; Add conditional for Xerox 820. I thought at first I could -; live with the kaypro conditional, but it's enough of a pain -; that I added it back in. The clear-to-end-of-screen char -; is different, breaking many programs in VT52 mode, and the -; default escape char control-\, is not at all obvious how -; to type on the 820 keyboard. If you muddle through the -; key translation table, it turns out to be control-comma. -; Rather than OR xer820 all the occurances of kpII conditionals -; I added a bbI conditional for all common code for the big -; board I based machines that is automatically turned on by -; either kpII or xer820. This will also make it easier in -; the future if another flavor of bigboard is added. -; -;pcc010 2-Jan-85 vjc modules:cp4pkt,cp4typ -; Control-C during send or recieve clobbers some of the screen -; and doesn't look nice. Position the cursor to end of screen -; before returning to main loop. -; -;pcc013 8-Jan-85 vjc modules:cp4mit,cp4utl,cp4typ -; Replace CLOSE command to cancel session logging to SET -; LOGGING ON/OFF. This seems to fit in with the command -; structure better. Default the log file to KERMIT.LOG -; incase no previous LOG command. Logging is also enabled -; by LOG command, as before. -; -; edit 5: October 13, 1984 by L M Jones, JCC, for New York Botanical Garden -; Add support for CPT-85xx series of word processors when running CP/M. -; -; edit 4: August 29, 1984 by Bdale Garbee @ CMU -; Add support for Digicomp Delphi 100 and Netronics Smartvid terminal. -; -; edit 3: July 27, 1984 (CJC) -; Shuffle files around for easier assembly by both M80 and LASM. -; -; edit 2: June 4, 1984 [Toad Hall] -; Added Morrow Decision I (the big S100 bus sucker, not the -; little single motherboard one); added Toad Hall TACTrap to deal -; with those working through a TAC and its intercept character. -; -; edit 1: May, 1984 (CJC) -; extracted from CPMBASE.M80 version 3.9; modifications are described -; in the accompanying .UPD file. -; - -FALSE EQU 0 -TRUE EQU NOT FALSE - -; -; Assembler type. Define the appropriate one TRUE, the rest FALSE. (We can't -; use ASM, because it cannot handle multiple input files) -mac80 EQU FALSE ; For assembly via MAC80 cross-assembler. -m80 EQU FALSE ; For assembly via Microsoft's M80. -lasm EQU TRUE ; For assembly via LASM, a public-domain - ; assembler. -; -; Address at which the overlay should be loaded. This will not -; change often (no more than once per version of KERMIT); it should -; be updated when a new version of KERMIT is released. -; - -ovladr EQU 7000H ; [18] address = 6c00h for Kermit v4.10 - ;[MF]... - -cpsker EQU FALSE ; building the system-dependent part... - -; SET some options to FALSE, then SET them TRUE if needed -iobyt SET FALSE ;assume we dont want IOBYTE.. -inout SET FALSE ;... or IN/OUT code -termin SET FALSE ; we are not using a terminal -; Also set the CPU speed to a default 2.0 Mhz -cpuspd SET 20 ; default to 2 Mhz, in case we dont know -; Assume kit is Z80 based, and set z80 false for non z80 systems. -;z80 SET TRUE - -;Which CP/M system hardware are we building KERMIT-80 for? -;One of the following should be TRUE, the rest FALSE: -; -;We have basically three "classes" of systems: - -;Systems supporting the IO-redirection via I/O-Byte - -bbc EQU FALSE ;[9] Acorn BBC model B -;added code by JAS -cifer2 EQU FALSE ; Cifer 1886 using io byte flipping [OBS] -cifer3 EQU FALSE ; Cifer 1886 with CP/M Plus [JAS] - ; (Not IOBYTE but easier to keep together) -cifaux EQU FALSE ; One of above Cifers using AUX port else VL port -dmII EQU FALSE ;"Generic" KERMIT-80 for DECMATE II. -gener EQU FALSE ;"Generic" Kermit-80, CP/M calls only. - ; (terminal required) -mikko EQU FALSE ;"Generic" KERMIT-80 for MikroMikko -robin EQU FALSE ;DEC VT180 = Generic + VT100 screen control - -;.. \and Systems supporting direct IN / OUT handling of ports -advant EQU FALSE ;[10] North Star Advantage -access EQU FALSE ; Access Matrix .. uses port J5 [12] - ; (terminal required) [MF] -ampro EQU FALSE ; Ampro Little Board (terminal required) -basicns EQU FALSE ; Basic Northstar using printer port (CRT req.) -bbII EQU FALSE ;BigBoard II (terminal required) -brainm EQU FALSE ;Select Superbrain Main port **[obs] -braina EQU FALSE ;Select Superbrain AUX port **[obs] -comart EQU FALSE ;[10] Comart Communicator - ; (terminal required) -compro EQU FALSE ;Compupro Interfacer 4 (or 3) [gv] - ; (terminal required) [MF] -cpt85xx EQU FALSE ;CPT-85xx word processor w/CPM (set ADM3A TRUE) -cmemco EQU FALSE ;[10] Cromemco (TU-ART) (terminal required) -delphi EQU FALSE ;Digicomp Delphi 100 (terminal required) -disc EQU FALSE ; Action Computer Enterprises "Discovery" - ; Port B on an 83U user board (CRT required) -genie EQU FALSE ;Eaca Genie III -h8quad EQU FALSE ;[24] Entry for heath-8. NOT same as H-89 -heath EQU FALSE ;For Heath/Zenith H89. -kpII EQU FALSE ;Kaypro-II -horizon EQU FALSE ;[10] North Star Horizon (mother-board) - ; (terminal required) -m2215 EQU FALSE ; BT Merlin [23] - uses 2651, Terminal rqd -mmate EQU FALSE ; PMC - 101 MicroMate (Crt required) -mmdI EQU FALSE ;Morrow Micro Decision I (terminal required) -mdI EQU FALSE ;Morrow Decision I (the big sucker) - ; (terminal required) [Toad Hall] -ncrdmv EQU FALSE ; NCR Desision Mate V. (2651 USART) (Term rqd.) -norths EQU FALSE ;[CSM] NorthStar Horizon with HSIO-4 board - ; (terminal required) -pci2651 EQU FALSE ; CP/M with 2651 USART. Needs VDU. [11] -rm380zm EQU FALSE ;[14] Research Machines 380Z MDS (5.25" discs) -rm380zf EQU FALSE ;[14] Research Machines 380Z FDS (8" discs) -s1008 EQU FALSE ; US Micro Sales s1008 (Terminal required) -sb6 EQU FALSE ; SB180 6/9 MHz cpu speed conditionals - -sb9 EQU FALSE ; set one of these to TRUE, - it will - ; automatically set sb180 TRUE - ; (terminal reqd for Sb-180 systems) -scntpr EQU FALSE ; [majoc 870305] For OEM ScreenTyper -sanyo EQU FALSE ;For sanyo mbc-1100 series -telcon EQU FALSE ;For TELCON Zorba portable -teletek EQU FALSE ; Teletek SYSTEMASTER (terminal rqd) -trs80lb EQU FALSE ;For Lifeboat 2.25C CP/M Display -trs80pt EQU FALSE ;For Pickles + Trout CP/M Display -trsm4 EQU FALSE ;TRS80 Model 4 under Montezuma Micro CPM 2.2 -vector EQU FALSE ;For Vector Graphics. -xer820 EQU FALSE ;[pcc001] Xerox 820 -z100 EQU FALSE ;For Z-100 under CP/M-85. - -;.. and Systems doing neither... -apmmdm EQU FALSE ;jb Micromodem II in slot 2 -ap6551 EQU FALSE ;jb apple with 6551 ACIA in serial interface -ap6850 EQU FALSE ;[14] Apple with 6850 ACIA in serial interface - ;[14] e.g PACT, SSM AIO, Aristocard -apcps EQU FALSE ;[9] Apple with CP multifunction card -cpc EQU FALSE ; Amstrad CPC CP/M Plus computers -cpm3 EQU FALSE ;"Generic" Kermit-80 for CP/M 3.0 (CP/M Plus) - ; (terminal required) -lobo EQU FALSE ;Lobo Max-80 -osi EQU FALSE ;For Ohio Scientific. -osbrn1 EQU FALSE ;For Osborne 1 -pcw EQU FALSE ; Amstrad PCW 8256/8512 computers -px8 EQU FALSE ;[12] For Epson PX-8 -torch EQU FALSE ;[obs] Torch does comms via Beeb as IO processor -z80mu EQU FALSE ; CP/M-80 Kermit under z80mu emulator on PC -hp125 EQU FALSE ;[MF]HP-125 Business Assistant, 8-bit data - ; path thru Data Comm 1, 7-bit data path - ; thru Data Comm 2 (requires 8th-bit quoting - ; for binary transfers on Data Comm 2) - ; set VT52 TRUE -mbee EQU FALSE ; Microbee Systems - Microbee - -;.. and for Micros, like the MDI, which have "terminals of choice", you must -;select one of these in addition to selecting the micro itself. -;Also select a terminal for "gener" and "cpm3": use "crt" for the TRUE generic. -crt EQU FALSE ;Basic CRT, no cursor positioning -adm3a EQU FALSE ;Adm3a Display (or CPT built-in display) -adm22 EQU FALSE ;ADM 22 terminal -h1500 EQU FALSE ;Hazeltine 1500 -smrtvd EQU FALSE ;Netronics Smartvid terminal. -soroq EQU FALSE ;Soroq IQ-120.. this a guess [OBS] -am230 EQU FALSE ;Ampro 230 [13] -tvi912 EQU FALSE ;[10] TVI912/920 -tvi925 EQU FALSE ;TVI925 Display - ; (works for Freedom 100 also) [Toad Hall] -vt52 EQU FALSE ;VT52 or equivalent (or H19) -vt100 EQU FALSE ;VT100 or equivalent -wyse EQU FALSE ;Wyse 100 terminal -; -; Several systems are basically the same, with very slight variations, -; so use common code. List these sysems below -; -cifer EQU cifer2 OR cifer3 ; DO NOT TOUCH THIS LINE -brain EQU brainm OR braina ;For Intertec SuperBrain. **[obs] -; -; flag 380Z system if either selected -; -rm380z EQU rm380zm OR rm380zf ;[14] -; -trs80 EQU trs80lb OR trs80pt ; if either, flag TRS-80 system. -bbI EQU kpII OR xer820 ;[pcc001] flag for bigboard I -sb180 EQU sb6 OR sb9 ; Micromint SB180 (BYTE Oct 85) -; -; flag apple system if either selected -; -apple EQU apmmdm OR ap6551 OR ap6850 OR apcps -; -; also set termin(al) TRUE if any terminal selected (crt included) -termin SET crt OR adm3a OR adm22 OR h1500 OR smrtvd OR am230 -termin SET termin OR tvi912 OR tvi925 OR vt52 OR vt100 -termin SET termin OR wyse OR soroq - -; Now set iobyt or inout TRUE for those systems doing so -; IOBYTE systems... -IF robin OR dmII OR gener OR mikko OR cifer2 OR bbc;[**obs] -iobyt SET TRUE ;Short conditional for above -ENDIF;robin OR dmII OR gener OR cifer2 OR bbc - -; INOUT systems... -IF brain OR vector OR sanyo or compro -inout SET TRUE ;Short conditional for above -ENDIF;brain OR vector OR sanyo OR compro - -IF heath OR h8quad OR z100 OR trs80 OR telcon OR bbI -inout SET TRUE ;Short conditional for above -ENDIF;heath OR h8quad OR z100 OR trs80 OR telcon OR bbI - -IF bbII OR mmdI OR mdI OR delphi OR cpt85xx OR norths ;running out of room -inout SET TRUE ;Short conditional for above -ENDIF;bbII OR mmdI OR mdI OR delphi OR cpt85xx OR norths - -IF advant OR rm380z OR comart OR horizon OR cmemco ;[9] [10] more room here -inout SET TRUE ;Short conditional for above -ENDIF;advant OR rm380z OR comart OR horizon OR cmemco - -IF pci2651 OR m2215 OR sb180 OR ncrdmv OR teletek;[11] and even more room -inout SET TRUE ;Short conditional for above -ENDIF ;pci2651 OR m2215 OR sb180 OR ncrdmv OR teletek [11] - -IF access OR basicns OR s1008 OR mmate OR disc ; [12] -inout SET TRUE ;Short conditional for above -ENDIF ; access OR basicns OR s1008 OR mmate OR disc [12] - -IF genie OR trsm4 OR ampro -inout SET TRUE ;Short conditional for above -ENDIF ; genie OR trsm4 OR ampro - - -; Toad Hall TAC Trap: If you're going through a TAC, it will -; cough on its Intercept Character (usually a @ (* - 40H)). Sending it -; twice forces the TAC to recognize it as a valid ASCII character, -; and it'll send only one on to the host. If you've SET the TACTrap -; to OFF, it will be a null character, and nothing will happen. If you -; set it on, it will be your selected TAC intercept character (or will -; default to the common intercept char, '@'. -; If you never expect to have to work through such a beastie, just set -; TAC to false and forget all this mess. [Toad Hall] - -tac EQU FALSE ; gonna work through a TAC? -tacval EQU '@' ;Typical TAC intercept character - -; Processor speed in units of 100KHz -; for bbII, kpII, cpt85xx, advance, apple,bbc,px8 & rm380z timing loop [12] -; We have to set these before CPXCOM to make sure we update the CPU speed. - -; The following systems I have no idea of cpu speed. Can anyone oblige?? -; robin, dmII, mikko, vector, heath, h8quad, z100, scntpr -; trs80 (both), telcon, mmdI, mdI, delphi, ncrdmv, -; cromemco, teletek, osi, lobo - -IF z80mu -cpuspd SET 2 ; a PC is about 200khz Z80 equivalent -ENDIF; z80mu - -IF apple OR cpt85xx OR px8 OR heath OR h8quad ;[9] [12] What rate is heath? -cpuspd SET 20 ; Apple Softcard, CPT-85xx: 2.0 MHz - ; ('cause of integral video?) -ENDIF; apple OR cpt85xx OR px8 OR heath OR h8quad [12] - -IF kpII OR xer820 OR scntpr OR osbrn1 ;[9] What speed is scntpr?? -cpuspd SET 25 ; original Kaypro II,Xerox 820: 2.5 MHz -ENDIF;kpII OR xer820 OR scntpr OR osbrn1 - -IF PCW or CPC -cpuspd SET 33 ; all 4MHz but insterted wait states - ; reduce to an effective 3.3 MHz. -ENDIF ;pcw OR cpc - -IF brain OR advant OR bbII OR torch OR z100 OR genie OR trsm4 -cpuspd SET 40 ; 4.0 MHz CPU -ENDIF; brain OR advant OR bbII OR torch OR z100 OR genie OR trsm4 - -IF cifer OR rm380z OR comart OR horizon OR norths -cpuspd SET 40 ; 4.0 MHz CPU -ENDIF; cifer OR rm380z OR comart OR horizon OR norths - -IF disc OR mmate OR s1008 OR access OR basicns ;[29] This is a guess.. Most are 4Mhz -cpuspd SET 40 ; 4.0 MHz CPU -ENDIF ;disc OR mmate OR s1008 OR access OR basicns [29] - -IF m2215 -cpuspd SET 50 ; BT Merlin Rair Black Box is 8085 at 5 Mhz -ENDIF ;m2215 - -IF bbc or sb6 -cpuspd SET 60 ; BBC or SB-180 with 6Mhz Z80/61480 -ENDIF;bbc OR sb6 - -IF sb9 -cpuspd SET 90 ; SB-180 with 9 Mhz clock -ENDIF;sb9 - -IF hp125 OR telcon -cpuspd SET 40 ;[MF]HP125 or TELCON -ENDIF;hp125 OR telcon - -IF mbee -cpuspd SET 33 ; Microbee has 3.375MHz Z80 -ENDIF; mbee - -; Set Z80 flag FALSE for non Z80 or unknown CPU systems -IF FALSE ; assume all systems are not z80 based -;z80 SET FALSE -ENDIF ;FALSE - -; Now, lets see what family we are assembling for. Reset all -; family file to FALSE - -torfam SET FALSE ; not Torch family file -ciffam SET FALSE ; not Cifer kit -appfam SET FALSE ; not Apples -norfam SET FALSE ; not North Star kit -pcwfam SET FALSE ; not Amstrad PCW kit -bbifam SET FALSE ; not the BBI family -heafam SET FALSE ; not Heath, Z100, telcon,or screentyper -sbfam SET FALSE ; not an SB180 system -merfam SET FALSE ; not a BT Merlin system -sanfam SET FALSE ; not a Sanyo -comfam SET FALSE ; not a compupro -genfam SET FALSE ; not a genie -trsfam SET FALSE ; not a trs-80 Model 4 -z80fam SET FALSE ; not z80mu system -beefam SET FALSE ; not a Microbee system -sysfam SET TRUE ; ... but assume the worst, and its in - ; the CPXSYS.ASM file - - -IF (torch OR pci2651 OR ncrdmv OR brain) ;[15] -torfam SET TRUE ; we are to use the Torch family file -.printx * torfam set TRUE * -;(Yeah, I know, there are more than Torch systems in it) -ENDIF ;(torch OR pci2651 OR ncrdmv OR brain) [15] - -IF (cifer) -ciffam SET TRUE ; we are to use the cifer family file -.printx * ciffam set TRUE * -ENDIF ;cifer - -IF apple ;[15] -appfam SET TRUE ; apples -.printx * appfam set TRUE * -ENDIF ;apple [15] - -IF (horizon OR basicns OR norths OR advant OR comart) ;[15] -norfam SET TRUE ; north star kit -.printx * norfam set TRUE * -ENDIF ;(horizon OR basicns OR norths OR advant OR comart) [15] - -IF (pcw OR cpc) ;[15] -pcwfam SET TRUE ; Amstrad PCW kit -.printx * pcwfam set TRUE * -ENDIF ;pcw OR cpc [15] - -IF (kpII OR xer820 OR bbII OR ampro) -bbifam SET TRUE ; The Bigboard, Kaypro, Xerox and Ampro family -.printx * bbifam set TRUE * -ENDIF ;(kpII or xer820 OR bbII OR ampro) - -IF (heath OR h8quad OR telcon OR z100 OR scntpr) -heafam SET TRUE ; Doing Heath, z100, telcon, or screentyper -.printx * heafam set TRUE * -ENDIF ;(heath OR h8quad OR telcon OR z100 OR scntpr) - -IF sb180 -sbfam SET TRUE ; doing an SB180 system -.printx * sbfam set TRUE * -ENDIF ; sb180 - -IF m2215 -merfam SET TRUE ; doing a BT Merlin system -.printx * merfam set TRUE * -ENDIF ; m2215 - -IF sanyo -sanfam SET TRUE ; doing a Sanyo MBC-1100 system -.printx * sanfam set TRUE * -ENDIF ; sanyo - -IF compro -comfam SET TRUE ; doing a Compupro system -.printx * comfam set TRUE * -ENDIF ; compro - -IF genie -genfam SET TRUE ; doing a Genie system -.printx * genfam set TRUE * -ENDIF ; genie - -IF trsm4 -trsfam SET TRUE ; doing a TRS-80 M4 system -.printx * trsfam set TRUE * -ENDIF ; trs4m - -IF z80mu -z80fam SET TRUE ; doing a z80mu emulation -.printx * z80fam set TRUE * -ENDIF ; z80mu - -IF mbee -beefam SET TRUE ; doing a Microbee system -.printx * beefam set TRUE * -ENDIF ; mbee - -; Now, if none of the above, then its the older CPXSYS.ASM file we want - -IF (torfam OR ciffam OR appfam OR norfam OR sanfam OR comfam) AND sysfam -sysfam SET FALSE ; Were not doing the CPXSYS.ASM file -.printx * sysfam set FALSE * -ENDIF ; (torfam OR ciffam OR appfam OR norfam OR sanfam OR comfam) AND sysfam - -IF (pcwfam OR bbifam OR heafam OR sbfam OR merfam) AND sysfam -sysfam SET FALSE ; Were not doing the CPXSYS.ASM file -.printx * sysfam set FALSE * -ENDIF ; (pcwfam OR bbifam OR heafam OR sbfam OR merfam) AND sysfam - -IF (genfam OR trsfam OR z80fam OR beefam) AND sysfam -sysfam SET FALSE ; Were not doing the CPXSYS.ASM file -.printx * sysfam set FALSE * -ENDIF ; (genfam OR trsfam OR z80fam OR mbeefam) AND sysfam - -IF sysfam -.printx * sysfam set TRUE * -ENDIF - -IF lasm - LINK CPSDEF ; Use the system independent declares -ENDIF;lasm [Toad Hall] - -; If we're still here, must be M80 or MAC80. Collect the rest of -; the sources. -.sfcond - - - INCLUDE CPSDEF.ASM ; common definitions - INCLUDE CPXLNK.ASM ; linkage area description - INCLUDE CPXCOM.ASM ; include common code - INCLUDE CPXSWT.ASM ; this wont do much, but will announce machine - -IF torfam ;[15] - INCLUDE CPXTOR.ASM ; we are assembling for Torch, Cifer etc -ENDIF ;torfam [15] - -IF ciffam - INCLUDE CPXCIF.ASM ; we are assembling for a Cifer -ENDIF ;ciffam - -IF appfam ;[15] - INCLUDE CPXAPP.ASM ; we are assembling for an apple -ENDIF ;appfam [15] - -IF norfam ;[15] - INCLUDE CPXNOR.ASM ; we are assembling a NortStar machine -ENDIF ;norfam [15] - -IF pcwfam ;[15] - INCLUDE CPXPCW.ASM ; we are assembling for the Amstrad PCW machine -ENDIF ;pcwfam [15] - -IF bbifam - INCLUDE CPXBBI.ASM ; assembling for BigBoard, Kaypro, Xerox - ; & Ampro Little Board -ENDIF ;bbifam - -IF sysfam ;[15] - INCLUDE CPXSYS.ASM ; system-dependent code and tables (Part 1) - INCLUDE CPXSY2.ASM ; system-dependent code and tables (Part 2) -ENDIF ;sysfam [15] - -IF heafam - INCLUDE CPXHEA.ASM -ENDIF ;heafam - -IF m2215 - INCLUDE CPXMRL.ASM -ENDIF ;m2215 - -IF sbfam - INCLUDE CPXSB.ASM -ENDIF ;sbfam - -IF sanfam - INCLUDE CPXSYO.ASM -ENDIF ;sanfam - -IF comfam - INCLUDE CPXPRO.ASM -ENDIF ;comfam - -IF genfam - INCLUDE CPXGNI.ASM -ENDIF ;genfam - -IF trsfam - INCLUDE CPXTM4.ASM -ENDIF ;trsfam - -IF z80fam - INCLUDE CPXZ80.ASM -ENDIF ;z80fam - -IF beefam - INCLUDE CPXBEE.ASM -ENDIF ;beefam - -IF termin ; any terminal selected? - INCLUDE CPXVDU.ASM ;[15] Just in case we need a VDU... -ENDIF ;termin - END +; CPXTYP.ASM +; KERMIT - (Celtic for "FREE") +; +; This is the CP/M-80 implementation of the Columbia University +; KERMIT file transfer protocol. +; +; Version 4.0 +; +; Copyright June 1981,1982,1983,1984,1985 +; Columbia University +; +; Originally written by Bill Catchings of the Columbia University Center for +; Computing Activities, 612 W. 115th St., New York, NY 10025. +; +; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, +; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many +; others. +; +; This is the header file for building the system-dependent overlay +; for KERMIT. It contains the definitions used to select the target +; system, and collects (via INCLUDE or LINK directives) the remaining +; code. If the target system is one of the supported systems +; described below, then this is the only file that needs to be +; edited. +; +; revision history: +; +;edit 34, 10-Jan-1991 by MF. Put in "terminal required" notation for +; more machines that need terminals. +;edit 33, 9-Jan-1991 by MF. Put in "terminal required" notation for Access +; Matrix and eliminated an extra "sysfam set FALSE" when torfam set TRUE +;edit 32, 7-Jan-1991 by MF. Added code by Jay. S. Rouman to support the +; Ampro Little Board (see CPXBBI.ASM). +; Also put in a couple of missing .printx's +;edit 31, 2-Nov-1990 by MF. Moved overlay address to 7000H. +;edit 30, 14-Sep-1990 by MF. Added INCOMPLETE-FILE flag for SET +; INCOMPLETE-FILE +;edit 29, 11-Sep-1990 by MF. Moved overlay address for version 4.10. +; to 6C00H. +; edit 28, 1st September 1990 by Russell Lang, rjl@monu1.cc.monash.edu.au +; Added support for MicroBee (CPXBEE.ASM). +; +; edit 27, 28-Aug-89 by Mike Freeman, Bonneville Power Administration, +; P.O. Box 491, Vancouver WA 98666 USA: add support for Hewlett- +; Packard HP-125 "Business Assistant" computer using a HP-modified + ;CP/M Version 2.2. +; +; edit 26, 2 December, by OBSchou. Added code for CP/M-80 Kermit to +; run on an IBM-PC under Z80MU. Perverse?? No, its to allow testing +; of independent code on a PC running CP/M kermit. +; +; edit 25, 27 October, 1987 by OBSchou. Merged in Sanyo, CompuPro, Genie +; and TRS Model 4 code, and added four new families. +; CPXSYO.ASM for the Sanyo, CPXPRO.ASM for the Compupro, +; CPXTRS.ASM for the TRS-80 Model 4, CPXGNI.ASM for the Genie. +; Many thanks to G. Smith for these latter two systems. Also +; added the WYSE 100 Terminal type to the VDU table. +; +; edit 24, 17 July, 1987 by OBSchou. Added (hopefully) code from +; CP/M Kermit 3.5 (WOW) for the Heath 8. (h8quad) The actual code +; has been put into the CPXHEA.ASM family file, but I do not actually +; *KNOW* if this new version works. Anyone willing to test it out?? +; +; edit 23 16 July, 1987 for for Will Rose: +; edit of 15 Jan 1987 by C W Rose +; Added code for Micromint SB180 and Ampro 230 terminal. +; +; edit of 10 Apr 87 by C W Rose +; Amended code for pci2651 to handle Telecom Merlin M2215. +; (8085 at 5 MHz, 2651 USART, port TTY1:, Ampro 230 terminal equivalent). +; +; edit of 13 Jul 1987 by C W Rose +; Added Micromint SB180 with 6/9 MHz. option. +; +; edit 22, 15th July, 1987 by OBSchou for David Moore. +; David submitted a paper copy of Kermit 4.05 overlay for a Teletek +; system: I have (hopefully) correctly appended his code. He also +; send in the code for ADM 22 terminals. +; +; edit 21, 14 July, 1986 by OBSchou for John Shearwood of Birmingham +; University. His edits: +; edit of Apr 7th, 1987 by JA Shearwood. Added entry for Cifer Aux port +; edit of Mar 24 1987 by JA Shearwood, Birmingham. Added code for Cifer +; 1886 with CP/M Plus +; +; Also added in code from Chris Miles: +; edit of 19 May 26, 1987 by C.J.MILES@UMRCC. +; Kaypro II, Xerox 820 and Big Board II code seperated +; from CPXSYS.ASM and put in a new family file called +; CPXBBI.ASM. +; +; Finally added code from MJ Carter of Nottingham University: +; edit 16a of 5th Mar 1987 by M J Carter, Nottingham Uni [majoc], to add +; entry for OEM ScreenTyper (scntpr). See also CPXFRK.ASM ("fork"), +; the tail end of CPXLNK.ASM, and the Heath-Zenith family file +; CPXHEA.ASM (heath, z100, telcon, and scntpr). +; +; [Note: Martins CPXFRK is another version of CPXSWT.ASM] +; +; +; edit 20, 21 May 1987 by OBSchou for Colin Burns of the Institute +; of Neurological Sciences, Glasgow. Added flag for Hazeltine 1500 +; VDU (h1500) +; +; edit 19, 6th April, 1987 by OBSchou. +; Added in EQUs for Amstrad 664 and 6128 machines (CPC) and NCR +; Decsision mate V, bot sets of code submitted by Chris Miles of +; Manchester University. NCR code is similar to the PCI2651 code, so +; NCRDMV chains to CPXTOR.ASM. CPC cahins to the modified CPXPCW file +; as submitted by Chris. *** NOTE *** All Amstrad versions require +; CP/M 3, so the 664 version must both have the system upgraded to +; CP/M 3 and have an aditional RAM pack. All Amstrad systems require +; a serial interface. +; +; edit 18, 30 March, 1986. OBSchou. +; * * * Here Begineth kermit-80 Version 4.09 * * * +; +; Biggest change is the overlay address has been moved (again) to 6000h +; and the files have all been diced into families. M80 (almost) back +; in, though I have found some bugs. Will worry about those later. +; CPXSYS.ASM (CP4SYS.ASM in V4.05) now is a family file as well. +; +; Comments and all that would be much appreciated. +; +; Bertil Schou, +; The Computer Centre, +; Loughborough University of Technology, +; Loughborough +; Leicestershire, LE11 3TU +; Great Britain +; +; tel (0509) 222313 +; E-Mail (Janet) OBSchou at LOUGHBOROUGH.MULTICS +; +; +; edit 17, March 15, by OBSchou to add in support for M80 Macro Assembler. +; Now its a little messy using the M80 Assembler,asn we have family files +; and how are we gonna tell M80 what files to use? +; Sort of Simple: we generate a set of EQUs that only INCLUDE the family +; file being assembled. I hope. +; +; edit 16 Dec 1st, 1986 by OBSchou. Added entry for Amstrad PCW range (PCW) +; Code in Family file CPXPCW.ASM, submitted by Ian Young of Lattice +; Logic Systems. +; +; Edit 15 June 20 1986. Had to chand org address to 5000h to give room for +; multi-fcb space for DIR command and other additions in the system +; indepentent part. This starts Kermit-80 version 4.08... +; +; Edit 14: March 20, 1986 by OBSchou Loughborough University for +; B Robertson, Aberdeen Univ. Computing Centre. +; Add support for APPLE II with serial cards based on the 6850 ACIA. +; Mod 380Z support to allow both MDS (5 1/4" discs) and FDS (8" discs) +; configurations. Any mistakes on this merge all my fault (OBSchou) +; +; edit 13 22 April, 1986 by OBSchou Loughborough University +; Changed org address to 4000h to allow for mods to the system +; independent part for kermit version 4.06 +; +; edit 12 5 Febuary, 1986 by OBSchou +; merged in conditionals for Epson PX8 (px8). Code from Tony Addyman +; Salford University, England. +; Added code from other contibutors for Basic Northstar (basicns), +; Access-Matrix (access), US Micro Sales s1008 (s1008), +; Micro Mate (mmate), A.C.E. Discovery (disc). +; These I cannot test: please send comments back if these are buggy. +; +; edit 11 29 January 1985 by OBSchou @ multics.lut.ac.uk +; added in code for 2651 USART for use with CP/M and a VDU +; +; edit 10: 21 November, 1985 by ajcole @ leeds.ai +; Merged in support for the following: +; North Star Horizon without SIO-4 (horizon) +; Comart Communicator (comart) +; Cromemco TU-ART interface (cmemco) +; TVI912/920 VDUs (tvi912) +; +; edit 9 24 October by OBSchou. Merged code from B Robertson from +; Aberdeen University. He writes: +; September 20, 1985 by B Robertson, Aberdeen Univ. Computing Centre. +; Add support for Research Machines 380Z, North Star Advantage, Acorn +; BBC with Z80 co-processor and APPLE II with Mountain Computers CPS +; Multifunction card. +; +; edit 8: 11 October, 1985 by OBSchou +; tidied up code around Superbrain main/aux port business +; +; edit 7: 11 June, 1985 by O B Schou, Loughborough University of Tech. +; Loughborough, Leics, England. +; Added code for Torch (Second processor to BBC-B) and Cifer 1886 +; Hopefully this code will work with Torchpacks, and Cifer 26xx +; and 28xx series computers. Edits marked by OBS +; +; edit 6: 9-Feb-85 by CJC +; Merge Northstar Horizon, Lobo MAX, and Xerox 820 changes: +; 13-Dec-84 Add Northstar Horizon with SIO-4 board, port 5 at 1200 [CSM] +; 13-Jan-85 by Vanya J.Cooper Pima Commun. College Tel: 602-884-6809 +; +;pcc001 27-Dec-84 vjc modules: cp4sys,cp4typ +; Add conditional for Xerox 820. I thought at first I could +; live with the kaypro conditional, but it's enough of a pain +; that I added it back in. The clear-to-end-of-screen char +; is different, breaking many programs in VT52 mode, and the +; default escape char control-\, is not at all obvious how +; to type on the 820 keyboard. If you muddle through the +; key translation table, it turns out to be control-comma. +; Rather than OR xer820 all the occurances of kpII conditionals +; I added a bbI conditional for all common code for the big +; board I based machines that is automatically turned on by +; either kpII or xer820. This will also make it easier in +; the future if another flavor of bigboard is added. +; +;pcc010 2-Jan-85 vjc modules:cp4pkt,cp4typ +; Control-C during send or recieve clobbers some of the screen +; and doesn't look nice. Position the cursor to end of screen +; before returning to main loop. +; +;pcc013 8-Jan-85 vjc modules:cp4mit,cp4utl,cp4typ +; Replace CLOSE command to cancel session logging to SET +; LOGGING ON/OFF. This seems to fit in with the command +; structure better. Default the log file to KERMIT.LOG +; incase no previous LOG command. Logging is also enabled +; by LOG command, as before. +; +; edit 5: October 13, 1984 by L M Jones, JCC, for New York Botanical Garden +; Add support for CPT-85xx series of word processors when running CP/M. +; +; edit 4: August 29, 1984 by Bdale Garbee @ CMU +; Add support for Digicomp Delphi 100 and Netronics Smartvid terminal. +; +; edit 3: July 27, 1984 (CJC) +; Shuffle files around for easier assembly by both M80 and LASM. +; +; edit 2: June 4, 1984 [Toad Hall] +; Added Morrow Decision I (the big S100 bus sucker, not the +; little single motherboard one); added Toad Hall TACTrap to deal +; with those working through a TAC and its intercept character. +; +; edit 1: May, 1984 (CJC) +; extracted from CPMBASE.M80 version 3.9; modifications are described +; in the accompanying .UPD file. +; + +FALSE EQU 0 +TRUE EQU NOT FALSE + +; +; Assembler type. Define the appropriate one TRUE, the rest FALSE. (We can't +; use ASM, because it cannot handle multiple input files) +mac80 EQU FALSE ; For assembly via MAC80 cross-assembler. +m80 EQU FALSE ; For assembly via Microsoft's M80. +lasm EQU TRUE ; For assembly via LASM, a public-domain + ; assembler. +; +; Address at which the overlay should be loaded. This will not +; change often (no more than once per version of KERMIT); it should +; be updated when a new version of KERMIT is released. +; + +ovladr EQU 7000H ; [18] address = 6c00h for Kermit v4.10 + ;[MF]... + +cpsker EQU FALSE ; building the system-dependent part... + +; SET some options to FALSE, then SET them TRUE if needed +iobyt SET FALSE ;assume we dont want IOBYTE.. +inout SET FALSE ;... or IN/OUT code +termin SET FALSE ; we are not using a terminal +; Also set the CPU speed to a default 2.0 Mhz +cpuspd SET 20 ; default to 2 Mhz, in case we dont know +; Assume kit is Z80 based, and set z80 false for non z80 systems. +;z80 SET TRUE + +;Which CP/M system hardware are we building KERMIT-80 for? +;One of the following should be TRUE, the rest FALSE: +; +;We have basically three "classes" of systems: + +;Systems supporting the IO-redirection via I/O-Byte + +bbc EQU FALSE ;[9] Acorn BBC model B +;added code by JAS +cifer2 EQU FALSE ; Cifer 1886 using io byte flipping [OBS] +cifer3 EQU FALSE ; Cifer 1886 with CP/M Plus [JAS] + ; (Not IOBYTE but easier to keep together) +cifaux EQU FALSE ; One of above Cifers using AUX port else VL port +dmII EQU FALSE ;"Generic" KERMIT-80 for DECMATE II. +gener EQU FALSE ;"Generic" Kermit-80, CP/M calls only. + ; (terminal required) +mikko EQU FALSE ;"Generic" KERMIT-80 for MikroMikko +robin EQU FALSE ;DEC VT180 = Generic + VT100 screen control + +;.. \and Systems supporting direct IN / OUT handling of ports +advant EQU FALSE ;[10] North Star Advantage +access EQU FALSE ; Access Matrix .. uses port J5 [12] + ; (terminal required) [MF] +ampro EQU FALSE ; Ampro Little Board (terminal required) +basicns EQU FALSE ; Basic Northstar using printer port (CRT req.) +bbII EQU FALSE ;BigBoard II (terminal required) +brainm EQU FALSE ;Select Superbrain Main port **[obs] +braina EQU FALSE ;Select Superbrain AUX port **[obs] +comart EQU FALSE ;[10] Comart Communicator + ; (terminal required) +compro EQU FALSE ;Compupro Interfacer 4 (or 3) [gv] + ; (terminal required) [MF] +cpt85xx EQU FALSE ;CPT-85xx word processor w/CPM (set ADM3A TRUE) +cmemco EQU FALSE ;[10] Cromemco (TU-ART) (terminal required) +delphi EQU FALSE ;Digicomp Delphi 100 (terminal required) +disc EQU FALSE ; Action Computer Enterprises "Discovery" + ; Port B on an 83U user board (CRT required) +genie EQU FALSE ;Eaca Genie III +h8quad EQU FALSE ;[24] Entry for heath-8. NOT same as H-89 +heath EQU FALSE ;For Heath/Zenith H89. +kpII EQU FALSE ;Kaypro-II +horizon EQU FALSE ;[10] North Star Horizon (mother-board) + ; (terminal required) +m2215 EQU FALSE ; BT Merlin [23] - uses 2651, Terminal rqd +mmate EQU FALSE ; PMC - 101 MicroMate (Crt required) +mmdI EQU FALSE ;Morrow Micro Decision I (terminal required) +mdI EQU FALSE ;Morrow Decision I (the big sucker) + ; (terminal required) [Toad Hall] +ncrdmv EQU FALSE ; NCR Desision Mate V. (2651 USART) (Term rqd.) +norths EQU FALSE ;[CSM] NorthStar Horizon with HSIO-4 board + ; (terminal required) +pci2651 EQU FALSE ; CP/M with 2651 USART. Needs VDU. [11] +rm380zm EQU FALSE ;[14] Research Machines 380Z MDS (5.25" discs) +rm380zf EQU FALSE ;[14] Research Machines 380Z FDS (8" discs) +s1008 EQU FALSE ; US Micro Sales s1008 (Terminal required) +sb6 EQU FALSE ; SB180 6/9 MHz cpu speed conditionals - +sb9 EQU FALSE ; set one of these to TRUE, - it will + ; automatically set sb180 TRUE + ; (terminal reqd for Sb-180 systems) +scntpr EQU FALSE ; [majoc 870305] For OEM ScreenTyper +sanyo EQU FALSE ;For sanyo mbc-1100 series +telcon EQU FALSE ;For TELCON Zorba portable +teletek EQU FALSE ; Teletek SYSTEMASTER (terminal rqd) +trs80lb EQU FALSE ;For Lifeboat 2.25C CP/M Display +trs80pt EQU FALSE ;For Pickles + Trout CP/M Display +trsm4 EQU FALSE ;TRS80 Model 4 under Montezuma Micro CPM 2.2 +vector EQU FALSE ;For Vector Graphics. +xer820 EQU FALSE ;[pcc001] Xerox 820 +z100 EQU FALSE ;For Z-100 under CP/M-85. + +;.. and Systems doing neither... +apmmdm EQU FALSE ;jb Micromodem II in slot 2 +ap6551 EQU FALSE ;jb apple with 6551 ACIA in serial interface +ap6850 EQU FALSE ;[14] Apple with 6850 ACIA in serial interface + ;[14] e.g PACT, SSM AIO, Aristocard +apcps EQU FALSE ;[9] Apple with CP multifunction card +cpc EQU FALSE ; Amstrad CPC CP/M Plus computers +cpm3 EQU FALSE ;"Generic" Kermit-80 for CP/M 3.0 (CP/M Plus) + ; (terminal required) +lobo EQU FALSE ;Lobo Max-80 +osi EQU FALSE ;For Ohio Scientific. +osbrn1 EQU FALSE ;For Osborne 1 +pcw EQU FALSE ; Amstrad PCW 8256/8512 computers +px8 EQU FALSE ;[12] For Epson PX-8 +torch EQU FALSE ;[obs] Torch does comms via Beeb as IO processor +z80mu EQU FALSE ; CP/M-80 Kermit under z80mu emulator on PC +hp125 EQU FALSE ;[MF]HP-125 Business Assistant, 8-bit data + ; path thru Data Comm 1, 7-bit data path + ; thru Data Comm 2 (requires 8th-bit quoting + ; for binary transfers on Data Comm 2) + ; set VT52 TRUE +mbee EQU FALSE ; Microbee Systems - Microbee + +;.. and for Micros, like the MDI, which have "terminals of choice", you must +;select one of these in addition to selecting the micro itself. +;Also select a terminal for "gener" and "cpm3": use "crt" for the TRUE generic. +crt EQU FALSE ;Basic CRT, no cursor positioning +adm3a EQU FALSE ;Adm3a Display (or CPT built-in display) +adm22 EQU FALSE ;ADM 22 terminal +h1500 EQU FALSE ;Hazeltine 1500 +smrtvd EQU FALSE ;Netronics Smartvid terminal. +soroq EQU FALSE ;Soroq IQ-120.. this a guess [OBS] +am230 EQU FALSE ;Ampro 230 [13] +tvi912 EQU FALSE ;[10] TVI912/920 +tvi925 EQU FALSE ;TVI925 Display + ; (works for Freedom 100 also) [Toad Hall] +vt52 EQU FALSE ;VT52 or equivalent (or H19) +vt100 EQU FALSE ;VT100 or equivalent +wyse EQU FALSE ;Wyse 100 terminal +; +; Several systems are basically the same, with very slight variations, +; so use common code. List these sysems below +; +cifer EQU cifer2 OR cifer3 ; DO NOT TOUCH THIS LINE +brain EQU brainm OR braina ;For Intertec SuperBrain. **[obs] +; +; flag 380Z system if either selected +; +rm380z EQU rm380zm OR rm380zf ;[14] +; +trs80 EQU trs80lb OR trs80pt ; if either, flag TRS-80 system. +bbI EQU kpII OR xer820 ;[pcc001] flag for bigboard I +sb180 EQU sb6 OR sb9 ; Micromint SB180 (BYTE Oct 85) +; +; flag apple system if either selected +; +apple EQU apmmdm OR ap6551 OR ap6850 OR apcps +; +; also set termin(al) TRUE if any terminal selected (crt included) +termin SET crt OR adm3a OR adm22 OR h1500 OR smrtvd OR am230 +termin SET termin OR tvi912 OR tvi925 OR vt52 OR vt100 +termin SET termin OR wyse OR soroq + +; Now set iobyt or inout TRUE for those systems doing so +; IOBYTE systems... +IF robin OR dmII OR gener OR mikko OR cifer2 OR bbc;[**obs] +iobyt SET TRUE ;Short conditional for above +ENDIF;robin OR dmII OR gener OR cifer2 OR bbc + +; INOUT systems... +IF brain OR vector OR sanyo or compro +inout SET TRUE ;Short conditional for above +ENDIF;brain OR vector OR sanyo OR compro + +IF heath OR h8quad OR z100 OR trs80 OR telcon OR bbI +inout SET TRUE ;Short conditional for above +ENDIF;heath OR h8quad OR z100 OR trs80 OR telcon OR bbI + +IF bbII OR mmdI OR mdI OR delphi OR cpt85xx OR norths ;running out of room +inout SET TRUE ;Short conditional for above +ENDIF;bbII OR mmdI OR mdI OR delphi OR cpt85xx OR norths + +IF advant OR rm380z OR comart OR horizon OR cmemco ;[9] [10] more room here +inout SET TRUE ;Short conditional for above +ENDIF;advant OR rm380z OR comart OR horizon OR cmemco + +IF pci2651 OR m2215 OR sb180 OR ncrdmv OR teletek;[11] and even more room +inout SET TRUE ;Short conditional for above +ENDIF ;pci2651 OR m2215 OR sb180 OR ncrdmv OR teletek [11] + +IF access OR basicns OR s1008 OR mmate OR disc ; [12] +inout SET TRUE ;Short conditional for above +ENDIF ; access OR basicns OR s1008 OR mmate OR disc [12] + +IF genie OR trsm4 OR ampro +inout SET TRUE ;Short conditional for above +ENDIF ; genie OR trsm4 OR ampro + + +; Toad Hall TAC Trap: If you're going through a TAC, it will +; cough on its Intercept Character (usually a @ (* - 40H)). Sending it +; twice forces the TAC to recognize it as a valid ASCII character, +; and it'll send only one on to the host. If you've SET the TACTrap +; to OFF, it will be a null character, and nothing will happen. If you +; set it on, it will be your selected TAC intercept character (or will +; default to the common intercept char, '@'. +; If you never expect to have to work through such a beastie, just set +; TAC to false and forget all this mess. [Toad Hall] + +tac EQU FALSE ; gonna work through a TAC? +tacval EQU '@' ;Typical TAC intercept character + +; Processor speed in units of 100KHz +; for bbII, kpII, cpt85xx, advance, apple,bbc,px8 & rm380z timing loop [12] +; We have to set these before CPXCOM to make sure we update the CPU speed. + +; The following systems I have no idea of cpu speed. Can anyone oblige?? +; robin, dmII, mikko, vector, heath, h8quad, z100, scntpr +; trs80 (both), telcon, mmdI, mdI, delphi, ncrdmv, +; cromemco, teletek, osi, lobo + +IF z80mu +cpuspd SET 2 ; a PC is about 200khz Z80 equivalent +ENDIF; z80mu + +IF apple OR cpt85xx OR px8 OR heath OR h8quad ;[9] [12] What rate is heath? +cpuspd SET 20 ; Apple Softcard, CPT-85xx: 2.0 MHz + ; ('cause of integral video?) +ENDIF; apple OR cpt85xx OR px8 OR heath OR h8quad [12] + +IF kpII OR xer820 OR scntpr OR osbrn1 ;[9] What speed is scntpr?? +cpuspd SET 25 ; original Kaypro II,Xerox 820: 2.5 MHz +ENDIF;kpII OR xer820 OR scntpr OR osbrn1 + +IF PCW or CPC +cpuspd SET 33 ; all 4MHz but insterted wait states + ; reduce to an effective 3.3 MHz. +ENDIF ;pcw OR cpc + +IF brain OR advant OR bbII OR torch OR z100 OR genie OR trsm4 +cpuspd SET 40 ; 4.0 MHz CPU +ENDIF; brain OR advant OR bbII OR torch OR z100 OR genie OR trsm4 + +IF cifer OR rm380z OR comart OR horizon OR norths +cpuspd SET 40 ; 4.0 MHz CPU +ENDIF; cifer OR rm380z OR comart OR horizon OR norths + +IF disc OR mmate OR s1008 OR access OR basicns ;[29] This is a guess.. Most are 4Mhz +cpuspd SET 40 ; 4.0 MHz CPU +ENDIF ;disc OR mmate OR s1008 OR access OR basicns [29] + +IF m2215 +cpuspd SET 50 ; BT Merlin Rair Black Box is 8085 at 5 Mhz +ENDIF ;m2215 + +IF bbc or sb6 +cpuspd SET 60 ; BBC or SB-180 with 6Mhz Z80/61480 +ENDIF;bbc OR sb6 + +IF sb9 +cpuspd SET 90 ; SB-180 with 9 Mhz clock +ENDIF;sb9 + +IF hp125 OR telcon +cpuspd SET 40 ;[MF]HP125 or TELCON +ENDIF;hp125 OR telcon + +IF mbee +cpuspd SET 33 ; Microbee has 3.375MHz Z80 +ENDIF; mbee + +; Set Z80 flag FALSE for non Z80 or unknown CPU systems +IF FALSE ; assume all systems are not z80 based +;z80 SET FALSE +ENDIF ;FALSE + +; Now, lets see what family we are assembling for. Reset all +; family file to FALSE + +torfam SET FALSE ; not Torch family file +ciffam SET FALSE ; not Cifer kit +appfam SET FALSE ; not Apples +norfam SET FALSE ; not North Star kit +pcwfam SET FALSE ; not Amstrad PCW kit +bbifam SET FALSE ; not the BBI family +heafam SET FALSE ; not Heath, Z100, telcon,or screentyper +sbfam SET FALSE ; not an SB180 system +merfam SET FALSE ; not a BT Merlin system +sanfam SET FALSE ; not a Sanyo +comfam SET FALSE ; not a compupro +genfam SET FALSE ; not a genie +trsfam SET FALSE ; not a trs-80 Model 4 +z80fam SET FALSE ; not z80mu system +beefam SET FALSE ; not a Microbee system +sysfam SET TRUE ; ... but assume the worst, and its in + ; the CPXSYS.ASM file + + +IF (torch OR pci2651 OR ncrdmv OR brain) ;[15] +torfam SET TRUE ; we are to use the Torch family file +.printx * torfam set TRUE * +;(Yeah, I know, there are more than Torch systems in it) +ENDIF ;(torch OR pci2651 OR ncrdmv OR brain) [15] + +IF (cifer) +ciffam SET TRUE ; we are to use the cifer family file +.printx * ciffam set TRUE * +ENDIF ;cifer + +IF apple ;[15] +appfam SET TRUE ; apples +.printx * appfam set TRUE * +ENDIF ;apple [15] + +IF (horizon OR basicns OR norths OR advant OR comart) ;[15] +norfam SET TRUE ; north star kit +.printx * norfam set TRUE * +ENDIF ;(horizon OR basicns OR norths OR advant OR comart) [15] + +IF (pcw OR cpc) ;[15] +pcwfam SET TRUE ; Amstrad PCW kit +.printx * pcwfam set TRUE * +ENDIF ;pcw OR cpc [15] + +IF (kpII OR xer820 OR bbII OR ampro) +bbifam SET TRUE ; The Bigboard, Kaypro, Xerox and Ampro family +.printx * bbifam set TRUE * +ENDIF ;(kpII or xer820 OR bbII OR ampro) + +IF (heath OR h8quad OR telcon OR z100 OR scntpr) +heafam SET TRUE ; Doing Heath, z100, telcon, or screentyper +.printx * heafam set TRUE * +ENDIF ;(heath OR h8quad OR telcon OR z100 OR scntpr) + +IF sb180 +sbfam SET TRUE ; doing an SB180 system +.printx * sbfam set TRUE * +ENDIF ; sb180 + +IF m2215 +merfam SET TRUE ; doing a BT Merlin system +.printx * merfam set TRUE * +ENDIF ; m2215 + +IF sanyo +sanfam SET TRUE ; doing a Sanyo MBC-1100 system +.printx * sanfam set TRUE * +ENDIF ; sanyo + +IF compro +comfam SET TRUE ; doing a Compupro system +.printx * comfam set TRUE * +ENDIF ; compro + +IF genie +genfam SET TRUE ; doing a Genie system +.printx * genfam set TRUE * +ENDIF ; genie + +IF trsm4 +trsfam SET TRUE ; doing a TRS-80 M4 system +.printx * trsfam set TRUE * +ENDIF ; trs4m + +IF z80mu +z80fam SET TRUE ; doing a z80mu emulation +.printx * z80fam set TRUE * +ENDIF ; z80mu + +IF mbee +beefam SET TRUE ; doing a Microbee system +.printx * beefam set TRUE * +ENDIF ; mbee + +; Now, if none of the above, then its the older CPXSYS.ASM file we want + +IF (torfam OR ciffam OR appfam OR norfam OR sanfam OR comfam) AND sysfam +sysfam SET FALSE ; Were not doing the CPXSYS.ASM file +.printx * sysfam set FALSE * +ENDIF ; (torfam OR ciffam OR appfam OR norfam OR sanfam OR comfam) AND sysfam + +IF (pcwfam OR bbifam OR heafam OR sbfam OR merfam) AND sysfam +sysfam SET FALSE ; Were not doing the CPXSYS.ASM file +.printx * sysfam set FALSE * +ENDIF ; (pcwfam OR bbifam OR heafam OR sbfam OR merfam) AND sysfam + +IF (genfam OR trsfam OR z80fam OR beefam) AND sysfam +sysfam SET FALSE ; Were not doing the CPXSYS.ASM file +.printx * sysfam set FALSE * +ENDIF ; (genfam OR trsfam OR z80fam OR mbeefam) AND sysfam + +IF sysfam +.printx * sysfam set TRUE * +ENDIF + +IF lasm + LINK CPSDEF ; Use the system independent declares +ENDIF;lasm [Toad Hall] + +; If we're still here, must be M80 or MAC80. Collect the rest of +; the sources. +.sfcond + + + INCLUDE CPSDEF.ASM ; common definitions + INCLUDE CPXLNK.ASM ; linkage area description + INCLUDE CPXCOM.ASM ; include common code + INCLUDE CPXSWT.ASM ; this wont do much, but will announce machine + +IF torfam ;[15] + INCLUDE CPXTOR.ASM ; we are assembling for Torch, Cifer etc +ENDIF ;torfam [15] + +IF ciffam + INCLUDE CPXCIF.ASM ; we are assembling for a Cifer +ENDIF ;ciffam + +IF appfam ;[15] + INCLUDE CPXAPP.ASM ; we are assembling for an apple +ENDIF ;appfam [15] + +IF norfam ;[15] + INCLUDE CPXNOR.ASM ; we are assembling a NortStar machine +ENDIF ;norfam [15] + +IF pcwfam ;[15] + INCLUDE CPXPCW.ASM ; we are assembling for the Amstrad PCW machine +ENDIF ;pcwfam [15] + +IF bbifam + INCLUDE CPXBBI.ASM ; assembling for BigBoard, Kaypro, Xerox + ; & Ampro Little Board +ENDIF ;bbifam + +IF sysfam ;[15] + INCLUDE CPXSYS.ASM ; system-dependent code and tables (Part 1) + INCLUDE CPXSY2.ASM ; system-dependent code and tables (Part 2) +ENDIF ;sysfam [15] + +IF heafam + INCLUDE CPXHEA.ASM +ENDIF ;heafam + +IF m2215 + INCLUDE CPXMRL.ASM +ENDIF ;m2215 + +IF sbfam + INCLUDE CPXSB.ASM +ENDIF ;sbfam + +IF sanfam + INCLUDE CPXSYO.ASM +ENDIF ;sanfam + +IF comfam + INCLUDE CPXPRO.ASM +ENDIF ;comfam + +IF genfam + INCLUDE CPXGNI.ASM +ENDIF ;genfam + +IF trsfam + INCLUDE CPXTM4.ASM +ENDIF ;trsfam + +IF z80fam + INCLUDE CPXZ80.ASM +ENDIF ;z80fam + +IF beefam + INCLUDE CPXBEE.ASM +ENDIF ;beefam + +IF termin ; any terminal selected? + INCLUDE CPXVDU.ASM ;[15] Just in case we need a VDU... +ENDIF ;termin + END diff --git a/cpxvdu.asm b/cpxvdu.asm index 332fd8f..85704a6 100644 --- a/cpxvdu.asm +++ b/cpxvdu.asm @@ -1,462 +1,462 @@ -IF NOT lasm -.printx * CPXVDU.ASM * -ENDIF ;NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -;edit 6, 12-Oct-1990 by MF. Added a semicolon to the comment "If we -; need cursor ..." so it isn't seen as an undefined symbol -; edit 5, 20 July by OBSchou. Put in the cursor positioning code for -; all the terminal supported, and moved the vtval EQUs and defesc EQUs -; here if the system requires andn external terminal. If the system -; has a 'built in' terminal (ie own scrteen driver) you will not come -; to this file, so you must declare these three lables etc in your -; own code. -; This will allow only those systems requiring a terminal to require -; CPXVDU.ASM during assembly. -; -; edit 4, 16 July, 1987 by OBSchou for will Rose. -; Added code for Ampro 230 terminal -; -; edit 3, 15 July, 1987 by OBSchou for David Moore. Added adm22 terminal -; codes. -; -; edit 2 21 May, 1987 by OBSchou. Added in definitions for Hazeltine 1500 -; submitted by Colin Burns of the Institute of Neurological Sciences -; in Glasgow. -; edit 1 ??? date. Split the terminal codes off from the CPXSYS.ASM file -; -vduver: db 'CPXVDU.ASM (6) 12-Oct-1990 $' ;file, edit version,, date. - - -; First, print out what terminal (if any) we are assembling for - -IF crt -.printx * generic CRT selected * -ENDIF - -IF adm3a -.printx * ADM3A selected * -ENDIF - -IF adm22 -.printx * ADM22 selected * -ENDIF - -IF smrtvd ;[7] -.printx * Netronics Smartvid-80 selected * -ENDIF ;[7] - -IF tvi912 -.printx * TVI912/920 selected * -ENDIF - -IF tvi925 -.printx * TVI925 selected * -ENDIF - -IF vt52 -.printx * VT52 selected * -ENDIF - -IF vt100 -.printx * VT100 selected * -ENDIF - -IF am230 -.printx * Ampro 230 terminal selected * -ENDIF - -IF wyse -.printx * Wyse 100 terminal selected * -ENDIF -; - -; -; If we need cursor positioning, here is the code to do it -; -; Screen manipulation routines -; csrpos - move to row B, column C -; -; csrpos for terminals that use a leadin sequence followed -; by (row + 31.) and (column + 31.) -; -IF NOT (vt100 OR crt OR h1500) -csrpos: push b ; save coordinates - lxi d,curldn ; get cursor leadin sequence - call prtstr ; print it - pop h ; restore coordinates - mov a,h ; get row - adi (' '-1) ; space is row one - mov e,a - push h - call outcon ; output row - pop h - mov a,l ; get column - adi (' '-1) ; space is column one - mov e,a - jmp outcon ; output it and return -ENDIF;NOT (vt100 OR crt OR h1500) -; -; -; -; -; csrpos for ANSI terminals -; -IF vt100 -csrpos: push b ; save coordinates - lxi d,curldn ; get cursor leadin sequence - call prtstr ; print it - pop h ; peek at coordinates - push h ; then save away again - mov l,h ; l = row - mvi h,0 ; hl = row - call nout ; output in decimal - mvi e,';' ; follow with semicolon - call outcon ; print it - pop h ; restore column - mvi h,0 ; hl = column - call nout - mvi e,'H' ; terminate with 'move cursor' command - jmp outcon ; output it and return -ENDIF;vt100 - -;Definition for Hazeltine 1500 does things a little strange. -; -IF h1500 -csrpos: push b ; save coordinates - lxi d,curldn ; get cursor leadin sequence - call prtstr ; print it - pop h ; restore coordinates - mov a,l ; get col - nop - nop -; adi (' '-1) ; space is row one - mov e,a - push h - call outcon ; output row - pop h - mov a,h ; get row - adi (' '-1) ; space is column one - mov e,a - jmp outcon ; output it and return -ENDIF; h1500 - - -IF crt ; systems without cursor positioning -csrpos: ret ; dummy routine referenced by linkage section -ENDIF;crt -; -; -; -; Now for the rest of CPXVDU.ASM -; -; -; -IF crt ;Set flags etc for systems with CRT selected -defesc EQU '\'-100O ;Still Control-\ (just ran out of room...) -vtval EQU 0FFH ; we can't support VT52 emulation -ttytyp: db 'Generic (Dumb) CRT Terminal type selected $' -ENDIF;crt - -; - -IF vt52 ; DEC VT52 -ttytyp: db 'VT52$' -ENDIF;vt52 - -IF vt52 -vtval EQU 0 ; we don't need VT52 emulation -defesc EQU '\'-100O ;Still Control-\ (just ran out of room...) -outlin: db esc,'H',esc,'J',cr,lf,tab,tab,'$' -erascr: db esc,'H',esc,'J$' ;Clear screen and go home. -eralin: db cr,esc,'K$' ;Clear line. -curldn: db esc,'Y$' ;cursor leadin -ttab: ;Table start location. -ta: db esc,'A$',0 ;Cursor up. -tb: db esc,'B$',0 ;Cursor down. -tc: db esc,'C$',0 ;Cursor right. -td: db esc,'D$',0 ;Cursor left -te: db esc,'E$',0 ;Clear display -tf: db esc,'F$',0 ;Enter Graphics Mode -tg: db esc,'G$',0 ;Exit Graphics mode -th: db esc,'H$',0 ;Cursor home. -ti: db esc,'I$',0 ;Reverse linefeed. -tj: db esc,'J$',0 ;Clear to end of screen. -tk: db esc,'K$',0 ;Clear to end of line. -ENDIF;vt52 -; - -IF adm22 -vtval EQU 1 ; we can do VT52 emulation -defesc EQU '\'-100O ;Still Control-\ (just ran out of room...) -ttytyp: db 'ADM22$' -outlin: db 1ah,cr,lf,tab,tab,'$' -erascr: db 1ah,'$' ;Clear screen and go home. -eralin: db esc,'>$' ;Clear line. -curldn: db esc,'=$' ;Cursor lead-in -ttab: ;Table start location. -ta: db 0BH,'$',0,0 ;Cursor up. -tb: db lf,'$',0,0 ;Cursor down. -tc: db 0CH,'$',0,0 ;Cursor right. -td: db bs,'$',0,0 ;Cursor left -te: db 1ah,':$',0 ;Clear display -tf: db '$',0,0,0 ;(can't) Enter Graphics Mode -tg: db '$',0,0,0 ;(can't) Exit Graphics mode -th: db 1EH,'$',0,0 ;Cursor home. -ti: db 0BH,'$',0,0 ;Reverse linefeed. -tj: db esc,'Y$',0 ;Clear to end of screen. -tk: db esc,'T$',0 ;Clear to end of line. -ENDIF;adm22 -; - -IF am230 -; Select initial setting for VT-52 emulation flag. -vtval EQU 1 -defesc EQU '\'-100O ;The default is Control-\ -- it's easier -ttytyp: db 'Am230$' -outlin: db 'Z'-64,0,0,cr,lf,'$' -erascr: db 'Z'-64,0,0,'$' ;Clear screen and home -eralin: db esc,'R$',0 ;Erase line -curldn: db cr,esc,'=$' ;Cursor lead-in -ttab: ;Table start location ;(MUST be 4 bytes each) -ta: db 'K'-64,'$',0,0 ;Cursor up, stop at top -tb: db 'V'-64,'$',0,0 ;Cursor down, stop at bottom -tc: db 'L'-64,'$',0,0 ;Cursor right, stop at right -td: db 'H'-64,'$',0,0 ;Cursor left, stop at left -te: db 'Z'-64,0,0,'$' ;Clear display (2 pad nulls) -tf: db '$',0,0,0 ;(can't) Enter Graphics mode -tg: db '$',0,0,0 ;(can't) Exit Graphics mode -th: db 1EH,'$',0,0 ;Cursor home -ti: db esc,'j$',0 ;Reverse linefeed, scroll -tj: db esc,'Y$',0 ;Clear to end of sreen -tk: db esc,'T$',0 ;Clear to end of line -ENDIF -; -; - - -IF vt100 -ttytyp: db 'VT100$' -ENDIF;vt100 - - -IF vt100 -; Note that we cannot support Graphics Mode or the H19 erase-screen command -; (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 +; (E), because the sequences are more than three bytes. +defesc EQU '\'-100O ;Still Control-\ (just ran out of room...) +vtval EQU 0 ; we probably don't want VT52 emulation +outlin: db esc,3CH,esc,'[H',esc,'[J',cr,lf,tab,tab,'$' +erascr: db esc,'[H',esc,'[J$' ;Clear screen and go home. +eralin: db cr,esc,'[K$' ;Clear line. +curldn: db esc,'[$' ; Cursor leadin +ttab: +ta: db esc,'[A$' ; Cursor up. +tb: db esc,'[B$' ; Cursor down. +tc: db esc,'[C$' ; Cursor right. +td: db esc,'[D$' ; Cursor left +te: db '$',0,0,0 ; (can't) Clear display +tf: db '$',0,0,0 ; (don't) Enter Graphics Mode +tg: db '$',0,0,0 ; (don't) Exit Graphics mode +th: db esc,'[H$' ; Cursor home. +ti: db esc,'M$',0 ; Reverse linefeed. +tj: db esc,'[J$' ; Clear to end of screen. +tk: db esc,'[K$' ; Clear to end of line. +ENDIF;vt100 +; + +IF gener or cpm3 +sysver: db 'Generic CP/M-80$' +ENDIF;gener or cpm3 + + +IF soroq ;[29] Should this not be with terminals..... +ttytyp: db 'Soroc IQ-120$' +outlin: db 1EH,esc,'Y',cr,lf,tab,tab,'$' +erascr: db 1EH,esc,'Y$' ;clear screen and home cursor +eralin: db cr,esc,'T$' ;clear line +curldn: db esc,'=$' ;cursor lead-in string +delstr: db bs,' ',bs,bs,'$' ;??adjust for echoing delete +ttab: ;table start location +ta: db 0BH,'$',0 ;cursor up +tb: db 0AH,'$',0 ;cursor down +tc: db 0CH,'$',0 ;cursor right +td: db 08H,'$',0 ;cursor left +te: db esc,'*$',0 ;clear display (homes cursor) +tf: db esc,')$',0 ;enter inverse video mode +tg: db esc,'($',0 ;exit inverse video mode +th: db 01EH,'$',0 ;home cursor +ti: db 0BH,'$',0 ;reverse linefeed (insert line) +tj: db esc,'Y$',0 ;clear to end of screen +tk: db esc,'T$',0 ;clear to end of line +ENDIF;soroq + +IF crt +outlin: db cr,lf,'Starting ...$' +erascr equ crlf ;"Home & clear" (best we can do). +eralin: db '^U',cr,lf,'$' ;Clear line. +prpack: db cr,lf,'RPack: $' +pspack: db cr,lf,'SPack: $' +ttab equ 0 ; no VT52 table +ENDIF;crt +; + +IF tvi912 +vtval EQU 1 ; we do emulation +defesc EQU '\'-100O ;Still Control-\ (just ran out of room...) +ttytyp: db 'TVI912/920$' +outlin: db 'Z'-64,0,0,cr,lf,'$' +erascr: db 'Z'-64,0,0,'$' ;Clear screen and home +eralin: db esc,'Y$',0 ;Clear to end of sreen +curldn: db cr,esc,'=$' ;Cursor lead-in +ttab: ;Table start location ;(MUST be 4 bytes each) +ta: db 'K'-64,'$',0,0 ;Cursor up, stop at top +tb: db 'J'-64,'$',0,0 ;Cursor down, stop at bottom +tc: db 'L'-64,'$',0,0 ;Cursor right, stop at right +td: db 'H'-64,'$',0,0 ;Cursor left, stop at left +te: db 'Z'-64,0,0,'$' ;Clear display (2 pad nulls) +tf: db '$',0,0,0 ;(can't) Enter Graphics mode +tg: db '$',0,0,0 ;(can't) Exit Graphics mode +th: db 1EH,'$',0,0 ;Cursor home +ti: db esc,'j$',0 ;Reverse linefeed, scroll +tj: db esc,'Y$',0 ;Clear to end of sreen +tk: db esc,'T$',0 ;Clear to end of line +ENDIF;tvi912 +; +; + +IF tvi925 +;(incidentally, works fine for Freedom 100 also [Toad Hall]) +;adm3a entry and tvi925 entry separated to remove warning message. +vtval EQU 1 ; we VT52 emulation +defesc EQU '\'-100O ;Still Control-\ (just ran out of room...) +ttytyp: db 'TVI925$' +outlin: db 'Z'-64,0,0,cr,lf,'$' +erascr: db 'Z'-64,0,0,'$' ;Clear screen and home +eralin: db esc,'Y$',0 ;Clear to end of sreen +curldn: db cr,esc,'=$' ;Cursor lead-in +ttab: ;Table start location ;(MUST be 4 bytes each) +ta: db 'K'-64,'$',0,0 ;Cursor up, stop at top +tb: db 'V'-64,'$',0,0 ;Cursor down, stop at bottom +tc: db 'L'-64,'$',0,0 ;Cursor right, stop at right +td: db 'H'-64,'$',0,0 ;Cursor left, stop at left +te: db 'Z'-64,0,0,'$' ;Clear display (2 pad nulls) +tf: db '$',0,0,0 ;(can't) Enter Graphics mode +tg: db '$',0,0,0 ;(can't) Exit Graphics mode +th: db 1EH,'$',0,0 ;Cursor home +ti: db esc,'j$',0 ;Reverse linefeed, scroll +tj: db esc,'Y$',0 ;Clear to end of sreen +tk: db esc,'T$',0 ;Clear to end of line +ENDIF;tvi925 +; +; + +IF adm3a +defesc EQU '\'-100O ;Still Control-\ (just ran out of room...) +ttytyp: db 'ADM3A$' +outlin: db 'Z'-64,0,0,cr,lf,'$' +erascr: db 'Z'-64,0,0,'$' ;Clear screen and home +eralin: db esc,'Y$',0 ;Clear to end of sreen +curldn: db cr,esc,'=$' ;Cursor lead-in +ttab: ;Table start location ;(MUST be 4 bytes each) +ta: db 'K'-64,'$',0,0 ;Cursor up, stop at top +tb: db 'J'-64,'$',0,0 ;Cursor down CTRL-J +tc: db 'L'-64,'$',0,0 ;Cursor right, stop at right +td: db 'H'-64,'$',0,0 ;Cursor left, stop at left +te: db 'Z'-64,0,0,'$' ;Clear display (2 pad nulls) +tf: db '$',0,0,0 ;(can't) Enter Graphics mode +tg: db '$',0,0,0 ;(can't) Exit Graphics mode +th: db 1EH,'$',0,0 ;Cursor home +ti: db 'K'-64,'$',0,0 ;Reverse linefeed +tj: db '$',0,0,0 ;(can't) Clear to end of screen +tk: db '$',0,0,0 ;(can't) Clear to end of line +ENDIF;adm3a + + +IF smrtvd ; [7] new terminal +vtval EQU 1 ; we do VT52 emulation +defesc EQU '\'-100O ; escpae character, ok? +ttytyp: db 'Smartvid-80$' +outlin: db esc,'+',cr,lf,tab,tab,'$' +eralin: db cr,esc,'T$' ;Clear to end of line. +erascr: db esc,'+$' ;Clear screen and go home. +curldn: db esc,'=$' ;Cursor lead-in +ttab: ;Table start location. +ta: db ('K'-100O),'$',0,0 ;Cursor up. +tb: db 12O,'$',0,0 ;Cursor down. +tc: db ('A'-100O),'$',0,0 ;Cursor right. +td: db ('H'-100O),'$',0,0 ;Cursor left. +te: db ('L'-100O),'$',0,0 ;Clear screen and home cursor +tf: db '$',0,0,0 ;(can't) Enter Graphics mode +tg: db '$',0,0,0 ;(can't) Exit Graphics mode +th: db ('Z'-100O),'$',0,0 ;Cursor home. +ti: db ('K'-100O),'$',0,0 ;Reverse linefeed. +tj: db esc,'Y$',0 ;Clear to end of screen. +tk: db esc,'T$',0 ;Clear to end of line. +ENDIF;smrtvd + +IF h1500 +vtval EQU 1 ; we can do VT52 emulation +defesc EQU '\'-100O ;Still Control-\ (just ran out of room...) +ttytyp: db 'Hazeltine$' +outlin: db 7eh,1ch,7eh,12h,'$' +erascr: db 7eh,1ch,7eh,12h,'$' ;Clear screen and home +eralin: db 7eh,13h,'$',0 ;Clear to end of sreen +curldn: db 7eh,11h,'$',0 ;Cursor lead-in +ttab: ;Table start location ;(MUST be 4 bytes each) +ta: db 7eh,0ch,'$',0 ;Cursor up, stop at top +tb: db 7eh,0bh,'$',0 ;Cursor down CTRL-J +tc: db 10h,'$',0,0 ;Cursor right, stop at right +td: db 8h,'$',0,0 ;Cursor left, stop at left +te: db 7eh,1ch,'$',0 ;Clear display (2 pad nulls) +tf: db '$',0,0,0 ;(can't) Enter Graphics mode +tg: db '$',0,0,0 ;(can't) Exit Graphics mode +th: db 7eh,0ch,'$',0 ;Cursor home +ti: db 7eh,0ch,'$',0 ;Reverse linefeed +tj: db '$',0,0,0 ;(can't) Clear to end of screen +tk: db 7eh,0fh,'$',0 ;Clear to end of line +ENDIF;h1500 + +IF wyse ;[gv] +vtval equ 1 ; we can do VT52 emulation +defesc EQU '\' ;Still Control-\ (just ran out of room...) +ttytyp: db ' [Wyse 100]',cr,lf,'$' +outlin: db esc,'+$',0 ;Clear screen and home +erascr: db esc,'+$',0 ;Clear screen and home +eralin: db esc,'Y$',0 ;Clear to end of sreen +curldn: db cr,esc,'=$' ;Cursor lead-in +ttab: ;Table start location ;(MUST be 4 bytes each) +ta: db 03h,'$',0,0 ;Cursor up, stop at top +tb: db lf,'$',0,0 ;Cursor down, stop at bottom +tc: db ff,'$',0,0 ;Cursor right, stop at right +td: db bs,'$',0,0 ;Cursor left, stop at left +te: db sub,0,0,'$' ;Clear display (2 pad nulls) +tf: db '$',0,0,0 ;Enter Graphics mode NONE +tg: db '$',0,0,0 ;Exit Graphics mode NONE +th: db 1eh,'$',0,0 ;Cursor home +ti: db esc,'v$',0 ;Reverse linefeed, scroll ??? +tj: db esc,'Y$',0 ;Clear to end of sreen +tk: db esc,'T$',0 ;Clear to end of line +ENDIF;wyse + + + +ovlend equ $ ; End of overlay + +IF lasm ;Not really needed, as M80 ignores END in include files + END +ENDIF ;lasm diff --git a/cpxz80.asm b/cpxz80.asm index 9e80e8b..82a5692 100644 --- a/cpxz80.asm +++ b/cpxz80.asm @@ -1,350 +1,350 @@ -IF NOT LASM -.printx * CPXZ80.ASM * -ENDIF ;NOT lasm -; KERMIT - (Celtic for "FREE") -; -; This is the CP/M-80 implementation of the Columbia University -; KERMIT file transfer protocol. -; -; Version 4.0 -; -; Copyright June 1981,1982,1983,1984,1985 -; Columbia University -; -; Originally written by Bill Catchings of the Columbia University Center for -; Computing Activities, 612 W. 115th St., New York, NY 10025. -; -; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, -; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many -; others. -; -; This file contains the system-dependent code and data for -; Kermit-80 emulated on an IBM PC or clone running Z80MU. -; -; revision history (last edit first) -; -; edit 1, 2 December, 1987. Built code for Z80MU emulation. Uses BIOS -; calls to 0FF12-15 to read/write from/to the PC COM1 port. -; - -.printx * Assembling for Z80MU system * - -; -; Family is the string used in VERSION to say which of several -; smaller overlay files are used. These are (will be) derived from -; the juge CP4SYS.ASM file, in which case we will never get here. -; Just a Dollar, but put a sting in for a family of machines. -; -family: db 'CPXZ80.ASM (1) 2-Dec-87$' ; Used for family versions.... - - - -sysxin: ; continuation of system dependent initialisation code - ret ; return from system-dependent routine -; -; -; system-dependent termination processing -; If we've changed anything, this is our last chance to put it back. -sysexit: - ret - -; -; system-dependent processing for start of CONNECT command -; -syscon: - ret - -conmsg: ; Messages printed when entering transparent (CONNECT) mode: -; -; -; syscls - system-dependent close routine -; called when exiting transparent session. -; -syscls: - ret -; -; sysinh - help for system-dependent special functions. -; called in response to ?, 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: ,,, and 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 ?, 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: ,,, and are always discarded. +sysflt: + mov a,e ; get character for testing + ret + +; mdmflt - modem filter [30] +; called with character to be sent to printer in E +; with parity set as appropriate. +; return with accumulator = 0 do do nothing, +; <> 0 to send char in E. +mdmflt: + mov a,e ;[30] get character to test + ret + + + +; prtflt - printer filter [30] +; called with character to be sent to printer in E +; returns with a = 0 to do nothing +; a <> 0 to print it. +; +; this routine for those printer that automatically insert +; a lf on cr, or cr for lf. Should this be shifted to +; the system indep. stuff, in say 4.06? +prtflt: + mov a,e ; [30] get character to test + ret + + +; +; system-dependent processing for BYE command. +; for apmmdm, heath, and lobo, hang up the phone. +sysbye: + ret +; +; +; This is the system-dependent command to change the baud rate. +; DE contains the two-byte value from the baud rate table; this +; value is also stored in 'speed'. +sysspd: + ret +; +; +; The following conditionals were once a huge if not statement. There +; wasn't enough room to add the lobo to the list, so it had to be broken +; into 2, which you can't do with an if not. I redid it as two ifs and +; applied them to those that wouldn't set baud. [Hal Hostetler] +spdtbl EQU 0 ;[hh] SET BAUD not supported. +sphtbl EQU 0 ;[hh] ran out of room above... +; +; +; This is the system-dependent SET PORT command. +; HL contains the argument from the command table. +sysprt: + ret + +prttbl equ 0 ; SET PORT not supported +prhtbl equ 0 +; + +; +; selmdm - select modem port +; selcon - select console port +; selmdm is called before using inpmdm or outmdm; +; selcon is called before using inpcon or outcon. +; For iobyt systems, diddle the I/O byte to select console or comm port; +; For Decision I, switches Multi I/O board to console or modem serial +; port. [Toad Hall] +; For the rest, does nothing. +; preserves bc, de, hl. +selmdm: +selcon: + ret +; + +; Get character from console, or return zero. +; result is returned in A. destroys bc, de, hl. +; +inpcon: + mvi c,dconio ;Direct console I/O BDOS call. + mvi e,0FFH ;Input. + call BDOS + ret +; + +; +; Output character in E to the console. +; destroys bc, de, hl +; +outcon: + mov c,e ;Console output via BIOS + jmp bcnout +; + +; +; outmdm - output a char from E to the modem. +; the parity bit has been set as necessary. +; returns nonskip; bc, de, hl preserved. +outmdm: + mov c,e ; get char to c + call 0ff12h ; send to com1 via PC BIOS + ret +; +; +; get character from modem; return zero if none available. +; for IOBYT systems, the modem port has already been selected. +; destroys bc, de, hl. +inpmdm: +;Note: modem port should already be selected for mdI. [Toad Hall] + call 0ff15h ;Get the port status into A. + ana a ;See if the is non-null. + ret ; return with character or NULL in A. + + +; +; flsmdm - flush comm line. +; Modem is selected. +; Currently, just gets characters until none are available. + +flsmdm: call inpmdm ; Try to get a character + ora a ; Got one? + jnz flsmdm ; If so, try for another + ret ; Receiver is drained. Return. +; + +; +; lptstat - get the printer status. Return a=0ffh if ok, or 0 if not. +lptstat: + xra a ; assume it is ok.. this may not be necessary + ret + +; +; outlpt - output character in E to printer +; console is selected. +; preserves de. +outlpt: + push d ; save DE in either case + call prtflt ; go through printer filter [30] + ana a ; if A = 0 do nothing, + jz outlp1 ; [30] if a=0 do nothing + mvi c,lstout + call bdos ;Char to printer +outlp1: pop d ; restore saved register pair + ret + +; +; delchr - make delete look like a backspace. Unless delete is a printing +; character, we just need to print a backspace. (we'll output clrspc +; afterwards) +; For Kaypro and Vector General, delete puts a blotch on the screen. +; For Apple and Osborne 1, delete moves but doesn't print. +delchr: + mvi e,bs ;get a backspace + jmp outcon + +; erase the character at the current cursor position +clrspc: mvi e,' ' + call outcon + mvi e,bs ;get a backspace + jmp outcon + +; erase the current line +clrlin: lxi d,eralin + jmp prtstr + +; erase the whole screen, and go home. preserves b (but not c) +clrtop: lxi d,erascr + jmp prtstr + + +sysver: db 'Z80MU on IBM PC $' +IF lasm +LINK CPXVDU.ASM +ENDIF ;lasm - m80 will INCLUDE CPXVDU.ASM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mload.asm b/mload.asm index 668796a..14df5c3 100644 --- a/mload.asm +++ b/mload.asm @@ -1,1493 +1,1493 @@ - title 'MLOAD MULTI-FILE HEX LOAD UTILITY' -; -; ********************************* -; * MLOAD.ASM * -; * Multi-file Hex Load Utility * -; * for CP/M * -; ********************************* -; -; -; Replacement for the cp/m "LOAD" program: this program -; fixes many of the problems associated with the "CP/M" -; load program, and adds many new features. -; -; ---------------- -; -; Rev 2.5 -; 03/10/88 -; Property of NightOwl Software, Inc. Fort Atkinson, WI 53538 -; Written by Ron Fowler, Nightowl Software, Inc. -; -; ---------------- -; Notice: this program is NOT public domain; copyright is retained by -; NightOwl Software, Inc. of Fort Atkinson, WI ... All Rights Reserved. -; -; License is granted for free use and re-distribution this program, as -; long as such use and re-distribution is done without profit. -; -; ---------------- -; -; modification history: -; -; 2.5 (WOD) This version corrects a bug that overlayed the first six -; bytes of the CCP. The error did not show up unless a -; jump to the CCP was done without a warm boot since MLOAD -; used. This source file has been modified here with -; concurrence of the author of MLOAD, Ron Fowler. -; -; 2.4 (RGF) We apologize for this relatively insubstantial update, -; but someone has caused what we consider to be a problem, -; by making changes to the program, and re-releasing under -; the same version number. The changes in this case were -; conversion of the opcode fields (but not the comments, -; can you believe that??) of every line to upper case! That -; totally invalidated the CRC of the source file, since there -; are now two different MLOAD 2.3's running around. -; -; We DO NOT want these stupid mixed upper/lower case changes. -; Someone somewhere has decided that this is the way assembly -; language source should be, and we most VEHEMENTLY disagree. -; It's a pain in the neck to make changes to and we don't -; care to run our programs through conversion programs every -; time we make changes. -; -; So ... leave the case of this file AS IS. Any changes made -; to this program and not co-ordinated through us may very -; well endanger availability of source code when we make -; future updates. 'nuff said --NightOwl Software -; -; 2.3 (RGF) Trivial cosmetic changes -; 2.2 (RGF) Modified copyright notice to show new owner of the -; program. -; 2.1 (RGF) Fixed problem on disk-full when writing output file -; (mload previously didn't error out on a full disk) -; 2.0 (RGF) Added the ability to pre-load a non-hex file, allowing -; mload to be used to load hex file patches (obviating any -; need to use DDT). The normal mload syntax is preserved. -; the first (and only the first) filespec (after the "=", -; if used) may be non-hex; the filetype must be specified. -; Examples: -; -; 1) mload ws.com,wspatch -; 2) mload MEXTEST=MEX112.COM,MXO-US13 -; 3) mload ws.ovr,ovrpatch -; -; The first example loads WS.COM, overlays it with -; wspatch.hex, and writes the output to WS.COM. The -; second example loads MEX112.COM, overlays it with -; MXO-US13.HEX, and writes the output file to MEXTEST.COM. -; (note that the second example is the recommended technique, -; since it preserves the original file). The third example -; loads WS.OVR and patches it with the file "OVRPATCH.HEX". -; -; Also added this rev: ZCPR2-style du specs are now fully -; supported, for both input and output files. Thus, the -; following command lines are permissable: -; -; b3>mload a4:myfile.com=0:bigfil,b6:patch1,c9:patch2 -; a6>mload b5:=c3:mdm717.com,mdmpatch -; -; After loading, an additional information line is now printed -; in the statistics report, which displays the true size of the -; saved image (the previous report was technically correct, but -; could result in confusion for certain kinds of files with -; imbedded "DS" and "ORG" statements in the original source code). -; -; 1.0 - 1.4 (RGF) change log removed to conserve space -; -; originally written by ron fowler, fort atkinson, wisconsin -; -; -; -; For assembly with asm.com or mac (delete above title line if -; assembling with asm.com). -; -; This program is a replacement for the cp/m "LOAD" program. -; Why replace "LOAD"? well... LOAD.COM has a few deficiencies. -; For example, if your hex file's origin is above 100h, LOAD.COM -; prepends blank space to the output file to insure it will work -; as a CP/M transient. It cares not if the file is not intended -; as a CP/M transient. it also doesn't like hex records with mixed -; load addresses (for example, one that loads below a previous record -- -; which is a perfectly legitimate happenstance). Also, LOAD.COM -; can load only one program at a time, and has no provision for -; a load bias in the command specification. Finally, there is no -; provision for user specification of the output file name. -; -; -; Hence, this program.... -; -;------------------------------------------------------------ -; -; Syntax is as follows: -; -; mload [[,...] [bias] -; -; where 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), -; specifies files to load and 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:=" -; 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 [=] [,...] []',cr,lf - db tab,' (brackets denote optional items)',cr,lf,cr,lf - db tab,' is the optional output filename',cr,lf - db tab,' are input file(s)',cr,lf - db tab,' is a hex load offset within the output file' - db cr,lf,cr,lf - db tab,' 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:=" or "C4:=". 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 (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 [[,...] [bias] +; +; where 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), +; specifies files to load and 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:=" +; 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 [=] [,...] []',cr,lf + db tab,' (brackets denote optional items)',cr,lf,cr,lf + db tab,' is the optional output filename',cr,lf + db tab,' are input file(s)',cr,lf + db tab,' is a hex load offset within the output file' + db cr,lf,cr,lf + db tab,' 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:=" or "C4:=". 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 (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 -- 2.39.2