diff options
| author | Jeff Armstrong <jeff@approximatrix.com> | 2026-10-25 17:42:06 -0400 |
|---|---|---|
| committer | Jeff Armstrong <jeff@approximatrix.com> | 2026-10-25 17:42:06 -0400 |
| commit | ebb2ff2af569d5822b70ee555a32d27cf7494816 (patch) | |
| tree | 7ac5e7b3fa73f7a8d996129086932ecce66374ad /src/cpxsys.asm | |
| download | kermit-80-main.tar.gz kermit-80-main.zip | |
Diffstat (limited to 'src/cpxsys.asm')
| -rw-r--r-- | src/cpxsys.asm | 1386 |
1 files changed, 1386 insertions, 0 deletions
diff --git a/src/cpxsys.asm b/src/cpxsys.asm new file mode 100644 index 0000000..0b179b9 --- /dev/null +++ b/src/cpxsys.asm @@ -0,0 +1,1386 @@ +IF NOT lasm +.printx * CPXSYS.ASM * +ENDIF ;NOT lasm +; KERMIT - (Celtic for "FREE") +; +; This is the CP/M-80 implementation of the Columbia University +; KERMIT file transfer protocol. +; +; Version 4.0 +; +; Copyright June 1981,1982,1983,1984,1985 +; Columbia University +; +; Originally written by Bill Catchings of the Columbia University Center for +; Computing Activities, 612 W. 115th St., New York, NY 10025. +; +; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben, +; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many +; others. +; +; This file contains the system-dependent code and data for KERMIT. +; It will be probably be broken into independent files to generate +; overlays for the various systems, one or more overlay possible +; from each file. For now, we will leave it in one piece. +; +; revision history: +; +; +; Edit 40, 28-Aug-89 by Mike Freeman of Bonneville Power Administration, +; P.O. Box 491, Vancouver WA 98666 USA, Telephone (206)690-2307: +; Home address: 301 N.E. 107th Street; Vancouver, WA 98685 USA +; Home telephone: (206)574-8221 +; added support for Hewlett-Packard HP-125 Business Assistant computer +; running a HP-modified CP/M Version 2.2; communications on +; DAta Comm 1 or Data Comm 2 (8th-bit quoting must be used on +; Data Comm 2 to transfer binary files as Data Comm 2 only supports +; a 7-bit data path); printer cannot be used with communications on +; Data Comm 2 (the printer port). +; edit 39, 4 August, 1987b by OBSchou for Charles Lasner re. DECMATE II +; fixes to set xon/off control off for the duration of Kermit-80. +; +; His header reads: +; +; IBM mode restore program +; +; This routine must be run after using CP4DMF (and KERMIT-80) to restore +; the normal handling of XON/XOFF; the user may also elect to cold-boot +; the DECMATE instead. +; +; acknowledgments and limitations. +; +; This program is based on DECMATE specific implementation details +; provided by Walt Lamia of DEC. It is of course, specific to DECMATE +; implementations of CP/M-80 for DECMATE II, III, III-plus, etc. +; +; usage consists of merely: +; +; CP4DMF run xon/xoff disable program +; KERMIT80 then run kermit +; <KERMIT-80 commands used normally here, including SET IBM ON> +; CP4DMU run this program to restore normal XON +; +; unless CP4DMU is run following KERMIT-80, the normal handling of +; XON/XOFF provided by KERMIT-80 will not work (cold boot is another +; alternative). +; +; [Note - These edits now included in the init/de-init code] +; +; edit 38, 23 July, 1987 by OBSchou. Moved out commonly used code +; to CPXCOM.ASM, and adjusted this (ond other family) files accordingly. +; Also filtered out code now in other family files. +; +; edit 37 , 15 July 1987 by OBSchou for David Moore, who has submitted +; code for Teletek SYSTEMASTER (teletek) and for an ADM 22 terminal. +; +; edit 36 28 Jan 87 by OBSchou. +; Removed the printx etc and should only have this file if a system +; does not have a family file. +; +; edit 35 1st Dec 1986 by OBSchou. Added test for Amstrad PCW range (PCW) +; Links to CPXPCW.ASM, which was submitted by Ian Young, Lattice +; Logic Systems. +; +; edit 34 20 August by OBSchou for Brian Robertson, Aberdeen University: +; I have discovered a bug in my code for the BBC/Z80 version of Kermit. +; At startup the transmitter baud rate is read from the serial ULA. +; The TX and RX baud rates are then reset to this value and the +; value is stored in location 'baud:' for the STATUS (or SHOW) +; command. That is how it is supposed to work ! Unfortunately +; my code at present "misreads" the initial TX baud rate - there +; is some bit manipulation that needs to be done to extract the +; correct value. +; +; edit 33 30-May-86 OBSchou. Added two new enties to the overly. One for +; printer status and the other for the address of the family of +; computer using the overlay. If it is still in CPXSYS.ASM then it +; is a dollar only. +; +;edit 32, 27 May, 1986 by OBSchou Loughborough University for +; B Robertson, Aberdeen Univ. Computing Centre. Any mistakes my fault. +; Add support for APPLE II with serial cards based on the 6850 ACIA. +; Mod 380Z support to allow both MDS (5 1/4" discs) and FDS (8" discs) +; configurations. +; +; edit 31, 22 April, 1986, OBSchou. +; Kermit version 4.06 starts here. All previous edits have been +; put aside (leave in a BWR file?). Hived off some definitions +; to the CPSDEF.ASM file as that is where they belong. +; Start on splitting off individual +; systems from this huge file. It is done using the LINK facility +; LASM. We link to a collection of systems under CPXxxx.ASM. +; I have started with the systems I know, the Torch, Cifer and +; pci2651. These will all be held under CPXTOR.ASM +; +; +; Keep module name, edit number, and last revision date in memory. +family: db 'CPXSYS.ASM (40) 28-Aug-89 $' ; now a family... +; + + +; Processor speed in units of 100KHz +; for cpt85xx, advance, apple,bbc,px8 & rm380z timing loop [12] +IF rm380z +cpuspd SET 40 ; 4.0 MHz CPU +ENDIF; rm380z + +IF disc OR mmate OR s1008 OR access +cpuspd SET 40 ; 4.0 MHz CPU +ENDIF ;disc OR mmate OR s1008 OR access + +IF bbc ;[9] +cpuspd SET 60 ; BBC with 6Mhz Z80 +ENDIF;bbc + + +; the basics... + +IF gener +batio EQU 056H ;I/O byte CON=BAT,LIST=CRT,READER=RDR,PUNCH=PTP +defio EQU 095H ;I/O byte CON=CRT,LIST=LPT,READER=RDR,PUNCH=PTP +crtio equ 01010101B ; use CRT: device +ptrio equ 01010110B ; use PTR: device +ttyio equ 00000000B ; use TTY: device +uc1io equ 01010111B ; use UC1: device +ur1io equ 01101010B ; use UR1: device +ur2io equ 01111110B ; use UR2: device +ENDIF;gener + +IF robin +batio EQU 056H ;I/O byte CON=BAT,LIST=CRT,READER=RDR,PUNCH=PTP +defio EQU 095H ;I/O byte CON=CRT,LIST=LPT,READER=RDR,PUNCH=PTP +lptio EQU 054H ;I/O byte CON=TTY,LIST=CRT,READER=PTR,PUNCH=PTP +gppio EQU 057H ;I/O byte CON=UC1,LIST=CRT,READER=RDR,PUNCH=PTP +ENDIF;robin + + +IF dmII OR bbc ;[22] +batio EQU 042H ;I/O byte CON=BAT,LIST=CRT,READER=RDR +defio EQU 081H ;I/O byte CON=CRT,LIST=LPT,READER=RDR +ENDIF;dmII + +IF mikko +batio EQU 10110010B ; I/O byte console => serial line +defio EQU 10000001B ; I/O byte console => CRT and Keyboard +ENDIF;mikko +; +IF lobo ;[hh] +mnport EQU 0F7E4H ;Modem data port A +mnprts EQU 0F7E5H ;Modem status/conrtol port A +baudrt EQU 0F7D0H ;Baud rate port A +output EQU 04H ;Transmit buffer empty +input EQU 01H ;Receive data available +z80 SET TRUE ;a good z80, here +ENDIF;lobo + +IF osi +mnport EQU 0CF01H ;Modem data port +mnprts EQU 0CF00H ;Modem status port +output EQU 02H ;Transmitter empty +input EQU 01H ;Input data available +z80 SET FALSE ;I don't know... +ENDIF;osi + +IF vector +mnport EQU 04H ;Modem data port +mnprts EQU 05H ;Modem status port +output EQU 01H ;Transmitter empty +input EQU 02H ;Input data available +z80 SET FALSE ;I don't know... +ENDIF;vector + +IF delphi ;[7] +mnport EQU 22H ;[7] Modem data port +mnprts EQU 23H ;[7] Modem status port +output EQU 01H ;[7] Transmitter empty +input EQU 02H ;[7] Input data available +baudrt equ 29h ;[7] Baud rate port for channel 2 (default) +z80 SET true ;[7] We're using the z80 side of the dual processor +ENDIF;[7] delphi + +IF trs80 +;NEEDS display definition (e.g. trs80lb or trs80pt) +mnport EQU 0F4H ;Modem data port (0F5H for port B) +mnprts EQU 0F6H ;Modem status port (0F7H for port B) +output EQU 04H ;Transmitter empty +input EQU 01H ;Input data available +z80 SET TRUE ;[hh] All TRS-80's but the CoCo +ENDIF;trs80 + +IF teletek +mnport EQU 00H ;Modem data port (02 for port B (console)) +mnprts EQU 01H ;Modem status port (03 for port B (console)) +baudrt EQU 08H ;ctc0 control port (09 for port B (console)) +output EQU 04H ;Transmitter empty +input EQU 01H ;Input data available +z80 SET TRUE ;All Teleteks +ENDIF;teletek + +IF osbrn1 +;Osborne 1 uses 6850 ACIA, but memory mapped. Derived from Apple. +BAUDRT EQU 0EFC1H ;Memory location where baud rates are stored. +OSTOP EQU 4000H ;Where we move OSMOVE to at startup +OSPORT EQU 2A01H ;Communications Port. +OSPRTS EQU 2A00H ;Communications Port Status. +OUTPUT EQU 02H ;Output Buffer Empty. +INPUT EQU 01H ;Input Register Full. +OSBIN1 EQU 57H ;First Init Character for 6850 ACIA (Reset) +;(I would have thought 03, but prom code writes 57 there) +OSBI12 EQU 55H ;Second Init Character for ACIA (8-bits, 1200) +OSBI03 EQU 56H ;Second init char. for ACIA (8 bits, 300) +;(don't ask.. I don't know why SETUP writes 55 and 56 either) +z80 SET TRUE ;[hh] a z80 here, also +ENDIF;osbrn1 + +IF robin +;Those definitions below that are commented out are just for information +;***** NOT generally found in distributed documentation **** + +;pbausl EQU 90H ;The Baud-Rate register. +prntst EQU 49H ;Printer +;prndat EQU 48H +contst EQU 41H ;Console +;condat EQU 40H +gentst EQU 51H ;General port. +;gendat EQU 50H +comtst EQU 59H ;COMM-Port +;comdat EQU 58H +;output EQU 01H ;Output ready bit. +;input EQU 02H ;Input ready bit. +z80 SET TRUE ; This one's a Z80. +ENDIF;robin + +IF s1008 ;[29] +mnport equ 00 ;printer port data +mnprts equ 01 ;printer port status +output equ 4 ;transmitter ready +input equ 2 ;receiver ready +z80 equ FALSE ;not important +ENDIF;s1008 [29] + +IF mmate ;[29] +mnport EQU 89H ;MODEM data port +mnprts EQU 8BH ;MODEM status/control port +output EQU 04H ;Transmit buffer empty, ready to send +input EQU 01H ;Receive data available +baudrt EQU 93H ;MODEM baud rate port + ;NOTE - also used for console +z80 SET TRUE +ENDIF;mmate [29] + +IF disc ;[29] +mnport EQU 05 ;Discovery 83U port B data +mnprts EQU 04 ;Discovery 83U port B status/command +output EQU 04 ;Transmit buffer empty +input EQU 01 ;Receiver ready +z80 SET TRUE +ENDIF;disc [29] + +IF cmemco ;[25] +tuart EQU 020H ;TU-ART address +mnport EQU tuart+1 ;Modem data port +mnprts EQU tuart ;Modem status port +output EQU 080H ;Transmitter empty +input EQU 040H ;Input data available +baudrt EQU tuart ;Baud rate port +;Note: Needs terminal definition +z80 SET TRUE ;This one's a Z80. +ENDIF;cmemco + +IF cpt85xx +baudrt EQU 4Ch ; Baud rate generater (National MM5307) +mnport EQU 4Bh ; Comm port data register (Intel 8251) +mnprts EQU 4Ah ; Comm port command/status register +output EQU 01h ; Transmitter buffer empty flag +input EQU 02h ; Reciver buffer full flag +TxEmpty EQU 04h ; Transmitter empty flag +z80 SET FALSE ; It's really an 8080 [or 8085 ... same thing] +ENDIF;cpt85xx + +IF mmdI ;Morrow MicroDecision - the single-board one +mnport EQU 0FEH ;Morrow Printer UART data port +mnprts EQU 0FFH ;Morrow Printer UART command/status +output EQU 01H ;Output ready bit. +input EQU 02H ;Input ready bit. +;Note: Needs terminal definition +z80 SET FALSE ;I don't know... +ENDIF;mmdI + +IF bbc ;[22] +osbyte EQU 0FFF4H ; OS entry point +osword EQU 0FFF1H ; " " " +term EQU 0FFC8H ;Terminal mode OS entry +z80 SET TRUE +ENDIF;[22] bbc + +;Two types of 380Z system +IF rm380zm ;[27] MDS - 5 1/4" discs +mnport EQU 0C8H ;Modem data port +mnprts EQU 0C9H ;Modem status port +ENDIF;[32] rm380zm + +IF rm380zf ;[32] FDS - 8" discs +mnport EQU 0E8H ;Modem data port +mnprts EQU 0E9H ;Modem status port +ENDIF;[32] rm380zf + +IF rm380z ;[32] Common to both systems +output EQU 01H ;Transmitter buffer empty +input EQU 02H ;Input data available +TxEmpty EQU 04h ;Transmitter empty flag +z80 SET TRUE +ENDIF;[22] rm380z + +IF px8 ; [29] +z80 SET TRUE +mnprts EQU 0dh ; used in sending a break +ENDIF ;px8 [29] + +IF mdI ;Morrow Decision I - the big sucker +mnport equ 48H ; Modem data port. +mnprts equ 4DH ; Modem status port. +output equ 20H ; Transmitter empty. +input equ 1 ; Input data available. +mbase equ 48H ; Base address of Multi I/O port + ; selector area. +grpsel equ 4FH ; Group select port. +rbr equ 48H ; Read Data Buffer. +group equ 1 ; Multi I/O Group byte for serial ports. +congrp equ 1 ; Serial Port 1 for console +mdmgrp equ 3 ; Serial Port 3 for modem. + +; Following are needed for baud rate changes...[Toad Hall] + +dlm equ 49H ; Baud Rate Divisor (Most Sig Bit) +dll equ 48H ; Baud Rate Divisor (Least Sig Bit) +ier equ 49H ; Interrupt Enable Register +lcr equ 4BH ; Line Control Register +lsr equ 4DH ; Line Status Register +msr equ 4EH ; Modem Status Register +dlab equ 80H ; Divisor Latch Access Bit +wls0 equ 1 ; Word Length Select Bit 0 +wls1 equ 2 ; Word Length Select Bit 1 for 8 bit word +stb equ 4 ; Stop bit count - 2 stop bits +imask equ 0 ; Interrupt mask (all disabled) +z80 SET TRUE ; This one's a Z80. +ENDIF ;mdI NOTE: needs terminal definition. [Toad Hall] + +IF mikko +sioac EQU 0FF12H ;SIO channel A register(s) address +sioo3 EQU 01000001B ;SIO Write Reg. 3 original setup (?) + ;RX 7 bits,synch mode bits 0,RX enable +sion3 EQU 11001111B ;SIO Write Reg. 3 KERMIT setup + ;RX 8 bits,synch mode bits 0,RX enable +sioo4 EQU 01001111B ;SIO Write Reg. 4 original setup (?) + ;X16 clock,8 bit synch(ignored), + ;2stop bits,par even(on) +sion4 EQU 01000100B ;SIO Write Reg. 4 KERMIT setup + ;X16 clock,8 bit synch(ignored), + ;1stop bit,par off +sioo5 EQU 10101010B ;SIO Write Reg. 5 original setup (?) + ;DTR,TX 7 bits,TX enable,RTS +sion5 EQU 11101010B ;SIO Write Reg. 5 KERMIT setup + ;DTR,TX 8 bits,TX enable,RTS +txclk EQU 0FF30H ;Baud rate generator (CTC) for transmitter +rxclk EQU 0FF31H ;Baud rate generator (CTC) for receiver +chmask EQU 0F1F2H ;Mask byte address for SIO ch. A reception +z80 SET TRUE ;It's got a SIO and a CTC, it must be a Z80 +ENDIF;mikko + + +IF access ;[29] +mnport EQU 40H ;Modem data port A +mnprts EQU 42H ;Modem status/conrtol port A +output EQU 04H ;Transmit buffer empty +input EQU 01H ;Receive data available +z80 SET TRUE ;a good z80, here +ENDIF;access [29] + + +IF robin OR dmII +z80 SET TRUE ; This one's a Z80 +ENDIF;robin OR dmII + +IF hp125 ;[MF] +z80 SET TRUE ;HP-125 uses a Z80 +ENDIF;hp125 [MF] + +IF gener OR cpm3 ; To be truly generic, we must assume 8080. +z80 SET FALSE +ENDIF;gener OR cpm3 +; +IF osi +defesc EQU ']'-100O ;The default escape character. +ENDIF; osi + +IF vector +defesc EQU '~' ;Vector can't type ']'. +ENDIF;vector + +IF mikko OR osbrn1 OR lobo +defesc EQU '\'-100O ;The default is Control \ -- it's easier B.E. +ENDIF;mikko OR osbrn1 OR lobo + +IF cpt85xx +defesc EQU '\'-100O ;Still Control-\ (just ran out of room...) +ENDIF;cpt85xx + +IF bbc OR rm380z OR px8 OR access OR S1008 ;[22] [29] +defesc EQU '\'-100O ;Still Control-\ (just ran out of room...) +ENDIF ;bbc OR rm380z OR px8 OR access OR s1008[29] + +IF trs80 +defesc EQU '_'-100O ;CTRL-_ (Down-arrow on TRS-80 keyboard) +ENDIF;trs80 + +; Select initial setting for VT-52 emulation flag. + +IF vt52 ; If console looks like (or is) VT52 +vtval EQU 0 ; we don't need VT52 emulation +ENDIF;vt52 + +; If none of the above, default to VT52-EMULATION ON. +IF NOT (crt OR vt52 OR robin OR dmII OR vt100 OR hp125);[MF] +vtval EQU 1 +ENDIF;NOT (crt OR vt52 OR robin OR dmII OR vt100 OR hp125)[MF] + + +; sysxin - system dependent initialisation code, called from SYSINIT +; +sysxin: + +IF dmII +; edit added by OBSchou for C. Lasner. If this dont work, tell me whats +; wrong, as I have no DMII or IBM to play with +; +; IBM mode fixup program +; +; This routine must be run before attempting to use KERMIT-80 with half +; duplex KERMIT implementations such as CMS-KERMIT, as the 6120 processor +; will otherwise "swallow" the XON character. +; +; acknowledgments and limitations. +; +; This program is based on DECMATE specific implementation details +; provided by Walt Lamia of DEC. It is of course, specific to DECMATE +; implementations of CP/M-80 for DECMATE II, III, III-plus, etc. +; +; usage consists of merely: +; +; CP4DMF run this program +; KERMIT80 then run kermit +; <KERMIT-80 commands used normally here, including SET IBM ON> +; CP4DMU run companion program to restore normal XON +; +; unless CP4DMU is run following KERMIT-80, the normal handling of +; XON/XOFF provided by KERMIT-80 will not work (cold boot is another +; alternative). +; +; CP4DMF.ASM +; +; last edit: 12-jun-87 20:00:00 Charles J. Lasner (CJL) + +;oboff equ 3fh ; offset of outbyt routine for 6120 +;prtctl equ 02h ; port control +nocoxon equ 001h ; turn off comm. output XON + + lxi b,(nocoxon * 100h) + prtctl ; c/prtctl, b/no out. xon + call outbyt + ret ; and return + +;outbyt has been catered for (in break routine) +ENDIF ;dmII + +IF osbrn1 ;(Note now no longer needs code > 4000h as it is already there +; lxi d,ostop ;where we're moving it to +; lxi h,osmove ;what we're moving +; mvi b,osmct ;How many bytes we're moving +; call mover + lda baudrt ; Find out what speed is current + ani 1 + mvi a,osbi03 ; assume 300 baud + jz osstr1 + mvi a,osbi12 ; nope, it's 1200. +osstr1: sta speed ; save initial speed + sta speed+1 ; as 16 bits, to match speed table entries + mov d,a + mov e,a ; get initial speed in DE + call sysspd ;set up parity etc. +ENDIF;osbrn1 + +IF cpt85xx + mvi a,80h ; Send UART reset [force idle] by setting + out baudrt ; bit 7 of baud rate I/O port + lxi H,0f0fh ; Clear reset and default to 9600 baud [23] + shld speed ; store current speed + xchg + call sysspd ; set default baud rate + mvi a,4Eh ; Set UART mode to async 16x clock, 8 data + out mnprts ; bits, no parity, and 1 stop bit + mvi a,37h ; Set command to Tx enable, DTR on, Rx enable, + out mnprts ; break off, error reset, and RTS on +ENDIF ; cpt85x + +IF bbc ;[22] + lxi d,modstr ; Set MODE 3 + call prtstr + mvi a,1 ; Set terminal mode on + call term + mvi a,0F2H ; Read current transmit speed + lxi h,0FF00H ; .. 3 lsb of ULA register + call osbyte ; FX242,0,255 + mov a,l + ani 7 ; Mask of 3 lsb +; +; Edit of July 22, 1986 by B Robertson, Aberdeen Univ. Computing Centre. +; Correct bug in sysinit for BBC - reads the initial baud rate at +; start up incorrectly. +; +; + rar ; Reverse order of 3 lsb + rar ; Bit2 now in bit0 + jnc binit1 ; + ori 2 ; Restore bit1 +binit1: ana a ; Set sign bit as appropriate + jp binit2 ; + ori 4 ; Bit0 now in bit2 +binit2: ani 7 ; Mask off unwanted bits +; End of Edit + + xri 7 ; Stored as 2's complement + inr a + sta speed ; Store 16 bit value + sta speed+1 + mov e,a ; Ensure RX and TX speeds are the same + call sysspd +ENDIF;[22] bbc + +IF rm380z ;[22] + mvi e,11h ;Output ctrl-Q to clear autopaging + call outcon +ENDIF;[22] rm380z + + +IF lobo ;[hh] + lxi d,siotbl ;[hh] address of status table + mvi c,siolen ;[hh] length of the table +siolup: ;[hh] loop here for each command byte + ldax d ;[hh] load first byte into A + inx d ;[hh] index pointer to next bute + sta mnprts ;[hh] send it to status port A + sta mnprts+2 ;[hh] and to status port B + dcr c ;[hh] decrement the counter + jnz siolup ;[hh] loop back for more commands + mvi a,05H ;[hh] value for 300 baud + sta baudrt ;[hh] starting default for port A + sta baudrt+4 ;[hh] and for port B + sta speed ;[hh] tell program they're set + mvi a,0E4H ;[hh] value for port A + sta port ;[hh] tell program we've set this, too + mvi a,0D0H ;[hh] port A baud rate value + sta port+1 ;[hh] save this as well, for consistancy +ENDIF ;lobo + +IF mikko + lxi d,mintbl ;Address of KERMIT Reg values (what) + mvi c,minlen ;Length of table (how many) + lxi h,sioac ;Send data to ch. A SIO registers (to where) + call movmik + mvi a,0FFH ;Set ch. A mask to use all bits + sta chmask +ENDIF;mikko + +IF mdI + lxi h,96 ;Default 1200 baud modem port speed + shld speed ;Store as modem port speed + call sysspd ;Initialize the port +ENDIF;mdI [Toad Hall] + +IF cmemco ;[25] + mvi a,01h ; Reset TU-ART + out tuart+2 + mvi a,90h ; Set default baud rate (2400), and 1 stop bit + out tuart + sta speed ; save for status display + sta speed+1 +ENDIF;cmemco + +IF delphi ;[7] +; +; shove the default baud rate (1200) in to the Delphi port address +; for the baud rate generator on port 2, the default port; save this +; value so we can tell what speed is selected. +; + mvi a,07h ;[7] get value for 1200 baud + out baudrt ;[7] set it for port 2 + sta speed ;[7] save for status display + sta speed+1 +ENDIF;[7] delphi + +IF px8 ; [29] + lda 0f6a9h ; get baud rate value set by CONFIG + sta px8blk+4 ; put into parameter block + mov h, a ; initialise global speed indicator + mov l, a + shld speed + lhld 6 ; base of CP/M +; buffer starts at ovlend+8192, immediately after sector buffer +; We must also allow (800h) for the CCP as Kermit exits with a RET + lxi d, ovlend+8192+800h ; calc buffer length + ora a ; clear carry + db 0edh, 52h ; sbc hl, de + shld px8blk+2 + call rsopen +ENDIF ; px8 [29] + +IF disc ;[29] +;Initialization sequence for Discovery 83U port B +;Sets port to 9600 baud, 8 data bits, 1 stop bit, no parity + mvi a,12 ;Register 12 + out mnprts + mvi a,11 ;Low byte of time constant for 9600 + out mnprts + mvi a,13 ;Register 13 + out mnprts + mvi a,0 ;High byte of time constant for 9600 + out mnprts + mvi a,14 ;Register 14 + out mnprts + mvi a,3 ;Enable baud rate generator + out mnprts + mvi a,11 ;Register 11 + out mnprts + mvi a,52h ;No Xtal, tclk=rclk=/trxc out=br gen + out mnprts + mvi a,4 ;Register 4 + out mnprts + mvi a,44h ;16x clock, 1 stop, no parity + out mnprts + mvi a,3 ;Register 3 + out mnprts + mvi a,71h ;rx 8 bit/ch, autoenable, rx enable + out mnprts + mvi a,5 ;Register 5 + out mnprts + mvi a,0eah ;tx 8 bit/ch, tx enable, rts + out mnprts +ENDIF;disc [29] +; +; +IF mikko ;currently for MIKROMIKKO only +; copy command block into memory-mapped SIO. +movmik: di ;disable interrupts +movmk1: ldax d ;Get a register value + mov m,a ;Output it + inx d ;Next value + dcr c ;Decrement counter + jnz movmk1 ;Repeat until done + ei + ret +ENDIF;mikko + +; +IF osbrn1 +osmove: +osflag equ 0EF08H ;Osborne 1 Bank-2 flag +; +; return modem status in A +; +OSLDST: + DI + OUT 0 + LDA osprts ;Read the status port + OUT 1 + EI + ret +; +; set modem status from A +; +OSSTST: + DI + OUT 0 + STA osprts ;Write the control port + jmp osstex +; +; read character from modem into A +; +OSLDDA: + DI + OUT 0 + LDA osport + OUT 1 + EI + ret +; +; output character in A to modem +; +OSSTDA: + DI + OUT 0 + STA osport +osstex: + OUT 1 + mvi a,1 + sta osflag + EI + ret +ENDIF;osbrn1 + +IF lobo +; List of commands to set up SIO channel A for asynchronous operation. +siotbl: DB 18H ; Channel reset + DB 18H ; another, in case register 0 wasn't selected + DB 04H ; Select register 4 + DB 44H ; 1 stop bit, clock*16 + DB 01H ; Select register 1 + DB 00H ; No interrupts enabled + DB 03H ; Select register 3 + DB 0C1H ; Rx enable, 8 bit Rx character + DB 05H ; Select register 5 + DB 0EAH ; Tx enable, 8 bit Tx character, + ; raise DTR and RTS +siolen equ $-siotbl ; length of command list +ENDIF;lobo + +IF mikko +; command list to set SIO chip back to normal state +miotbl: db 3 ;reg. 3 + db sioo3 + db 5 ;reg. 5 + db sioo5 + db 4 ;reg. 4 + db sioo4 + db 0 ;reselect reg. 0 +miolen equ $-miotbl ;MikroMikko SIO table length (original values) + +; command list to set up SIO chip for operation with Kermit +mintbl: db 3 ;reg. 3 + db sion3 + db 5 ;reg. 5 + db sion5 + db 4 ;reg. 4 + db sion4 + db 0 ;reselect reg. 0 +minlen equ $-mintbl ;MikroMikko SIO table length (KERMIT values) +ENDIF;mikko + + +IF bbc ;[22] +modstr: db 16h,03h,'$' ; String to put screen into MODE 3 +ENDIF + +IF px8 ; [29] +rsget: mvi b, 50h + jmp rsiox +rsinst: mvi b, 30h + jmp rsiox +rsput: mvi b, 60h + jmp rsiox +rsoutst:mvi b, 40h + jmp rsiox +rserst: mvi b, 90h + jmp rsiox +rsopen: lxi h, px8blk ; copy px8blk to px8prm + lxi d, px8prm + lxi b, 9 + call mover + mvi b, 10h ; open code + jmp rsiox +rsclose:mvi b, 20h ; close code +rsiox: lxi h, px8prm + lxi d, 51h ; offset into BIOS jump table + push h + lhld 1 ; start of BIOS + dad d + xthl ; entry point on stack, px8prm addr in hl + ret ; jump indirect + +px8prm: dw 0, 0 + db 0, 0, 0, 0, 0 ; the param area is overwritten in rsopen +px8blk: dw ovlend+8192 ; buffer address + dw 0 ; buffer size - overwritten + db 0 ; baud rate - overwritten + db 3 ; 8 bits/char + db 0 ; no parity, it is done internally + db 1 ; 1 stop bit + db 0cfh ; special bits - activate xon/xoff +; The documentation suggests that the xon/xoff bit is bit 4, i.e the pattern +; should be 0efh, but the top bit is omitted from the diagram. I will try +; clearing both bit 4 and bit 5. +ENDIF ; px8 [29] + +IF hp125 ;[MF] + lxi b,73ffh ;Prepare Data Comm 1 to + call bdos ;Transfer eight-bit data + lxi d,jbuf ;Point to bios jump-table vector + lxi b,7effh ;Set up special subfunction code to + call bdos ;Get rdr routine address + lhld jbuf+3 ;Remember this address + shld readin+1 ;for our eight-bit rdr routine + mvi a,1 ;We want to write into the bios jump table + sta jbuf+1 ;... + lxi h,readin ;Point to our rdr routine (all 8 bits) + shld jbuf+3 ;as new RDR routine + lxi d,jbuf ;Point to jump vector argument block + lxi b,7effh ;Set subfunction code to + call bdos ;Substitute our rdr routine in dispatch table + lxi h,mapon1 ;Make Data Comm 1 the default port + shld port ;at program-start + xchg ;Put in DE + call prtstr ;Print escape sequences to connect + ;DAta Comm 1 to rdr/punch +ENDIF ;hp125 [MF] + + ret ; end of sysxin + +; +; system-dependent termination processing +; If we've changed anything, this is our last chance to put it back. +sysexit: + +IF dmII +; Edited by OBSchou for Charles Lasner. His bug fix now in Kermit-80: +; +; IBM mode restore program +; +; This routine must be run after using CP4DMF (and KERMIT-80) to restore +; the normal handling of XON/XOFF; the user may also elect to cold-boot +; the DECMATE instead. +; +; acknowledgments and limitations. +; +; This program is based on DECMATE specific implementation details +; provided by Walt Lamia of DEC. It is of course, specific to DECMATE +; implementations of CP/M-80 for DECMATE II, III, III-plus, etc. +; +; usage consists of merely: +; +; CP4DMF run xon/xoff disable program +; KERMIT80 then run kermit +; <KERMIT-80 commands used normally here, including SET IBM ON> +; CP4DMU run this program to restore normal XON +; +; unless CP4DMU is run following KERMIT-80, the normal handling of +; XON/XOFF provided by KERMIT-80 will not work (cold boot is another +; alternative). +; +; CP4DMF.ASM +; +; last edit: 12-jun-87 20:00:00 Charles J. Lasner (CJL) +; +coxon equ 000h ; enable comm. output XON +;oboff equ 3fh ; offset of outbyt routine for 6120 +;prtctl equ 02h ; port control + + + lxi b,(coxon * 100h) + prtctl ; c/prtctl, b/with out. xon + call outbyt ;[OBS] declared elswhere + ret ; and return + +ENDIF ;dmII + +IF mikko + lxi d,miotbl ;Load the adress of original reg values + mvi c,miolen ;Length of table + lxi h,sioac ;Send data to ch A SIO registers + call movmik + mvi a,07FH ;Set ch A mask to use just 7 bits + sta chmask +ENDIF;mikko + +IF teletek +;Note - This code was handwritten onto the lising I was sent, with the +; comment that David had just thought of the code, so it was +; not on the listing. If you have problems I suggest you +; comment out these few lines. +;Bertil Schou. +; + di + mvi a,47h ; reset baud rate to 9600 + out baudrt + mvi a,08h + out baudrt + ei +ENDIF ;teletek + +IF cpt85xx + mvi a,80h ; Reset (force idle) the 8251 UART via bit 7 + out baudrt ; of the baud rate generater port + mvi a,00h ; and turn off the baud rate generater + out baudrt +ENDIF;cpt85xx + +IF bbc ;[22] + mvi a,0 ; Turn off terminal mode + call term +ENDIF;[22] bbc + +IF px8 ;[29] + call rsclose +ENDIF ;px8 [29] + +IF hp125 ;[MF] + lxi b,74ffh ;Set subfunction code to + call bdos ;Reset Data Comm 1 for 7-bit data + lhld readin+1 ;Get original rdr routine address + shld jbuf+3 ;and store in jump vector + lxi d,jbuf ;Point to jump vector + lxi b,7effh ;Set subfunction code to + call bdos ;Put original rdr routine back in bios + ;dispatch table + lxi d,mapoff ;Point to escape sequences to + call prtstr ;Turn off Data Comm 1/2 mappings +ENDIF ;hp125 [MF] + + ret + +; +; system-dependent processing for start of CONNECT command +; +syscon: +IF robin OR trs80 OR cpt85xx ;For Robin/TRS80/CPT-85xx, add some more info + lxi d,conmsg ; about obscure key combinations + call prtstr +ENDIF;robin OR trs80 OR cpt85xx + +IF osbrn1 ;*** This is Software dependent *** + lhld 1 ;Modify back-arrow code to DELETE + mvi l,0 ;Get BIOS-start address + lxi d,85H ;Adress for key-code = XX85H + dad d + mov e,m ;Get it in DE + inx h + mov d,m + xchg ;Memory pointer to HL + mvi m,del ;modify the code +ENDIF;osbrn1 + ret + +conmsg: ; Messages printed when entering transparent (CONNECT) mode: +IF robin ; for Robin, control-S key is hidden + db ' (Type Left Arrow to send CTRL-S)',cr,lf,'$' +ENDIF;robin +IF trs80 ; for TRS-80, the preferred escape key is hidden + db ' (Control-_ is the Down-Arrow key on the TRS-80 keyboard)' + db cr,lf,'$' +ENDIF;trs80 +IF cpt85xx ; for CPT-85xx, some graphics map "funny" to keyboard in CP/M + db ' (Use CODE + SHIFT + 1/2 key to generate a Control-\)' + db cr,lf,'$' +ENDIF;cpt85xx +; +; syscls - system-dependent close routine +; called when exiting transparent session. +; +syscls: +IF osbrn1 + lhld 1 ;Modify back-arrow code to BACKSPACE + mvi l,0 ;Get BIOS address + lxi d,85H ;Address for key-code =XX85H + dad d + mov e,m ;Get it in DE + inx h + mov d,m + xchg ;Address to HL + mvi m,bs ;Modify code +ENDIF;osbrn1 + ret +; +; sysinh - help for system-dependent special functions. +; called in response to <escape>?, after listing all the +; system-independent escape sequences. +; +sysinh: +IF robin OR dmII OR cpt85xx OR lobo + lxi d,inhlps ; we got options... + call prtstr ; print them. +ENDIF;robin OR dmII OR cpt85xx OR lobo + +IF bbc OR rm380z ; some more + lxi d,inhlps ; we got options... + call prtstr ; print them. +ENDIF;[22] bbc OR rm380z + +IF px8 OR access OR mmate OR disc ;and more... + lxi d,inhlps ; we got options... + call prtstr ; print them. +ENDIF ;px8 OR access OR mmate OR disc + + ret + + +;additional, system-dependent help for transparent mode +; (two-character escape sequences) +inhlps: + +IF robin OR dmII OR cpt85xx OR lobo + db cr,lf,'B Transmit a BREAK' +ENDIF;robin OR dmII OR cpt85xx OR lobo + +IF bbc OR rm380z + db cr,lf,'B Transmit a BREAK' +ENDIF;bbc OR rm380z + +IF px8 OR access OR mmate + db cr,lf,'B Transmit a BREAK' +ENDIF ;px8 OR access OR mmate + +IF disc ;[29] [32] + db cr,lf,'B Transmit a 300ms BREAK' + db cr,lf,'L Transmit a 5 second BREAK' +ENDIF;disc [29] + +IF lobo + db cr,lf,'D Drop the line' +ENDIF;lobo + + db '$' ;[hh] table terminator + +; +; sysint - system dependent special functions +; called when transparent escape character has been typed; +; the second character of the sequence is in A (and in B). +; returns: +; non-skip: sequence has been processed +; skip: sequence was not recognized + +sysint: ani 137O ; convert lower case to upper, for testing... + +IF robin OR dmII OR cpt85xx OR lobo + cpi 'B' ; send break? + jz sendbr ; yes, go do it. return nonskip when through. +ENDIF;robin OR dmII OR cpt85xx OR lobo + +IF bbc OR rm380z ; [22] [25] ... some more + cpi 'B' ; send break? + jz sendbr ; yes, go do it. return nonskip when through. +ENDIF; bbc OR rm380z + +IF px8 OR access OR mmate ;[28] [29] and anothers + cpi 'B' ; send break? + jz sendbr ; yes, go do it. return nonskip when through. +ENDIF ; px8 OR access OR mmate [28] [29] + +IF lobo ;[hh] + cpi 'D' ;[hh] disconnect? + jz discon ;[hh] yes, go do it. nonskip return when done. +ENDIF ;lobo + +IF disc ;[29] + cpi 'B' ;Send short break? + jz sendbr + cpi 'L' ;Send long break? + jz sendlbr +ENDIF;disc [29] + + jmp rskp ; take skip return - command not recognized. + + +; +IF robin ;Definitions & code to send a BREAK (ungenerically, no other way). + +comctl equ 59h ;VT180 communications port +crtctl equ 41h ;VT180 crt port + +;VT180 serial port command bits + +txe equ 1 ;transmit enable +dtr equ 2 ;dtr on +rxe equ 4 ;rx enable +sndbrk equ 8 +rerr equ 10h ;reset error +rts equ 20h ;RTS on +reset equ 40h ;port reset + +;Send a break to the communications port. +; + +sendbr: lxi h,38500 ;250 ms(?) + lda prtadr ;Get address of selected port + mov c,a ;Into C + mvi a,sndbrk+dtr +; OUT C,A ;Want to send to port addressed by C + db 0EDH,079H ;Op code for above instruction +sndbr1: dcx h ;timing loop... + mov a,l + ora h + jnz sndbr1 ;...until over + lda prtadr ;Get the address for the port + mov c,a ;Into C + mvi a,txe+dtr+rxe+rerr+rts ;enable tr/rc, dtr, reset error +; out c,a ;Z-80 only instruction + db 0EDH,079H ;Op code for above instruction + out contst ;reset ports + ret +ENDIF;robin +; +IF dmII ;[jd] this added to send break on DECmate + +; DECmate command codes for 6120 I/O processor +oboff equ 3fh ; offset of outbyt routine for 6120 +prtctl equ 02h ; port control +brdat equ 06h ; data to tell 6120 to send a break +brdur equ 30 ; duration, 30 = 300 ms. + +sendbr: lxi b,(brdat * 100h) + prtctl ; c/prtctl, b/brdat + call outbyt + lxi b,brdur*100h ; b/duration, c/0 +; fall through into outbyt + +outbyt: lhld 1 ; get warm boot address + lxi d,oboff ; offset of outbyt routine + dad d ; compute address + pchl ; branch there (a callret) + +ENDIF;dmII +; +IF access OR mmate ;[cjc] send break on Kaypro [29] +; Officially, a "break" is 300 milliseconds of "space" (idle line is +; "mark"). (or maybe 200 milliseconds; I forget.) The timing isn't +; usually that critical, but we'll make an attempt, at least. Sending +; too long a break can cause some modems to hang up. + +sendbr: +; First, make sure the transmitter is really empty. (The SIO sets +; "transmitter buffer empty" when it can accept another character; +; the previous character is still being shifted onto the line. +; Another status bit, "all done", is set to indicate that the +; transmitter is really idle. +sndbr1: mvi a,1 ; select Read Register 1 + out mnprts + in mnprts ; read the contents + ani 1 ; test "all done" flag + jz sndbr1 ; loop until it's nonzero. +; +; Next, set the "send break" bit to start the transmitter spacing. + mvi a,5 ; select Write Register 5 + out mnprts + mvi a,0FAH ; Tx enable, 8 bit Tx character, Send Break, + out mnprts ; DTR and RTS on. +; +; Now, delay for 30 hundredths of a second + mvi a,30 ; delay count + call delay +; +; Time's up. Put transmitter back in normal state (data byte is the +; same as the one in siotbl: for Write Register 5) and return. + mvi a,5 ; select Write Register 5 + out mnprts + mvi a,0EAH ; Tx enable, 8 bit Tx character, + out mnprts ; DTR and RTS on. + ret ; done. +ENDIF;access OR mmate [29] + +IF lobo ;[hh] This routine sends a break tone or disconnects a modem +; (those that respond to it) by setting the DTR line low +; for 300 ms. +; +sendbr: mvi a,05H ;[hh] write register 5 + call outctl ;[hh] send it to control port + mvi a,0FAH ;[hh] value to send break tone + jmp sndbr1 ;[hh] +; +discon: mvi a,05H ;[hh] write register 5 + call outctl ;[hh] send it to the control port + mvi a,06AH ;[hh] DTR off and break tone on +sndbr1: call outctl ;[hh] send to control port + mvi a,30 ;[hh] delay count for 300 ms. + call delay ;[hh] wait a while... + mvi a,05H ;[hh] write register 5 + call outctl ;[hh] get it's attention + mvi a,0EAH ;[hh] normal 8 bits, DTR on, RTS on, etc. + call outctl ;[hh] restore SIO + ret +; +outctl: sta mnprts ;[hh] + ret +ENDIF ;lobo +; +IF cpt85xx OR rm380z ;[lmj] [22] [25] +sendbr: +; +; Ensure that the transmitter has finished sending buffered chars +sndbr1: in mnprts ; get UART status + ani TxEmpty ; everything sent? + jz sndbr1 ; no, wait a bit more +; +; Begin sending a break by setting bit in UART command register + mvi a,3Fh ; Set TxEna, DTR, RxEna, SBreak, ErrRst, RTS + out mnprts +; +; Wait for 250 milliseconds (using hundredths second delay routine) + mvi a,25 + call delay +; +; Resume normal operation by clearing the SendBreak command bit + mvi a,37h ;Set TxEna, DTR, RxEna, ErrRst, RTS + out mnprts +; + ret ;done +ENDIF;cpt85xx OR rm380z + +IF px8 ; [29] +sendbr: mvi a, 3fh ; set break bit + out mnprts + mvi a, 25 + call delay ; wait 250 msec + mvi a, 37h ; clear break bit + out mnprts + ret +ENDIF ; px8 [29] + +; +IF bbc ;[22] +sendbr: +; +; Ensure that the transmitter has finished sending buffered chars +sndbr1: mvi a,96h ; get ACIA status + mvi l,8 + call osbyte ; *FX150,8 + mov a,h + ani 2 ; everything sent? + jz sndbr1 ; no, wait a bit more +; +; Disable centisecond clock (system VIA) which interferes with break + lxi h,0FE4Eh ; system VIA interrupt enable register + mvi a,40H ; disable timer 1 + call wrtiom ; write to I/O processor memory +; +; Begin sending a break by setting bit in ACIA control register + mvi a,9Ch + lxi h,9F60h ; Set Rxint, Txint, Break, RTS + call osbyte ; *FX 156,96,159 +; +; Wait for 250 milliseconds (using hundredths second delay routine) + mvi a,25 + call delay +; +; Resume normal operation by returning old control byte + mvi a,9Ch + mvi h,0 ;Set TxEna, DTR, RxEna, ErrRst, RTS + call osbyte ; *FX 156,oldvalue,0 +; +; Enable centisecond clock (system VIA) + lxi h,0FE4Eh ; system VIA interrupt enable register + mvi a,0C0H ; enable timer 1 + call wrtiom ; write to I/O processor memory +; + ret ;done +; +; Routine to write byte in A to I/O processor memory address +; given by HL +wrtiom: + shld parblk ; store address to parameter block + sta parblk+4 ; store data + lxi h,parblk ; load hl with address of param block + mvi a,6 ; write I/O processor memory + call osword ; go do it + ret +; +parblk: DS 5 ; reserve space for parameter block +ENDIF;bbc [22] +; +IF disc ;[29] +; This is almost an exact copy of the bbI sendbr routine. +; Modifications to include a long break have been made. +; +; Officially, a "break" is 300 milliseconds of "space" (idle line is +; "mark"). (or maybe 200 milliseconds; I forget.) The timing isn't +; usually that critical, but we'll make an attempt, at least. Sending +; too long a break can cause some modems to hang up. + +sendlbr: + push d ;save d, this may not be necessary, but safe + mvi d,17 ;do short break 17 times (approx. 5 sec.) + jmp sndbr1 +sendbr: + push d + mvi d,1 ;On short break, do only once +; First, make sure the transmitter is really empty. (The SIO sets +; "transmitter buffer empty" when it can accept another character; +; the previous character is still being shifted onto the line. +; Another status bit, "all done", is set to indicate that the +; transmitter is really idle. +sndbr1: mvi a,1 ; select Read Register 1 + out mnprts + in mnprts ; read the contents + ani 1 ; test "all done" flag + jz sndbr1 ; loop until it's nonzero. +; +; Next, set the "send break" bit to start the transmitter spacing. + mvi a,5 ; select Write Register 5 + out mnprts + mvi a,0FAH ; Tx enable, 8 bit Tx character, Send Break, + out mnprts ; DTR and RTS on. +; +; Now, delay for 30*d hundredths of a second +sendbr2: + mvi a,30 ; delay count + call delay +; The following has been added to allow doing .03 delay d times + dcr d ; decrement # of times to do loop + jnz sendbr2 ; if not done, do again + pop d ; reload d +; +; Time's up. Put transmitter back in normal state (data byte is the +; same as the one in siotbl: for Write Register 5) and return. + mvi a,5 ; select Write Register 5 + out mnprts + mvi a,0EAH ; Tx enable, 8 bit Tx character, + out mnprts ; DTR and RTS on. + ret ; done. +ENDIF ;disc [29] + + +; +; sysflt - system-dependent filter +; called with character in E. +; if this character should not be printed, return with A = zero. +; preserves bc, de, hl. +; note: <xon>,<xoff>,<del>, and <nul> are always discarded. +sysflt: + mov a,e ; get character for testing +IF mikko + cpi 'O'-100O ;Control-O's lock keyboard + rnz ; if not control-O, it's ok. + xra a ; don't allow control-O out. +ENDIF;mikko + + ret + +; mdmflt - modem filter [30] +; called with character to be sent to printer in E +; with parity set as appropriate. +; return with accumulator = 0 do do nothing, +; <> 0 to send char in E. +mdmflt: + mov a,e ;[30] get character to test + ret + + + +; prtflt - printer filter [30] +; called with character to be sent to printer in E +; returns with a = 0 to do nothing +; a <> 0 to print it. +; +; this routine for those printer that automatically insert +; a lf on cr, or cr for lf. Should this be shifted to +; the system indep. stuff, in say 4.06? +prtflt: + mov a,e ; [30] get character to test + ret + + +; +; system-dependent processing for BYE command. +; for lobo, hang up the phone. +sysbye: +IF lobo ;[hh] + call discon ;[hh] force modem to hang up +ENDIF;lobo + ret + +IF lasm + LINK CPXSY2.ASM ; If m80 then this ignored +ENDIF ; lasm |
