IMD 1.16: 8/06/2007 14:11:47 ebmmug.018 eastbay micromate users' group mkermit-80 & cms for cp/m+ ucb version 36.16 disk issued: april 4, 1985 CMS DOC CPM DOC{ MKERMIT ASM !"#$%&'()*+MKERMIT ASM,-./0123456789:;MKERMIT ASM<=>?@ABCDEFGHIJKMKERMIT ASMLMNOPQRSTUVWXYZ[MKERMIT ASM \]^_`abcdefghijkMKERMIT ASM lmnopqrstuMKERMIT COMUvwxyz{MKERMIT HEXd|}~-EBMMUG 018UNIX DOCVT52 DOCREADME EBMDIR18TXT-EBMMUG BAK KERMIT-CMS(1C) UCB Microcomputer Users Manual KERMIT-CMS(1C) NAME _K_e_r_m_i_t-_C_M_S - Microcomputer to _C_M_S file transfer program SYNOPSIS Use `set ibm on' on the micro _K_e_r_m_i_t, connect to CMS using CAL mode at 300 or 1200 baud, logon to CMS and give the KER- MIT command. _K_e_r_m_i_t-_C_M_S is interactive and prompts with `KERMIT-CMS>': RECeive [FN FT [FM]] SENd FN FT [FM] CMS CP SET END-of-line 00-31 Exit HELP SET LRECL 1-133 SET PACket-size 26-94 Quit SET QUOTE SET RECFM V | F SHOw [ RECFM | END of line | QUOTE | LRECL | PACket-size ] STATUS The commands and keywords can be abbreviated, CAPITAL letters must be entered, small letters are optional. Typing a `?' in place of a command or keyword will display the options. DESCRIPTION  _K_e_r_m_i_t is a file transfer and terminal emulation utility distributed by Columbia University. It has been implemented for many different computers, including microcomputers. Any two machines running _K_e_r_m_i_t can reliably exchange files over normal character terminal lines. For file transfers, a _K_e_r_- _m_i_t program must be running in the microcomputer to exchange data packets with the _K_e_r_m_i_t program on _C_M_S. Micro versions differ slightly from one to another and only a few are currently supported by UCB, however, in principle, with any other microcomputer or mainframe _K_e_r_m_i_t. At this time, only UCB micro _K_e_r_m_i_t versions can communicate with UCB _K_e_r_m_i_t- _C_M_S ( see IMPLEMENTATION). RECeive [FN FT [FM]] In receive mode, also called uploading, _K_e_r_m_i_t-_C_M_S attempts to store the file with the name supplied by the sending micro. A file specification on the _K_e_r_m_i_t-_C_M_S receive command can specify the full name of a single file to be received or a single file to col- lect multiple files received (use `set file ascii' on the micro to avoid imbedded ^Z's). The file mode can Printed 2/13/84 13 February 1984 1 KERMIT-CMS(1C) UCB Microcomputer Users Manual KERMIT-CMS(1C) specify the disk on which files are to be received (`= = D'). CAUTION: if the file already exists with the same record format, the incoming file will be appended, otherwise Kermit-CMS will abort. BUG: if `%' or `*' used in name or type field, _K_e_r_m_i_t-_C_M_S does not abort until the micro _K_e_r_m_i_t attempts to send, then several error messages preceed an abort for `disk full'.  _K_e_r_m_i_t-_C_M_S cannot receive files without a type field from the sender (a period plus at least one following character), unless the full name is specified on the receive command. _K_e_r_m_i_t-_C_M_S only accepts letters, digits and `#$+-:@_' in file names. Lower case letters are converted to upper case. The received ASCII characters are converted to seven bit EBCDIC (see table in Kermit Users Guide). Carriage-return alone, line-feed alone, or carriage- return and line-feed togeather will be interpreted as an end-of-record and will be removed. BUG: if a record does not end with carriage-return or line-feed, the partial record is held by _K_e_r_m_i_t-_C_M_S and is prepended to the next file received. BUG: Kermit-CMS cannot write zero length files, but will accept them as if it had. If the record format is variable (the default, recfm V), the record length can be up to 256. Records longer than 256 are broken into multiple records. BUG: records that are exact multiples of 256 bytes are writ- ten as multiple records of length 256 followed by sin- gle a blank record of length 1. If the record format is fixed (recfm F), any record longer than the logical record length (lrecl) will be truncated. If shorter, it is padded to lrecl with blanks. The record length can be set up to 133 (default is 80). BUG: if the record length received is greater than 256, _K_e_r_m_i_t-_C_M_S will truncate the first 256 bytes to lrecl then act as though the next record begins with the 257th character. BUG: if the record received is exactly 256 bytes, _K_e_r_m_i_t-_C_M_S writes one record of length lrecl then aborts for `disk full'. SENd FN FT [FM] In send mode, also known as downloading, files are sent from _C_M_S to your microcomputer. Multiple files may be sent by using "*" or "%" as wildcard characters (`*' matches any number of characters, `%' matches exactly one). If the file-mode (FM) is not specified _K_e_r_m_i_t- _C_M_S assumes the A disk, and sets the file mode to A1. Printed 2/13/84 13 February 1984 2 KERMIT-CMS(1C) UCB Microcomputer Users Manual KERMIT-CMS(1C) For a different disk, the filemode must be cited. If filemode `*' is used, _K_e_r_m_i_t-_C_M_S will send only the first matching file. Bytes are converted from EBCDIC characters to seven bit ASCII characters for sending (see table in Kermit Users Guide). Trailing blanks are removed from each record and carriage-return and line-feed are appended. The maximum record length is 256 and only fixed (F) and variable (V) records are allowed. (?? what happens if longer than 256 ??). Kermit-CMS must wait 15 seconds before sending the first packet to allow time for the user to escape back to the micro and enter the receive command. SET RECFM V | F Sets the record format to be used when receiving a file. Only fixed (F) and variable (V) length records are allowed, variable is the default. SET LRECL 1-133 Sets the logical record length (default is 80). BUG: 0 is allowed and if set, gives `Disk full' during receive. SET QUOTE The quote character to be used for escaping control characters in packets (default `#'). It must be a sin- gle, printable character from among the following: 33- 62, 96, or 123-126 (decimal). Note that `(' and `)' are word separators on the input line and do not count as characters. SET END 00-31 Sets the end-of-line character (default is carriage- return, 13 decimal) to any ASCII character from 00 to 31 decimal. SET PACket-size 26-94 Sets the packet size the micro _K_e_r_m_i_t should use when sending to _K_e_r_m_i_t-_C_M_S (default is 94). _K_e_r_m_i_t-_C_M_S itself always sends one record per packet. If the record is longer than 91, _K_e_r_m_i_t-_C_M_S sends packets of length 94 followed by a short packet. SHOw [ RECFM | END of line | QUOTE | LRECL | PACket-size ] Displays the current value of any one SET parameter. STATUS Displays the status of the last previous receive or send command. BUG: `Disk full' is the last status Printed 2/13/84 13 February 1984 3 KERMIT-CMS(1C) UCB Microcomputer Users Manual KERMIT-CMS(1C) given for almost any file error. CMS Issues a CMS command from within _K_e_r_m_i_t-_C_M_S. If the cms command fails, _K_e_r_m_i_t-_C_M_S says only `Command rc equals nn'. CP Issues a CP command from within _K_e_r_m_i_t-_C_M_S. If the cms command fails, _K_e_r_m_i_t-_C_M_S says only `Command rc equals nn'. Some micro kermits do not send an error packet when they "abort", so _K_e_r_m_i_t-_C_M_S does not always know that the micro has stopped. When connected back to CMS, _K_e_r_m_i_t-_C_M_S may still be sending packets (they will appear on the screen). Type carriage-returns until _K_e_r_m_i_t-_C_M_S has done the maximum number of retries and aborts. The error message will not indicate the micro abort, but rather that _K_e_r_m_i_t-_C_M_S gave up. If _K_e_r_m_i_t-_C_M_S must terminate a send or receive abnormally, an error packet is sent to the micro. The _K_e_r_m_i_t-_C_M_S status command will display the same message. _K_e_r_m_i_t-_C_M_S will retry 20 times on initialization packets and 5 times on other packets. EXAMPLES (see micro kermit manuals) Micro Kermits are interactive and will prompt for commands. The micro command connect initiates or continues a terminal connection with _C_M_S and a connect-escape character followed by `c' closes the connection and returns to the micro kermit (`^]c'). Each micro may use a different first character for the connect-escape, so the connect-escape is displayed at each connect. For the example below, the micro is turned on and booted with the disk containing the micro _K_e_r_m_i_t in drive A and a formatted data disk in drive B. What you type is in bold- face; annotations appear in italics. A> # _M_i_c_r_o _p_r_o_m_p_t, _d_e_f_a_u_l_t _d_i_s_k _A: A>b: # _S_w_i_t_c_h _t_o _t_h_e _d_a_t_a _d_i_s_k. B>a:mkermit # _R_u_n _m_i_c_r_o _k_e_r_m_i_t. Kermit-80> # _T_h_e _c_p/_m _k_e_r_m_i_t _p_r_o_m_p_t. Kermit-80>set ibm on # _S_e_t _f_o_r _I_B_M _C_A_L _m_o_d_e. Kermit-80>connect # _C_o_n_n_e_c_t _t_o _t_h_e _c_o_m_m. _l_i_n_e. # _N_o_w _t_h_e _m_i_c_r_o _a_c_t_s _a_s _a # _n_o_r_m_a_l _t_e_r_m_i_n_a_l.  # _D_i_a_l-_i_n _o_r _p_r_e_s_s _p_o_r_t-_s_e_l_e_c_t_o_r # _b_u_t_t_o_n _a_n_d _s_e_l_e_c_t _C_A_L _m_o_d_e. # _L_o_g_i_n _t_o _y_o_u_r _C_M_S _a_c_c_o_u_n_t. Printed 2/13/84 13 February 1984 4 KERMIT-CMS(1C) UCB Microcomputer Users Manual KERMIT-CMS(1C) ... # _C_M_S _m_e_s_s_a_g_e_s, _e_t_c. . # _N_o_w _y_o_u _a_r_e _t_a_l_k_i_n_g _t_o _C_M_S, . # _a_s _a _l_i_n_e _m_o_d_e _t_e_r_m_i_n_a_l. .kermit # _C_a_l_l _i_n_t_e_r_a_c_t_i_v_e _K_e_r_m_i_t-_C_M_S. Kermit-CMS> # _K_e_r_m_i_t-_C_M_S prompt. Kermit-CMS> receive # _S_e_t _u_p _C_M_S _t_o _r_e_c_e_i_v_e _f_i_l_e_s. . ^[c # _C_M_S waits, return to micro. Kermit-80>send *.for # _S_e_n_d _a_l_l _f_o_r_t_r_a_n _f_i_l_e_s _t_o _C_M_S. ... # _M_i_c_r_o _d_i_s_p_l_a_y_s _s_e_n_d _p_r_o_g_r_e_s_s. Kermit-80> # _S_e_n_d _i_s _f_i_n_i_s_h_e_d. Kermit-80>connect # _C_o_n_n_e_c_t _b_a_c_k _t_o _K_e_r_m_i_t-_C_M_S. Kermit-CMS> send frog file # _S_e_t _u_p _C_M_S to send `frog file'. ^[c # _C_M_S waits, return to micro. Kermit-80>receive # _R_e_c_e_i_v_e `_f_r_o_g._f_i_l' _o_n _m_i_c_r_o. ... # _M_i_c_r_o _d_i_s_p_l_a_y_s _r_e_c_e_i_v_e _p_r_o_g_r_e_s_s. Kermit-80>  # _R_e_c_e_i_v_e _i_s _f_i_n_i_s_h_e_d. Kermit-80>connect # _C_o_n_n_e_c_t _b_a_c_k _t_o _K_e_r_m_i_t-_C_M_S. Kermit-CMS> exit # _E_x_i_t _f_r_o_m _K_e_r_m_i_t-_C_M_S. .^[c # _R_e_t_u_r_n _t_o _m_i_c_r_o. Kermit-80>exit # _E_x_i_t _f_r_o_m _m_i_c_r_o _K_e_r_m_i_t. A> # _M_i_c_r_o _p_r_o_m_p_t, _d_e_f_a_u_l_t _d_i_s_k _A: FEATURES The Kermit file transfer protocol uses 96 character check- summed packets, with ACK/NACK packet responses and timeouts. Only printing ASCII characters, control-A, carriage-return, line-feed are used for transmission, hence, packets should pass through most modems and networks unharmed. Control characters are mapped into two characters, an escape charac- ter (usually `#') and a printing character corresponding to the control character (control-character exclusive or'ed with 40 hex). _C_M_S does not preserve the eighth bit of each byte and is limited to text data. IMPLEMENTATIONS Various microcomputer kermit versions are available from the CS Microcomputer Consultant (262 Evans Hall, 642-4072). Currently, IBM-PC, TRS-80 II (Pickles and Trout CP/M), KAYPRO II and Morrow MICRO DECISION versions are available. Versions for the Apple II, Apple II with cp/m card and the Compupro are under developement. Source for many other machines with UCB changes is available, but versions built from them cannot be supported by UCB, since machines and staff time for testing are not available. Micro kermits to be used for file transfer with UCB CMS must have local modifications. The UCB port selector echos received characters. This requires that the micro kermit not echo locally. More important, the echoed start-of- Printed 2/13/84 13 February 1984 5 KERMIT-CMS(1C) UCB Microcomputer Users Manual KERMIT-CMS(1C) header from a packet sent is received and retained by the serial port circuitry and confuses the packet driver into thinking its own tail is the next packet to be received. These UCB modifications should not interfere with use on other CMS systems except that `set local on' should be used after `set ibm on' since UCB ibm does not set local echo. SEE ALSO kermit(1c), kermit-80(1c), kermit-86(1c), upload(1). _K_e_r_m_i_t _U_s_e_r_s _G_u_i_d_e, Fourth Edition (19 July 83), Frank da Cruz, Daphne Tzoar, Bill Catchings _K_e_r_m_i_t _P_r_o_t_o_c_o_l _M_a_n_u_a_l, Fourth Edition (4 November 83), Frank da Cruz, Bill Catchings BUGS Most file or file name errors give a good message to the terminal, but _K_e_r_m_i_t-_C_M_S says only `Disk full' in the error packet to the micro. When ^Z or ^X are used to terminate a send or receive, _K_e_r_m_i_t-_C_M_S does not stop immediately or may even abort or hang. This is due to protocol differences with our older _K_e_r_m_i_t-_C_M_S. If the record length sent is greater than 256, _K_e_r_m_i_t-_C_M_S will truncate to lrecl then act as though the next record begins with the 257th character. If the record is exactly 256 bytes, _K_e_r_m_i_t-_C_M_S writes one record of length lrecl then aborts for `disk full'. If `%' or `*' used in name or type field, _K_e_r_m_i_t-_C_M_S does not abort until the remote _K_e_r_m_i_t attempts to send, then several error messages preceed an abort for `disk full'. CMS Kermit will abort out of CMS into CP for various errors, including timeouts. If you get the CP prompt, type BEGIN to restart _K_e_r_m_i_t-_C_M_S or IPL CMS to restart CMS. When connected to UCB cal, a BREAK must be used to interrupt terminal output since cal is half-duplex. Many kermit ver- sions cannot generate a BREAK. CMS Kermit will not write zero length files, but will accept them. CMS Kermit cannot receive eight bit image files. Individual microcomputer Kermit bugs are listed in their documentation. Printed 2/13/84 13 February 1984 6 KERMIT-CMS(1C) UCB Microcomputer Users Manual KERMIT-CMS(1C) Please report other problems to micros@opal or the CS Micro- computer Consultant (262 Evans Hall, 642-4072). Printed 2/13/84 13 February 1984  7 nnected to UCB cal, a BREAK must be used to interrupt terminal output since cal is half-duplex. Many kermit ver- sions cannot generate a BREAK. CMS Kermit will not write zero length files, but will accept them. CMS Kermit cannot receive eight bit image files. Individual microcomputer Kermit bugs are listed in their documentation. Printed 2/13/84 13 February 1984 6 KERMIT-CMS(1C) UCB Microcomputer Users Manual KERMIT-CMS(1C) Please report other problems to micros@opal or the CS Micro- computer Consultant (262 Evans Hall, 642-4072). Printed 2/13/84 13 February 1984  KERMIT-80(1C) UCB Microcomputer Users Manual KERMIT-80(1C) NAME _K_e_r_m_i_t-_8_0 - CP/M 80 file transfer program SYNOPSIS _K_e_r_m_i_t-_8_0 is interactive and understands the following com- mands: Connect Receive SENd afn ERa afn EXit Help Dir [ afn ] LOG ufn SET BAud rate SET BLock-check-type 1 | 2 | 3 SET Default-disk d: SET Escape SET File-mode Ascii | Binary | Default SET Ibm ON | OFf SET Local-echo ON | OFf SET PArity Even | Mark | None | Odd | Space SET POrt SET Vt52 ON | OFf SET Warning ON | OFf SHow STatus The commands and keywords can be abbreviated, CAPITAL letters must be entered, small letters are optional. Typing a `?' in place of a command or keyword will display the options. Control-H (^H) is backspace and control-U (^U) is  delete line. DESCRIPTION _K_e_r_m_i_t is a file transfer and terminal emulation utility distributed by Columbia University. It has been implemented for many different computers, including microcomputers. Any two machines running _K_e_r_m_i_t can reliably exchange files over normal character terminal lines. For file transfers, a _K_e_r_- _m_i_t program must be running in the microcomputer to exchange data packets with the _K_e_r_m_i_t program on UNIX, _C_M_S or another micro. Micro versions differ slightly from one to another and only a few are currently supported by UCB, however, in principle, any _K_e_r_m_i_t should be able to communicate with the UCB UNIX version and any other microcomputer or mainframe _K_e_r_m_i_t. At this time, only UCB micro _K_e_r_m_i_t versions can communicate with the UCB _C_M_S _K_e_r_m_i_t ( see IMPLEMENTATION). ufn is a unique cp/m file name of the form Printed 2/13/84 13 February 1984 1 KERMIT-80(1C) UCB Microcomputer Users Manual KERMIT-80(1C) `d:NAME5678.TYP'. _K_e_r_m_i_t-_8_0 commands allow only letters, digits and `@[\]^' in the name and type fields. Other characters cause an error or the command acts as if no file name was given. When an afn can be specified, these characters can be overlooked by using `?' instead. afn is a ufn or an ambiguous file name of the form `d:NAME5678.TYP' with cp/m wild-card characters `?' or `*' in the name or type field. The afn matches all files on disk d: with the specified character name and type. `?' matches any single character; `*` matches any number of characters from none to the end of the name or type field in which it occurs.  Connect The connect command initiates or continues a terminal emulation session. Characters typed on the micro con- sole are sent out on the communications line and char- acters received by the micro are displayed on the micro console. The transmission speed may have to be set before calling up _K_e_r_m_i_t-_8_0, although some _K_e_r_m_i_t-_8_0 versions can set the rate with the `set baud' command. For connection to CMS, the parity should be even (use `set ibm on'). One character is reserved to allow escape from the con- nection. The micro shows the connect-escape character each time you connect, but it is usually control- backslash (`^\'). The connect-escape character can be changed with `set escape'. The connect-escape followed by `c' closes the connec- tion and returns to _K_e_r_m_i_t-_8_0 command mode. Close is used to switch back to _K_e_r_m_i_t-_8_0 to start a file send or receive, to change parameters, etc.. The connect command can be used to resume connect mode. Closing connect mode does not drop the terminal connection, UNIX or _C_M_S will wait if they are idle or continue to output if they are sending to your terminal. Be sure to logout from UNIX or _C_M_S, when that is your inten- tion, before closing the connection. There are other command characters that follow the connect-escape character. `s' shows the _K_e_r_m_i_t-_8_0 parameters. `0' sends a NULL character (ascii 00 hex). `b' sends a `break' character (actually a 300 mil- lisecond broken line signal). Two connect-escape char- acters send the connect-escape character itself. The connection is not closed, but if output is arriving, some characters may be lost between the time the connect-escape is typed and the command character is Printed 2/13/84 13 February 1984 2 KERMIT-80(1C) UCB Microcomputer Users Manual KERMIT-80(1C) typed. `?' displays all the connect-escape commands and waits for you to type one. Receive In receive mode, also called downloading, _K_e_r_m_i_t-_8_0 attempts to store the file with the name supplied by the sending computer. The first eight valid characters before the first period are used as the name part, and the first three valid characters after the first period are used as the type part. Some _K_e_r_m_i_t versions will not send or receive files with names containing control characters or certain special characters. If a file is received with the same name as an existing file on the micro, _K_e_r_m_i_t-_8_0 changes the incoming name by appending ampersands (`&') to the name part and issuing a warning message. If warning is off, _K_e_r_m_i_t-_8_0 will overwrite the existing file on the micro. BUG: if the file is $r/o, cp/m will abort _K_e_r_m_i_t-_8_0 `BDOS err on d: $r/o'. All characters are written to the file, both printable and control. All eight bits of each received byte are stored if _K_e_r_m_i_t-_8_0 is in parity none mode, otherwise the eigth parity bit is trimmed off leaving a seven bit character. Do not forget that the sender may trim off the eighth bit itself, or the communication path may not pass it (_C_M_S). Files that are not an exact multi- ple of 128 bytes are padded to the next 128 byte boun- dry with the cp/m end-of-file character (^Z = 1Ah). SENd ufn In send mode, also called uploading, files are sent from _K_e_r_m_i_t-_8_0 to UNIX _K_e_r_m_i_t, _C_M_S _K_e_r_m_i_t or another micro. Each file is sent with its cp/m name (`NAME5678.TYP'). _K_e_r_m_i_t-_8_0 will not send control characters or spaces (00-20 hex) in a name but will send the rest of the name without them. Files are sent in cp/m directory order. All characters are sent exactly as they occur in the file, both printable and control. All eight bits of each file character are sent if _K_e_r_m_i_t-_8_0 is in parity none mode, otherwise the eigth bit is set to the speci- fied parity. Remember that the receiver may trim the eighth bit and may add or delete characters to suit its own file system (UNIX may map CR-LF to newline; _C_M_S  cannot receive eight bits, removes CR-LF for recfm V and pads to lrecl for recfm F). If the _K_e_r_m_i_t-_8_0 file-mode parameter is default or binary, the entire cp/m file will be sent including the cp/m end-of-file characters (control-Z is ^Z is 1A hex). Cp/m files are allways a multiple of 128 bytes Printed 2/13/84 13 February 1984 3 KERMIT-80(1C) UCB Microcomputer Users Manual KERMIT-80(1C) long with ^Z is used to pad to the next 128 byte multi- ple, if necessary. BUG: the default file-mode is sup- posed to trim off the trailing ^Z's. If the file-mode is ascii, the file is truncated at the first cp/m end-of-file character (^Z). BUG: this works properly only if the ^Z occurs in the last block, oth- erwise, all blocks with ^Z's are truncated and file transfer continues. However, such files are not proper cp/m files. Send / Receive Display The packet display shows the progress of a send or receive: Number of packets: 12 Number of retries: 3 File Name: EXAMPLE.TXT ?File renamed to EXAMPLE&.TXT RECEIVE [CR retry, ^X skip file, ^Z quit, ^A abort] Noise or Messages Received: The number of packets is the count of packets sucessfully sent or received. The count should increment about once each second at 1200 baud. The count includes the send- initiate packet (once), the file-name packet (once per file), the data packets (once per 91 data bytes), the end- of-file packet (once per file) and the end-of-transmission packet (once). The number of retries is the count of times _K_e_r_m_i_t-_8_0 had to restart a packet send or receive. If the communication line is noisy, you may also see junk characters appear below the noise line. If a message is lost or doesn't arrive within 14 seconds, _K_e_r_m_i_t-_8_0 will retry. A carriage-return will cause one retry, if doing that makes you feel better. _K_e_r_m_i_t-_8_0 never gives up, but the remote _K_e_r_m_i_t may quit for various reasons. If the remote sends an error packet, _K_e_r_m_i_t-_8_0 will display the message and abort the transfer. If the remote quits without sending an error packet, mes- sages or a prompt from the remote system may appear under the noise and messages line. You should probably abort with control-A. The file name is the name of the cp/m file being sent or the name given by the sender of a file being received. The error message line is normally blank, but may give warning of transmission problems. _K_e_r_m_i_t-_8_0 will continue trying. The next line gives the name of the operation being per- formed and a list of control characters. Control-X discon- tinues the current file and starts the next file. Control-Z cancels the whole send or receive, but tries to close the packet exchange by notifying the remote _K_e_r_m_i_t. Printed 2/13/84 13 February 1984 4 KERMIT-80(1C) UCB Microcomputer Users Manual KERMIT-80(1C) Utility Commands Dir [ ufn ] Displays the file names, file sizes and space remaining on the default drive. If a ufn is specified, the display covers the names matched on the drive specified (or default); the space remaining takes all files into account. Typing any key stops the file display and displays the space remaining. If ufn contains any characters not allowed by _K_e_r_m_i_t, all files are displayed. Era ufn The erase command is the same as for CP/M. EXit The exit command is used to go back to cp/m. Exit does not drop the terminal connection, so be sure to logout from UNIX or _C_M_S when that is your intention. If exit is used without logging out of UNIX or _C_M_S, to use cp/m, etc., then _K_e_r_m_i_t-_8_0 can be restarted and the connect command used to resume the terminal connection. CAUTION: inadvertently using the micro exit command while still connected to UNIX will logout (actually exit from csh). Use the micro abreviation `ex' instead. HELP Lists the commands available. Typing a `?' in place of a command gives the same list. Typing a `?' in place of keyword will display the options. During terminal connect mode, a connect-escape character followed by `?' lists the connect-escape commands and wait for you to type one. SET Baud rate  Set the transmission speed of the communications line. Implemented in the Kaypro version, but not in the TRS- 80 P+T or Morrow MicroDecision versions. SET BLock-check-type 1 | 2 | 3 This sets the type of error checking used during file transfer. Each data or control packet has a block check to validate its contents. 1 is a single byte checksum and is the default packet checksum. 2 is a two byte checksum that is more reliable but is not yet supported on UNIX or _C_M_S _K_e_r_m_i_t. 3 is a two character cyclic redundancy check (CCITT) and is probably the most reliable of the three, but is not yet supported on UNIX or _C_M_S _K_e_r_m_i_t. 3 is probably the best checkusm to use for micro to micro transfers, but is more compli- cated to calculate and may reduce the maximum transfer rate. SET Default-disk d: Printed 2/13/84 13 February 1984 5 KERMIT-80(1C) UCB Microcomputer Users Manual KERMIT-80(1C) Changes the default disk drive to disk `d:'. This is necessary for receiving because the sender cannot and should not be able to specify the disk drive to write on. For sending, the disk can alternatively be speci- fied in the file name to be sent. CAUTION: the colon (:) is necessary; check that the next _K_e_r_m_i_t-_8_0 promt shows the proper disk letter. BUG: if the disk selected does not exist on your cp/m, cp/m will abort _K_e_r_m_i_t-_8_0 `BDOS err on d: Select'. SET Escape This allows the connect-escape character to be changed (see Connect). _K_e_r_m_i_t-_8_0 will prompt for the charac- ter. SET File-mode Ascii | Binary | Default Sets the send file mode (see SENd). SET Ibm ON | OFf Ibm off is the normal mode for file transfers UNIX and other micros. Ibm ON is used for transfers with _C_M_S _K_e_r_m_i_t, it sets even parity and enables IBM xon half- duplex line turn around processing. Set ibm off restores the default values for local-echo and parity. SET Local-echo ON | OFf Normally, local echo is off for communication with both UNIX and UCB _C_M_S because both services provide full duplex communication with UCB Port Selectors. To use UCB _K_e_r_m_i_t-_8_0 with a non-UCB _C_M_S _K_e_r_m_i_t or other half- duplex connection, use `set local on' after `set ibm on`. SET PArity Even | Mark | None | Odd | Space The normal parity for UNIX is none. The normal parity for CMS is even, however even parity is set by the `set ibm on' command. The parity applies both to terminal connection and file transfer, so none is required for eight-bit transfers. SET POrt Some microcomputers have more than one serial port. This command allows changing the port to be used. SET Vt52 ON | OFf The _K_e_r_m_i_t-_8_0 terminal emulation is primitive and is based on a DEC VT52 terminal screen without reverse scrolling or hard tabs, no keyboard emulation is done. If you know that your microcomputer terminal type is available from UNIX or _C_M_S, use that terminal type and tell _K_e_r_m_i_t-_8_0 to `set vt52 off'. Otherwise, use a terminal type of `kermit' (or `pckermit' if you have a Printed 2/13/84 13 February 1984 6 KERMIT-80(1C) UCB Microcomputer Users Manual KERMIT-80(1C)  25-line display). SET Warning ON | OFf Sets file-warning on or off (see Receive). SHow Shows the current setting of all _K_e_r_m_i_t-_8_0 parameters. Can be displayed while terminal connected by typing connect-escape `?'. The same as STatus. STatus Shows the current setting of all _K_e_r_m_i_t-_8_0 parameters. Can be displayed while terminal connected by typing connect-escape `?'. The same as SHow. Bye, Finish, LOGOut Not used at UCB, see Columbia manuals. EXAMPLES For the examples below, the micro is turned on, the disk containing _K_e_r_m_i_t-_8_0 is put in the A drive, and your own formatted data disk is put in the B drive. What you type is in boldface; annotations appear in italics. For UNIX _K_e_r_m_i_t: A> # _C_p/_m _8_0 _p_r_o_m_p_t, _d_e_f_a_u_l_t _d_i_s_k _A. A>mkermit # _R_u_n _K_e_r_m_i_t-_8_0. Kermit-80 V3.6 (UCB36.16) [TRS-80 II P+T CP/M]# _V_e_r_s_i_o_n _b_a_n_n_e_r Kermit-80 A:> # _K_e_r_m_i_t-_8_0 prompt, default disk A:. Kermit-80 A:>set default b: # _S_e_t _d_e_f_a_u_l_t _d_i_s_k _t_o _B:. Kermit-80 B:>connect # _C_o_n_n_e_c_t _t_o _t_h_e _c_o_m_m. _l_i_n_e. # _N_o_w _t_h_e _m_i_c_r_o _a_c_t_s _a_s _a # _n_o_r_m_a_l _t_e_r_m_i_n_a_l. # _D_i_a_l-_i_n _o_r _p_r_e_s_s _p_o_r_t-_s_e_l_e_c_t_o_r # _b_u_t_t_o_n _a_n_d _s_e_l_e_c_t _a _s_y_s_t_e_m. # _L_o_g_i_n _t_o _y_o_u_r _U_n_i_x _a_c_c_o_u_n_t. ...  # _U_n_i_x _m_e_s_s_a_g_e_s, _e_t_c. TERM = (tvi920c): kermit # _o_r `_p_c_k_e_r_m_i_t', _e_t_c. % # _N_o_w _y_o_u _a_r_e _t_a_l_k_i_n_g _t_o _U_n_i_x, % kermit r # _S_e_t _u_p _U_N_I_X _t_o _r_e_c_e_i_v_e _f_i_l_e_s. % ^\c # _U_N_I_X _w_a_i_t_s, _r_e_t_u_r_n _t_o _m_i_c_r_o. Kermit-80 B:>send *.for # _S_e_n_d _a_l_l _f_o_r_t_r_a_n _f_i_l_e_s _t_o _U_N_I_X. ... # _M_i_c_r_o _d_i_s_p_l_a_y_s _s_e_n_d _p_r_o_g_r_e_s_s. Kermit-80 B:> # _S_e_n_d _i_s _f_i_n_i_s_h_e_d. Kermit-80 B:>connect # _C_o_n_n_e_c_t _b_a_c_k _t_o _U_N_I_X. % kermit s frog # _S_e_t _u_p _U_N_I_X _t_o _s_e_n_d `_f_r_o_g'. % ^\c # _U_N_I_X _w_a_i_t_s, _r_e_t_u_r_n _t_o _m_i_c_r_o. Kermit-80 B:>receive # _R_e_c_e_i_v_e _t_h_e _f_i_l_e `_f_r_o_g' _o_n _m_i_c_r_o. ... # _M_i_c_r_o _d_i_s_p_l_a_y_s _r_e_c_e_i_v_e _p_r_o_g_r_e_s_s. Kermit-80 B:> # _R_e_c_e_i_v_e _i_s _f_i_n_i_s_h_e_d. Printed 2/13/84 13 February 1984 7 KERMIT-80(1C) UCB Microcomputer Users Manual KERMIT-80(1C) Kermit-80 B:>connect # _C_o_n_n_e_c_t _b_a_c_k _t_o _U_N_I_X. % logout # _L_o_g_o_u_t _f_r_o_m _U_N_I_X. ^\c # _R_e_t_u_r_n _t_o _m_i_c_r_o. Kermit-80 B:>exit # _R_e_t_u_r_n _t_o _c_p/_m. A> # _C_p/_m _8_0 _p_r_o_m_p_t, _d_e_f_a_u_l_t _d_i_s_k _A. Similarly, for _C_M_S _K_e_r_m_i_t: A> # _C_p/_m _8_0 _p_r_o_m_p_t, _d_e_f_a_u_l_t _d_i_s_k _A. A>mkermit # _R_u_n _K_e_r_m_i_t-_8_0. Kermit-80 V3.6 (UCB36.16) [TRS-80 II P+T CP/M]# _V_e_r_s_i_o_n _b_a_n_n_e_r Kermit-80 A:> # _K_e_r_m_i_t-_8_0 prompt, default disk A:. Kermit-80 A:>set drive b: # _S_e_t _d_e_f_a_u_l_t _d_i_s_k _t_o _B:. Kermit-80 B:>set ibm on # _S_e_t _f_o_r _I_B_M _c_a_l _m_o_d_e. Kermit-80 B:>connect # _C_o_n_n_e_c_t _t_o _t_h_e _c_o_m_m. _l_i_n_e. # _N_o_w _t_h_e _m_i_c_r_o _a_c_t_s _a_s _a # _n_o_r_m_a_l _t_e_r_m_i_n_a_l. # _D_i_a_l-_i_n _o_r _p_r_e_s_s _p_o_r_t-_s_e_l_e_c_t_o_r # _b_u_t_t_o_n _a_n_d _s_e_l_e_c_t _C_A_L _m_o_d_e. # _L_o_g_i_n _t_o _y_o_u_r _C_M_S _a_c_c_o_u_n_t. ... # _C_M_S _m_e_s_s_a_g_e_s, _e_t_c. . # _N_o_w _y_o_u _a_r_e _t_a_l_k_i_n_g _t_o _C_M_S, . # _a_s _a _l_i_n_e _m_o_d_e _t_e_r_m_i_n_a_l. Kermit-CMS> receive # _S_e_t _u_p _C_M_S _t_o _r_e_c_e_i_v_e _f_i_l_e_s. . ^\c # _C_M_S waits, return to micro. Kermit-80 B:>send *.for # _S_e_n_d _a_l_l _f_o_r_t_r_a_n _f_i_l_e_s _t_o _C_M_S. ... # _M_i_c_r_o _d_i_s_p_l_a_y_s _s_e_n_d _p_r_o_g_r_e_s_s.  Kermit-80 B:> # _S_e_n_d _i_s _f_i_n_i_s_h_e_d. Kermit-80 B:>connect # _C_o_n_n_e_c_t _b_a_c_k _t_o _U_N_I_X. Kermit-CMS> send frog file # _S_e_t _u_p _C_M_S to send `frog file'. ^\c # _C_M_S waits, return to micro. Kermit-80 B:>receive # _R_e_c_e_i_v_e `_f_r_o_g._f_i_l' _o_n _m_i_c_r_o. ... # _M_i_c_r_o _d_i_s_p_l_a_y_s _r_e_c_e_i_v_e _p_r_o_g_r_e_s_s. Kermit-80 B:> # _R_e_c_e_i_v_e _i_s _f_i_n_i_s_h_e_d. Kermit-80 B:>connect # _C_o_n_n_e_c_t _b_a_c_k _t_o _C_M_S. % logoff # _L_o_g_o_f_f _f_r_o_m _C_M_S. ^\c # _R_e_t_u_r_n _t_o _m_i_c_r_o. Kermit-80 B:>exit # _R_e_t_u_r_n _t_o _c_p/_m. A>  # _C_p/_m _8_0 _p_r_o_m_p_t, _d_e_f_a_u_l_t _d_i_s_k _A. FEATURES The Kermit file transfer protocol uses 96 character check- summed packets, with ACK/NACK packet responses and timeouts. Only printing ASCII characters, control-A, carriage-return, line-feed are used for transmission, hence, packets should pass through most modems and networks unharmed. Control characters are mapped into two characters, an escape charac- ter (usually `#') and a printing character corresponding to the control character (control-character exclusive or'ed Printed 2/13/84 13 February 1984 8 KERMIT-80(1C) UCB Microcomputer Users Manual KERMIT-80(1C) with 40 hex). Some connections may not preserve the eighth bit of each byte and are limited to text data. _K_e_r_m_i_t-_8_0 uses a fourteen second timeout designed to be much longer than UNIX or _C_M_S _K_e_r_m_i_t. The time out is necessary to keep the packet exchange going when lost packets occur. _K_e_r_m_i_t-_8_0 never gives up, the operator must manually abort the send or receive (see Send / Receive Display). IMPLEMENTATIONS Various microcomputer kermit versions are available from the CS Microcomputer Consultant (262 Evans Hall, 642-4072). Currently, IBM-PC, TRS-80 II (Pickles and Trout CP/M), KAYPRO II and Morrow MICRO DECISION versions are available. Versions for the Apple II, Apple II with cp/m card and the Compupro are under developement. Source for many other machines with UCB changes is available, but versions built from them cannot be supported by UCB, since machines and staff time for testing are not available. Micro kermits to be used for file transfer with UCB CMS must have local modifications. The UCB port selector echos received characters. This requires that the micro kermit not echo locally. More important, the echoed start-of- header from a packet sent is received and retained by the serial port circuitry and confuses the packet driver into thinking its own tail is the next packet to be received. These UCB modifications should not interfere with use on other CMS systems except that `set local on' should be used after `set ibm on' since UCB ibm does not set local echo. SEE ALSO kermit(1c), kermit-86(1c), kermit-CMS(1c), upload(1). _K_e_r_m_i_t _U_s_e_r_s _G_u_i_d_e, Fourth Edition (19 July 83), Frank da Cruz, Daphne Tzoar, Bill Catchings _K_e_r_m_i_t _P_r_o_t_o_c_o_l _M_a_n_u_a_l, Fourth Edition (4 November 83), Frank da Cruz, Bill Catchings BUGS for _K_e_r_m_i_t-_8_0 Version UCB36.16 Send with file-mode default is supposed to truncate the trailing ^Z's (cp/m end-of-file padding). Send with file- mode ascii is supposed to truncate the file at the first ^Z, but works properly only if the ^Z occurs in the last block, otherwise, blocks with ^Z's are truncated but file transfer continues. However, such files are not proper cp/m files. When ^Z or ^X are used to terminate a receive, _K_e_r_m_i_t-_8_0 does not stop immediately or may even abort or hang. This is due to protocol differences between our older UNIX _K_e_r_m_i_t and _C_M_S _K_e_r_m_i_t and the newer _K_e_r_m_i_t-_8_0. Printed 2/13/84 13 February 1984 9 KERMIT-80(1C) UCB Microcomputer Users Manual KERMIT-80(1C) Certain cp/m BDOS errors abort _K_e_r_m_i_t-_8_0. Simply type CR or ^C, wait for cp/m to warm boot, and reload _K_e_r_m_i_t-_8_0. Any operation on an invalid disk gives `BDOS err on D: Select'. ERA of a $r/o file will give `BDOS err on A: R/O'. _K_e_r_m_i_t-_8_0 commands allow only letters, digits and `@[\]^' in the name and type fields. Other characters cause an error or the command acts as if no file name was given. When connected to UCB CAL mode, a BREAK must be used to interrupt output since CAL mode is half-duplex. _K_e_r_m_i_t-_8_0 cannot generate a BREAK. The Kaypro displays RUBOUTS (7F hex). CMS uses rubouts as idle characters to hold the line while it prepares to send the next packet, hence for very long delays, enough RUBOUTS may be displayed below the noise line to to scroll the display which messes up the full screen presentation. If the file does not exist for a send command, the error message is displayed on line 5 assuming the packet display is up, which it is not, hence the message and the prompt may appear in a field of previous lines. PDP-11 UNIX _K_e_r_m_i_t (A-F) fails to respond at the end of a send or receive command. It appears that UNIX does not respond to an "EOT" message. The file has been transfered correctly. The _K_e_r_m_i_t-_8_0 retry counter increments on each new file when receiving from UNIX. The fact that the retry counter incre- ments at the end of each new file, suggests a timing or pro- tocol problem. File transfer is not affected. Please report other problems to micros@opal or the CS Micro- computer Consultant (262 Evans Hall, 642-4072). BUGS for _K_e_r_m_i_t-_8_0 Version UCB 3.1 These old bugs are listed for convienence. All _K_e_r_m_i_t-_8_0 users should upgrade to the latest version UCB36.16. Line noise or system messages can cause a received packet to be longer than 96 characters, hence exceeding the receive packet buffer. Depending on the length of the packet and the junk, this could cause the file buffer, subroutine argu- ments, and other later data to be clobbered. Probably mani- fested as occasional junk in files and mystery probelms that go away. When sending in image mode, sometimes an additional 32k of data appears in the file. Printed 2/13/84 13 February 1984 10 KERMIT-80(1C) UCB Microcomputer Users Manual KERMIT-80(1C) VT52 emulation does not work properly in most versions. Caused by absence of cursor addressing and errors in the vt52 to terminal table. CP/M files with $r/o or $sys attributes set loose one or more characters of the file type when that file is sent out because the attribute bit (bit 8) on the type characters causes them to be rejected. If a duplicate file name is received kermit crashes with "file r/o" if the existing file is $r/o. This is because the attribute bits are not cleared in the file control block (fcb) after the initial open and, hence, the modified filename is created $r/o and kermit cannot write it! Printed 2/13/84 13 February 1984 11  10 KERMIT-80(1C) UCB Microcomputer Users Manual KERMIT-80(1C) VT52 emulation does not work properly in most versions. Caused by absence of cursor addressing and errors in the vt52 to terminal table. CP/M files with $r/o or $sys attributes set loose one or more characters of the file type when that file is sent out because the attribute bit (bit 8) on the type characters causes them to be rejected. If a duplicate file name is received kermit crashes with "file r/o" if the existing file is $r/o. This is because the attri title 'KERMIT Version 3.6 (UCB36.16) 2/3/84 02:39:46' ;UCB3605 ;-----------------------------------------------------------------------; ; ; ; KERMIT File Transfer Program for CP/M 80 (UCB36.16) ; ; ; ; Last changes included as of: 2/3/84 02:39:46 ; ; Extracted from CAL source: 2/3/84 10:44:47 ; ; ; ; This source has been modified and added to by the staff of ; ; the University of California at Berkeley but was obtained ; ; from Columbia University and various other contributors. ; ; ; ; The revision record below describes both UCB changes and ; ; those that came with the Columbia distribution. ; ; ; ; The University of California does not support versions of ; ; Kermit derived from this source, but supports the Kermit ; ; protocol for file exchange with its Unix and CMS systems ; ; to the extent that certain released object code versions ; ; will work with our systems on a reasonable effort basis. ; ; ; ; Computing Services / Computer Facilities and Operations ; ; Evans Hall, University of California, Berkeley, Ca 94720 ; ;-----------------------------------------------------------------------; ;UCB 36.16asm 84-01-31 gts, CFO ;UCB3616 ; Repair problems with UCBIBM mods (UCB3613) due to fixes to inpkt: ;UCB3616 ; buffering in UCB3612. Since UCB3613 fills the packet buffer from ;UCB3616 ; soh to xon rather than to cr, the rubouts sent by CMS to block the ;UCB3616 ; line will cause the buffer to overflow when a max size packet is ;UCB3616 ; received. CMS Kermit sends packets the size of the line being sent ;UCB3616 ; rather than blocking more than one line into a packet, hence the ;UCB3616 ; problem only shows up on lines longer than 80 or so. ;UCB3616 ; Display noise or messages after cr but before xon. ;UCB3616 ; Caution: since the UCB Port Selector echos the packets sent by the ;UCB3616 ; micro, the micro receives the echoed soh and the prompt from CMS as ;UCB3616 ; if it is the next packet (the serial USART is double buffered). The ;UCB3616 ; is lost. This is why the ucbibm mods are necessary. ;UCB3616 ;UCB 36.15asm 84-01-26 gts, CFO ;UCB3615 ; Do not abort at max retry, rather post the appropriate error message, ;UCB3615 ; reset the retry counter and continue. User must manually intervene ;UCB3615 ; with ^X, ^Z or ^A (to abort in inchr:). Allows going out for coffee ;UCB3615 ; and for very slow response (as for overloaded UNIX). ;UCB3615 ; Display ^Z, ^X, ^A and cr commands during send and receive. ;UCB3615 ; Change nak: to increment and display retry count, same as nak0:. ;UCB3615 ; Beep each time updrtr: is called. ;UCB3615 ; Display pre soh noise (usually text from the aborted remote kermit). ;UCB3615 ; Change bye, logout and finish to use send/receive packet display, ;UCB3615 ; so that error and other features do not cause funny screen probs. ;UCB3615 ; Reset stack pointer at kermit: to assure that not losing control. ;UCB3615 ;UCB 36.14asm 83-08-?? vaf, CS and gts, CFO ;UCB3614 ; Implement fuzzy timer for inchr: auto-retry, some machines only. ;UCB3614 ; Timeout uses a two byte counter giving 65536 repetitions of the ;UCB3614 ; inchr: loop. This gave 13.5 seconds on a TRS-80 Model 16. ;UCB3614 ;UCB 36.13asm 83-08-?? vaf, CS and gts, CFO ;UCB3613 ; Implement allows access to UCB CMS through 3705 "cal" or "line mode". ;UCB3613 ; Different from native kermit IBM ON because portselector echos, ;UCB3613 ; parity is even, and outkpt: does not have to wait for xon because ;UCB3613 ; xon is sent as the packet terminator. Set ucbibm equ true. ;UCB3613 ;UCB 36.12asm 84-01-15 gts, CFO ;UCB3612 ; Inpkt: prevent recpkt: buffer overflow from clobbering other storage. ;UCB3612 ; If overflow, restart packet collection (see UCB3603). ;UCB3612 ; Inpkt: store a cariage-return beyond the received packet to stop ;UCB3612 ; rpack: if some error confuses it. ;UCB3612 ;UCB 36.11asm 83-10-13 gts, CFO ;UCB3611 ; Put a unique comment line past all conditional assembly parameters. ;UCB3611 ; This point is used to insert TRUE equ's for selecting the machine ;UCB3611 ; and terminal to be assembled. Since all conditionals above are FALSE, ;UCB3611 ; the assembler will give a P "phase" error but will use the new value. ;UCB3611 ; The P error lines will will show the version assembling (ASM or MAC). ;UCB3611 ;UCB 36.10asm 83-10-06 gts, CFO ;UCB3610 ; Implement seperate terminal definitions for machines that do not ;UCB3610 ; have a built in and therefore standard terminal. ;UCB3610 ; Implement tvi925 and adm3a cursor positionable crts. The tvi925 ;UCB3610 ; implementation is designed to work acceptably on the adm3a and the ;UCB3610 ; adm3a implementation is just a tiny revision to the vt52 emulation. ;UCB3610 ; Most other similar crts can either use the tvi925 implementation or ;UCB3610 ; be implemented as small changes similar to the adm3a implementation. ;UCB3610 ; Implement crt, basic non-positionable crt similar to generic. ;UCB3610 ; Implement the Morrow Micro Decision I (mdI). ;UCB3610 ;UCB 36.09asm 84-01-05 gts, CFO ;UCB3609 ; Fix misplaced "if debug" at line 2399. ;UCB3609 ; Fix split line for "baudtb: ...baud ra","te.." for brain. ;UCB3609 ; Change "If debug" for rppos:/sppos: to "IF debug AND brain". ;UCB3609 ;UCB 36.08asm 83-08-?? vaf, CS and gts, CFO ;UCB3608 ; Split screen dependant trs-80 code into original for lifeboat cp/m ;UCB3608 ; (trs80lb) and newer for Pickles and Trout cp/m (trs80pt). ;UCB3608 ; Do not display xon, it is a graphics character for P+T cp/m. ;UCB3608 ; Note: trs80 variable must also be set. ;UCB3608 ;UCB 36.07asm 83-10-31 gts, CFO ;UCB3607 ; Force received file names to upper case (gofil2:, gofil6:). ;UCB3607 ;UCB 36.06asm 83-10-23 gts, CFO ;UCB3606 ; Fix more problems with cp/m 2.2 attribute bits (see also [UTK013]). ;UCB3606 ; Trim attribute bits from fcb after each open when file to be received ;UCB3606 ; already exists (gofil8:) so that subsequent file creation with ;UCB3606 ; modified name does not have attribute bits set (e.g. $r/o)! ;UCB3606 ;UCB 36.05asm 83-10-23 gts, CFO ;UCB3605 ; Changes for assembly under RMAC. ;UCB3605 ; Local is a reserved name and is changed to locall. ;UCB3605 ; Title and aseg pseudo ops inserted. Title gives warning in ASM. ;UCB3605 ;UCB 36.04asm 83-08-?? vaf, CS and gts, CFO ;UCB3604 ; Fix Kaypro II ttab: and clrlin: clear to eos + eol. ;UCB3604 ; Remove default off for vtflg: now that ttab: fixed. ;UCB3604 ; Add clear to end of line to most positioning strings. ;UCB3604 ; Fix scrend: to past send/receive display. ;UCB3604 ; When ibmflag, do not display null, xon, xoff or del (kpii graphics). ;UCB3604 ;UCB 36.03asm 83-08-?? vaf, CS ;UCB3603 ; Improve packet receive reliability under error conditions. ;UCB3603 ; Inpkt: skip leading junk until soh and restart if another soh. ;UCB3603 ; Rpack: did check for imbedded soh's, but this only worked if the ;UCB3603 ; buffer was allowed to overflow. Rpack: not changed to remove soh ;UCB3603 ; checks, they do not cost much. ;UCB3603 ;UCB 36.02asm 83-12-30 gts, CFO ; UCB version header prepended and added to all version messages. ; All conditionals set to false. ; All revision and update comments except the most current removed. ; All .printx and associated text removed. ; All ^L characters removed. ;UCB 36.01asm 83-12-30 gts, CFO ; Original Columbia version 3.6 of 83-12-13. ;COLUMBIA-20::PS:CPMBAS.M80.2, 12-Dec-83 17:47:18, Frank ; Change version number to 3.6 ; KERMIT - (Celtic for "FREE") ; ; Version 3.6 ; ; Based on the KERMIT Protocol. ; ; Copyright June 1981 ; Bill Catchings ; Columbia University ; 612 W. 115th St. ; New York City, NY 10025 ; ; Special thanks to Frank da Cruz, Daphne Tzoar and Bernie Eiben for ; their help and contributions. ; (And Bruce Tanner, and Nick Bush, and ...) ASEG ;UCB3605 ORG 100H TRUE EQU -1 ; Define the boolean constants. FALSE EQU NOT TRUE ; ... debug EQU FALSE ; For debugging (SuperBrain only). ; Which CP/M system hardware are we building KERMIT-80 for? ; One of the following should be TRUE, the rest FALSE: ; robin EQU FALSE ; DEC VT180 = Generic + VT100 screen control brain EQU FALSE ; For Intertec SuperBrain. vector EQU FALSE ; For Vector Graphics. osi EQU FALSE ; For Ohio Scientific. heath EQU FALSE ; For Heath/Zenith H89. z100 EQU FALSE ; For Z-100 under CP/M-85. apple EQU FALSE ; For APPLE ][ with D.C. Hayes Micromodem II. trs80 EQU FALSE ; For TRS-80 model II ;UCB3608 trs80lb EQU FALSE ; Lifeboat 2.25C CP/M Display ;UCB3608 trs80pt EQU FALSE ; Pickles + Trout CP/M Display ;UCB3608 osbrn1 EQU FALSE ; For Osborne 1 telcon EQU FALSE ; For TELCON Zorba portable rainbo EQU FALSE ; Rainbow (=Generic with VT100 screen control). gener EQU FALSE ; "Generic" Kermit-80, CP/M calls only. dmII EQU FALSE ; "Generic" KERMIT-80 for DECMATE II. kpII EQU FALSE ; Kaypro-II mdI EQU FALSE ; Morrow Micro Decision I ;UCB3610 crt EQU FALSE ; Basic crt, no cursor positioning ;UCB3610 adm3a EQU FALSE ; Adm3a Display ;UCB3610 tvi925 EQU FALSE ; TVI925 Display ;UCB3610 ;UCB Conditional Point (all inserted TRUE conditionals after here) ;UCB3611 cpm3 EQU TRUE ; "Generic" Kermit-80 for CP/M 3.0 (CP/M Plus) ucbibm EQU TRUE ; UCB IBM: even, no local echo, no xon ;UCB3613 kpii EQU FALSE ;UCB ;========================================================================= ; 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 rainbo OR robin OR 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 ENDIF ;rainbo OR robin OR gener IF robin 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 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 ; Symbolic Definitions for some ASCII characters ; bell EQU 07O ;ASCII BEL (Control-G) ctrlc EQU 03O ;ASCII ETX (Control-C) 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) xon EQU 21O ;The the ASCII character used for XON xoff EQU 23O ;The the ASCII character used for XOFF esc EQU 33O ;ASCII ESCape subt EQU 32O ;ASCII SUB (CTRL-Z) del EQU 177O ;ASCII DELete (rubout) bdos EQU 0005H ;Call BDOS npl EQU 04H ; Number of names per line for dir command. [UTK008] ; BDOS calls ; ;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 auxout EQU 04H ;Auxiliary output punout EQU 04H ;Write Punch ASCII Char in E NONE 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 auxist EQU 07H ;Get AUXIN: status A=FF is character ; ready, A=0 if none gtiob EQU 07H ;Get I/O status NONE I/O Status in A auxost EQU 08H ;Get AUXOUT: status A=FF if ready, A=0 ; if not ready ptiob EQU 08H ;Put I/O status I/O Status in E NONE 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 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 renam EQU 17H 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 getalv EQU 1BH ;Get All.Vect. NONE All.Vect in HL 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 IF brain baudst EQU 60H ; Port number for baud rate setting. baudrt EQU 0EF00H ; Memory location where baud rates are stored. mnport EQU 58H mnprts EQU 59H output EQU 01H input EQU 02H ENDIF ;brain IF osi mnport EQU 0CF01H mnprts EQU 0CF00H output EQU 02H input EQU 01H ENDIF ;osi IF vector mnport EQU 04H mnprts EQU 05H output EQU 01H input EQU 02H ENDIF ;vector IF heath mnport EQU 330O mnprts EQU 335O output EQU 20H input EQU 01H ENDIF ;heath IF z100 mnport EQU 0ECH mnprts EQU 0EDH output EQU 001H input EQU 002H ENDIF ;z100 IF trs80 mnport EQU 0F4H ; 0F5H for port B mnprts EQU 0F6H ; 0F7H for port B output EQU 04H input EQU 01H ;NEEDS display definition (e.g., trs80lb, trs80pt) ;UCB3608 ENDIF ;trs80 IF apple ; 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 ENDIF ;apple 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) ENDIF ; osbrn1 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 ENDIF ; telcon 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. ENDIF ;robin IF mdI ;UCB3610 mnport EQU 0FEH ; Morrow Printer UART data port ;UCB3610 mnprts EQU 0FFH ; Morrow Printer UART command/status ;UCB3610 output EQU 01H ; Output ready bit. ;UCB3610 input EQU 02H ; Input ready bit. ;UCB3610 ;Note: ; NEEDS terminal definition (e.g. tvi925 or adm3a above) ;UCB3610 ENDIF ;mdI ;UCB3610 IF brain OR osi OR apple OR telcon defesc EQU ']'-100O ; The default escape character. ENDIF ;brain OR osi OR apple OR telcon IF vector defesc EQU '~' ; Vector can't type ']'. ENDIF ;vector IF robin OR heath OR z100 OR rainbo OR gener OR osbrn1 OR dmII OR cpm3 OR kpII defesc EQU '\'-100O ; The default is Control \ -- it's easier B.E. ENDIF ; robin OR heath or z100 or rainbo or gener OR osbrn1 OR dmII or kpII IF crt OR tvi925 OR adm3a ;UCB3610 defesc EQU '\'-100O ; The default is Control \ ;UCB3610 ENDIF ; crt OR tvi925 OR adm3a  ;UCB3610 IF trs80 defesc EQU '_'-100O ; CTRL-_ (CTRL-downarrow on TRS-80 keyboard) ENDIF ; trs80 maxpkt EQU '~'-' '+2O ; Maximum size of a packet. maxtry EQU 05O ; Default number of retries on a packet. imxtry EQU maxtry ; Default number of retries send init. ;UCB3615 drpsiz EQU 5EH ; Default receive packet size. dspsiz EQU 20H ; Default send packet size. dstime EQU 08H ; Default send time out interval. IF NOT (apple OR osbrn1) drtime EQU 05H ; Default receive time out interval. ENDIF ; NOT (apple OR osbrn1) IF apple OR osbrn1 drtime EQU 0AH ENDIF ; apple OR osbrn1 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 parevn EQU 00H ; Even parity. parmrk EQU 03H ; Mark parity. parnon EQU 06H ; No parity. parodd EQU 09H ; Odd parity. parspc EQU 0CH ; Space parity. defpar EQU parnon ; Default parity. IF NOT ucbibm ;UCB3613 ibmpar EQU parmrk ; IBM COMTEN's parity. ibmeco EQU 1 ; IBM COMTEN's needs local echo. ;UCB3613 ENDIF ;NOT ucbibm ;UCB3613 IF ucbibm ;UCB3613 ibmpar EQU parevn ; UCB IBM parity is even ;UCB3613 ibmeco EQU 0 ; UCB IBM echoes, so no local echo ;UCB3613 ENDIF ;ucbibm ;UCB3613 soh EQU 01H ; Start of header char. 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. diasw EQU 01H ; Default is diagnostics on. 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. cmifin equ 10H ; Parse an input file spec (but no ; Error output if kpii mnport equ 04h ;Modem data port mnprts equ 06h ;Modem status port output equ 04h ;Transmit buffer empty input equ 01h ;Receive data available kpslen equ 0ah ;length of sio status table endif ;kpii start: nop ; Make sure we have a zero where nop ; DDT will set the stack pointer 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 ; and move in our own stack. IF (gener OR rainbo OR robin OR dmII) call iniadr ; Initialize the BIOS addresses ENDIF ; (gener OR rainbo OR robin OR dmII) mvi c,rddrv ; Get our logged in drive call BDOS inr a ; relative 1 ! sta CURDSK ; and save it for later IF gener OR rainbo OR robin OR dmII mvi c,gtiob ; Get current I/O byte call bdos ; From CP/M sta coniob ; Remember where console is ENDIF IF crt OR tvi925 OR adm3a ;UCB3610 lxi h,versi0 ; Move machine mame ;UCB3610 lxi d,versi1 ; to display header ;UCB3610 mvi c,versi2-versi1 ; (limit to space) ;UCB3610 start2: mov a,m ; (get character) ;UCB3610 ani 7Fh ; (clean ascii) ;UCB3610 jz start3 ; (stop if end of string) ;UCB3610 stax d ; (store it) ;UCB3610 inx h ; (increment source pointer) ;UCB3610 inx d ; (increment destination pointer) ;UCB3610 dcr c ; (continue if not too long) ;UCB3610 jnz start2 ; ;UCB3610 start3: ;UCB3610 ENDIF ;crt OR tvi925 OR adm3a ;UCB3610 lxi d,versio ; Print version header call prtstr IF osbrn1 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 start1: call mover lda baudrt ani 1 sta osbaud ; Find out what speed is current call osbset ; ...and set up parity etc. ENDIF ; osbrn1 if kpii lxi d,kpstbl ;Load the address of the status able mvi c,kpslen ;Length of status table kploop: ;Loop back here for each status word ldax d ;Load the first word into A inx d ;Index the pointer out mnprts ;Send it to the status port dcr c ;Decrement the byte counter jnz kploop ;Jump back for more status bytes endif ;kpii call kermit ; Start things going. call exit1 ; Finish up. IF (gener OR rainbo OR robin OR dmII) ; 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 - thats done by BDOS. ; ; How do we "get" the call-adresses? . Location 0 has a CALL 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 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) ENDIF ;(gener OR rainbo OR robin OR dmII) ; This is the main KERMIT loop. It prompts for and gets the users commands. kermit: lda curdsk adi 'A'-1 sta kerm1 lxi sp,stack+2 ; Assure stack not running away ;UCB3615 xra a sta mfflg1 ;reset MFNAME sta mfflg2 ; ditto lxi d,kerm call prompt ; Prompt the user. lxi d,comtab lxi h,tophlp mvi a,cmkey call comnd jmp kermt2 lxi h,kermtb ; Get the address of the jump table. mov c,a mvi b,0 dad b pchl kermtb: jmp telnet jmp exit jmp help jmp log jmp read jmp send jmp setcom ; Set is an assembler keyword!! jmp show jmp status  jmp finish jmp logout jmp bye jmp dir ; do directory [utk008] jmp era ; do "ERA"se file kermt2: lxi d,ermes1 ; An error message. call prtstr jmp kermit ; Do it again. kermt3: lxi d,ermes3 ; An error message. call prtstr jmp kermit ; Do it again. ; RECEIVE command infrec: db 'RECEIVE$' ; Function name for Display. ;UCB3615 read: lxi d,data ; 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 read1 ; Nope, just a regular send. sta argblk+1 ; Store the number of chars. xchg ; Get pointer into HL. mvi m,'$' ; Put in a dollar sign for printing. lxi d,infrec ; Say what we are doing. ;UCB3615 call init ; Clear the line and initialize the buffers. lxi d,scrfln ; Position cursor call prtstr lxi d,data ; Print the file name call prtstr 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! jmp read12 read1: lxi d,infrec ; Say what we are doing. ;UCB3615 call init ; Clear the line and init. buffers. ;UCB3615 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. lxi d,scrnrt ; Position cursor call prtstr lxi h,0 call nout ; Write the number of retries. mvi a,'R' sta state ; Set the state to receive initiate. ;... ; RECEIVE state table switcher. read2: lxi d,scrnp ; Position cursor call prtstr lhld numpkt call nout ; Write the current packet number. lda state ; Get the state. cpi 'D' ; Are we in the DATA receive state? jnz read3 call rdata 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 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: call finmes ; Print completion message in right place. jmp kermit read6: cpi 'A' ; Are we in the Receive-"Abort" state? jnz read7 lxi d,infms4 ; Print message. call finmes jmp kermit read7: lxi d,infms4 ; Anything else is equivalent to "abort". call finmes jmp kermit ; Initialize buffers and clear line. init: push d ; Save function name. ;UCB3615 lxi d,outlin ; Put Banner on screen ;UCB3615 call prtstr IF NOT (gener OR osi OR cpm3 OR crt) ;UCB3610 lxi d,outln2 ; Put statistics headers on the screen call prtstr ;  only for screen-formatting versions. ENDIF ; NOT (gener OR osi OR cpm3 OR crt) ;UCB3610 pop d ; Restore function name. ;UCB3615 call prtstr ; and display it ;UCB3615 lxi d,outln1 ; with CR, ^Z, ^X, ^A options. ;UCB3615 call prtstr ; ;UCB3615 IF NOT (gener OR osi OR cpm3 OR crt) ;UCB3615 lxi d,outln3 ; Display Noise/Message header. ;UCB3615 call prtstr ; ;UCB3615 ENDIF ; NOT (gener OR osi OR cpm3 OR crt) ;UCB3615 init1: mvi a,bufsiz ; Buffer size. sta chrcnt ; Number of chars left. lxi h,buff ; Addr for beginning. shld bufpnt ; Store addr for beginning. ret ; Receive routines ; Receive init 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. xra a ; Clear retry count and continue ;UCB3615 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. 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.) inr a ; Increment it. ani 3FH ; Turn off the two high order bits. sta pktnum ; Save modulo 64 of the number. lhld numpkt inx h ; Increment the number of packets. shld numpkt 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 ; These are some utility routines. ; Abort abort: mvi a,'A' ; Otherwise abort. sta state ret abortf: lxi d,infms2 ; Abort from receive or send ;UCB3615 call finmes ; ;UCB3615 jmp kermit ; ;UCB3615 ; NAK nak: ;UCB3615 nak0: call updrtr ; Update number of retries. lda pktnum ; Get the packet number ;UCB3615 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. updrtr: lxi d,scrnrt ; Position cursor call prtstr lhld numrtr inx h ; Increment the number of retries shld numrtr call nout ; Write the number of retries. mvi e,bell ; BEEP ;UCB3615 mvi c,conout ; ;UCB3615 call bdos ; ;UCB3615 ret ; This routine sets up the data for init packet (either the ; Send_init or ACK packet). rpar: lda rpsiz ; Get the receive packet size. adi ' ' ; 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 ' ' ; Add a space. mov m,a ; Put it in the packet. inx h lda rpad ; Get the number of padding chars. adi ' ' 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 ' ' mov m,a inx h lda rquote ; Get the quote char. mov m,a inx h mvi m,'N' ; We do not do 8-bit quoting yet inx h ; Advance to next lda inichk ; Get desired block check type mov m,a ; Store it inx h ; Advance pointer mvi a,08H ; Six pieces of data. ret ; This routine reads in all the send_init packet information. spar: sta temp4 ; Save the number of arguments. mov a,m ; Get the max packet size. sbi ' ' ; 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 ' ' 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 ' ' 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 mov a,m ; Get the supplied character ; Perhaps we should validate that the 8-bit quote character is only ; 'Y' or 'N', however, if the other end really desires 8-bit quoting, ; it should give an error due to our stating that we do not do 8-bit ; quoting at all. 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? jz spar01 ; If so, use it mvi a,'1' ; No, use single character sta inichk ; Store as type desired after init done ret ; And return spar01: sta inichk ; Store the desired block check type ret ; And return ; Receive file 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. xra a ; Clear retry count and continue ;UCB3615 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. xra a ; Clear retry count and continue ;UCB3615 rfil12: inr a ; Increment it. sta oldtry ; Save the updated number of tries. lda pktnum ; Get the present packet number. dcr a ; Decrement. 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 pack et? 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. xra a ; Clear retry count and continue ;UCB3615 rfil21: inr a ; Increment it. sta oldtry ; Save the updated number of tries. lda pktnum ; Get the present packet number. dcr a ; Decrement. 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. xra a sta numtry ; Reset number of tries. sta argblk+1 ; No data. (The packet number is in argblk.) mvi a,'Y' ; Acknowledge packet. call spack ; Send the packet. jmp abort ; Failed, abort. ret rfile3: cpi 'F' ; Start of file? jnz rfile4 lda pktnum ; Get the packet number. mov b,a lda argblk cmp b ; Is it the right packet number? jnz nak0 ; No, NAK it and try again. inr a ; Increment the packet number. ani 3FH ; Turn off the two high order bits. sta pktnum ; Save modulo 64 of the number. lhld numpkt inx h ; Increment the number of packets. shld numpkt call gofil ; Get a file to write to. jmp abort call init1 ; Initialize all the buffers. lda numtry ; Get the number of tries. sta oldtry ; Save it. xra a sta numtry ; Reset the number of tries. sta argblk+1 ; No data. (The packet number is in argblk.) mvi a,'Y' ; Acknowledge packet. call spack ; Send the packet. jmp abort 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 (Control-X is only for one file) sta czseen ; And store the flag back ret rfile4: cpi 'B' ; End of transmission. jnz rfile5 lda pktnum ; Get the packet number. mov b,a lda argblk cmp b ; Is it the right packet number? 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 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. xra a ; Clear retry count and continue ;UCB3615 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. rdat11: lda pktnum ; Get the present packet number. mov b,a lda argblk ; Get the packet's number. cmp b ; Is the packet's number correct? jz rdat14 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. xra a ; Clear retry count and continue ;UCB3615 rdat12: inr a ; Increment it. sta oldtry ; Save the updated number of tries. lda pktnum ; Get the present packet number. dcr a ; Decrement. 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. xra a sta numtry ; Reset number of tries. sta argblk+1 ; No data. (The packet number is in argblk.) mvi a,'Y' ; Acknowledge packet. call spack ; Send the packet. jmp abort ; Failed, abort. ret rdat14: inr a ; Increment the packet number. ani 3FH ; Turn off the two high order bits. sta pktnum ; Save modulo 64 of the number. lhld numpkt inx h ; Increment the number of packets. shld numpkt lda numtry ; Get the number of tries. sta oldtry ; Save it. lda argblk+1 ; Get the length of the data. call ptchr jmp abort ; 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 abort 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. xra a ; Clear retry count and continue ;UCB3615 rdat21: inr a ; Increment it. sta oldtry ; Save the  updated number of tries. lda pktnum ; Get the present packet number. dcr a ; Decrement. 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. xra a sta numtry ; Reset number of tries. sta argblk+1 ; No data. (The packet number is in argblk.) mvi a,'Y' ; Acknowledge packet. call spack ; Send the packet. jmp abort ; Failed, abort. ret rdata3: cpi 'Z' ; Is it a EOF packet? jnz rdata4 ; Try and see if its an error. lda pktnum ; Get the present packet number. mov b,a lda argblk ; Get the packet's number cmp b ; Is the packet's number correct? jnz nak0 ; No, NAK it and try again. inr a ; Increment the packet number. ani 3FH ; Turn off the two high order bits. sta pktnum ; Save modulo 64 of the number. lhld numpkt inx h ; Increment the number of packets. shld numpkt 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: lhld bufpnt ; Get the dma pointer. lda chrcnt ; Get the number of chars left in the DMA. rdat34: dcr a ; Lower the count. ora a jm rdat35 ; If full then stop. mvi m,'Z'-100O ; Put in a ^Z for EOF. inx h ; Point to the next space. jmp rdat34 rdat35: call outbuf ; Output the last buffer. jmp abort ; Give up if the disk is full. mvi c,closf ; Close up the file. lxi d,fcb call bdos xra a ; Since we kept the file, sta czseen ; don't say it was discarded. rdat36: lda numtry ; Get the number of tries. sta oldtry ; Save it. xra a sta numtry ; Reset the number of tries. sta argblk+1 ; No data. (The packet number is in argblk.) mvi a,'Y' ; Acknowledge packet. call spack ; Send the packet. jmp abort mvi a,'F' sta state ret rdata4: cpi 'E' ; Is it an error packet. jnz abort  call error jmp abort ; Send command infsnd: db 'SEND$' ; Function name for Display. ;UCB3615 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. send1: mvi a,cmcfm call comnd ; Get a confirm. jmp kermit ; Didn't get a confirm. send11: call mfname ; handle (multi) files jnc send14 ; got a valid file-name lxi d,erms15 call error3 ; Display error msg. jmp kermit send14: lxi d,infsnd ; Say what we are doing. ;UCB3615 call init ; Clear the line and initialize buffers ;UCB3615 xra a sta pktnum ; Set the packet number to zero. sta numtry ; Set the number of tries to zero. lxi h,0 shld numpkt ; Set the number of packets to zero. shld numrtr ; Set the number of retries to zero. lxi d,scrnrt ; Position cursor call prtstr lxi h,0 call nout ; Write the number of retries. 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: lxi d,scrnp ; Position cursor call prtstr lhld numpkt call nout ; Write the packet number. 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 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 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 xra a ; Clear retry count and continue ;UCB3615 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 mvi a,'S' ; Send initiate 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 sinit3 ; If not try next. lda pktnum ; Get the packet number. mov b,a lda argblk cmp b ; Is it the right packet number? rnz ; If not try again. inr a ; Increment the packet number. ani 3FH ; Turn off the two high order bits. sta pktnum ; Save modulo 64 of the number. lhld numpkt inx h ; Increment the number of packets. shld numpkt lda argblk+1 ; Get the number of pieces of data. lxi h,data ; Pointer to the data. call spar ; Read in the data. lda numtry ; Get the number of tries. sta oldtry ; Save it. xra a sta numtry ; Reset the number of tries. 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. sta state call getfil ; Open the file. jmp abort ; Something is wrong, die. ret 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. 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 call error jmp abort ; Send file header 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 xra a ; Clear retry count and continue ;UCB3615 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. 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.[UTK013] 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. lxi d,scrfln ; Position cursor call prtstr lxi d,data ; Print the file name 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. lda pktnum ; Get the packet number. mov b,a lda argblk cmp b ; Is it the right packet number? rnz ; If not hold out for the right one. sfil14: inr a ; Increment the packet number. ani 3FH ; Turn off the two high order bits. sta pktnum ; Save modulo 64 of the number. lhld numpkt inx h ; Increment the number of packets. shld numpkt lda numtry ; Get the number of tries. sta oldtry ; Save it. xra a sta numtry ; Reset the number of tries. sfil15: xra a ; Get a zero. sta fcb+20H ; Set the record number to zero. sta eoflag ; Indicate not EOF. mvi a,0FFH sta filflg ; Indicate file buffer empty. call gtchr jmp sfil16 ; Error go see if its EOF. jmp sfil17 ; Got the chars, proceed. sfil16: cpi 0FFH ; Is it EOF? jnz abort ; If not give up. mvi a,'Z' ; Set the state to EOF. sta state ret sfil17: sta size ; Save the size of the data gotten. mvi a,'D' ; Set the state to data send. 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. 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 ; Send data 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 xra a ; Clear retry count and continue ;UCB3615 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 posi tion in char buffer. mvi b,1 ; First char. sdat11: lhld cbfptr mov a,m inx h shld cbfptr ; Save position in char buffer. 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. lda pktnum ; Get the packet number. mov b,a lda argblk cmp b ; Is it the right packet number? rnz ; If not hold out for the right one. lda argblk ; Get the packet number back inr a ; Increment the packet number. ani 3FH ; Turn off the two high order bits. sta pktnum ; Save modulo 64 of the number. lhld numpkt inx h ; Increment the number of packets. shld numpkt 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 sdat14: cpi 'X' ; Desire abort of current file? jnz sdat15 ; If not, just continue sta czseen ; Yes, remember that sdat15: lda czseen ; Also get control-Z flag ora a ; Check if either given jz sdat12 ; If neither given, continue 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. 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 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 xra a ; Clear retry count and continue ;UCB3615 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. lda pktnum ; Get the packet number. mov b,a lda argblk cmp b ; Is it the right packet number? rnz ; If not hold out for the right one. seof12: inr a ; Increment the packet number. ani 3FH ; Turn off the two high order bits. sta pktnum ; Save modulo 64 of the number. lhld numpkt inx h ; Increment the number of packets. shld numpkt 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 jmp abort ; Something is wrong, die. 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. 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 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  xra a ; Clear retry count and continue ;UCB3615 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. lda pktnum ; Get the packet number. mov b,a lda argblk cmp b ; Is it the right packet number? rnz ; If not hold out for the right one. seot12: inr a ; Increment the packet number. ani 3FH ; Turn off the two high order bits. sta pktnum ; Save modulo 64 of the number. lhld numpkt inx h ; Increment the number of packets. shld numpkt 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. 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 ; File routines ; Output the chars in a packet. ptchr: sta temp1 ; Save the size. 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. ptchr1: lxi h,temp1 dcr m ; Decrement # of chars in packet. jm rskp ; Return successfully if done. 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 r ; 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. cmp b ; Is it the quote char? jnz ptchr4 ; If not proceed. 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. 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. 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. ptchr4: lhld bufpnt ; Destination buffer. mov m,a ; Store it. inx h shld bufpnt ; Update the pointer jmp ptchr1 ; and loop to next char. ; output the buffer, reset bufpnt and chrcnt outbuf: push b mvi c,writef ; The write code. lxi d,fcb call bdos ; Write the record. pop b ora a ; Successful. jz outbf1 lxi d,erms11 call error3 ret outbf1: lxi h,buff ; Addr for beginning. shld bufpnt ; Store addr for beginning. mvi a,bufsiz-1 ; Buffer size. sta chrcnt ; Number of chars left. jmp rskp ; Get the chars from the file. gtchr: lda squote ; Get the quote char. mov c,a ; Keep quote char in c. lda filflg ; Get the file flag. ora a ; Is there anything in the DMA? jz gtchr0 ; Yup, proceed. mvi b,0 ; No chars yet. call inbuf jmp gtceof ; No more chars, go return EOF. gtchr0: 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. mov a,d ; Restore the char. ani 7FH ; Turn off the parity. cpi ' ' ; 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. cmp c ; Is it the quote char? jnz gtchr8 ; If not proceed. lxi h,temp1 ; Point to the char total remaining. dcr m   ; Decrement it. lhld cbfptr ; Position in character buffer. mov m,a ; Put the char in the buffer. inx h shld cbfptr inr b ; Increment the char count. jmp gtchr8 gtchr5: 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 ; First Control-Z stops text lda eoflag ; EOF flag set? ora a jz gtchr6 ; If not just go on. lda cpmflg ; Was the file created by CPM? cpi 2 ; in BINARY (same as default) jz gtchr6 ; Yes (this code currently does the same) 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 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 they 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. gtceof: mvi a,0FFH ; Get a minus one. ret inbuf: lda eoflag ; Have we reached the end? ora a jz inbufa ; no mvi b,0 rnz ; Return if set. inbufa: push b push d push h lxi h,chrcnt ; Reset character count. lda filflg ; Get the file flag. ora a ; Has there ever been anything in the DMA? jz inbuf1 ; If so just set it. mvi m,bufsiz ; If not set it the buffer size. xra a ; Zero the flag. sta filflg jmp inbuf2 inbuf1: mvi m,bufsiz-1 ; ELse set it to one less than the buffer size. inbuf2: lxi h,buff ; Set the buffer pointer. shld bufpnt mvi c,readf ; Read a record. lxi d,fcb call bdos ora a ; 00H => read O.K jz inbuf4 jmp inbuf5 ; we either hit EOF or an ERROR inbuf3: pop h pop d pop b ret ; Either EOF or ERROR => finish ; with NON-skip return inbuf4: pop h ; more data, restore and rskp pop d pop b jmp rskp inbuf5: xra a sta chrcnt ; say no more chars in buffer mvi a,0FFH sta eoflag ; Set the EOF flag. jmp inbuf3 ; and return ;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. ; ;The FCB will be set up with the next name, ready to do normal proces- ;sing (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 ; ; 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!! ; mfname: jnc mfn00 cmc ;clear carry mfn00: push b ;Save registers push d push h if rainbo push h ; Hack for RAINBOW *** endif mvi c,setdma ; Init DMA addr, FCB lxi d,80H call bdos if rainbo pop h ; Hack for RAINBOW *** endif 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 if rainbo push h ; Hack for RAINBOW *** endif mvi c,SFIRST ; Search first lxi d,fcb call bdos if rainbo pop h ; Hack for RAINBOW *** endif 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 if rainbo push h ; Hack for RAINBOW *** endif mvi c,sfirst ; Search first old one,we got it before lxi d,fcb call bdos ;no error's expected -we got that before if rainbo pop h ; Hack for RAINBOW *** endif mfn01a: if rainbo push h ; Hack for RAINBOW *** endif mvi c,snext ;Search next call bdos if rainbo pop h ; Hack for RAINBOW *** endif mfn02: push a 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 a ;no error-check, we got it before jmp mfn01a ;next SNEXT mfn02a: pop a ora a jm mffix2 ;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 mffix1: pop h ; restore registers pop d pop b ret ;and return mffix2: stc ;set carry jmp mffix1 ;return with CARRY set ; ; Move subroutine ; from H-pointer to D-pointer B-bytes ; would be nice to use the Z80 Block-move -sigh ; mover: mov a,m stax d inx h inx d dcx b mov a,b ora c jnz mover ret movfcb: add a add a add a add a add a ; * 32 adi 80H mov l,a mvi h,0 lxi d,fcb lxi b,12 call mover ret getfil: mvi a,0FFH sta filflg ; Nothing in the DMA. xra a sta eoflag ; Not the end of file. 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 jmp rskp ; Get the file name (including host to micro translation) gofil: lxi h,data ; Get the address of the file name. 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 sta fcb ; Set the drive to default to current. mvi b,' ' gofil1: mov m,b ; Blank the FCB. inx h inr a cpi 0CH ; Twelve? jm gofil1 gofil2: lhld datptr ; Get the NAME field. mov a,m cpi 'a' ; Force upper case ;UCB3607 jm gofl2a ; ;UCB3607 ani 5Fh ; ;UCB3607 gofl2a: ; ;UCB3607 inx h shld datptr cpi '.' ; Seperator? jnz gofil3 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. 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 ;UCB3607 jm gofl6a ; ;UCB3607 ani 5Fh ; ;UCB3607 gofl6a: ; ;UCB3607 inx h shld datptr ora a ; Trailing null? jz gofil7 ; Then we're done. 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. lxi d,scrfln ; Position cursor call prtstr lxi d,data ; Print the file name call prtstr 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. lxi d,infms5 call error3 lda temp2 ; Get the number of chars in the file name. ora a jnz gofil8 lda temp1 sta temp2 gofil8: mvi b,0 mov d,b ;[UTK2] Zero d for dad index into filename inr a ; Replace next character after filename cpi 9H ; Is the first field full? jnz gofl80 mvi b,0FFH ; Set a flag saying so. dcr a gofl80: mov e,a ; Keep current, replace index in d,e. gofl81: lxi h,fcb ; Get the FCB. dad d ; Add in the character number. mvi m,'&' ; Replace the char with an ampersand. push b push d lxi h,fcb ; Trim off any cp/m 2.2 attribute bits ;UCB3606 mvi c,1+8+3 ; so they do not effect the new file. ;UCB3606 gofl82: mov a,m ; ;UCB3606 ani 7Fh ; ;UCB3606 mov m,a ; ;UCB3606 inx h ; ;UCB3606 dcr c ; ;UCB3606 jnz gofl82 ; ;UCB3606 mvi c,openf ; See if the file exists. lxi d,fcb call bdos pop d pop b cpi 0FFH ; Does it exist? jz gofl89 ; If not create it. mov a,b ; Get the field-full flag. ora a ; Incr. or decr. ? jz gofl83 ; Jump if increment dcr e ; Decrement the number of chars. mov a,e ora a jz gofl88 ; If no more, die. jmp gofl81 gofl83: inr e ; Increment the number of chars. mov a,e cpi 9H ; Are we to the end? jm gofl81 ; If not try again. lda temp2 ; Get the original size. mov e,a mvi b,0FFH ; Set flag saying field-full, decrement jmp gofl81 gofl88: lxi d,erms16 ; Tell user that we can't rename it. call prtstr ret gofl89: lxi h,fcb+0CH ; Point past the end of the file name. mov b,m ; Save the present contents. mvi m,'$' ; Put in a dollar sign. push b lxi d,fcb+1 ; Print the file name call prtstr pop b lxi h,fcb+0CH ; Restore over the dollar sign. mov m,b gofil9: 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. mvi c,makef ; Now create it. lxi d,fcb call bdos cpi 0FFH ; Is the disk full? jnz rskp lxi d,erms11 call error3 ret ; 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: +1 on failure ; +2 on success spack: sta argblk+2 lxi h,packet ; Get address of the send packet. mvi a,soh ; Get the start of header 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. ; rrc ; rrc ; rrc ; rrc ; rrc ; rrc ; 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 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. IF debug inx h ; Point to next char. mvi a,'$' ; Get a dollar sign. mov m,a ; Put in the packet. ENDIF ;debug call outpkt ; Call the system dependent routine. jmp r jmp rskp ; Write out a packet. outpkt: IF (robin OR rainbo OR gener OR dmII) lda prtiob ; Set up for output to go to the comm port sta iobyte ; Switch byte directly ENDIF ; (robin OR rainbo OR gener OR dmII) 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. mov e,a ; Put the char in right AC. call outchr ; Output it. jmp outpk2 outpk6: ; Xon wait not needed for UCB ;UCB3613 ; since ucb waits for the xon at the ;UCB3616 ; end of the packet to improve the ;UCB3616 ; reliability of detecting it. ;UCB3616 IF NOT ucbibm ;UCB3613 outpk6: lda ibmflg ; Is this the (dumb) IBM. ora a jz outpk8 ; If not then proceed. lda state ; Check if this is the Send-Init packet. cpi 'S' ;* This will also have to be taken care for 'R' (receive), 'G' (generic) ;* and 'C' (command) packets if the IBM becomes a server. jz outpk8 ; If so don't wait for the XON. outpk7: call inchr ; Wait for the turn around char. jmp outpk8 cpi xon ; Is it the IBM turn around character? jnz outpk7 ; If not, go until it is. outpk8: ENDIF ;NOT ucbibm ;UCB3613 IF (robin OR rainbo OR gener OR dmII) lda coniob ; Set up for output to go to the console port sta iobyte ; Switch directly ENDIF ; (robin OR rainbo OR gener OR dmII) IF debug ;UCB3609 lxi d,sppos ; Print the packet call prtstr lxi d,packet+1 call prtstr ENDIF ;debug IF (robin OR rainbo OR gener OR dmII) ; Must reset here in case of IBM mode or debug lda prtiob ; Set up for output to go to the comm port sta iobyte ; Switch I/O byte directly ENDIF ; (robin OR rainbo OR gener OR dmII) 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. mov e,a ; Put the char in right AC. call outchr ; Output the character. inx h ; Increment the char pointer. jmp outlup IF NOT (robin OR rainbo OR gener OR dmII) outlud: jmp rskp ; Just return ENDIF ; NOT (robin OR rainbo OR gener OR dmII) IF (robin OR rainbo OR gener OR dmII) outlud: lda coniob ; Back to console sta iobyte ; Store directly jmp rskp ; And return ENDIF ; (robin OR rainbo OR gener OR dmII) ; Set the parity for a character in A. 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 space 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 space: ani 7FH ; Turn off the parity bit. jmp parret parret: pop b pop h ; Restore HL. ret ;************************System Dependent**************************** ; Put a char in E to the port. IF osi OR apple outchr: push h outch2: lxi h,mnprts ; Get the port status into A. mov a,m ani output ; Loop till ready. jz outch2 mov a,e call setpar lxi h,mnport ; Write the character. mov m,a pop h ret ENDIF ; osi OR apple IF osbrn1 outchr: call osldst ; Read the status port ani output ; Loop till ready. jz outchr mov a,e call setpar ; What about Bit 7? jmp osstda ; Write to the data port ENDIF ; osbrn1 IF brain OR vector OR heath OR z100 OR trs80 OR telcon OR kpII OR mdI ;UCB3610 outchr: in mnprts ; Get the output ready flag. ani output ; Is it set? jz outchr ; If so, loop until it isn't. mov a,e call setpar out mnport ; Output it. ret ENDIF ;brain OR vector OR heath OR z100 OR trs80 OR telcon OR kpII OR mdI ;UCB3610 IF gener OR rainbo OR robin OR dmII ; ;****Note that we enter from outpkt with the I/O byte already set up for ; output to go to the comm port outchr: push h push b mov a,e call setpar mov e,a ; Put the char in E lda prtfun ; Get the output function mov c,a ; Into C call bdos ; And output the character pop b pop h ret ENDIF ;gener OR robin OR rainbo OR dmII IF cpm3 outchr: push h push b mov a,e call setpar mov e,a ; Put the char in E. mvi c,auxout ; Output to the aux output device call bdos pop b pop h ret ENDIF ;cpm3 ;************************System Dependent**************************** ; ; Get a char from the port and return in A. IF osi OR apple inchr: lda mnprts ; Get port status into A. ENDIF ; osi OR apple IF osbrn1 inchr: call osldst ENDIF ; osbrn1 IF osi OR apple OR osbrn1 ani input ; See if the input ready bit is on. jnz inchr2 ; If so go read the input. mvi c,consta ; Is a char on the console? call bdos ora a jz inchr ; If not go look for another char. mvi c,conin ; Get the char. call bdos cpi cr ; Is it a carriage return? jnz inchr4 ; If not go look for another char. ret ; Here if not a cr, check other possibilities inchr4: cpi ('Z'-100O) ; Control-Z? jz inchr5 ; Yes, go flag it cpi 'A'-64 ; Abort? ;UCB3615 jz abortf ; Yes, go do it now ;UCB3615 cpi ('X'-100O) ; Control-X? jnz inchr ; No, try for another character inchr5: adi 100O ; Convert to printing range sta czseen ; Flag we saw a control-Z pop b ; Restore B pop h ; And H ret ; And return ENDIF ; osi OR apple OR osbrn1 IF osi OR apple inchr2: lxi h,mnport ; If so, get the char. mov b,m ENDIF ; osi OR apple IF osbrn1 inchr2: CALL OSLDDA ; Read the data port mov b,a ENDIF ; osbrn1 IF osi OR apple OR osbrn1 lda parity ; Is the parity none? cpi parnon mov a,b jz rskp ; If so just return. ani 7FH ; Turn off the parity bit. jmp rskp ENDIF ; osi OR apple OR osbrn1 IF brain OR vector OR heath OR z100 OR trs80 OR telcon OR kpII OR mdI ;UCB3610 inchr: lxi h,0000h ; Reset fuzzy timer ;UCB3614 shld inchr6+1 ; ;UCB3614 inchr0: in mnprts ; Get the port status into A ;UCB3614 ani input ; See if the input ready bit is on. jnz inchr2 ; If so go read the input. mvi c,consta ; Is a char on the console? call bdos ora a jz inchr6 ; If not go look for another char. ;UCB3614 mvi c,conin ; Get the char. call bdos cpi cr ; Is it a carriage return? rz ; If so, return. ; Here if not a cr, check other possibilities inchr4: cpi ('Z'-100O) ; Control-Z? jz inchr5 ; Yes, go flag it cpi 'A'-64 ; Abort? ;UCB3615 jz abortf ; Yes, go do it now ;UCB3615 cpi ('X'-100O) ; Control-X? jnz inchr6 ; No, try for another character ;UCB3614 inchr5: adi 100O ; Convert to printing range sta czseen ; Flag we saw a control-Z ret ; And return inchr6: lxi h,0000h ; Increment fuzzy time-out ;UCB3614 inx h ; ;UCB3614 shld inchr6+1 ; (65,536 * loop time) ;UCB3614 mov a,h ; (Retry if not timeout) ;UCB3614 ora l ; ;UCB3614 jnz inchr0 ; ;UCB3614 call updrtr ; Count as retry ;UCB3614 ret ; and return to do the retry ;UCB3614 inchr2: in mnport ; If so, get the char. mov b,a lda parity ; Is the parity none? cpi parnon mov a,b jz rskp ; If so just return. ani 7FH ; Turn off the parity bit. jmp rskp ENDIF ;brain OR vector OR heath OR z100 or trs80 OR telcon OR kpII OR mdI ;UCB3610 IF gener OR rainbo OR robin OR dmII inchr: push h push b call bconst ; Check if anything at console first ora a ; . . . jnz inchr6 ; Yes, go see what it is inchr2: lda prtiob ; Get I/O byte for comm port sta iobyte ; Store I/O byte directly call bconst ;see if char at COMM-Port ora a ; jnz inchr3 ;we have one lda coniob ; Get I/O byte for console sta iobyte ; Store I/O byte directly call bconst ;see if char from keyboard ora a jz inchr2 ;nothing, check COMM-Port inchr6: call bconin ;get Keyboard-Input cpi cr ;Carriage return? jnz inchr4 ;take only Carriage returns pop b pop h ret ; Here if not a cr, check other possibilities inchr4: cpi ('Z'-100O) ; Control-Z? jz inchr5 ; Yes, go flag it cpi 'A'-64 ; Abort? ;UCB3615 jz abortf ; Yes, go do it now ;UCB3615 cpi ('X'-100O) ; Control-X? jnz inchr2 ; No, try for another character inchr5: adi 100O ; Convert to printing range sta czseen ; Flag we saw a control-Z pop b ; Restore B pop h ; And H ret ; And return inchr3: call bconin ; we got a char at COMM-Port mov b,a lda parity ;is the parity none? cpi parnon mov a,b push a lda coniob ; Want to talk to console again sta iobyte ; Store I/O byte directly pop a pop b pop h jz rskp ;return, we have COMM-Character ani 7FH ;strip Parity bit jmp rskp ;and return, we have COMM-Character ENDIF ;gener OR rainbo OR robin OR dmII IF cpm3 inchr: push h push b inchr2: mvi c,auxist ;get auxin status call bdos ora a  ; jnz inchr3 ;we have one mvi c,consta ;see if char from keyboard call bdos ora a jz inchr2 ;nothing, check auxin mvi c,conin call bdos ;get Keyboard-Input cpi cr ;Carriage return? jnz inchr4 ;take only Carriage returns pop b pop h ret ; Here if not a cr, check other possibilities inchr4: cpi ('Z'-100O) ; Control-Z? jz inchr5 ; Yes, go flag it cpi 'A'-64 ; Abort? ;UCB3615 jz abortf ; Yes, go do it now ;UCB3615 cpi ('X'-100O) ; Control-X? jnz inchr2 ; No, try for another character ret ; And return inchr5: adi 100O ; Convert to printing range sta czseen ; Flag we saw a control-Z pop b ; Restore B pop h ; And H ret ; And return inchr3: mvi c,auxin call bdos ; we got a char at COMM-Port mov b,a lda parity ;is the parity none? cpi parnon mov a,b pop b pop h jz rskp ;return, we have COMM-Character ani 7FH ;strip Parity bit jmp rskp ;and return, we have COMM-Character ENDIF ;cpm3 ; 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: +1 failure (if the checksum is wrong or the packet trashed) ; +2 success with A - message type ; ARGBLK - message number ; ARGBLK+1 - length of data rpackn: db cr,lf,lf,lf,'$' ; Position for noise display (screrr+3) ;UCB3615 rpack: ;UCB3615 IF NOT (crt OR gener OR cpm3) ;UCB3615 lxi d,screrr ; Position for noise/message display ;UCB3615 call prtstr ; ;UCB3615 lxi d,rpackn ; ;UCB3615 call prtstr ; ;UCB3615 ENDIF ;NOT (crt OR gener OR cpm3) ;UCB3615 call inpkt ; Read up to a carriage return. ;UCB3615 jmp r ; Return bad. rpack0: call getchr ; Get a character. jmp rpack ; Hit a CR; null line; just start over. cpi soh ; Is the char the start of header char? jnz rpack0 ; No, go until it is. rpack1: call getchr ; Get a character. jmp r ; Hit the carriage return, return bad. cpi soh ; Is the char the start of header char? 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 the carriage return, return bad. cpi soh ; Is the char the start of header char? 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 the carriage return, return bad. cpi soh ; Is the char the start of header char? 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 the carriage return, return bad. cpi soh ; Is the char the start of header char? 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 the carriage return, return bad. cpi soh ; Is the char the start of header char? 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. ; rrc ; rrc ; rrc ; rrc ; rrc ; rrc ; 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 the carriage return, return bad. cpi soh ; Is the char the start of header char? 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 the carriage return, return bad. cpi soh ; Is the char the start of header char? 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: lxi h,recpkt ; Point to the beginning of the packet. shld pktptr inpkt1: call inchr ; Get first character. ;UCB3603 jmp r ; Return failure. ;UCB3603 cpi soh ; is it the beginning of a packet? ;UCB3603 jz inpkt3 ; if so, put it in the packet. ;UCB3615 call inpkn ; else, display noise or message ;UCB3615 jmp inpkt1 ; And continue. ;UCB3615 inpkt2: call inchr ; Get a character. jmp r ; Return failure. cpi soh ; is it a new begining of packet? ;UCB3603 jnz inpkt3 ; If not continue ;UCB3603 inpkt6: lxi h,recpkt ; else throw away waht you've got so far;UCB3616 shld pktptr ; ;UCB3603 inpkt3: ; ;UCB3603 lhld pktptr mov m,a ; Put the char in the packet. inx h shld pktptr lxi d,-recpkx-1 ; Start over if packet buffer overflow ;UCB3612 dad d ; ;UCB3612 jc inpkt ; ;UCB3612 mov b,a lda reol ; Get the EOL char. cmp b jnz inpkt2 ; If not loop for another. lhld pktptr ; Reload packet pointer ;UCB3612 mvi m,cr ; Set a carriage-return to stop rpack: ;UCB3612 IF ucbibm ;UCB3616 lda ibmflg ; Wait for xon if IBM ;UCB3616 ora a ; ;UCB3616 jz inpkt5 ; ;UCB3616 inpkt4: call inchr ; Get a character ;UCB3616 jmp inpkt5 ; (OK if error, cr already received) ;UCB3616 cpi xon ; Continue if xon ;UCB3616 jz inpkt5 ; ;UCB3616 cpi soh ; But if soh, start over ;UCB3616 jz inpkt6 ; ;UCB3616 call inpkn ; else, display noise or message ;UCB3616 jmp inpkt4 ; and continue. ;UCB3616 inpkt5: lhld pktptr ; Reload packet pointer ;UCB3616 ENDIF ;ucbibm ;UCB3616 IF debug mvi a,'$' ; Get a dollar sign. inx h ; Point to next char. ;UCB3612 mov m,a ; Put in the packet. lxi d,rppos ; Print the packet call prtstr lxi d,recpkt+1 call prtstr ENDIF ;debug lxi h,recpkt shld pktptr ; Save the packet pointer. jmp rskp ; If so we are done. inpkn: ; Display a noise or message character ;UCB3615 ani 7Fh ; trim for noise display. ;UCB3615 cpi ' ' ; If not a control character, display. ;UCB3615 jp inpkn1 ; ;UCB3615 cpi cr ; If carriage-return, display it. ;UCB3615 jz inpkn1 ; ;UCB3615 cpi lf ; If line-feed, display it. ;UCB3615 jz inpkn1 ; ;UCB3615 mvi a,' ' ; Else, display a blank. ;UCB3615 inpkn1: mov e,a ; Display a noise character. ;UCB3615 mvi c,conout ; ;UCB3615 jmp bdos ; return through bdos ;UCB3615 getchr: lhld pktptr ; Get the packet pointer. mov a,m ; Get the char. inx h shld pktptr cpi cr ; Is it the carriage return? jnz rskp ; If not return retskp. ret ; If so return failure. ;CRCCLC - Routine to calculate a CRC-CCITT for a string. ; ; This routine will calculate a CRC using the CCITT polynomial for ;a string. ; ; Usage: ; HL/ Address of string ; A/ Length of string ; CALL CRCCLC ; ; 16-bit CRC value is returned in DE. ; ; Registers BC and HL are preserved. ; 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. ; Call error prints the error packet on line 6 or so. ; Call error1 print CRLF followed by the error packet. ; Call error2 just prints the error packet. ; Call error3 positions cursor and prints error message specified in DE. error: call error9 ; Position the cursor. mvi a,'A' ; Set the state to abort. sta state jmp error2 error1: lxi d,crlf ; Print a CRLF. 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 a,'$' ; Put a dollar sign at the end. mov m,a lxi d,data ; Print error message call prtstr ret error3: push d ; Save the pointer to the message. call error9 ; Position the cursor. lxi d,clrlin ; Clear the line call prtstr pop d ; Get the pointer back. call prtstr ; Print error message ret error9: lxi d,screrr ; Position cursor call prtstr ret finmes: push d ; Save message. lxi d,scrst ; Position the cursor call prtstr pop d ; Print the termination message call prtstr lxi d,scrend ; Position cursor for prompt call prtstr ret ; This is the FINISH command. It tells the remote KERSRV to exit. inffin: db 'FINISH$' ; Function name for display. ;UCB3615 finish: mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. xra a sta numtry ; Inititialize count. mvi a,'1' ; Reset block check type to single character sta curchk ; . . . lxi d,inffin ; Say what we are doing. ;UCB3615 call init ; and start packet display. ;UCB3615 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. inflog: db 'LOGOUT$' ; Function name for display. ;UCB3615 logout: mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. call logo ; Send the logout packet. jmp kermit ; Go get another command jmp kermit ; whether we succeed or not. logo: xra a sta numtry ; Inititialize count. mvi a,'1' ; Reset block check type to single character sta curchk ; . . . lxi d,inflog ; Say what we are doing. ;UCB3615 call init ; and start packet display. ;UCB3615 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. ; This is the BYE command. It tells the remote KERSRV to logout and exits. bye: mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. call logo ; Tell the main frame to logout. jmp kermit ; If it fails, don't exit. IF apple xra a ; Hangup our end too! sta mnmodm ENDIF ; apple jmp exit1 ; Exit Kermit. ; This is the 'exit' command. It leaves KERMIT and returns to CP/M. exit: mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. exit1: lhld oldsp ; Get back the system stack sphl ; and restore it. ret ; Then return to system. ; This is the log command. It logs a session to a file. log: mvi a,cmofi ; Parse an input file spec. lxi d,fcb call comnd jmp kermt3 mvi a,cmcfm ; Parse a confirm. call comnd jmp kermt3 lxi h,logflg mvi m,0FFH ; Set the log flag. lxi h,buff shld bufpnt 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. mvi c,makef ; Now create it. lxi d,fcb call bdos cpi 0FFH ; Is the disk full? jnz kermit ;[UTK3] lxi d,erms17 ; If so tell the user call prtstr jmp kermit ; This is the 'help' command. It gives a list of the commands. help: mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. help2: lxi d,tophlp ; The address of the help message. call prtstr jmp kermit ; This is the CONNECT command. telnet: mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. IF apple call ckdial ; See if dialing is required. jmp kermit ; Go to command loop if aborted. ENDIF ; apple lxi d,infms7 ; Output start of message call prtstr call escpr ; Print the escape char. lxi d,infms8 ; Output the rest of the message call prtstr IF robin ; For Robin only, ; give hint about how to type a ^S lxi d,inms11 ; during terminal emulation. call prtstr ENDIF ; robin IF apple call ckdial ; See if dialing is required. jmp kermit ; Go to command loop if aborted. ENDIF ; apple chrlup: call prtchr ; See if char at port (type to cons). call conchr ; See if char at cons (type to port). jmp kermit ; Go to command loop. jmp chrlup ; Go do it again. ;************************System Dependent**************************** IF gener OR rainbo OR robin OR dmII prtchr: lda prtiob ; do it direct - its faster sta iobyte prtchx: call bconst ; Is Char at COMM-Port? ora a ;something there? jnz prtret ;Something there, get char prtchy: lda coniob ; do it direct - its faster sta iobyte ret prtret: call bconin ; Read COMM-PORT ; and fall into "normal " code ENDIF ;gener or rainbo OR robin OR dmII IF cpm3 prtchr: mvi c,auxist call bdos ;is char at auxin? ora a ;something there? rz ;no mvi c,auxin call bdos ;read char from auxin ; and fall into "normal" code ENDIF ;cpm3 IF osi OR apple prtchr: lda mnprts ; Get the port status into A. ani input ; See if the input ready bit is on. rz ; If not then return. prtch2: lda mnport ; If so, get the char. ENDIF ; osi OR apple IF osbrn1 prtchr: CALL OSLDST ; Read the status port ani input rz prtch2: CALL OSLDDA ; read the data port ENDIF IF brain OR vector OR heath OR z100 OR trs80 OR telcon OR kpII OR mdI ;UCB3610 prtchr: in mnprts ; Get the port status into A. ani input ; See if the input ready bit is on. rz ; If not then return. prtch2: in mnport ; If so, get the char. ENDIF ;brain OR vector OR heath OR z100 OR trs80 OR telcon OR kpII OR mdI ;UCB3610 ani 7FH ; Make seven bit. mov e,a ; Set the char aside. IF kpII ;UCB3604 lda ibmflg ; on the Kaypro II the following chars ;UCB3604 ora a ; are displayed as greek symbols ... ;UCB3604 jz prtch0 ; ;UCB3604 mov a,e ; Get the char for testing. ;UCB3604 cpi 0 ; if the char is a null ;UCB3604 jz prtchr ; ignore it ;UCB3604 cpi xon ; likewise for xons ;UCB3604 jz prtchr ; ;UCB3604 cpi xoff ; and xoffs ;UCB3604 jz prtchr ; ;UCB3604 cpi del ; and deletes ;UCB3604 jz prtchr ; ;UCB3604 prtch0: ; ;UCB3604 ENDIF ;kpII ;UCB3604 IF trs80pt ;UCB3608 cpi xon ; For P+T cp/m, xon is a graphic ;UCB3608 jz prtchr ; so ignore it. ;UCB3608 ENDIF ;trs80pt ;UCB3608 IF NOT (robin OR rainbo OR gener OR dmII OR osi OR cpm3 OR crt) ;UCB3610 lda vtflg ; Get the VT52 emulation flag. ora a ; Is the flag set? jz prtch1 ; If not, don't do this stuff. ENDIF ;NOT (robin OR rainbo OR gener OR dmII OR osi OR cpm3 OR crt) ;UCB3610 IF vector lda vtvflg ; Get the vector cursor control flag. ora a jnz vtvect ; If its not zero go process the char. ENDIF ;vector IF NOT (robin OR rainbo OR gener OR dmII OR osi OR cpm3 OR crt) ;UCB3610 lda escflg ; Get the escape flag. ora a ; Is the flag set? jnz vt52 ; If so go translate the sequence. mov a,e ; Get the char for testing. cpi del ; Is the char a delete. rz ; If so then forget this foolishness. cpi esc ; Is the char an escape? jnz prtch1 ; If not skip on. mvi a,1 ; Get a one. sta escflg ; Set the escape flag. jmp prtchr ; Get another char... ENDIF ; NOT (robin OR rainbo OR gener OR dmII OR osi OR cpm3 OR crt) ;UCB3610 prtch1: lda logflg ; Get the log flag. ora a cnz logit ; Log the char if it is set. IF NOT (robin OR rainbo OR gener OR dmII) mvi c,dconio ; Console output bdos call. call bdos ; Output the char to the console. jmp prtchr ; Go see if there is another character. ENDIF ;NOT (robin OR rainbo OR gener OR dmII) IF (robin OR rainbo OR gener OR dmII) lda coniob ; Need to talk to console again sta iobyte ; Store in I/O byte mov c,e ; Character call bcnout ; to Console jmp prtchy ; and check Console-Input ENDIF ; (robin OR rainbo OR gener OR dmII) conchr: IF NOT (robin OR rainbo OR gener OR dmII) mvi c,dconio ; Direct console I/O BDOS call. mvi e,0FFH ; Input. call BDOS ENDIF ; NOT (robin OR rainbo OR gener OR dmII) IF robin OR rainbo OR gener OR dmII call bconst ; Get the status ora a ; Anything there? jz rskp ; No, forget it call bconin ; Yes, get the character ENDIF ; robin OR rainbo OR gener OR dmII ani 07FH ; Keep only 7 bits jz rskp ; Null means nothing there. [UTK014] mov e,a ; Move the char for comparison. lda escchr ; Get the escape char. cmp e ; Is it an escape char? jz intchr ; If so go process it. mov a,e ; Get the char. call setpar ; Set parity (if any). mov e,a ; Restore it. push d ; Save the character call prtout ; Output the char to the port. pop d ; Restore the character 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. IF NOT (robin OR rainbo OR gener OR dmII) mov e,a ; Return it. mvi c,dconio ; Direct console output. call bdos ; Echo the char. ENDIF ; NOT (robin OR rainbo OR gener OR dmII) IF (robin OR rainbo OR gener OR dmII) mov c,a ; Get the character call bcnout ; And write it directly ENDIF jmp rskp intchr: mvi c,dconio ; Direct console I/O. mvi e,0FFH ; Input. call bdos ; Get a char. ora a ; Is the char a null? jz intchr ; If so, go 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 lda logflg ; Get the log flag. ora a ; Is it set? rz ; Return if it is zero. xra a sta logflg ; Turn off the log flag. lxi d,infms6 ; Tell user we are closing file. call prtstr lhld bufpnt mvi m,('Z'-100O) ; Put in a ^Z. mvi c,writef ; Write the last buffer. lxi d,fcb call bdos mvi c,closf ; Close the file. lxi d,fcb call bdos ret ; Here if not an 'S' intch0: IF apple cpi 'D' ;Disconnect Modem? jnz intc00 ;No. xra a ;Yes, hangup the modem sta mnmodm ret intc00: ENDIF ; apple cpi 'S' ; Is it status? jnz inch01 ; If not, proceed. call stat01 ; Print out the status stuff. jmp rskp inch01: mov a,b ; Get the char. cpi '?' ; Is it a help request? jnz intch1 ; If not, go to the next check. lxi d,inthlp ; If so, get the address of the help message. call prtstr jmp intchr ; Get another char. intch1: mov a,b ; Get the character. ani 137O ; Convert to upper case if necessary. cpi 'B' ; Send a BREAK?  jnz intch2 ; No, try next thing. IF robin jmp sendbr ; Yes, go send a BREAK (only for VT180). ENDIF ; robin IF not robin lxi d,inms12 ; (Not implemented) Only Robin can send BREAK call prtstr jmp rskp ENDIF ; not robin intch2: mov a, b ; '0' to send a null. cpi '0' ; Is it? jnz intch3 ; No. mvi e,0 ; Yes, send an ASCII zero. call prtout jmp rskp intch3: mov e,a ; Put the char into another reg. lda escchr ; Get the escape char. cmp e ; Is it the escape char? jnz intchz ; If not, go send a beep to the user. mov a,e ; Get the char. call setpar mov e,a ; Restore it. call prtout ; Output it. jmp rskp ; Return, we are done here. intchz: mvi e,'G'-100O ; Otherwise send a beep. mvi c,dconio call bdos jmp rskp 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 jmp rskp ENDIF ; robin IF apple ; 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 ;apple IF NOT (robin OR rainbo OR gener OR dmII OR osi OR cpm3 OR crt) ;UCB3610 vt52: mvi a,00H ; Reset the ol' escape flag. sta escflg mov a,e ; Get the char. ENDIF ;NOT (robin OR rainbo OR gener OR dmII OR osi OR cpm3 OR crt) ;UCB3610 IF vector cpi 'Y' ; Is it cursor position? jnz vt52a ; If so handle it special. mvi a,2 sta vtvflg ; Save the flag saying so. mvi c,conout ; Output the escape. mvi e,esc call bdos ret vt52a: ENDIF ;vector ; those machines which use other than vt52, et.al.'s 'Y' [UTK016] ; as a cursor lead in need to have that translated to ; their native cursor lead-in sequences, e.g.: '=', etc. ; or they CANNOT do ANY cursor addressing, EVER, other than that ; hardwired into kermit itself. we do that here. [UTK016] ; (fixed second time, very sigh) IF osbrn1 or apple OR trs80lb OR kpii OR tvi925 OR adm3a ;[UTK016];UCB3610 cpi 'Y' ; if cursor lead-in handle it. [UTK016] jnz vt52a ; if not, go on. [UTK016] lxi d,CURLDN ; point to our cursor lead-in. [UTK016] call prtstr ; have cpm print it. [UTK016] ret ; and back for another one. [UTK016] vt52a: ;[UTK016] ENDIF ;osbrn1 or apple OR trs80lb OR kpii OR tvi925 OR adm3a ;[UTK016];UCB3610 IF trs80pt ;UCB3608 ;P+T CP/M uses the same cursor positioning as the H19 or VT52. ;UCB3608 ENDIF ;trs80pt ;UCB3608 IF NOT (robin OR rainbo OR gener OR dmII OR osi OR cpm3 OR crt) ;UCB3610 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.) lxi h,ttab ; 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 prtstr ; and syscall. ret ; Return. ENDIF ;NOT (robin OR rainbo OR gener OR dmII OR osi OR cpm3 OR crt) ;UCB3610 IF vector vtvect: ; Treat cursor control special. lda vtvflg ; Get the flag. cpi 02H ; Is this the first char? jnz vtvct2 ; If not go write it. dcr a sta vtvflg ; Save the updated flag. mov a,e ; Get the char. sbi ' '-1 ; Subtract a space to get a number. sta vctccc ; Save the vector cursor control char. ret vtvct2: dcr a sta vtvflg ; Save the updated flag. mov a,e ; Get the char. sbi ' '-1 ; Subtract a space. mov e,a ; Move to output register. mvi c,dconio ; The function call bdos ; and the syscall. lda vctccc ; Get the first char. mov e,a mvi c,dconio ; Output it. call bdos ret ; Return home. ENDIF ;vector IF NOT (robin OR rainbo OR gener OR dmII OR crt) ;UCB3610 vtig: ; Ignore escape sequence. push psw ; Push the char to be output. mvi e,esc ; Load an escape. mvi c,conout ; The function code call bdos ; and the syscal. pop psw ; Restore the character mov e,a ; and move to output register. mvi c,conout ; The function call bdos ; and the syscall. ret ; Return home. ENDIF ;NOT (robin OR rainbo OR gener OR dmII OR crt) ;UCB3610 logit: lhld bufpnt mov m,e ; Store the char. inx h shld bufpnt mov a,l ora a ; Buffer full? rnz push d mvi e,xoff ;[UTK3] ^Q to stop the call prtout ;[UTK3] host until we mvi c,writef ; write out the buffer. lxi d,fcb call bdos ora a ; Successful. jz logit2 lxi d,erms11 call prtstr logit2: mvi e,xon ;[UTK3] ^Q to restart call prtout ;[UTK3] the host. lxi h,buff shld bufpnt ; Reset the buffer pointer. pop d ret ; This is the SET command. setcom: lxi d,settab ; Parse a keyword from the set table. lxi h,sethlp mvi a,cmkey call comnd jmp kermt2 lxi h,setjtb ; Get the address of the jump table. mov c,a mvi b,0 dad b pchl setjtb: jmp escape ; 00H SET ESC jmp ibmset ; 03H SET IBM jmp locall ; 06H SET LOCAL ;UCB3605 jmp kermt3 ; 09H SET RECEIVE (not currently used) jmp setsnd ; 0CH SET SEND (not currently used) jmp filwar ; 0FH SET WARNING jmp setcpm ; 12H SET FILE-MODE jmp parset ; 15H SET PARITY jmp blkset ; 18H SET BLOCK-CHECK-TYPE jmp vt52em ; 1BH SET VT52 jmp prtset ; 1EH SET PORT jmp baud ; 21H SET BAUD jmp setdisk ; 24H SET DEFAULT-DISK ; 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 mvi a,cmkey ; Parse a keyword call comnd ; Go get it jmp kermt2 ; Couldn't, complain sta temp1 ; Save the parsed item  mvi a,cmcfm ; Want to end the command call comnd ; Go do it jmp kermt2 ; Give up lda temp1 ; Get the value back sta chktyp ; Save desired checksum type jmp kermit ; Go get another command ; SET DEFAULT DISK command setdisk: lxi d,fcb mvi a,cmifin ; get "file-spec" silently call comnd jmp setdi1 setdi1: lda fcb cpi 0 ; In case he didn't type .. 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. setsnd: lxi d,stsntb ; Parse a keyword from the set send table. lxi h,stshlp mvi a,cmkey call comnd jmp kermt2 lxi h,stsjtb ; Get the address of the jump table. mov c,a mvi b,0 dad b pchl stsjtb: jmp stpdch jmp stpad stpad: mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. jmp kermit stpdch: mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. jmp kermit IF brain ; This is the BAUD change SET subcommand. baud: mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. lxi d,baudtb ; Get the address of the baud rate table. call prtstr mvi c,conin ; Console input (with echo). call bdos ani 137O ; Capitalize the char. sui 'A' ; Normalize to zero. jm bderr ; Go tell the user he flubbed. cpi 10H ; Is the number greater than 15? jp bderr ; Go tell the user he flubbed. mov b,a ; Save the number. lda baudrt ; Get the present baud rates. mov d,a ; Set it aside. mov a,b ; Get the new baud rate. rlc ; Shift left 4 places. rlc rlc rlc mov b,a ; Set it aside. mov a,d ; Get the old baud rates. ani 0FH ; Turn off the left. baud2: add b ; Combine the two rates. sta baudrt ; Store the new baud rates. out baudst ; Set the baud rates. jmp kermit bderr: lxi d,ermes2 ; Get the error message. call prtstr jmp kermit ENDIF ;brain IF osbrn1 ; The same command, this time for the Osborne 1 baud: mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. lxi d,baudtb ; Get the address of the baud rate table. ; Output to the user. call prtstr mvi c,conin ; Console input (with echo). call bdos ani 137O ; Capitalize the char. cpi 'A' ; A means 300 mvi c,0 ; and 0 means 300 in the baud byte jz baud1 cpi 'B' ; B means 1200 jnz bderr ; and anything else is wrong inr c ; non-zero means 1200 baud1: mov a,c sta osbaud ; Remember it. call osbset ; Osborne setup routine jmp kermit bderr: lxi d,ermes2 ; Get the error message. ; Print it. call prtstr jmp kermit osbset: mvi a,osbin1 ; Reset the ACIA call osstst ; Write the control port osbs1: inr c ; Waiting loop jnz osbs1 lda osbaud ; Go for 300 or 1200? ora a mvi a,osbi03 ; Guess 300 jz osbs2 mvi a,osbi12 ; wrong: 1200 osbs2: sta baudrt ; (seems this is what one does on an Osborne) jmp osstst ; Write the control reg. ENDIF ; osbrn1 ;This is the set speed command for kaypro ii if kpii baud: lxi d,spdtab lxi h,spdhlp mvi a,cmkey call comnd jmp kermt3 sta temp1 ; Save the parsed value. mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. lda temp1 ; Get the parsed value. sta speed ; Set the speed. out 00h ; output to port 0. jmp kermit endif ;kaypro ii IF NOT (brain OR osbrn1 OR kpii) baud: lxi d,inms12 ; Not implemented. call prtstr jmp kermit ENDIF ; not (brain OR osbrn1 OR kpii) ; This is the ESCAPE character SET subcommand. escape: mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. 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 LOCAL echo SET subcommand. locall: lxi d,ontab ;UCB3605 lxi h,onhlp mvi a,cmkey call comnd jmp kermt2 sta temp1 ; Save the parsed value. mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. lda temp1 ; Get the parsed value. sta ecoflg ; Set the local echo flag. jmp kermit IF NOT (robin OR rainbo OR gener OR dmII OR osi OR cpm3 OR crt) ;UCB3610 ; This is the VT52 emulation SET subcommand. vt52em: lxi d,ontab lxi h,onhlp mvi a,cmkey call comnd jmp kermt2 sta temp1 ; Save the parsed value. mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. lda temp1 ; Get the parsed value. sta vtflg ; Set the VT52 emulation flag. jmp kermit ENDIF ;NOT (robin OR rainbo OR gener OR dmII OR osi OR cpm3 OR crt) ;UCB3610 IF robin OR rainbo OR gener OR dmII OR osi OR cpm3 OR crt ;UCB3610 vt52em: lxi d, inms12 ; Say it's not implemented. call prtstr jmp kermit ENDIF ; robin OR rainbo OR gener OR dmII OR osi OR cpm3 OR crt ;UCB3610 ; This is the FILE-WARNING SET subcommand filwar: lxi d,ontab lxi h,onhlp mvi a,cmkey call comnd jmp kermt2 sta temp1 ; Save the parsed value. mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. lda temp1 ; Get the parsed value. sta flwflg ; Set the file-warning flag. jmp kermit ; This is the SET IBM command. ibmset: lxi d,ontab lxi h,onhlp mvi a,cmkey call comnd jmp kermt2 sta temp1 ; Save the parsed value. mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. lda temp1 ; Get the parsed value. sta ibmflg ; Set the IBM flag. ora a ; Is it turned on? jz ibmst1 ; If not, set parity to the default. mvi a,ibmpar ; Get the IBM parity. mvi b,ibmeco ; Set the IBM echo. ;UCB3613 jmp ibmst2 ibmst1: mvi a,defpar mvi b,0 ; Set local echo off. ibmst2: sta parity ; Save them. mov a,b sta ecoflg jmp kermit ; This is the SET PORT command. IF robin OR rainbo OR gener OR dmII prtset: lxi d,prttab ; Get the table address lxi h,prthlp ; And the address of the help text mvi a,cmkey ; Want a keyword call comnd ; Get the field of the command jmp kermt2 ; Not valid, give error sta temp1 ; Save the parsed value. mov a,d ; Get the function to use sta temp2 ; Save for later mvi a,cmcfm ; Make sure command is finished call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. lhld temp1 ; Get the table pointer 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 IF robin inx h ; Point at next entry mov a,m ; Get the hardware address for the port sta prtadr ; Store it ENDIF ; robin jmp kermit ENDIF ; robin OR rainbo OR gener OR dmII ; Table of port information for ROBIN ; 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. IF robin comptb: db batio,punout,comtst gppptb: db gppio,conout,gentst prnptb: db lptio,conout,prntst ENDIF ; robin IF rainbo OR gener OR dmII comptb: db batio,punout,0 ENDIF IF NOT (robin OR rainbo OR gener OR dmII) prtset: lxi d,inms12 ; (Not implemented) call prtstr jmp kermit ENDIF ; NOT (robin OR rainbo OR gener OR dmII) ; SET FILE-MODE command. setcpm: lxi d,typtab lxi h,typhlp mvi a,cmkey call comnd jmp kermt3 sta temp1 ; Save the parsed value. mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. lda temp1 ; Get the parsed value. sta cpmflg ; Set the CPM flag. jmp kermit parset: lxi d,partab lxi h,parhlp mvi a,cmkey call comnd jmp kermt3 sta temp1 ; Save the parsed value. mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. lda temp1 ; Get the parsed value. sta parity ; Set the CPM flag. jmp kermit ; This is the SHOW command. show: mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. ;* Reconcile this and status. call stat01 ; For now just cop out. jmp kermit ; This is the STATUS command. status: call stat0 jmp kermit stat0: mvi a,cmcfm call comnd ; Get a confirm. jmp kermt3 ; Didn't get a confirm. stat01: lxi d,locst ; Get the address of the local echo string. call prtstr lda ecoflg ; Get the local echo flag. ora a ; Is it on? jz stat02 ; If not say so. lxi d,onstr ; Say on. jmp stat03 stat02: lxi d,offstr ; Say off. stat03: call prtstr IF NOT (robin OR rainbo OR gener OR dmII OR cpm3 OR crt) ;UCB3610 lxi d,vtemst ; Get the address of the VT52 emulation string. call prtstr lda vtflg ; Get the VT52 emulation flag. ora a ; Is it on? jz stat1 ; If not say so. lxi d,onstr ; Say on. jmp stat11 stat1: lxi d,offstr ; Say off. stat11: call prtstr ENDIF ; NOT (robin OR rainbo OR gener OR dmII OR cpm3 OR crt) ;UCB3610 lxi d,cpmst ; Get the address of the CPM created file. call prtstr lda cpmflg ; Get the CPM flag. ora a ; Is it on? jz stat2 ; If not say so. cpi 1 ; ASCII? lxi d,ascstr ; jz stat21 ; Say ASCII lxi d,binstr ; Say binary jmp stat21 stat2: lxi d,defstr ; Say default. stat21: call prtstr lxi d,ibmst ; IBM string. call prtstr lda ibmflg ; IBM flag. ora a ; Is it on? jz stat3 ; If not say so. lxi d,onstr ; Say on. jmp stat31 stat3: lxi d,offstr ; Say off. stat31: call prtstr lxi d,filst ; File warning string. call prtstr lda flwflg ; File warning flag. ora a ; Is it on? jz stat4 ; If not say so. lxi d,onstr ; Say on. jmp stat41 stat4: lxi d,offstr ; Say off. stat41: call prtstr lxi d,parst ; Parity string. call prtstr lda parity ; Get the parity setting. lxi d,pnonst ; None by default. cpi parmrk ; Is it mark? jnz stat5 ; If not say so. lxi d,pmrkst ; Say mark. jmp stat55 stat5: cpi parspc ; Is it space? jnz stat51 ; If not say so. lxi d,pspcst ; Say space. jmp stat55 stat51: cpi parodd ; Is it odd? jnz stat52 ; If not say so. lxi d,poddst ; Say odd. jmp stat55 stat52: cpi parevn ; Is it even? jnz stat55 ; If not say so. lxi d,pevnst ; Say even. stat55: call prtstr ; Print out current BLOCK-CHECK-TYPE 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") call prtstr ; . . . ; Print the current escape character lxi d,escst ; Escape string. call prtstr call escpr ; Print the escape char. lxi d,crlf ; Get the address of a crlf. call prtstr IF osbrn1 lxi d,osbsms ; Print "Line Speed: " call prtstr lxi h,300 ; Assume 300 baud lda osbaud ora a jz stat61 dad h ; No, it's 1200 dad h stat61: call nout ; Print "300" or "1200" lxi d,osbmsg ; Print " baud",cr,lf  call prtstr ENDIF ; osbrn1 ret ; Display the directory for the requested drive [UTK008] ; ; Note: This is abstracted from Keith Peterson's DIRF.ASM ; directory print function. Thank's again Keith. ; ; dir: lxi d,fcb ; Where to put the data, if any. mvi a,cmifin call comnd ; Plse 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: lda fcb cpi 0 ; default? jnz dir4a lda curdsk ; get default dir4a: adi 'A'-1 ; Asciize it sta dnam14 ; Save it in message. lxi d,crlf ;[UTK009] call prtstr ;[UTK009] 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. ; call dir26 ; Get disk parameters dir5: call mfname ; get some names jnc dir6 ; got one jmp dir17 ; got none - do summary ; dir6: ;Check for console break 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 ; ;Print two spaces dir8: call dir9 ; ;Print one space dir9: mvi a,' ' ; ;Type char in A register 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: mvi a,CR ;CR. call dir10 mvi a,LF ;LF. call dir10 mvi m,npl ; Number of names per line. ret ; ; Error exit dir13: pop d ; Get msg. call prtstr ; ;Fall into EXIT ; ;Exit - All done, return via jmp (as for all main commands) dir16: lxi d,crlf ;[UTK009] call prtstr ;[UTK009] 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 ora a jz dir18 dcr a mov e,a mvi c,logdsk call bdos dir18: 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 jz dir23 ;Skip shifts if 1K blocks dir22: dad h ;Multiply blocks by 'K per Block' dcr a jnz dir22 dir23: 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 ; " 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: mvi c,cflsz ;get file-size lxi d,fcb call bdos lda fcbrno ;shift least sign. part mov l,a ani 7 jz dir250 adi 8 dir250: add l rrc rrc rrc ani 1fH ;remove crud mov l,a mvi d,0 lda fcbrno+1 ;shift most sign. part rrc jnc dir25a mvi e,20H dad d ani 7FH dir25a: rrc jnc dir25b mvi e,40H dad d ani 7FH dir25b: rrc jnc dir25c mvi e,80H dad d ani 7FH dir25c: mov h,a ; LDA bmask ;Get SECTORS/BLK-1 ; RRC ; RRC ;Convert to K/BLK ; RRC ; ANI 1FH ; CMA ;Use to finish rounding ; ANA L ; MOV L,A mov a,l cpi 10 jp dir25d call dir8 jmp dir25e dir25d: cpi 100 jp dir25e call dir9 dir25e: call dir9 ; a space 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 ; ERAse a CP/M file era: mvi a,cmifi ; Parse a file-spec lxi d,fcb ; into FCB call comnd jmp kermit ; bad parse 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 ; Print the escape char. escpr: lda escchr ; Get the escape char. cpi ' ' ; Is it a control char? jp escpr2 lxi d,inms10 ; Output Control-. call prtstr lda escchr ori 100O ; De-controlify. escpr2: mvi c,conout ; Output the char mov e,a call bdos ret ;************************System Dependent**************************** IF osi OR apple prtout: lxi h,mnport ; Output it. mov m,e ret ENDIF ;osi OR apple IF osbrn1 prtout: mov a,e jmp OSSTDA ENDIF ; osbrn1 IF brain OR heath OR z100 OR trs80 OR telcon OR kpII OR mdI ;UCB3610 prtout: in mnprts ; Get the output ready flag. ani output ; Is it set? jz prtout ; If so, loop until it isn't. mov a,e ; Get the char to output. prtou2: out mnport ; Output it. ret ENDIF ; brain OR heath OR z100 OR trs80 OR telcon OR kpII OR mdI ;UCB3610 IF vector prtout: mov a,e ; Get the char to output. out mnport ; Output it. ret ENDIF ;vector IF gener OR rainbo OR robin OR dmII prtout: push d ; Save the character lda prtiob ; Get the I/O byte sta iobyte ; Store I/O byte directly pop d ; Restore the character lda prtfun ; Get the output function mov c,a ; Into C call bdos ; And output the character lda coniob ; Reset to console sta iobyte ; Store I/O byte directly ret ENDIF ;gener OR rainbo OR robin OR dmII IF cpm3 prtout: mvi c,auxout ;Get Char in E auxout call bdos ret ENDIF ;cpm3 ; Utility routines ; Jumping to this location is like retskp. It assumes the instruction ; after the call is a jmp addr. 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. r: ret ; This routine prints the number in HL on the screen, in hex. ; (Thanks to Jeff Damens) (Not currently used, now we print in decimal) ; (but let's keep it around in case we need again for something) ; ;nout: xra a ; sta temp4 ; mov a,h ; push psw ; Save argument. ; ani 0F0H ; Only want high order nibble. ; rrc ; rrc ; rrc ; rrc ; call pdig ; Print the digit. ; pop psw ; Restore argument. ; ani 0FH ; Just the low order nibble. ; call pdig ; mov a,l ; push psw ; Save argument. ; ani 0F0H ; Only want high order nibble. ; rrc ; rrc ; rrc ; rrc ; call pdig ; Print the digit. ; mvi a,0FFH ; sta temp4 ; Make sure at least one zero is printed. ; pop psw ; Restore argument. ; ani 0FH ; Just the low order nibble. ; ; ; print the digit in register a ; ;pdig: push psw ; Save the digit. ; ora a ; jnz pdig2 ; lda temp4 ; Is the print zero flag set? ; ora a ; jnz pdig2 ; pop psw ; ret ;pdig2: mvi a,0FFH ; Set the print zero flag. ; sta temp4 ; pop psw ; Restore the digit. ; cpi 10 ; Do we use digits or a-f? ; jm usedig ; Digit. ; adi 'A'-10 ; Compute digit ; jmp havdig ; and proceed. ;usedig:adi '0' ; Convert to digit ;havdig:mov e,a ; mvi c,conout ; push h ; call bdos ; pop h ; Save h & l from bdos ; ret ; and return. ; This routine prints the number in HL on the screen in decimal. ; Saves all ACs. nout: push psw ; Save our ACs. push b push d push h lxi b,-10 ; Get some useful constants. lxi d,-1 nout2: dad b ; Subtract as many 10s as possible. inx d ; Count them. jc nout2 ; If some left keep going. lxi b,10 ; Restore the last 10 we took away. dad b xchg ; Swap the remainder and the quotient. mov a,h ; Get the number of 10s found. ora l ;* I think this checks if h equals zero. If ;* so, this should just be a CPI 0 for clarity. cnz nout ; If non zero, recurse. mov a,e ; Get the remainder. adi '0' ; Make the number printable. mov e,a ; Output the digit. mvi c,conout call bdos pop h ; Restore the ACs. pop d pop b pop psw ret ; This set of routines provides a user oriented way of parsing ; commands. It is similar to that of the COMND JSYS in TOPS-20. ; This routine prints the prompt in DE and specifies the reparse ; address. 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 lxi d,cmcrlf call prtstr lhld cmprmp ; Print the prompt. xchg call prtstr ret ; This address is jumped to on reparse. 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. 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 lxi d,cmcrlf call prtstr lhld cmprmp ; Get the prompt. xchg call prtstr ;* 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) comnd: sta cmstat ; Save what we are presently parsing. call cminbf ; Get chars until an action or a erase char. 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. 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 cmtext: 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 cmtxt5 ; No, put in user space. 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 cmtxt3 ; If so put it in the text. cpi ff ; Is it a formfeed? cz cmblnk ; If so blank the screen. mov a,b ; Return the count. lhld cmptab ; Return updated pointer in HL. xchg jmp rskp ; Return success. cmtxt3: lxi h,cmaflg ; Point to the action flag. mvi m,0 ; Set it to zero. cmtxt5: 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. jmp cmtxt1 ; Get another char. ; This routine gets a confirm. 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 lxi d,cmcrlf ; Print a crlf. call prtstr lhld cmprmp ; Reprint the prompt. xchg call prtstr 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 cmblnk ; 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. 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. 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 terminater? 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 prtstr lxi d,cmcrlf ; Print a crlf. call prtstr lhld cmprmp ; Reprint the prompt. xchg call prtstr 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. 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. cmifil: 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? jm cmifi0 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 lxi h,cmaflg ; Blank the action flag. mvi m,0 lhld cmcptr ; Decrement the buffer pointer. dcx h shld cmcptr jmp cmifi8 ; Treat like any other character. cmif12: cpi esc ; An escape? jnz cmif13 xra a sta cmaflg ; Turn off the action flag. 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. jmp repars 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. 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 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 '0' jm cmifi9 cpi 'z'+1 jp cmifi9 cpi 'A' ; Don't capitalize non-alphabetics. jm cmifi8 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 ; what was the wish? cpi cmifin jz cmifi10 ; he don't want to know about errors lxi d,cmer02 call prtstr cmifi10: ret cmofil: jmp cmifil ; For now, the same as CMIFI. 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. call bdos 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? jnz cminb2 cmnb12: lxi d,clrlin ; Clear the line. call prtstr lhld cmprmp ; Print the prompt. xchg call prtstr 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 ; Or backspace? jz cminb3 cpi del ; Delete? jnz cminb4 lxi d,delstr ; Print the delete string. call prtstr 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. lxi d,clrspc ; Erase the character. call prtstr 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 cminb7 call cmblnk cminb5: 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 cminb7: cpi ' ' jz cminb1 ; Get another char. cpi tab jz cminb1 ; Get another char. jmp cminb1 ; Get another. cminb9: pop h pop d pop psw ret 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. ; This routine blanks the screen. cmblnk: lxi d,clrtop ; Print the string to blank the screen. call prtstr ret ; This routine replaces many, many calls to bdos prtstr: mvi c,prstr jmp bdos ; a CALL flwd by a RET becomes a JMP ; Pure storage. outln2: db cr,lf,'Number of packets:' db cr,lf,'Number of retries:' db cr,lf,'File name:' ;UCB3615 db cr,lf,lf,'$' ;UCB3615 outln1: db ' [CR retry, ^X skip file, ^Z quit, ^A abort]$' ;UCB3615 outln3: db cr,lf,'Noise or Messages Received:$' ;UCB3615 kerm: db 'Kermit-80 ' kerm1: db 'x:>$' ;'x' filled in at startup with DRIVE name delpr: db 'Delete it? $' crlf: db cr,lf,'$' ermes1: db cr,lf,'?Unrecognized command$' ermes2: db cr,lf,'?Illegal character$' 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,'$' 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$' infms2: db bell,'ABORTED$' 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 IF NOT trs80 db '$' ENDIF IF trs80 db '(Control-_ is the Down-Arrow key on the TRS-80 keyboard)',cr,lf,'$' ENDIF infms9: db cr,lf,'[Connection closed, back at micro]$' inms10: db 'Control-$' inms11: db ' (Type Left Arrow to send CTRL-S)',cr,lf,'$' inms12: db ' (Not implemented)',cr,lf,'$' inms13: db bell,'Interrupted$' inms14: db TAB,TAB,' Directory for drive ' ; [UTK008] dnam14: db 'x:',cr,lf,'$' ; filled in by dir routine.[UTK008] 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 baddrv: DB CR,LF,'++ Bad drive name$',CR,LF cfrmes: db ' Confirm with carriage return $' filhlp: db ' Input file spec (possibly wild) $' escmes: db cr,lf,'Type the new escape character: $' tophlp: db cr,lf,'BYE to host (LOGOUT) and exit to CP/M' db cr,lf,'CONNECT to host on selected port' db cr,lf,'ERA a CP/M file' db cr,lf,'EXIT to CP/M' db cr,lf,'FINISH running Kermit on the host' db cr,lf,'HELP by giving this message' db cr,lf,'DIR of current used Micro-disk' db cr,lf,'LOG the terminal session to a file' db cr,lf,'LOGOUT the host' db cr,lf,'RECEIVE file from host' 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$' sethlp: db cr,lf,'BAud (rate)' db cr,lf,'BLock-check-type (for error detection)' db cr,lf,'Default-disk (to receive data)' db cr,lf,'Escape (character during CONNECT)' db cr,lf,'File-mode (for outgoing files)' db cr,lf,'Ibm (parity and turn around handling)' db cr,lf,'Local-echo (half-duplex)' db cr,lf,'PArity (for communication line)' db cr,lf,'POrt (to communicate on)' ;* db cr,lf,'RECEIVE (parameter)' ; Not currently implemented ;* db cr,lf,'SEND (parameter)' ; Ditto db cr,lf,'Vt52-emulation' db cr,lf,'Warning (for filename conflicts)' db '$' stshlp: db cr,lf,'PAD-CHAR' db cr,lf,'PADDING$' blkhlp: db cr,lf,'1-CHARACTER-CHECKSUM' db cr,lf,'2-CHARACTER-CHECKSUM' db cr,lf,'3-CHARACTER-CRC-CCITT$' IF gener OR rainbo OR dmII prthlp: db cr,lf,'COMMUNICATIONS port$' ENDIF ; gener OR rainbo OR dmII IF robin prthlp: db cr,lf,'COMMUNICATIONS port' db cr,lf,'GENERAL purpose port' db cr,lf,'PRINTER port$' ENDIF ; robin parhlp: db cr,lf,'EVEN MARK NONE ODD SPACE$' onhlp: db cr,lf,'OFF ON$' yeshlp: db cr,lf,'NO YES$' inthlp: db cr,lf,'? This message' db cr,lf,'C Close the connection' IF apple db cr,lf,'D Close and disconnect the connection' ENDIF ;apple db cr,lf,'0 (zero) Transmit a NULL' IF robin db cr,lf,'B Transmit a BREAK' ENDIF ; robin db cr,lf,'S Status of the connection' db cr,lf,'Type the escape character again to send it to the host' db cr,lf,cr,lf,'Command>$' onstr: db ' on$' offstr: db ' off$' locst: db cr,lf,'Local echo$' defstr: db ' default$' ascstr: db ' ASCII$' binstr: db ' binary$' typhlp: db cr,lf,'ASCII BINARY DEFAULT$' IF NOT (robin OR gener OR rainbo OR dmII OR cpm3 OR crt) ;UCB3610 vtemst: db cr,lf,'VT52 emulation$' ENDIF ;NOT (robin OR gener OR rainbo OR dmII OR cpm3 OR crt) ;UCB3610 cpmst: db cr,lf,'File Mode$' ibmst: db cr,lf,'IBM flag$' filst: db cr,lf,'File warning$' escst: db cr,lf,'Escape char: $' parst: db cr,lf,'Parity: $' bckst: db cr,lf,'Block check type: $' bckst1: db '-character$' pnonst: db 'none$' pmrkst: db 'mark$' pspcst: db 'space$' poddst: db 'odd$' pevnst: db 'even$' IF osbrn1 osbsms: db 'Line Speed: $' osbmsg: db ' baud',cr,lf,'$' ENDIF ; osbrn1 IF brain baudtb: db ('A'-100O),esc,'~kType the letter corresponding with the baud rate desired.' ;UCB3609 db cr,lf,'(A) 50' db cr,lf,'(B) 75' db cr,lf,'(C) 110' db cr,lf,'(D) 134.5' db cr,lf,'(E) 150' db cr,lf,'(F) 300' db cr,lf,'(G) 600' db cr,lf,'(H) 1200' db cr,lf,'(I) 1800' db cr,lf,'(J) 2000' db cr,lf,'(K) 2400' db cr,lf,'(L) 3600' db cr,lf,'(M) 4800' db cr,lf,'(N) 7200' db cr,lf,'(O) 9600' db cr,lf,cr,lf,'Letter: $' ENDIF ;brain IF osbrn1 baudtb: db cr,lf,'Type a letter corresponding to the baud rate desired.' db cr,lf,'(A) 300' db cr,lf,'(B) 1200' db cr,lf,cr,lf,'Letter: $' ENDIF ; osbrn1 if kpii spdhlp: db cr,lf,' 50 75 110 134.5 150 300 600 1200' db cr,lf,' 1800 2000 2400 3600 4800 7200 9600 19200$' endif ;kaypro ii ;***************************System Dependent************************** IF brain outlin: db ('A'-100O),esc,'~k',cr,lf,tab,tab versio: db 'Kermit-80 V3.6 (UCB36.16) [Intertec SuperBrain]',cr,lf,'$' delstr: db 10O,' ',10O,10O,'$' ; Delete string. clrspc: db ' ',10O,'$' ; Clear space. clrlin: db cr,esc,'~K$' ; Clear line. clrtop: db ('A'-100O),esc,'~k$' ; Clear screen and go home. scrnp: db esc,'Y#4$' ; Place for number of packets. scrnrt: db esc,'Y#4',lf,'$' ; Place for number of retries. scrfln: db esc,'Y%,',esc,'~K$' ; Place for file name. screrr: db esc,'Y& $' ; Place for error messages. scrst: db esc,'Y#T$' ; Place for "Complete". scrend: db esc,'Y',27H,20H,'$' ; Place for prompt. [UTK015] 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 esc,'D$',0 ; No translation. te: db esc,'E$',0 tf: db esc,'F$',0 tg: db esc,'G$',0 th: db ('A'-100O),'$',0,0 ; Cursor home. ti: db ('K'-100O),'$',0,0 ; Reverse linefeed. tj: db esc,'~k$' ; Clear to end of screen. tk: db esc,'~K$' ; Clear to end of line. ENDIF ;brain IF debug AND brain ;UCB3609 rppos: db esc,'Y* RPack:',esc,'~K$' sppos: db esc,'Y( SPack:',esc,'~K$' ENDIF ;debug AND brain ;UCB3609 IF osbrn1 outlin: db 1AH,tab ; (Clear screen, home cursor) versio: db lf,lf,'Kermit-80 V3.6 (UCB36.16) [Osborne 1]',cr,lf,'$' delstr: db 10O,10O,'$' ; Delete string. clrspc: db ' ',10O,'$' ; Clear space. clrlin: db cr,esc,'T$' ; Clear line. clrtop: db 1AH,'$' ; Clear screen and go home. scrnp: db esc,'=',20H+03H,20H+15H,lf,'$' ; Place for number of packets. scrnrt: db esc,'=',20H+05H,20H+15H,'$' ; Place for number of retries. scrfln: db esc,'=',20H+06H,20H+0CH,'$' ; Place for file name. scrst: db esc,'=',20H+07H,20H+0FH,'$' ; Place for status. scrend: db cr,lf,'$' screrr: db esc,'=',20H+08H,20H+00H,'$' ; Place for error messages. curldn: db esc,'=$' ; Cursor lead-in [UTK016] 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 08H,'$',0,0 ; Cursor left. [UTK016] te: db subt,'$',0,0 ; Clear screen. [UTK016] tf: db esc,'F$',0 ; No translation. tg: db esc,'G$',0 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$' ; Clear to end of line. ENDIF ; osbrn1 IF apple outlin: db ('^'-100O),esc,'Y',cr,lf,' ' versio: db 'Kermit-80 V3.6 (UCB36.16) [Apple II CP/M]',cr,lf,'$' delstr: db 10O,10O,'$' ; Delete string. clrspc: db ' ',10O,'$' ; Clear space. clrlin: db cr,esc,'T$' ; Clear line. clrtop: db ('^'-100O),esc,'Y$' ; Clear screen and go home. scrnp: db esc,'=',20H+03H,20H+15H,'$' ; Place for number of packets. scrnrt: db esc,'=',20H+03H,20H+15H,'$' ; Place for number of retries. scrfln: db esc,'=',20H+05H,20H+0CH,'$' ; Place for file name. screrr: db esc,'=',20H+06H,20H+00H,'$' ; Place for error messages. scrst: db esc,'=',20H+07H,20H+0FH,'$' ; Place for "Complete". scrend: db cr,lf,'$' ; Place for prompt. curldn: db esc,'=$' ; Cursor lead-in [UTK016] 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 esc,'D$',0 ; No translation. te: db esc,'E$',0 tf: db esc,'F$',0 tg: db esc,'G$',0 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$' ; Clear to end of line. ENDIF ;apple IF vector outlin: db ('D'-100O),cr,lf,tab,tab versio: db 'Kermit-80 V3.6 (UCB36.16) [Vector Graphics]',cr,lf,'$' delstr: db 10O,' ',10O,10O,'$' ; Delete string. clrspc: db ' ',10O,'$' ; Clear space. clrlin: db cr,('Q'-100O),'$' ; Clear line. clrtop: db ('D'-100O),'$' ; Clear screen and go home. scrnp: db esc,15H,03H,'$' ; Place for number of packets. scrnrt: db esc,15H,04H,'$' ; Place for number of retries. scrfln: db esc,0CH,05H,('Q'-100O),'$' ; Place for file name. screrr: db esc,00H,06H,'$' ; Place for error messages. scrst: db esc,34H,03H,'$' ; Place for "Complete". scrend: db esc,00H,07H,'$' ; Place for prompt. 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 esc,'D$',0 ; No translation. te: db esc,'E$',0 tf: db esc,'F$',0 tg: db esc,'G$',0 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),'$' ; Clear to end of line. ENDIF ; vector IF telcon outlin: db esc,'H',esc,'J',cr,lf,tab,tab versio: db 'Kermit-80 V3.6 (UCB36.16) [Telcon Zorba]',cr,lf,'$' ENDIF IF heath outlin: db esc,'E',esc,'H',cr,lf,tab,tab versio: db 'Kermit-80 V3.6 (UCB36.16) [Heath/Zenith 89]',cr,lf,'$' ENDIF ; heath IF z100 outlin: db esc,'E',esc,'H',cr,lf,tab,tab versio: db 'Kermit-80 V3.6 (UCB36.16) [Heath/Zenith Z-100 CP/M]',cr,lf,'$' ENDIF ; z100 IF heath OR z100 OR telcon delstr: db 10O,' ',10O,'$' ;delete string clrspc: db ' ',10O,'$' ; Clear space. clrlin: db cr,esc,'l$' ; Clear line. clrtop: db esc,'H',esc,'J$' ; Clear screen and go home. scrnp: db esc,'Y#3$' ; Place for number of packets. scrnrt: db esc,'Y#3',esc,'B','$' ; Place for number of retries. scrfln: db esc,'Y%+',esc,'K$' ; Place for file name. screrr: db esc,'Y $' ; Place for error messages. scrst: db esc,'Y& $' ; Place for "Complete". scrend: db cr,lf,'$' ; Place for prompt. 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 z100 OR telcon IF trs80lb ;UCB3608 outlin: db esc,':',cr,lf,tab,tab versio: db 'Kermit-80 V3.6 (UCB36.16) [TRS-80 II Lifeboat CP/M]',cr,lf,'$' delstr: db 10O,' ',10O,'$' ;delete string clrspc: db ' ',10O,'$' ; Clear space. clrlin: db cr,esc,'T$' ; Clear line. clrtop: db esc,':$' ; Clear screen and go home. scrnp: db esc,'=#5$' ; Place for number of packets. scrnrt: db esc,'=#5',lf,'$' ; Place for number of retries. scrfln: db esc,'=%+',esc,'T$' ; Place for file name. scrst: db esc,'=#T$' ; Place for status. scrend: db cr,lf,'$' screrr: db esc,'=& $' ; Place for error messages. curldn: db esc,'=$' ; Cursor lead-in [UTK016] ttab: ; Table start location. ta: db 0BH,'$',0,0 ; Cursor up. [UTK016] tb: db 0AH,'$',0,0 ; Cursor down. [UTK016] tc: db 0CH,'$',0,0 ; Cursor right. [UTK016] td: db 08H,'$',0,0 ; Cursor left [UTK016] te: db esc,':$',0 ; Clear display tf: db esc,'F$',0 ; Enter Graphics Mode tg: db esc,'G$',0 ; Exit Graphics mode th: db 1EH,'$',0,0 ; Cursor home. [UTK016] ti: db 0BH,'$',0,0 ; Reverse linefeed. [UTK016] tj: db esc,'Y$',0 ; Clear to end of screen. tk: db esc,'T$',0 ; Clear to end of line. ENDIF ; trs80lb ;UCB3608 IF trs80pt ;UCB3608 outlin: db 0Ch,cr,lf,tab,tab ;UCB3608 versio: db 'Kermit-80 V3.6 (UCB36.16) [TRS-80 II P+T CP/M]',cr,lf,'$';UCB3608 delstr: db 10O,' ',10O,'$' ; Delete string ;UCB3608 clrspc: db ' ',10O,'$' ; Clear space. ;UCB3608 clrlin: db cr,01h,'$' ; Clear line. ;UCB3608 clrtop: db 0Ch,'$' ; Clear screen and go home. ;UCB3608 scrnp: db esc,'Y#5$' ; Place for number of packets. ;UCB3608 scrnrt: db esc,'Y#5',lf,'$' ; Place for number of retries. ;UCB3608 scrfln: db esc,'Y%+',01h,'$' ; Place for file name. ;UCB3608 scrst: db esc,'Y#T$' ; Place for status. ;UCB3608 scrend: db cr,esc,'Y( ',02h,'$' ; Place for prompt after done ;UCB3608 screrr: db esc,'Y& $' ; Place for error messages. ;UCB3608 curldn: db esc,'Y$' ; Cursor lead-in [UTK016] ;UCB3608 ttab: ; Table start location. ; (MUST be 4 bytes each) ;UCB3608 ta: db 1Eh,'$',0,0 ; Cursor up. [UTK016];UCB3608 tb: db 1Fh,'$',0,0 ; Cursor down. [UTK016];UCB3608 tc: db 1Dh,'$',0,0 ; Cursor right. [UTK016];UCB3608 td: db 1Ch,'$',0,0 ; Cursor left [UTK016];UCB3608 te: db 0Ch,'$',0,0 ; Clear display ;UCB3608 tf: db 11h,'$',0,0 ; Enter Graphics Mode ;UCB3608 tg: db 14h,'$',0,0 ; Exit Graphics mode ;UCB3608 th: db 06h,'$',0,0 ; Cursor home. [UTK016];UCB3608 ti: db 1Eh,'$',0,0 ; Reverse linefeed. [UTK016];UCB3608 tj: db 02h,'$',0,0 ; Clear to end of screen. ;UCB3608 tk: db 01h,'$',0,0 ; Clear to end of line. ;UCB3608 ENDIF ; trs80pt ;UCB3608 IF robin outlin: db esc,3CH,esc,'[H',esc,'[J',cr,lf,tab,tab versio: db 'Kermit-80 V3.6 (UCB36.16) [VT180 "Robin"]',cr,lf,'$' ENDIF ; robin IF rainbo outlin: db esc,3CH,esc,'[H',esc,'[J',cr,lf,tab,tab versio: db 'Kermit-80 V3.6 (UCB36.16) [Rainbow 100 CP/M-80]',cr,lf,'$' ENDIF ; rainbo IF dmII outlin: db esc,3CH,esc,'[H',esc,'[J',cr,lf,tab,tab versio: db 'Kermit-80 V3.6 (UCB36.16) [DECmate II CP/M-80]',cr,lf,'$' ENDIF ; dmII IF robin OR rainbo OR dmII delstr: db 10O,' ',10O,'$' ;delete string clrspc: db ' ',10O,'$' ; Clear space. clrlin: db cr,esc,'[K$' ; Clear line. clrtop: db esc,'[H',esc,'[J$' ; Clear screen and go home. scrnp: db esc,'[4;22H$' ; Place for number of packets. scrnrt: db esc,'[5;22H$' ; Place for number of retries. scrfln: db esc,'[6;12H',esc,'[K$' ; Place for file name. screrr: db esc,'[7;1H$' ; Place for error messages. scrst: db esc,'[4;53H$' ; Place for "Complete". scrend: db esc,'[8;1H$' ; Place for prompt. ENDIF ;robin OR rainbo OR dmII IF kpii outlin: db subt,cr,lf,tab,tab versio: db 'Kermit-80 V3.6 (UCB36.16) [Kaypro II]',cr,lf,'$' delstr: db 10O,' ',10O,'$' ;delete string clrspc: db ' ',10O,'$' ; Clear space. clrlin: db cr,18H,'$' ; Clear line. ;UCB3604 clrtop: db subt,'$' ; Clear screen and go home. scrnp: db esc,'=#5$' ; Place for number of packets. scrnrt: db esc,'=#5',lf,'$' ; Place for number of retries. scrfln: db esc,'=%+',esc,18h,'$' ; Place for file name. ;UCB3604 scrst: db esc,'=#T$' ; Place for status. scrend: db cr,esc,'=( ',17h,'$' ; Place for prompt after done ;UCB3604 screrr: db esc,'=& $' ; Place for error messages. ;UCB3615 curldn: db cr,esc,'=$' ; Cursor lead-in [UTK016] ;UCB3604 ttab: ; Table start location. ta: db 0BH,'$',0,0 ; Cursor up. [UTK016] tb: db 0AH,'$',0,0 ; Cursor down. [UTK016] tc: db 0CH,'$',0,0 ; Cursor right. [UTK016] td: db 08H,'$',0,0 ; Cursor left [UTK016] te: db subt,'$',0,0 ; Clear display [UTK016] tf: db esc,'G$',0 ; Enter Graphics Mode tg: db esc,'G$',0 ; Exit Graphics mode th: db 1EH,'$',0,0 ; Cursor home. [UTK016] ti: db 0BH,'$',0,0 ; Reverse linefeed. [UTK016] tj: db 17H,'$',0,0 ; Clear to end of screen. ;UCB3604 tk: db 18H,'$',0,0 ; Clear to end of line. ;UCB3604 ENDIF ; kpii IF gener or cpm3 outlin: db cr,lf,'Starting ...$' versio: db cr,lf,'Generic CP/M-80 Kermit-80 V3.6 (UCB36.16)',cr,lf,'$' ENDIF ; gener or cpm3 IF osi outlin: db cr,lf,'Starting ...$' versio: db 'Kermit-80 V3.6 (UCB36.16) [Ohio Scientific]',cr,lf,'$' ENDIF ; osi IF gener OR osi OR cpm3 OR crt ;UCB3610 delstr: db 10O,' ',10O,'$' ;delete string clrspc: db ' ',10O,'$' ; Clear space. clrlin: db '^U',cr,lf,'$' ; Clear line. clrtop: db cr,lf,'$' ; "Home & clear" (best we can do). scrnp: db ' ','$' ; Place for number of packets. scrnrt: db ' ','%$' ; Place for number of retries. scrfln: db cr,lf,'$' ; Place for file name. scrst: db cr,lf,'$' ; Place for status. screrr: db cr,lf,'$' ; Place for error messages. scrend: db cr,lf,'$' ; Place for prompt. ENDIF ; gener OR osi OR cpm3 OR crt ;UCB3610 IF crt ;UCB3610 versio: db 'Kermit-80 V3.6 (UCB36.16) [CRT] ' ;(35) ;UCB3610 versi1: db ' ' ;(40) ;UCB3610 versi2: db cr,lf,'$' ;UCB3610 outlin: equ versi2 ;UCB3610 ENDIF ;crt ;UCB3610 ;UCB3610 IF tvi925 ;UCB3610 outlin: db 'Z'-64,cr,lf ;UCB3610 versio: db 'Kermit-80 V3.6 (UCB36.16) [TVI925] ' ;(35) ;UCB3610 ENDIF ;tvi925 ;UCB3610 ;UCB3610 IF adm3a ;UCB3610 outlin: db 'Z'-64,0,0,cr,lf ;UCB3610 versio: db 'Kermit-80 V3.6 (UCB36.16) [ADM3A] ' ;(35) ;UCB3610 ENDIF ;adm3a ;UCB3610 ;UCB3610 IF tvi925 OR adm3a ;UCB3610 versi1: db ' ' ;(40) ;UCB3610 versi2: db cr,lf,'$' ;UCB3610 ;UCB3610 ;Note: These are designed to work on both the tvi925 and the adm3a. ;UCB3610 delstr: db 10O,' ',10O,'$' ; Delete string ;UCB3610 clrspc: db ' ',10O,'$' ; Clear space. ;UCB3610 clrtop: db 'Z'-64,0,0,'$' ; Clear screen and go home. ;UCB3610 scrnp: db esc,'=#3','$' ; Place for number of packets. ;UCB3610 scrnrt: db esc,'=#3',lf,'$' ; Place for number of retries. ;UCB3610 scrfln: db esc,'=%+',esc,'T',8,' $'; Place for file name. ;UCB3610 scrst: db esc,'=#T$' ; Place for status. ;UCB3610 scrend: db esc,'=( ',esc,'Y',cr,'$'; Place for prompt when done ;UCB3610 screrr: db esc,'=& $' ; Place for error messages. ;UCB3615 curldn: db cr,esc,'=$' ; Cursor lead-in (cr 0s lncnt) ;UCB3610 ENDIF ;tvi925 OR adm3a ;UCB3610 ;UCB3610 IF tvi925 OR adm3a ;UCB3610 ttab: ; Table start location. ; (MUST be 4 bytes each) ;UCB3610 ta: db 'K'-64,'$',0,0 ; Cursor up, stop at top ;UCB3610 tb: db 'V'-64,'$',0,0 ; Cursor down, stop at bottom ;UCB3610 tc: db 'L'-64,'$',0,0 ; Cursor right, stop at right ;UCB3610 td: db 'H'-64,'$',0,0 ; Cursor left, stop at left ;UCB3610 te: db 'Z'-64,0,0,'$' ; Clear display (2 pad nulls) ;UCB3610 tf: db esc,'F$',0 ; Enter Graphics Mode NONE ;UCB3610 tg: db esc,'G$',0 ; Exit Graphics Mode NONE ;UCB3610 th: db 1Eh,'$',0,0  ; Cursor home. ;UCB3610 ti: db esc,'j$',0 ; Reverse linefeed, scroll ;UCB3610 tj: db esc,'Y$',0 ; Clear to end of screen. ;UCB3610 clrlin: ; Clear line (same as tk:). ;UCB3610 tk: db esc,'T$',0 ; Clear to end of line. ;UCB3610 ENDIF ;tvi925 OR adm3a ;UCB3610 ;UCB3610 IF adm3a ;UCB3610 org tb ;UCB3610 tb: db 'J'-64,'$',0,0 ; Cursor down CTL J ;UCB3610 org ti ;UCB3610 ti: db 'K'-64,'$',0,0 ; Reverse linefeed. ;UCB3610 tj: db '$',0,0,0 ; Clear to end of screen NONE ;UCB3610 tk: db '$',0,0,0 ; Clear to end of line NONE ;UCB3610 ENDIF ;adm3a ;UCB3610 IF mdI ;UCB3610 versi0: db '[Micro Decision I]',0 ;UCB3610 ENDIF ;UCB3610 ; COMND tables ; ; Structure of command table: [UTK008] ; ; 1) Number of entries. ; 2) Each entry is arranged as follows: ; a) length of command in bytes. ; b) 'name of command and $-sign' ; c) offset into command table at KERMTB: ; d) offset into command table at KERMTB: ; ; ---> Note this command table is in alphabetic order. ; comtab: db 0FH ; Number of entries (currently 15.) db 03H,'BYE$',21H,21H db 07H,'CONNECT$',00H,00H db 03H,'DIR$',24H,24H db 03H,'ERA$',27H,27H db 04H,'EXIT$',03H,03H db 06H,'FINISH$',1BH,1BH db 03H,'GET$',0CH,0CH ; Same as RECEIVE db 04H,'HELP$',06H,06H db 03H,'LOG$',09H,09H db 06H,'LOGOUT$',1EH,1EH db 07H,'RECEIVE$',0CH,0CH db 04H,'SEND$',0FH,0FH db 03H,'SET$',12H,12H db 04H,'SHOW$',15H,15H db 06H,'STATUS$',18H,18H settab: db 0BH ; Number of entries (currently 11.) db 04H,'BAUD$',21H,21H ; Data keys to SETJTB positions. db 10H,'BLOCK-CHECK-TYPE$',18H,18H db 0CH,'DEFAULT-DISK$',24H,24H db 06H,'ESCAPE$',00H,00H db 09H,'FILE-MODE$',12H,12H db 03H,'IBM$',03H,03H db 0AH,'LOCAL-ECHO$',06H,06H db 06H,'PARITY$',15H,15H db 04H,'PORT$',1EH,1EH ;* db 07H,'RECEIVE$',09H,09H ; Not implemented yet. ;* db 04H,'SEND$',0CH,0CH ; Ditto db 0EH,'VT52-EMULATION$',1BH,1BH db 07H,'WARNING$',0FH,0FH stsntb: db 02H db 08H,'PAD-CHAR$',00H,00H db 07H,'PADDING$',03H,03H blktab: db 03H db 14H,'1-CHARACTER-CHECKSUM$','1','1' db 14H,'2-CHARACTER-CHECKSUM$','2','2' db 15H,'3-CHARACTER-CRC-CCITT$','3','3' partab: db 05H ; Five entries. db 04H,'EVEN$',parevn,parevn db 04H,'MARK$',parmrk,parmrk db 04H,'NONE$',parnon,parnon db 03H,'ODD$',parodd,parodd db 05H,'SPACE$',parspc,parspc ontab: db 02H ; Two entries. db 02H,'ON$',01H,01H db 03H,'OFF$',00H,00H typtab: db 03H ;Three entries db 05H,'ASCII$',01H,01H db 06H,'BINARY$',02H,02H db 07H,'DEFAULT$',00H,00H IF gener OR rainbo OR dmII prttab: db 01H ; Only one port known at this point db 0EH,'COMMUNICATIONS$' dw comptb ; address of info ENDIF ; gener OR rainbo OR dmII IF robin prttab: db 03H ; Three entries db 0EH,'COMMUNICATIONS$' dw comptb db 07H,'GENERAL$' dw gppptb db 07H,'PRINTER$' dw prnptb ENDIF ; robin yestab: db 02H ; Two entries. db 02H,'NO$',00H,00H db 03H,'YES$',01H,01H cmer00: db cr,lf,'?Program error: Invalid COMND call$' cmer01: db cr,lf,'?Ambiguous$' cmer02: db cr,lf,'?Illegal input file spec$' cmin00: db ' Confirm with carriage return$' cmcrlf: db cr,lf,'$' if kpii spdtab: db 10h ;16 entries db 02h,'50$',00h,00h db 02h,'75$',01h,01h db 03h,'110$',02h,02h db 05h,'134.5$',03h,03h db 03h,'150$',04h,04h db 03h,'300$',05h,05h db 03h,'600$',06h,06h db 04h,'1200$',07h,07h db 04h,'1800$',08h,08h db 04h,'2000$',09h,09h db 04h,'2400$',0ah,0ah db 04h,'3600$',0bh,0bh db 04h,'4800$',0ch,0ch db 04h,'7200$',0dh,0dh db 04h,'9600$',0eh,0eh db 05h,'19200$',0fh,0fh endif ;kaypro ii ; Impure data ; COMND storage cmstat: ds 1 ; What is presently being parsed. cmaflg: ds 1 ; Non-zero when an action char has been found. 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. cmfcb: ds 2 ; Pointer to FCB. cmfcb2: ds 2 ; Pointer to position in FCB. 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. oldsp: ds 2 ; Room for old system stack. ds 40H ; Room for 32 levels of calls. stack: ds 2 eoflag: ds 1 ; EOF flag; non-zero on EOF. filflg: ds 1 ; Non-zero when nothing in DMA buffer. curdsk: db 0 ; holds "logged" disk logflg: db 0 ; Flag for a log file. ecoflg: db 0 ; Local echo flag (default off). escflg: db 0 ; Escape flag (start off). IF vector vtvflg: db 1 ; Flag for VECTOR VT52 emulation. vctccc: ds 1 ; Storage for reversing row and column. ENDIF ;vector IF NOT (robin OR gener OR rainbo OR dmII OR cpm3) ;UCB3604 vtflg: db 1 ; VT52 emulation flag (default on).  ENDIF ;NOT (robin OR gener OR rainbo OR dmII OR cpm3) ;UCB3604 IF (gener OR rainbo OR robin OR dmII) 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 IF robin prtadr: db comtst ; Address of hardware register ENDIF ; robin ENDIF ;(gener OR rainbo OR robin OR dmII) IF brain flwflg: db 1 ; File warning flag (default on). ENDIF ;brain IF NOT brain flwflg: db 1 ; File warning flag (default off).[on][UTK016] ENDIF ;NOT brain ibmflg: db 0 ; IBM flag (default off). cpmflg: db 0 ; File was created by CPM. parity: db defpar ; Parity. escchr: db defesc ; Storage for the escape character. chrcnt: ds 1 ; Number of chars in the file buffer. 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 ; Poistion in receive packet. size: ds 1 ; Size of data from gtchr. 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 curchk: db dschkt ; Current checksum type inichk: db dschkt ; Agreed upon checksum type czseen: ds 1 ; Flag that control-Z was typed 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. packet: ds 4 ; Packet (data is part of it). data: ds 5AH ; Data and checksum field of packet. recpkt: ds 60H ; Receive packet storage (use the following). recpkx: db cr,'$' ; = = = buffer limit ;UCB3612 filbuf: ds 60H ; Character buffer. ;** Temp 1 & 2 must be in order temp1: ds 1 ; Temporary storage. temp2: ds 1 temp3: ds 1 temp4: ds 1 ;Unitialized storage for DIRLST 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 ; Dir - names per line counter. [UTK008] ; 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 ; argblk: ds 20H ; Used for subroutine arguments. if kpii speed: db 05h ;default speed for kaypro ii endif ;kaypro ii IF osbrn1 osbaud: db 1 ; Baud rate: 0=300, non-0=1200 osmove: osflag equ 0EF08H ; Osborne 1 Bank-2 flag OSLDST EQU ostop-osmove+$ DI OUT 0 LDA osprts ; Read the status port OUT 1 EI ret OSSTST equ ostop-osmove+$ DI OUT 0 STA osprts ; Write the control port jmp osstex OSLDDA equ ostop-osmove+$ DI OUT 0 LDA osport OUT 1 EI ret OSSTDA equ ostop-osmove+$ DI OUT 0 STA osport osstex equ ostop-osmove+$ OUT 1 mvi a,1 sta osflag EI ret osmct equ $-osmove ENDIF if kpii kpstbl: ;Status table for SIO DB 18H ;Channel reset DB 04H ;Register 2 DB 44H ;Interrupt vector 44 DB 01H ;Register 1 DB 00H ;Zero DB 03H ;Register 3 DB 0C1H ;Rx enable, 8 bit Rx character DB 05H ;Register 5 DB 0EAH ;DTR, 8 bit Tx character ;Tx enable, RTS DB 00H ;Zero endif ;kaypro ii END START  MFNAME ; argblk: ds 20H ; Used for subroutine arguments. if kpii speed: db 05h ;default speed for kaypro ii endif ;kaypro ii IF osbrn1 osbaud: db 1 ; Baud rate: 0=300, non-0=1200 osmove: osflag equ 0EF08H ; Osborne 1 Bank-2 flag OSLDS!9")1*<2*&!:*@21*2y+2z+m&!">y!OO M<ÓØHV{-!!RECEIVE$H*>Â2|+6$[&H*>129*2{+>R$Â[2;*!"=*"?*2<*2A*&!F>R2C*&*=*F:C*DͽF͸R(xCDV :;*>2;*.!!ARa !a !&U>2*!"!*:A*<2A*>129*͗S:A*2B*2A*:{+Y$::*29*>F2C*E>A2C*M ! :<*2{+2|+>N$&*?*#"?*F:-* w#:/* w#:1* w#:3*@w#:5* w#:7*w#6N#::*w#>2g+~ 2,*:g+##~ 20*:g+#~@22*:g+#~ 24*:g+#~26*:g+#~:g+#~G:8*ʴ>12:*2:*:A*<2A*͗S:B*<2B*:<*=G:{+ 2A*!H*#2|+>Y$ZE:B*"=<2B*:<*=G:{+ 2A*2|+>Y$F:<*G:{+Y$>D2C*:;*Zȯ2;*B²:<*G:{+2|+>Y$>C2C*E:A*^<2A*͗DV:<*G:{+:B*^<2B*:<*=G:{+ 2A*2|+>Y$2|+y2H*>Y$F:B*j<2B*:<*=G:{+ 2A*2|+>Y$Z:<*G:{+Y$>F2C*ESEND$>\!>! *![2<*2A*!"=*"?*&!F>129*>S2C*&*=*F:C*Dp_VF{mVZ†7 VS‘VBœ VC´V :;*ʮ.!!Aa !a !:A*<2A*>129*:8*2:*!H*#2|+:=*2{+>S$͗EYF:<*G:{+F2C*ͥ Nb :<*F2C*E:A*|<2A*2;*!H*"%*!]"#*x¥>.*%*w#"%* x *#*~#"#*!*%*w#"%* Ôy2|+*%*>$w&H*:<*2{+>F$͗EY?:<*G:{+2* +6>Z2C*2+*>D2C*NT :<*D$͗EY :<*G:{+:{+Z2C* 2+*>Z2C*N, :<*D2H*>2|+>Z$͗EY :<*G:{+F2C*>B2C*N :<*B$͗EY: :<*G:{+C2C*NO :<*2*@:6*O:* ͳ ð :9*1G:,*2d+!+"'*:d+= x@2d+:*= 2*% ͳ  % x@ð *!*~#"!*W_z R R £ !d+5*'*w#"'*ã Œ :*{ :*ʊ :*ʊ *!*:*Wz 2*x@~#v >2e+!d+5*'*q#"'*:e+@*'*w#"'* >:*ʽ !*:* 62* 6!"!*\ @2*>2*  ?2h:y+4 2z+!\m+ ͆ \Q =2z+!m+\ ͆ \:z+a =2z+L ͑ :m+2\:y+<2y+>2h2}7~ ~# x† ɇƀo&\ ͆ >2*2*2h2j2|\@!H*"%*!]"#*2d+2e+2\ p#< *%*~a _#"%*. !e"#*:d+2e+> 2d+6 ] *#*w#"#*:d+<2d+ 2e+*%*~#"%*] ." *%*~aA _#"%*] *#*w#"#*:d+<2d+ 6 *%*6$&H*:* \ i :e+• :d+2e+P< ¡ =_!\6&!\ ~w# ¯ \ x { â { :e+_â !hF6$]!hp\2h2j2|\@x2}+!D*>w#:9*1G:|+#w#O:{+ w#O>G:}+w#O>G:|+n=2|+~#O>GX:9*2ʟ҈y? w#ö6!E*RKBz w#xGy w#y? w#:4*w#wE@:0*2d+:d+=2d+:2*_4!D*~_4#@!*N! ",1111111{_| E dtE@2;*G:*x@@ $;EDםDEʨ2E*O:9*1Gy#2|+DEʨ2{+2F*O>G:{+ 2{+DEʨ2d+2G*O>G:|+2e+!H*"%*:e+/2e+DEʨ*%*w#"%*O>GDEʨ 2f+:9*2ʊ^y?G:f+ʳ *%*6!E*RKBzW:f+ZDEʨ 2f+xGyG:f+ZDEʨ Gy?Z*%*6:d+@!*")*CE+CE!*")**)*w#")*ھG:5**)*6 :*C+ *)*!*")*@ > > >> _*)*~#")* @~ʅ_O! {O! ~#V_#~W#W!1BRcs ƍ#2$FW6etHZӾl~>A2C*:|+O!H* >$wH*&&&&FINISH$>Â2A*>129*[:A*D!<2A*2{+>2|+!H*6F>G$;͗3Y!E3!LOGOUT$>Â͌!!2A*>129*t[:A*, <2A*2{+>2|+!H*6L>G$ã͗ÛY@E›>Â͌!>Â*)>\Â>Â!*6!"!*\2h2j2|\!!>Â"!>   p͎!d_:*hp@_:*ʿ{_::*@{_@ʿG_C :*ȯ2*| *!*6\\S d@x?5%ÿx_B-!@x0;:@_:*N{_:@@_*!*s#"!*}:\ʋx:!"!*w'!i#>y!O ]vÂ"á&ØT(!$>y2d+>y:d+28*!\>:\ :*2* :*=_!'!$>y!8O I>>Â!>Â!!!>Â!2*!(!#%>y2d+>Â:d+2*!!!(!#%>y2d+>Â:d+2*!(!#%>y2d+>Â:d+2*>>2*x2*!!!(! &>Â2d+>Â:d+2*!a(!%>Â2d+>Â:d+2*!>Âd!\!>Â%:*w%z%!&:*ʘ%ʛ&Û%-&:*ʱ%ô%8&:*%%W&:*&& & &&b&:8*_w&G& \>;S:\ G2\!] 6?#L:\^:*@2U!;!>2l+ Ҁ ʑ!]>.z!l+5ĵw>:> _~#> > 6:*=_!2y+2z+:\=_*h+#-W+}>z($i`:k+N)=IZ!:\b<@2e!e!Fl!#\:}oʍo:~Ң ҫ@Ҵg} dF>k##~2k+#~2j+##^#V"h+>\!\<!\{!!:* 3 :*@_### P |F{0_":)!9"8)"<)!B)")")25)26)>27)1)*<)*8)!B)")>27)*:)*8)!B)")")25)26)>27)1)*<)*:)24) \ʾ (">)͸P925)*)+")")!6)5?K x*>)@!5)6*>)w#">)͸„25)*)+")")!6)5\?¶)1)*<)*)>$w*)+")B)25)á @"@)">)F#")*)")x*)^#{͸?25)!6)5*@)1)*<)*)>$w*)+")B)áŽ25)M*)+")")!6)5*)+~$i#w#:6)<26)T:6)<26)> w#")") áß(ô#^#V{@a{_V#{")*)")K{F#*)~O*) @F#~#a{_")6#")6 #< ͸t?F!5)6*)+")g25)*)+")")!6)5á{ @.•{  *) ") ):²{*)+~@")+w)*{ *)>?w#"){)0{A_*)w#")):4)(:5)´!6)4*)w#")D&*<)!B)")!6)6áT{&:6)==g)26)&*)++")á?ʟʟ ʗ ʗ §:6)ʴ>25)ô  :5) *)~#")  :7)º>27)> 27)?   *)+")&  Number of packets: Number of retries: File name: $ [CR retry, ^X skip file, ^Z quit, ^A abort]$ Noise or Messages Received:$Kermit-80 x:>$Delete it? $ $ ?Unrecognized command$ ?Illegal character$ ?Not confirmed$?Unable to receive initiate $?Unable to receive file name $?Unable to receive end of file $?Unable to receive data $?Disk full $?Unable to receive an acknowledgement from the host $ ?Unable to find file $?Unable to rename file$ ?Disk full$ ?Unable to tell host that the session is finished$ ?Unable to tell host to logout$ABORTED$Completed$Failed$%Renaming file to $ [Closing the log file]$ [Connected to remote host, type $C to return] $ [Connection closed, back at micro]$Control-$ (Type Left Arrow to send CTRL-S) $ (Not implemented) $Interrupted$ Directory for drive x: $ Drive $ has $K bytes free $ File(s) erased$ ++ Bad drive name$ Confirm with carriage return $ Input file spec (possibly wild) $ Type the new escape character: $ BYE to host (LOGOUT) and exit to CP/M CONNECT to host on selected port ERA a CP/M file EXIT to CP/M FINISH running Kermit on the host HELP by giving this message DIR of current used Micro-disk LOG the terminal session to a file LOGOUT the host RECEIVE file from host SEND file to host SET a parameter SHOW the parameters STATUS of Kermit$ BAud (rate) BLock-check-type (for error detection) Default-disk (to receive data) Escape (character during CONNECT) File-mode (for outgoing files) Ibm (parity and turn around handling) Local-echo (half-duplex) PArity (for communication line) POrt (to communicate on) Vt52-emulation Warning (for filename conflicts)$ PAD-CHAR PADDING$ 1-CHARACTER-CHECKSUM 2-CHARACTER-CHECKSUM 3-CHARACTER-CRC-CCITT$ EVEN MARK NONE ODD SPACE$ OFF ON$ NO YES$ ? This message C Close the connection 0 (zero) Transmit a NULL S Status of the connection Type the escape character again to send it to the host Command>$ on$ off$ Local echo$ default$ ASCII$ binary$ ASCII BINARY DEFAULT$ File Mode$ IBM flag$ File warning$ Escape char: $ Parity: $ Block check type: $-character$none$mark$space$odd$even$ Starting ...$ Generic CP/M-80 Kermit-80 V3.6 (UCB36.16) $ $ $^U $ $ $ %$ $ $ $ $BYE$!!CONNECT$DIR$$$ERA$''EXIT$FINISH$GET$ HELP$LOG$ LOGOUT$RECEIVE$ SEND$SET$SHOW$STATUS$ BAUD$!!BLOCK-CHECK-TYPE$ DEFAULT-DISK$$$ESCAPE$ FILE-MODE$IBM$ LOCAL-ECHO$PARITY$PORT$VT52-EMULATION$WARNING$PAD-CHAR$PADDING$1-CHARACTER-CHECKSUM$112-CHARACTER-CHECKSUM$223-CHARACTER-CRC-CCITT$33EVEN$MARK$NONE$ODD$ SPACE$ ON$OFF$ASCII$BINARY$DEFAULT$NO$YES$ ?Program error: Invalid COMND call$ ?Ambiguous$ ?Illegal input file spec$ Confirm with carriage return$ $ ^ ##111 $BLOCK-CHECK-TYPE$ DEFAULT-DISK$$$ESCAPE$ FILE-MODE$IBM$ LOCAL-ECHO$PARITY$PORT$VT52-EMULATION$WARNING$PAD-CHAR$PADDING$1-CHARACTER-CHECKSUM$112-CHARACTER-CHECKSUM$223-CHARACTER-CRC-CCITT$33EVEN$MARK$NONE$ODD$ SPACE$ ON$OFF$ASCII$BINARY$DEFAULT$NO$YES$ ?Program error: Invalid COMND call$ ?Ambiguous$ ?Illeg:1001000000002100003922CE2931102A0E19CD0518 :10011000003C32142A11AA26CD181ECD2101CDF1A2 :10012000123A142AC64032AF1E31122AAF32792B4E :10013000327A2B11A41ECD6D1911F8262108223E0A :1001400001CDDE19C37901214F014F060009E9C332 :100150004D13C3E912C33C13C3F612C39301C30882 :1001600006C39814C34816C35616C31C12C37B1289 :10017000C3D812C32D17C3EF1811C21ECD181EC34A :10018000210111EF1ECD181EC321015245434549DF :1001900056452411482A3E05CDDE19C38201B7CA4F :1001A000CE01327C2BEB3624118B01CD5B0211EC9E :1001B00026CD181E11482ACD181E3E3132392AAFDD :1001C000327B2B3E52CD240EC38201C3D401118B4E :1001D00001CD5B02AF323B2A210000223D2A223FA3 :1001E0002A323C2A32412A11E926CD181E2100006C :1001F000CD46193E5232432A11E726CD181E2A3D1C :100200002ACD46193A432AFE44C21202CDBD04C388 :10021000F801FE46C21D02CDB803C3F801FE52C26A :100220002802CD7802C3F801FE43C24402115620D1 :100230003A3B2AB7CA3E02AF323B2A112E21CD03E8 :1002400012C32101FE41C25202116120CD0312C32B :100250002101116120CD0312C32101D5119B26CDAF :10026000181ED1CD181E11551ECD181E3E80321DF0 :100270002A21800022212AC93A412AFE05FA870252 :1002800011001FCDED11AF3C32412A3E3132392AE7 :10029000CD970FC3F502FE53C2DB023A412A324228 :1002A0002AAF32412A3A7B2B3CE63F323C2A2A3D98 :1002B0002A23223D2A3A7C2B21482ACD5803214863 :1002C0002ACD2303327C2B3E59CD240EC3E6023ABD :1002D0003A2A32392A3E4632432AC9FE45C2F5023D :1002E000CDC811C3E6023E4132432AC9114D20CD8B :1002F0000312C32101CD0B033A3C2A327B2BAF32D0 :100300007C2B3E4ECD240EC3E602C911E926CD1842 :100310001E2A3F2A23223F2ACD46191E070E02CD50 :100320000500C93A2D2AC62077233A2F2AC62077FE :10033000233A312AC62077233A332AC640E67F770C :10034000233A352AC62077233A372A7723364E2395 :100350003A3A2A77233E08C932672B7EDE20322CB8 :100360002A3A672BFE03F823237EDE2032302A3A16 :10037000672BFE04F8237EC640E67F32322A3A67B6 :100380002BFE05F8237EDE2032342A3A672BFE0648 :10039000F8237E32362A3A672BFE07F8237E3A6727 :1003A0002BFE08F8237E473A382AB8CAB4033E31F8 :1003B000323A2AC9323A2AC93A412AFE05FAC70313 :1003C000111E1FCDED11AF3C32412ACD970FC3F561 :1003D00002FE53C20E043A422AFE05FAE50311005A :1003E0001FCDED11AF3C32422A3A3C2A3D473A7BC1 :1003F0002BB8C2F502CD0B03AF32412A21482ACDDA :100400002303327C2B3E59CD240EC3E602C9FE5A8B :10041000C245043A422AFE05FA2204113D1FCDEDE1 :1004200011AF3C32422A3A3C2A3D473A7B2BB8C2B4 :10043000F502CD0B03AF32412A327C2B3E59CD243D :100440000EC3E602C9FE46C290043A3C2A473A7BF4 :100450002BB8C2F5023CE63F323C2A2A3D2A232231 :100460003D2ACDC20CC3E602CD6C023A412A32428B :100470002AAF32412A327C2B3E59CD240EC3E602EC :100480003E4432432A3A3B2AFE5AC8AF323B2AC97D :10049000FE42C2B2043A3C2A473A7B2BB8C2F5026C :1004A000AF327C2B3E59CD240EC3E6023E4332438D :1004B0002AC9FE45C2E602CDC811C3E6023A412A66 :1004C000FE05FACC04115E1FCDED11AF3C32412A7E :1004D000CD970FC3F502FE44C256053A3C2A473A6F :1004E0007B2BB8CA18053A422AFE05FAF504115EBC :1004F0001FCDED11AF3C32422A3A3C2A3D473A7BB0 :100500002BB8C2F502CD0B03AF32412A327C2B3E11 :1005100059CD240EC3E602C93CE63F323C2A2A3DAF :100520002A23223D2A3A412A32422A3A7C2BCD5AAA :100530000AC3E602AF32412A327C2B4F3A3B2AB73C :10054000CA4D054F3E01327C2B7932482A3E59CDA7 :10055000240EC3E602C9FE46C28D053A422AFE05B4 :10056000FA6A05111E1FCDED11AF3C32422A3A3C0A :100570002A3D473A7B2BB8C2F502CD0B03AF32417F :100580002A327C2B3E59CD240EC3E602C9FE5AC244 :10059000F8053A3C2A473A7B2BB8C2F5023CE63FC5 :1005A000323C2A2A3D2A23223D2A3A7C2BFE01C2D4 :1005B000BA053A482AFE44CADD052A212A3A1D2AEC :1005C0003DB7FACB05361A23C3C005CDAC0AC3E646 :1005D000020E10115C00CD0500AF323B2A3A412AD1 :1005E00032422AAF32412A327C2B3E59CD240EC3EF :1005F000E6023E4632432AC9FE45C2E602CDC81194 :10060000C3E60253454E44243E02115C00CDDE1980 :10061000C321013E04CDDE19C32101CD000CD22A35 :100620000611BB1FCDED11C32101110306CD5B02E5 :10063000AF323C2A32412A210000223D2A223F2AA1 :1006400011E926CD181E210000CD46193E31323960 :100650002A3E5332432A11E726CD181E2A3D2ACDC1 :1006600046193A432AFE44C27006CD5F08C35606B7 :10067000FE46C27B06CD6D07C35606FE5AC28606ED :10068000CD3709C35606FE53C29106CDCB06C356DD :1006900006FE42C29C06CDE409C35606FE43C2B420 :1006A000061156203A3B2AB7CAAE06112E21CD03B9 :1006B00012C32101FE41C2C206116120CD0312C343 :1006C0002101116120CD0312C321013A412AFE0507 :1006D000FADA0611851FCDED11AF3C32412A3E31C9 :1006E00032392A3A382A323A2A21482ACD2303328B :1006F0007C2B3A3D2A327B2B3E53CD240EC3E6029F :10070000CD970FC34519FE59C246073A3C2A473ACE :100710007B2BB8C03CE63F323C2A2A3D2A23223DAF :100720002A3A7C2B21482ACD58033A412A32422AC0 :10073000AF32412A3A3A2A32392A3E4632432ACD4A :10074000A50CC3E602C9FE4EC26207CD0B033A3CBC :100750002A3C473A7B2BB8C0AF32412A3E4632434F :100760002AC9FE45C2E602CDC811C3E6023A412AB3 :10077000FE05FA7C0711851FCDED11AF3C32412AF1 :10078000AF323B2A21482A22252A215D0022232A32 :1007900006000E0078FE08C2A5073E2E2A252A77FD :1007A0002322252A0C0478FE0CF2C7072A232A7E6E :1007B000E67F2322232AFE21FA94072A252A77237B :1007C00022252A0CC3940779327C2B2A252A3E2421 :1007D0007711EC26CD181E11482ACD181E3A3C2A56 :1007E000327B2B3E46CD240EC3E602CD970FC34588 :1007F00019FE59C23F083A3C2A473A7B2BB8C03C05 :10080000E63F323C2A2A3D2A23223D2A3A412A3217 :10081000422AAF32412AAF327C0032122A3EFF32E6 :10082000132ACDCF0AC32B08C33608FEFFC2E60247 :100830003E5A32432AC9322B2A3E4432432AC9FE49 :100840004EC25408CD0B033A3C2A3C473A7B2BB8A6 :10085000C0C3FF07FE45C2E602CDC811C3E6023A97 :10086000412AFE05FA6E0811851FCDED11AF3C320D :10087000412A21482A22252A21042B22272A06013F :100880002A272A7E2322272A2A252A772322252A55 :10089000043A2B2AB8F280083A2B2A327C2B3A3CB5 :1008A0002A327B2B3E44CD240EC3E602CD970FC3E4 :1008B0004519FE59C217093A3C2A473A7B2BB8C062 :1008C0003A7B2B3CE63F323C2A2A3D2A23223D2A12 :1008D0003A412A32422AAF32412A3A7C2BFE01C2E7 :1008E000F5083A482AFE5AC2ED08323B2AFE58C2A1 :1008F000F508323B2A3A3B2AB7CA02093E5A32432C :100900002AC9CDCF0AC30C09322B2AC9FEFFC2E681 :10091000023E5A32432AC9FE4EC22C09CD0B033A7D :100920003C2A3C473A7B2BB8C0C30209FE45C2E6CD :1009300002CDC811C3E6023A412AFE05FA46091162 :10094000851FCDED11AF3C32412A3A3C2A327B2B38 :10095000AF327C2B3A3B2AB7CA65093E4432482A5B :100960003E01327C2B3E5ACD240EC3E602CD970FBA :10097000C34519FE59C2C4093A3C2A473A7B2BB8F1 :10098000C03CE63F323C2A2A3D2A23223D2A3A41F6 :100990002A32422AAF32412A0E10115C00CD0500E6 :1009A0003A3B2AFE5ACABE09CD000CDABE09CDA5D3 :1009B0000CC3E602AF323B2A3E4632432AC93E42CE :1009C00032432AC9FE4EC2D909CD0B033A3C2A3C18 :1009D000473A7B2BB8C0C38109FE45C2E602CDC8A9 :1009E00011C3E6023A412AFE05FAF30911851FCD2B :1009F000ED11AF3C32412A3A3C2A327B2BAF327C9C :100A00002B3E42CD240EC3E602CD970FC34519FEFF :100A100059C23A0A3A3C2A473A7B2BB8C03CE63FD7 :100A2000323C2A2A3D2A23223D2A3A412A32422AAE :100A3000AF32412A3E4332432AC9FE4EC24F0ACD4D :100A40000B033A3C2A3C473A7B2BB8C0C31D0AFE35 :100A500045C2E602CDC811C3E60232642B21482A02 :100A6000221F2A3A372A4721642B35FA4019211DC3 :100A70002A35F27B0ACDAC0AC345192A1F2A7E23E8 :100A8000221F2AB8C2A10A7E23221F2A21642B35E5 :100A900057E6805F7AE67FB8CAA00A7AC640E67F4A :100AA000B32A212A772322212AC3670AC50E1511EA :100AB0005C00CD0500C1B7CAC10A11781FCDED1188 :100AC000C921800022212A3E7F321D2AC340193AC3 :100AD000362A4F3A132AB7CAE20A0600CDB30BC32F :100AE000B00B3A392AD631473A2C2AD605903264CF :100AF0002B21042B22272A06003A642B3DF2040BFB :100B000078C3401932642B3A1D2A3DFA140B321D6A :100B10002AC3250BCDB30BC31D0BC3250B78B7C25E :100B20004019C3B00B2A212A7E2322212A57E680AE :100B30005F7AE67FFE20FA520BFE7FCA520BB9C2E3 :100B4000A30B21642B352A272A772322272A04C3C3 :100B5000A30BB3FE1AC28C0B3A1A2AFE01CA7B0BF6 :100B60003A122AB7CA8A0B3A1A2AFE02CA8A0B2AF2 :100B7000212A3A1D2A57157AF2830BAF321D2A78A3 :100B8000C340197E23FE1ACA760B3E1A32652B210A :100B9000642B352A272A712322272A043A652BC67B :100BA00040E67F2A272AB3772322272A04C3F90A9B :100BB0003EFFC93A122AB7CABD0B0600C0C5D5E52B :100BC000211D2A3A132AB7CAD30B3680AF32132A13 :100BD000C3D50B367F21800022212A0E14115C0020 :100BE000CD0500B7CAEE0BC3F40BE1D1C1C9E1D109 :100BF000C1C34019AF321D2A3EFF32122AC3EA0B8D :100C0000D2040C3FC5D5E50E1A118000CD0500AF0A :100C10003268003A792BB7C2340C327A2B215C004F :100C2000116D2B010C00CD860C0E11115C00CD0551 :100C300000C3510C3D327A2B216D2B115C00010C4D :100C400000CD860C0E11115C00CD05000E12CD05F5 :100C500000F53A7A2BB7CA610C3D327A2BF1C34CBE :100C60000CF1B7FA820CCD910C3A6D2B325C003A44 :100C7000792B3C32792B3E00326800327D00E1D185 :100C8000C1C937C37E0C7E1223130B78B1C2860C08 :100C9000C98787878787C6806F2600115C00010C93 :100CA00000CD860CC93EFF32132AAF32122A3268B9 :100CB00000326A00327C000E0F115C00CD0500C3CB :100CC000401921482A22252A215D0022232AAF32F9 :100CD000642B32652B325C00062070233CFE0CFA3C :100CE000DA0C2A252A7EFE61FAED0CE65F23222526 :100CF0002AFE2EC20A0D21650022232A3A642B32D5 :100D0000652B3E0932642BC3360DB7CA5D0D2A230D :100D10002A772322232A3A642B3C32642BFE08FADA :100D2000E20C32652B2A252A7E2322252AB7CA5DAA :100D30000DFE2EC2220D2A252A7EFE61FA410DE605 :100D40005F2322252AB7CA5D0D2A232A772322236F :100D50002A3A642B3C32642BFE0CFA360D2A252AE3 :100D6000362411EC26CD181E11482ACD181E3A182B :100D70002AB7CAFE0D0E0F115C00CD0500FEFFCA9A :100D8000FE0D116920CDED113A652BB7C2950D3AD4 :100D9000642B32652B0600503CFE09C2A10D06FFF4 :100DA0003D5F215C00193626C5D5215C000E0C7E06 :100DB000E67F77230DC2AF0D0E0F115C00CD05004D :100DC000D1C1FEFFCAEC0D78B7CAD50D1D7BB7CADD :100DD000E50DC3A20D1C7BFE09FAA20D3A652B5F3F :100DE00006FFC3A20D11D41FCD181EC921680046ED :100DF0003624C5115D00CD181EC1216800700E1388 :100E0000115C00CD0500AF326800326A00327C0010 :100E10000E16115C00CD0500FEFFC2401911781FAF :100E2000CDED11C9327D2B21442A3E0177233A3979 :100E30002AD631473A7C2BC6238077230100004F06 :100E40003A7B2BC6207723814F3E0088473A7D2B83 :100E50007723814F3E0088473A7C2BB7CA6E0E3D00 :100E6000327C2B7E23814F3E008847C3580E3A398F :100E70002AFE32CA9F0ED2880E79E6C0070781E6A5 :100E80003FC6207723C3B60E3600E521452ACD5252 :100E900011E14B427A07070707E60FC62077237850 :100EA000E60F070747790707E603B0C620772379DF :100EB000E63FC62077233A342A7723AF77CDC60E94 :100EC000C34519C340193A302A32642B3A642B3D8A :100ED000B7FAE10E32642B3A322A5FCD340FC3CC1D :100EE0000E21442A7EB7CAF10E5FCD340F23C3E42E :100EF0000EC34019E5C5211B2A4E060021010F092A :100F0000E9C3130FC31D0FC3100FC3220FC32C0F50 :100F1000C3310FE67FEA310FF680C3310FF680C38D :100F2000310FE67FE2310FF680C3310FE67FC33128 :100F30000FC1E1C9E5C57BCDF40E5F0E04CD050000 :100F4000C1E1C9E5C50E07CD0500B7C27C0F0E0B88 :100F5000CD0500B7CA450F0E01CD0500FE0DC264D8 :100F60000FC1E1C9FE1ACA740FFE01CAEC02FE18D5 :100F7000C2450FC9C640323B2AC1E1C90E03CD05A7 :100F800000473A1B2AFE0678C1E1CA4019E67FC332 :100F900040190D0A0A0A24CDBE10C34519CD4411CB :100FA000C3970FFE01C29D0FCD4411C34519FE0129 :100FB000CAA80F32452A4F3A392AD6314779D62363 :100FC00090327C2B0600CD4411C34519FE01CAA8FE :100FD0000F327B2B32462A814F3E0088473A7B2BCB :100FE000D620327B2BCD4411C34519FE01CAA80F70 :100FF00032642B32472A814F3E0088473A7C2B329D :10100000652B21482A22252A3A652BD601FA2F1072 :1010100032652BCD4411C34519FE01CAA80F2A25FC :101020002A772322252A814F3E008847C30810CD06 :101030004411C34519FE01CAA80FD62032662B3AC7 :10104000392AFE32CA8A10D25E1079E6C0070781BB :10105000E63F473A662BB8CAB310CD0B03C92A2521 :101060002A360021452ACD52114B427A070707073D :10107000E60F573A662BBAC25A10CD4411C3451930 :10108000FE01CAA80FD62032662B78E60F07074765 :10109000790707E603B0473A662BB8C25A10CD4429 :1010A00011C34519FE01CAA80FD6204779E63FB8FB :1010B000C25A102A252A36003A642BC3401921A2AD :1010C0002A22292ACD430FC34519FE01CAE610CDB5 :1010D0002B11C3C410CD430FC34519FE01C2E61046 :1010E00021A22A22292A2A292A772322292A11FD04 :1010F000D419DABE10473A352AB8C2D5102A292A9F :10110000360D3A192AB7CA1F11CD430FC31F11FE5E :1011100011CA1F11FE01CAE010CD2B11C309112AFB :10112000292A21A22A22292AC34019E67FFE20F279 :101130003E11FE0DCA3E11FE0ACA3E113E205F0E50 :1011400002C305002A292A7E2322292AFE0DC24035 :1011500019C9E5C51100007EB7CA8511E5AB5FE688 :101160000F4F060021A8110909E57B0F0F0FE61E9E :101170004F218811097EAA2356E1AE5F237EAA572C :10118000E123C35711C1E1C900008110022183315D :101190000442855206638773088489940AA58BB537 :1011A0000CC68DD60EE78FF70000891112239B32F3 :1011B0002446AD573665BF74488CC19D5AAFD3BE27 :1011C0006CCAE5DB7EE9F7F8CDFC113E4132432ADB :1011D000C3D91111BF1ECD181E3A7C2B4F0600211A :1011E000482A093E247711482ACD181EC9D5CDFCBE :1011F0001111DF26CD181ED1CD181EC911F226CD32 :10120000181EC9D511EF26CD181ED1CD181E11F507 :1012100026CD181EC946494E495348243E04CDDE0A :1012200019C38201AF32412A3E3132392A111512D7 :10123000CD5B023A412AFE05FA441211F81FCD187F :101240001EC321013C32412AAF327B2B3E01327C4E :101250002B21482A36463E47CD240EC33B12CD975C :101260000FC33312FE59CA2101FE45C23312CDD33A :1012700011C321014C4F474F5554243E04CDDE1974 :10128000C38201CD8C12C32101C32101AF32412A97 :101290003E3132392A117412CD5B023A412AFE05E1 :1012A000FAAA12112C20CD181EC93C32412AAF32A5 :1012B0007B2B3E01327C2B21482A364C3E47CD24E5 :1012C0000EC3A312CD970FC39B12FE59CA4019FE3D :1012D00045C29B12CDD311C93E04CDDE19C3820194 :1012E000CD8C12C32101C3F1123E04CDDE19C3829D :1012F000012ACE29F9C93E03115C00CDDE19C38253 :10130000013E04CDDE19C3820121152A36FF21805A :101310000022212A0E13115C00CD0500AF326800B7 :10132000326A00327C000E16115C00CD0500FEFF13 :10133000C2210111EB1FCD181EC321013E04CDDED9 :1013400019C38201110822CD181EC321013E04CD0C :10135000DE19C38201119520CD181ECD201911B8B8 :1013600020CD181ECD7013CD8E13C32101C364137D :101370000E07CD0500B7C80E03CD0500E67F5F3A26 :10138000152AB7C468140E06CD0500C370130E06E7 :101390001EFFCD0500E67FCA40195F3A1C2ABBCA72 :1013A000BF137BCDF40E5FD5CD3A19D13A162AB7CB :1013B000CA40197BE67F5F0E06CD0500C340190EBB :1013C000061EFFCD0500B7CABF1347FE03CAD713D9 :1013D000E65FFE43C2021411C720CD181E3A152A3B :1013E000B7C8AF32152A117C20CD181E2A212A3603 :1013F0001A0E15115C00CD05000E10115C00CD0514 :1014000000C9FE53C20D14CD6416C3401978FE3FC7 :10141000C21C14113525CD181EC3BF1378E65FFE1C :1014200042C22D14111921CD181EC3401978FE3067 :10143000C23B141E00CD3A19C340195F3A1C2ABBA7 :10144000C24E147BCDF40E5FCD3A19C340191E076E :101450000E06CD0500C34019F51E1B0E02CD05007A :10146000F15F0E02CD0500C92A212A732322212A09 :101470007DB7C0D51E13CD3A190E15115C00CD05F0 :1014800000B7CA8B1411781FCD181E1E11CD3A1942 :1014900021800022212AD1C91177272169233E0109 :1014A000CDDE19C3790121AE144F060009E9C35DF1 :1014B00015C3C315C37615C38201C32215C3A11575 :1014C000C30416C32616C3D514C39815C3FB15C38E :1014D0005415C3F71411172821C4243E01CDDE1979 :1014E000C3790132642B3E04CDDE19C379013A641D :1014F0002B32382AC32101115C003E10CDDE19C306 :1015000002153A5C00FE00C20D153A142A32142A64 :101510000E0DCD05003A142A3D5F0E0ECD0500C319 :10152000210111FF2721B0243E01CDDE19C379012D :101530002138154F060009E9C34915C33E153E047D :10154000CDDE19C38201C321013E04CDDE19C38261 :1015500001C32101111921CD181EC321013E04CD63 :10156000DE19C3820111E521CD181E0E01CD050043 :10157000321C2AC32101118A282123253E01CDDEF8 :1015800019C3790132642B3E04CDDE19C382013ABE :10159000642B32162AC32101111921CD181EC32133 :1015A00001118A282123253E01CDDE19C37901329C :1015B000642B3E04CDDE19C382013A642B32182A13 :1015C000C32101118A282123253E01CDDE19C379CB :1015D0000132642B3E04CDDE19C382013A642B3202 :1015E000192AB7CAED153E000600C3F1153E0606DE :1015F00000321B2A7832162AC32101111921CD1875 :101600001EC32101119828210A263E01CDDE19C3EF :10161000820132642B3E04CDDE19C382013A642B71 :10162000321A2AC321011161282108253E01CDDE8D :1016300019C3820132642B3E04CDDE19C382013A04 :10164000642B321B2AC321013E04CDDE19C3820163 :10165000CD6416C32101CD5C16C321013E04CDDE4D :1016600019C3820111E525CD181E3A162AB7CA778B :101670001611DC25C37A1611E025CD181E1121267E :10168000CD181E3A1A2AB7CA9816FE0111FB25CAB0 :101690009B16110226C39B1611F225CD181E112D83 :1016A00026CD181E3A192AB7CAB11611DC25C3B4C3 :1016B0001611E025CD181E113826CD181E3A182A0D :1016C000B7CACA1611DC25C3CD1611E025CD181EE8 :1016D000115726CD181E3A1B2A118226FE03C2E797 :1016E00016118726C30517FE0CC2F216118C26C3ED :1016F0000517FE09C2FD16119226C30517FE00C28A :101700000517119626CD181E116226CD181E3A38DF :101710002A5F0E02CD0500117726CD181E1147262F :10172000CD181ECD201911BF1ECD181EC9115C0089 :101730003E10CDDE19C33B17C353173A5C00FE20A1 :10174000C24717AF325C00215D00060B363F230510 :10175000C24C173A5C00FE00C25E173A142AC6401B :1017600032552111BF1ECD181E113B21CD181E3E32 :1017700004326C2BCDD518CD000CD28017C30218C3 :101780000E0BCD0500B7CA91170E01CD0500C3029F :1017900018215D000608CDD2173E2ECDC5170603D1 :1017A000CDD217CD7A18216C2B35F5C4B517F1CCF5 :1017B000DE17C37717CDC3173E3ACDC517C3C3177E :1017C000CDC3173E20C5D5E55F0E02CD0500E1D1A2 :1017D000C1C97EE67FCDC5172305C2D217C93E0D0C :1017E000CDC5173E0ACDC5173604C9D1CD181E1177 :1017F000BF1ECD181E3A142A3D5F0E0ECD0500C344 :101800002101AF32792B327A2B3A5C00B7CA171814 :101810003D5F0E0ECD05000E1BCD0500EB2A682B9B :1018200023010000D51A1E0817DA2D1803572B7D47 :10183000B4CA3E187A1DC22818D113C32418D1691E :10184000603A6B2BD603CA4E18293DC24918E511E0 :101850005A21CD181E3A5C00B7C262180E19CD0588 :10186000003CC640326521116521CD181EE1CD46F0 :1018700019116C21CD181EC3EF170E23115C00CD7A :1018800005003A7D006FE607CA8D18C608850F0F60 :101890000FE61F6F16003A7E000FD2A2181E201905 :1018A000E67F0FD2AB181E4019E67F0FD2B4181E88 :1018B0008019E67F677DFE0AF2C118CDC017C3C943 :1018C00018FE64F2C918CDC317CDC317CD46193E13 :1018D0006BCDC517C90E1FCD050023237E326B2BA0 :1018E000237E326A2B23235E2356EB22682BC93ECC :1018F00002115C00CDDE19C32101115C000E11CD77 :1019000005003CC20F1911BB1FCD181EC3210111C8 :101910005C000E13CD0500117B21CD181EC32101E3 :101920003A1C2AFE20F2331911EC20CD181E3A1C65 :101930002AF6400E025FCD0500C90E04CD0500C990 :10194000E1232323E9C9F5C5D5E501F6FF11FFFF22 :101950000913DA5019010A0009EB7CB5C446197B5A :10196000C6305F0E02CD0500E1D1C1F1C9E1E5222B :101970003A2921000039223829EB223C29EB214267 :101980002922C62922C829AF3235293236293EFFFD :10199000323729113129CD181E2A3C29EBCD181ECA :1019A000C92A3829F921422922C8293EFF3237297C :1019B0002A3A29E92A3829F921422922C62922C8A6 :1019C00029AF3235293236293EFF323729113129E4 :1019D000CD181E2A3C29EBCD181E2A3A29E93234AB :1019E00029CD091DFE04CA5C1AFE01CABE1AFE02F8 :1019F000CA131CFE10CA131CFE03CA061DFE05CA2C :101A0000091A11C528CD181EC9EB223E290600CDA2 :101A1000B81DB7F2501AE67FFE1BC2391A0E021E1D :101A200007CD0500AF3235292AC6292B22C6292227 :101A3000C82921362935C30F1AFE3FCA4B1AFE0C9E :101A4000CC111E782A3E29EBC340192135293600D6 :101A5000042A3E297723223E29C30F1ACDB81DB789 :101A6000F0E67FFE1BC2841A0E021E07CD0500AFF2 :101A70003235292AC6292B22C62922C829213629EE :101A800035C35C1AFE3FC2B61A111329CD181E11B8 :101A90003129CD181E2A3C29EBCD181E2AC8293E13 :101AA00024772AC6292B22C629114229CD181EAF18 :101AB000323529C3A119FE0CCC111EC34019224096 :101AC00029EB223E29462322CA292AC82922CC29C9 :101AD00078B7C82ACA295E231D7BFEFFFABF1BCD3B :101AE000B81DB7F2AD1BE67FFE3FC21F1BAF3235FC :101AF00029213629352A4029EBCD181E113129CD4F :101B0000181E2A3C29EBCD181E2AC8293E24772A04 :101B1000C6292B22C629114229CD181EC3A119FEA0 :101B20001BC28E1BAF323529D5C5E5CDDA1BC34D9F :101B30001B0E021E07CD05002AC6292B22C629220C :101B4000C82921362935E1C1D11CC3D81A2AC62992 :101B50002BEBE1E57EFE24CA691B23EB7723EB3AEE :101B600036293C323629C3541B3A36293C323629B1 :101B7000EB3E20772322C62922C829E1E5EBCD18C8 :101B80001E0E021E20CD0500E1C1D1C3A11BE5D56B :101B9000CDDA1BC39F1B11EB28CD181EC3B419D17E :101BA000E11C160019235E23567BC34019FE61FA1F :101BB000B91BFE7BF2B91BE65F5623BACAD81A16C8 :101BC000007BB7F2C81B16FF191103001922CA299E :101BD000052ACC2922C829C3D01A05F81C4B7BB78B :101BE000C81600191E03194623EB2ACA297E914FF5 :101BF000B8CAF51BF02ACC290DFA4019EB4623EBA5 :101C00007E23FE61FA0E1CFE7BF20E1CE65FB8C05E :101C1000C3F81BEB22C2291E0036002322C429AFC1 :101C20003620233CFE0CFA201CCDB81DB7F2741CE4 :101C3000E67FFE3FC2461C21352936002AC6292BE5 :101C400022C629C3EB1CFE1BC2671CAF3235290E0E :101C5000021E07CD05002AC6292B22C62922C82923 :101C600021362935C3A1197BB7CAF71CFE0DF2F73F :101C70001CC34019FE2EC2951C1C7BFE01CAF71C1A :101C8000FE0AF2F71C0E0906002AC2290922C429FD :101C90001E09C3291CFE3AC2B21C1C7BFE02C2F7FD :101CA0001C2AC4292B7ED64022C4292B771E00C3B0 :101CB000291CFE2AC2DA1C7BFE08CAF71CF2C51CCE :101CC0000608C3C71C060C2AC4293E3F772322C43A :101CD000291C7BB8FAC71CC3291CFE30FAF71CFE6E :101CE0007BF2F71CFE41FAEB1CE65F2AC42977233E :101CF00022C4291CC3291C3A3429FE10CA051D110F :101D0000F828CD181EC9C3131CF5D5E53A3529B7F7 :101D1000C2B41D213629340E01CD05002AC629770B :101D20002322C629FE15C2441D11DF26CD181E2A06 :101D30003C29EBCD181E21422922C62921362936FD :101D400000C3A119FE08CA541DFE7FC27B1D11D815 :101D500026CD181E3A36293D3DB7F2671D0E021EEC :101D600007CD0500C3291D32362911DC26CD181EEA :101D70002AC6292B2B22C629C3A119FE3FCA9F1DA3 :101D8000FE1BCA9F1DFE0DCA971DFE0ACA971DFEA7 :101D90000CC2A71DCD111E3A3629FE01CAB4193E48 :101DA000FF323529C3B41DFE20CA131DFE09CA1314 :101DB0001DC3131DE1D1F1C9E5C53A3529B7CC09D9 :101DC0001D2AC8297E2322C829FE20CAD31DFE0948 :101DD000C2E61D3A3729B7C2BA1D3EFF3237293E47 :101DE00020C1E1C30E1EF5AF323729F1C1E1FE1B60 :101DF000CA0E1EFE3FCA051EFE0DCA051EFE0ACAF9 :101E0000051EFE0CC0E52AC8292B22C829E1F68050 :101E1000C911E426CD181EC90E09C305000D0A4ECE :101E2000756D626572206F66207061636B65747397 :101E30003A0D0A4E756D626572206F662072657488 :101E4000726965733A0D0A46696C65206E616D654D :101E50003A0D0A0A2420205B43522072657472797D :101E60002C20205E5820736B69702066696C652C8D :101E700020205E5A20717569742C20205E412061FB :101E8000626F72745D240D0A4E6F697365206F7204 :101E9000204D65737361676573205265636569766C :101EA00065643A244B65726D69742D383020207852 :101EB0003A3E2444656C6574652069743F20240DA6 :101EC0000A240D0A3F556E7265636F676E697A6505 :101ED0006420636F6D6D616E64240D0A3F496C6C04 :101EE0006567616C20636861726163746572240D5B :101EF0000A3F4E6F7420636F6E6669726D6564246D :101F00003F556E61626C6520746F20726563656910 :101F1000766520696E6974696174650D0A243F55A0 :101F20006E61626C6520746F2072656365697665A9 :101F30002066696C65206E616D650D0A243F556EE3 :101F400061626C6520746F207265636569766520D7 :101F5000656E64206F662066696C650D0A243F55C6 :101F60006E61626C6520746F207265636569766569 :101F700020646174610D0A243F4469736B206675A7 :101F80006C6C0D0A243F556E61626C6520746F2085 :101F90007265636569766520616E2061636B6E6F43 :101FA000776C656467656D656E742066726F6D2011 :101FB00074686520686F73740D0A240D0A3F556EAE :101FC00061626C6520746F2066696E642066696C5E :101FD000650D0A243F556E61626C6520746F207236 :101FE000656E616D652066696C65240D0A3F446904 :101FF000736B2066756C6C240D0A3F556E61626CC4 :102000006520746F2074656C6C20686F7374207425 :10201000686174207468652073657373696F6E20DE :1020200069732066696E6973686564240D0A3F559B :102030006E61626C6520746F2074656C6C20686FD3 :10204000737420746F206C6F676F7574240741423E :102050004F525445442407436F6D706C657465643A :1020600024074661696C6564242552656E616D695B :102070006E672066696C6520746F20240D0A5B43CF :102080006C6F73696E6720746865206C6F6720667B :10209000696C655D240D0A5B436F6E6E65637465E4 :1020A0006420746F2072656D6F746520686F73743F :1020B0002C207479706520244320746F207265741D :1020C00075726E5D0D0A240D0A5B436F6E6E65635B :1020D00074696F6E20636C6F7365642C206261633A :1020E0006B206174206D6963726F5D24436F6E7441 :1020F000726F6C2D24202854797065204C656674AD :10210000204172726F7720746F2073656E64204374 :1021100054524C2D53290D0A2420284E6F742069E7 :102120006D706C656D656E746564290D0A240749D0 :102130006E746572727570746564240909202020BC :10214000204469726563746F727920666F722064CF :102150007269766520783A0D0A240D0A09094472DD :102160006976652024202068617320244B206279E1 :1021700074657320667265650D0A240D0A46696CE4 :102180006528732920657261736564240D0A0D0A40 :102190002B2B20426164206472697665206E616D2C :1021A00065240D0A20436F6E6669726D207769742D :1021B0006820636172726961676520726574757207 :1021C0006E202420496E7075742066696C652073DA :1021D0007065632028706F737369626C792077690A :1021E0006C642920240D0A54797065207468652078 :1021F0006E657720657363617065206368617261E5 :10220000637465723A2020240D0A42594520746F88 :1022100020686F737420284C4F474F555429206114 :102220006E64206578697420746F2043502F4D0DC3 :102230000A434F4E4E45435420746F20686F7374A9 :10224000206F6E2073656C656374656420706F72B7 :10225000740D0A45524120612043502F4D2066697C :102260006C650D0A4558495420746F2043502F4D1A :102270000D0A46494E4953482072756E6E696E6765 :10228000204B65726D6974206F6E207468652068DC :102290006F73740D0A48454C502062792067697647 :1022A000696E672074686973206D65737361676513 :1022B0000D0A444952206F662063757272656E7410 :1022C0002075736564204D6963726F2D6469736B4B :1022D0000D0A4C4F4720746865207465726D696EF5 :1022E000616C2073657373696F6E20746F20612059 :1022F00066696C650D0A4C4F474F555420746865EC :1023000020686F73740D0A5245434549564520664F :10231000696C652066726F6D20686F73740D0A5367 :10232000454E442066696C6520746F20686F737435 :102330000D0A534554206120706172616D657465AA :10234000720D0A53484F572074686520706172619E :102350006D65746572730D0A535441545553206F63 :1023600066204B65726D6974240D0A4241756420C4 :102370002872617465290D0A424C6F636B2D636886 :1023800065636B2D747970652028666F72206572A5 :10239000726F7220646574656374696F6E290D0ACB :1023A00044656661756C742D6469736B2028746F65 :1023B00020726563656976652064617461290D0A20 :1023C0004573636170652028636861726163746539 :1023D0007220647572696E6720434F4E4E454354B8 :1023E000290D0A46696C652D6D6F64652028666F3E :1023F00072206F7574676F696E672066696C6573AC :10240000290D0A49626D2028706172697479206112 :102410006E64207475726E2061726F756E642068D0 :10242000616E646C696E67290D0A4C6F63616C2D77 :102430006563686F202868616C662D6475706C65D3 :1024400078290D0A5041726974792028666F7220CC :10245000636F6D6D756E69636174696F6E206C6911 :102460006E65290D0A504F72742028746F20636FB7 :102470006D6D756E6963617465206F6E290D0A5606 :102480007435322D656D756C6174696F6E0D0A5708 :1024900061726E696E672028666F722066696C656E :1024A0006E616D6520636F6E666C69637473292459 :1024B0000D0A5041442D434841520D0A50414444B5 :1024C000494E47240D0A312D43484152414354455A :1024D000522D434845434B53554D0D0A322D434829 :1024E000415241435445522D434845434B53554D6A :1024F0000D0A332D4348415241435445522D435216 :10250000432D4343495454240D0A4556454E094D25 :1025100041524B094E4F4E45094F444409535041D7 :102520004345240D0A4F4646094F4E240D0A4E4F8F :1025300009594553240D0A3F202054686973206DC2 :102540006573736167650D0A432020436C6F736583 :102550002074686520636F6E6E656374696F6E0DBD :102560000A302020287A65726F29205472616E73B8 :102570006D69742061204E554C4C0D0A5320205338 :102580007461747573206F662074686520636F6E64 :102590006E656374696F6E0D0A5479706520746896 :1025A000652065736361706520636861726163743F :1025B000657220616761696E20746F2073656E6457 :1025C00020697420746F2074686520686F73740DBF :1025D0000A0D0A436F6D6D616E643E24206F6E2498 :1025E000206F6666240D0A4C6F63616C206563681A :1025F0006F242064656661756C74242041534349DF :1026000049242062696E617279240D0A415343495D :10261000490942494E4152590944454641554C5495 :10262000240D0A46696C65204D6F6465240D0A49C6 :10263000424D20666C6167240D0A46696C652077FF :1026400061726E696E67240D0A457363617065205F :10265000636861723A20240D0A5061726974793A94 :1026600020240D0A426C6F636B20636865636B20E6 :10267000747970653A20242D6368617261637465B2 :1026800072246E6F6E65246D61726B24737061636A :1026900065246F6464246576656E240D0A53746145 :1026A0007274696E67202E2E2E240D0A47656E65A2 :1026B0007269632043502F4D2D3830204B65726D69 :1026C00069742D38302056332E3620285543423336 :1026D000362E3136290D0A24082008242008245ECD :1026E000550D0A240D0A2420242025240D0A240D2A :1026F0000A240D0A240D0A240F03425945242121DE :1027000007434F4E4E45435424000003444952248E :1027100024240345524124272704455849542403BF :10272000030646494E495348241B1B03474554247E :102730000C0C0448454C50240606034C4F47240912 :1027400009064C4F474F5554241E1E07524543451A :10275000495645240C0C0453454E44240F0F035393 :1027600045542412120453484F5724151506535448 :10277000415455532418180B044241554424212137 :1027800010424C4F434B2D434845434B2D54595019 :10279000452418180C44454641554C542D44495382 :1027A0004B24242406455343415045240000094648 :1027B000494C452D4D4F44452412120349424D24A6 :1027C00003030A4C4F43414C2D4543484F24060612 :1027D0000650415249545924151504504F5254245F :1027E0001E1E0E565435322D454D554C4154494F01 :1027F0004E241B1B075741524E494E47240F0F02D0 :10280000085041442D4348415224000007504144A0 :1028100044494E472403030314312D434841524198 :10282000435445522D434845434B53554D24313174 :1028300014322D4348415241435445522D4348459B :10284000434B53554D24323215332D4348415241A9 :10285000435445522D4352432D434349545424334A :102860003305044556454E240000044D41524B2487 :102870000303044E4F4E45240606034F44442409E7 :1028800009055350414345240C0C02024F4E2401CC :1028900001034F46462400000305415343494924A0 :1028A00001010642494E415259240202074445465D :1028B00041554C5424000002024E4F24000003599D :1028C00045532401010D0A3F50726F6772616D20FC :1028D0006572726F723A2020496E76616C6964206D :1028E000434F4D4E442063616C6C240D0A3F416D93 :1028F000626967756F7573240D0A3F496C6C656773 :10290000616C20696E7075742066696C65207370E7 :1029100065632420436F6E6669726D207769746801 :102920002063617272696167652072657475726E89 :04293000240D0A2444 :092A140000000000010000061C96 :0F2A2C00205E0805000000000D0D23233131311D :022B02000D24A0 :022B790000005A :00010000FF 41524198 :10282000435445522D434845434B53554D24313174 :1028300014322D4348415241435445522D4348459B :10284000434B53554D24323215332D4348415241A9 :10285000435445522D4352432D434349545424334A :102860003305044556454E240000044D41524B2487 :102870000303044E4F4E45240606034F44442409E7 :1028800009055350414345240C0C02024F4E2401CC :1028900001034F46462400000305415343494924A0 :1028A00001010642494E415259240202074445465D :1028B00041554C5424000002024E4F24000003599D :1028C00045532401010D0A3F50726F6772616D20FC :1028D0 VOLUME 018 DESCRIPTION: KERMIT-80 V36.16 WITH CP/M PLUS CONFIGURATION BY BILL WELLS U.C. BERKELEY'S KERMIT-CONVERSATIONAL MONITOR SYSTEM NUMBER SIZE NAME COMMENTS 018.1 2K -EBMMUG .018 DISK NAME & CONTENTS OF VOLUME 018 (APR 4,'85) 018.2 20K CMS .DOC KERMIT-CMS(CONVERSATIONAL MONITOR SYS)MANUAL 018.3 32K CPM .DOC KERMIT-80 MANUAL AND COMMANDS 018.4 2K EBMDIR18.TXT A DIRECTORY OF THIS DISK 018.5 180K MKERMIT .ASM SOURCE CODE FOR KERMIT 018.6 12K MKERMIT .COM KERMIT COMMAND FILE 018.7 30K MKERMIT .HEX HEX FILE FOR KERMIT 018.8 2K README . COMMENTS ABOUT KERMIT AND THESE FILES 018.9 4K UNIX .DOC KERMIT-80 UNIX MANUAL 018.10 2K VT52 .DOC VT52 EMULATION WRITE-UP _7 !p ~87!p  :4=q!CS!7v!4:8:6q6 #:v+!4v8!5~8:4=r!SC KERMIT(1) UNIX Programmer's Manual KERMIT(1) NAME kermit - microcomputer to mainframe communication program SYNOPSIS kermit [ r ] [ s file ... ] DESCRIPTION Kermit is a general purpose terminal emulation and file transfer utility from Columbia University. This version can be used to login to UNIX with your microcomputer, and to copy files from UNIX to your floppy disk (downloading) and vice versa (uploading). The kermit program on UNIX must have a counterpart program running on the micro in order for file transfers to take place. Micro versions differ slightly from one brand to another and only a few brands are currently supported. Only the micro program is needed to conduct a login session without file transfers. The terminal emulation is based on a DEC VT52 terminal without reverse scrolling or hard tabs; use a terminal type of `kermit' (or `pckermit' if you have a 25-line display) if you want the full-screen capabilities of UNIX. On the command line one and only one of the key letters r, for receive, or s, for send, must appear. In send mode, each file will arrive on the micro under the same name capitalized and truncated to 8 letters. Letters, digits, and the characters $&#@!%\'()-{}_^~|` are legal in a filename, and a 3-letter extension following a `.' is recognized. If the standard input is piped or redirected from a file, the standard input is collected and placed in a file on the micro corresponding to the first file listed. EXAMPLES Although the UNIX version of kermit is non-interactive, most micro versions are interactive and understand the following subcommands: send, receive, connect, exit, and help. On the micro you type mkermit to run the micro version of kermit and exit to return to the micro. Once you are running the micro version, the connect command allows you to initiate or continue a login session on UNIX and the 2-character sequence ^\c (control-\ followed by `c') returns you to the micro version. Logging-in: To initiate a login session, turn on the micro, put the disk containing mkermit in the A drive, and put your own formatted disk in the B drive. Then run mkermit and login as shown below (what you type is in boldface; annotations appear in italics). A>b: # Switch to your disk. B>a:mkermit # Run mkermit. Kermit-80> # The mkermit prompt; differs between micros. Kermit-80>connect # Tell it you want to connect to UNIX. # Connect: dial-in or press port-selector button. ... # Messages, etc., then a request for terminal type. TERM = (tvi920c): kermit # Terminal type is `kermit' or `pckermit'. T # Now you can send, receive, or just compute. % Downloading: Login as described above and refer to the examples below. % kermit s frog # Send file `frog'. ^\c  # Kermit pauses and you return to micro. Kermit-80>receive # Set up micro to receive file. Other examples of kermit ``send'' commands are: % kermit s *.for # Send all FORTRAN files. % tar cf - . | kermit s mydir # Send current directory subtree. Uploading: Login as described above and refer to the examples below. % kermit r # Set up UNIX to receive files. ^\c # Kermit pauses and you return to micro. Kermit-80>send *.for # Send all FORTRAN files. SEE ALSO upload(1) BUGS ----- Unix manual page dated 14 June 1983, control-] escape character changed to control-\ and page reformated 24 Apr 1984 - W.C.W. erminal type is `kermit' or `pckermit'. T # Now you can send, receive, or just compute. % Downloading: Login as described above and refer to the examples below. % kermit s frog # Send file `frog'. ^\c The VT52 emulation provided by CP/M kermit-80 (gts 02-05-84) --------------------------------------------- ------------- Kermit provides emulation ONLY for certain display output, no input translation is provided. esc description termcap 925 adm3a Kaypro TRS80pt ----- -------------- ------- ------ ----- ------ ------- A cursor up up ^K ^K ^K \036 B cursor down do ^V LF LF \037 C cursor right nd ^L ^L ^L \035 D cursor left bs ^H ^H ^H \034 E clear screen cl ^Z ^K ^Z \014 F enter graphics esc G \021 G exit graphics esc G \024 H cursor home ho ^^ ^^ ^^ \006 I reverse LF sr esc j ^K ^K \036 J clear to eos cd esc Y \027 \002 K clear to eol ce esc T \028 \001 Y r c cursor: cm esc = esc = esc = esc Y row column r c r c r c r c Esc A, B, C and D stop at the top, bottom, right and left of the screen; line-feed and reverse-line-feed scroll at bottom or top. Hence, LF for esc B and ^K for esc I do not work exactly right (Kaypro and Adm3a). This is UCB version 36.16 of Kermit-80 for CP/M Plus Systems (13 Feb 84). The 'mkermit.com' and 'mkermit.hex' files have been assembled with 'cpm3' and 'ucbibm' set to TRUE. The 'ucbibm' option turns off xon handling to permit access to IBM mainframe via "cal" portselector service at the University of California at Berkeley. This version also contains numerous "UCB" fixes. This diskette contains more than you need to know. To use Kermit-80, just copy mkermit.com to one of your system diskettes. cms.doc Kermit-CMS manual. cpm.doc Kermit-80 manual. mkermit.com Kermit-80 com file. unix.doc Kermit-UNIX manual. vt52.doc VT52 emulation write-up. The vt52 emulation is not used in this CP/M Plus version of mkermit. The vt52.doc information is provided for those assembling mkermit where vt52 emulation is required. 24 Apr 1984 e assembling mkermit where vt52 emulation is required. 24 Apr 1984  Files: 10 space used: 284k (102k free) -EBMMUG .018 2k : EBMDIR18.TXT 0k : MKERMIT .HEX 30k : VT52 .DOC 2k CMS .DOC 20k : MKERMIT .ASM180k : README . 2k : CPM .DOC 32k : MKERMIT .COM 12k : UNIX .DOC 4k : J6!_7t!:; ͂7?r JpQpWp4EDBACKUP$$$BAKNEW FILE:/25bp͒p͡pOqZ1:4:b2f5>0q:2i52g5:I!ڈp~<2k5>24!vi.>2vC!p ̀ʾp!p ̀p!8"J6×-!v.!6.292F2I2[[-*7"v"7p*7*7R|<2 72 7|D!"7>2 7%q)"7,q2 7!5wȷ!  .>2%!:C6!4̗!:~ͣwv:Jtqw::ʀq>26_7 !p ~87!p  :4=q!CS!7v!4:8:6q6 #:v+!4v8!5~8:4=r!SC VOLUME 018 DESCRIPTION: KERMIT-80 V36.16 WITH CP/M PLUS CONFIGURATION BY BILL WELLS U.C. BERKELEY'S KERMIT-CONVERSATIONAL MONITOR SYSTEM NUMBER SIZE NAME COMMENTS 018.1 2K -EBMMUG .018 DISK NAME & CONTENTS OF EBMMUG VOL. 018 018.2 20K CMS .DOC KERMIT-CMS(CONVERSATIONAL MONITOR SYS)MANUAL 018.3 32K CPM .DOC KERMIT-80 MANUAL AND COMMANDS 018.4 2K EBMDIR18.TXT A DIRECTORY OF THIS DISK 018.5 180K MKERMIT .ASM SOURCE CODE FOR KERMIT 018.6 12K MKERMIT .COM KERMIT COMMAND FILE 018.7 30K MKERMIT .HEX HEX FILE FOR KERMIT 018.8 2K README . COMMENTS ABOUT KERMIT AND THESE FILES 018.9 4K UNIX .DOC KERMIT-80 UNIX MANUAL 018.10 2K VT52 .DOC VT52 EMULATION WRITE-UP  015.46 80K XMDM .LBR LIBRARY OF XMODEM PROGRAMS INC 015.47 2K ZENITH37.ASM SOURCE FOR THE ZENITH 37 FMT DEVELOPMENT   !!""##$$%%&&''