4 ; KERMIT - (Celtic for "FREE")
6 ; This is the CP/M-80 implementation of the Columbia University
7 ; KERMIT file transfer protocol.
11 ; Copyright June 1981,1982,1983,1984,1985
14 ; Originally written by Bill Catchings of the Columbia University Center for
15 ; Computing Activities, 612 W. 115th St., New York, NY 10025.
17 ; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
18 ; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
21 ; This file contains the system-dependent code and data for KERMIT.
22 ; It will be probably be broken into independent files to generate
23 ; overlays for the various systems, one or more overlay possible
24 ; from each file. For now, we will leave it in one piece.
29 ; Edit 40, 28-Aug-89 by Mike Freeman of Bonneville Power Administration,
30 ; P.O. Box 491, Vancouver WA 98666 USA, Telephone (206)690-2307:
31 ; Home address: 301 N.E. 107th Street; Vancouver, WA 98685 USA
32 ; Home telephone: (206)574-8221
33 ; added support for Hewlett-Packard HP-125 Business Assistant computer
34 ; running a HP-modified CP/M Version 2.2; communications on
35 ; DAta Comm 1 or Data Comm 2 (8th-bit quoting must be used on
36 ; Data Comm 2 to transfer binary files as Data Comm 2 only supports
37 ; a 7-bit data path); printer cannot be used with communications on
38 ; Data Comm 2 (the printer port).
39 ; edit 39, 4 August, 1987b by OBSchou for Charles Lasner re. DECMATE II
40 ; fixes to set xon/off control off for the duration of Kermit-80.
44 ; IBM mode restore program
46 ; This routine must be run after using CP4DMF (and KERMIT-80) to restore
47 ; the normal handling of XON/XOFF; the user may also elect to cold-boot
48 ; the DECMATE instead.
50 ; acknowledgments and limitations.
52 ; This program is based on DECMATE specific implementation details
53 ; provided by Walt Lamia of DEC. It is of course, specific to DECMATE
54 ; implementations of CP/M-80 for DECMATE II, III, III-plus, etc.
56 ; usage consists of merely:
58 ; CP4DMF run xon/xoff disable program
59 ; KERMIT80 then run kermit
60 ; <KERMIT-80 commands used normally here, including SET IBM ON>
61 ; CP4DMU run this program to restore normal XON
63 ; unless CP4DMU is run following KERMIT-80, the normal handling of
64 ; XON/XOFF provided by KERMIT-80 will not work (cold boot is another
67 ; [Note - These edits now included in the init/de-init code]
69 ; edit 38, 23 July, 1987 by OBSchou. Moved out commonly used code
70 ; to CPXCOM.ASM, and adjusted this (ond other family) files accordingly.
71 ; Also filtered out code now in other family files.
73 ; edit 37 , 15 July 1987 by OBSchou for David Moore, who has submitted
74 ; code for Teletek SYSTEMASTER (teletek) and for an ADM 22 terminal.
76 ; edit 36 28 Jan 87 by OBSchou.
77 ; Removed the printx etc and should only have this file if a system
78 ; does not have a family file.
80 ; edit 35 1st Dec 1986 by OBSchou. Added test for Amstrad PCW range (PCW)
81 ; Links to CPXPCW.ASM, which was submitted by Ian Young, Lattice
84 ; edit 34 20 August by OBSchou for Brian Robertson, Aberdeen University:
85 ; I have discovered a bug in my code for the BBC/Z80 version of Kermit.
86 ; At startup the transmitter baud rate is read from the serial ULA.
87 ; The TX and RX baud rates are then reset to this value and the
88 ; value is stored in location 'baud:' for the STATUS (or SHOW)
89 ; command. That is how it is supposed to work ! Unfortunately
90 ; my code at present "misreads" the initial TX baud rate - there
91 ; is some bit manipulation that needs to be done to extract the
94 ; edit 33 30-May-86 OBSchou. Added two new enties to the overly. One for
95 ; printer status and the other for the address of the family of
96 ; computer using the overlay. If it is still in CPXSYS.ASM then it
99 ;edit 32, 27 May, 1986 by OBSchou Loughborough University for
100 ; B Robertson, Aberdeen Univ. Computing Centre. Any mistakes my fault.
101 ; Add support for APPLE II with serial cards based on the 6850 ACIA.
102 ; Mod 380Z support to allow both MDS (5 1/4" discs) and FDS (8" discs)
105 ; edit 31, 22 April, 1986, OBSchou.
106 ; Kermit version 4.06 starts here. All previous edits have been
107 ; put aside (leave in a BWR file?). Hived off some definitions
108 ; to the CPSDEF.ASM file as that is where they belong.
109 ; Start on splitting off individual
110 ; systems from this huge file. It is done using the LINK facility
111 ; LASM. We link to a collection of systems under CPXxxx.ASM.
112 ; I have started with the systems I know, the Torch, Cifer and
113 ; pci2651. These will all be held under CPXTOR.ASM
116 ; Keep module name, edit number, and last revision date in memory.
117 family: db 'CPXSYS.ASM (40) 28-Aug-89 $' ; now a family...
121 ; Processor speed in units of 100KHz
122 ; for cpt85xx, advance, apple,bbc,px8 & rm380z timing loop [12]
124 cpuspd SET 40 ; 4.0 MHz CPU
127 IF disc OR mmate OR s1008 OR access
128 cpuspd SET 40 ; 4.0 MHz CPU
129 ENDIF ;disc OR mmate OR s1008 OR access
132 cpuspd SET 60 ; BBC with 6Mhz Z80
139 batio EQU 056H ;I/O byte CON=BAT,LIST=CRT,READER=RDR,PUNCH=PTP
140 defio EQU 095H ;I/O byte CON=CRT,LIST=LPT,READER=RDR,PUNCH=PTP
141 crtio equ 01010101B ; use CRT: device
142 ptrio equ 01010110B ; use PTR: device
143 ttyio equ 00000000B ; use TTY: device
144 uc1io equ 01010111B ; use UC1: device
145 ur1io equ 01101010B ; use UR1: device
146 ur2io equ 01111110B ; use UR2: device
150 batio EQU 056H ;I/O byte CON=BAT,LIST=CRT,READER=RDR,PUNCH=PTP
151 defio EQU 095H ;I/O byte CON=CRT,LIST=LPT,READER=RDR,PUNCH=PTP
152 lptio EQU 054H ;I/O byte CON=TTY,LIST=CRT,READER=PTR,PUNCH=PTP
153 gppio EQU 057H ;I/O byte CON=UC1,LIST=CRT,READER=RDR,PUNCH=PTP
158 batio EQU 042H ;I/O byte CON=BAT,LIST=CRT,READER=RDR
159 defio EQU 081H ;I/O byte CON=CRT,LIST=LPT,READER=RDR
163 batio EQU 10110010B ; I/O byte console => serial line
164 defio EQU 10000001B ; I/O byte console => CRT and Keyboard
168 mnport EQU 0F7E4H ;Modem data port A
169 mnprts EQU 0F7E5H ;Modem status/conrtol port A
170 baudrt EQU 0F7D0H ;Baud rate port A
171 output EQU 04H ;Transmit buffer empty
172 input EQU 01H ;Receive data available
173 z80 SET TRUE ;a good z80, here
177 mnport EQU 0CF01H ;Modem data port
178 mnprts EQU 0CF00H ;Modem status port
179 output EQU 02H ;Transmitter empty
180 input EQU 01H ;Input data available
181 z80 SET FALSE ;I don't know...
185 mnport EQU 04H ;Modem data port
186 mnprts EQU 05H ;Modem status port
187 output EQU 01H ;Transmitter empty
188 input EQU 02H ;Input data available
189 z80 SET FALSE ;I don't know...
193 mnport EQU 22H ;[7] Modem data port
194 mnprts EQU 23H ;[7] Modem status port
195 output EQU 01H ;[7] Transmitter empty
196 input EQU 02H ;[7] Input data available
197 baudrt equ 29h ;[7] Baud rate port for channel 2 (default)
198 z80 SET true ;[7] We're using the z80 side of the dual processor
202 ;NEEDS display definition (e.g. trs80lb or trs80pt)
203 mnport EQU 0F4H ;Modem data port (0F5H for port B)
204 mnprts EQU 0F6H ;Modem status port (0F7H for port B)
205 output EQU 04H ;Transmitter empty
206 input EQU 01H ;Input data available
207 z80 SET TRUE ;[hh] All TRS-80's but the CoCo
211 mnport EQU 00H ;Modem data port (02 for port B (console))
212 mnprts EQU 01H ;Modem status port (03 for port B (console))
213 baudrt EQU 08H ;ctc0 control port (09 for port B (console))
214 output EQU 04H ;Transmitter empty
215 input EQU 01H ;Input data available
216 z80 SET TRUE ;All Teleteks
220 ;Osborne 1 uses 6850 ACIA, but memory mapped. Derived from Apple.
221 BAUDRT EQU 0EFC1H ;Memory location where baud rates are stored.
222 OSTOP EQU 4000H ;Where we move OSMOVE to at startup
223 OSPORT EQU 2A01H ;Communications Port.
224 OSPRTS EQU 2A00H ;Communications Port Status.
225 OUTPUT EQU 02H ;Output Buffer Empty.
226 INPUT EQU 01H ;Input Register Full.
227 OSBIN1 EQU 57H ;First Init Character for 6850 ACIA (Reset)
228 ;(I would have thought 03, but prom code writes 57 there)
229 OSBI12 EQU 55H ;Second Init Character for ACIA (8-bits, 1200)
230 OSBI03 EQU 56H ;Second init char. for ACIA (8 bits, 300)
231 ;(don't ask.. I don't know why SETUP writes 55 and 56 either)
232 z80 SET TRUE ;[hh] a z80 here, also
236 ;Those definitions below that are commented out are just for information
237 ;***** NOT generally found in distributed documentation ****
239 ;pbausl EQU 90H ;The Baud-Rate register.
240 prntst EQU 49H ;Printer
242 contst EQU 41H ;Console
244 gentst EQU 51H ;General port.
246 comtst EQU 59H ;COMM-Port
248 ;output EQU 01H ;Output ready bit.
249 ;input EQU 02H ;Input ready bit.
250 z80 SET TRUE ; This one's a Z80.
254 mnport equ 00 ;printer port data
255 mnprts equ 01 ;printer port status
256 output equ 4 ;transmitter ready
257 input equ 2 ;receiver ready
258 z80 equ FALSE ;not important
262 mnport EQU 89H ;MODEM data port
263 mnprts EQU 8BH ;MODEM status/control port
264 output EQU 04H ;Transmit buffer empty, ready to send
265 input EQU 01H ;Receive data available
266 baudrt EQU 93H ;MODEM baud rate port
267 ;NOTE - also used for console
272 mnport EQU 05 ;Discovery 83U port B data
273 mnprts EQU 04 ;Discovery 83U port B status/command
274 output EQU 04 ;Transmit buffer empty
275 input EQU 01 ;Receiver ready
280 tuart EQU 020H ;TU-ART address
281 mnport EQU tuart+1 ;Modem data port
282 mnprts EQU tuart ;Modem status port
283 output EQU 080H ;Transmitter empty
284 input EQU 040H ;Input data available
285 baudrt EQU tuart ;Baud rate port
286 ;Note: Needs terminal definition
287 z80 SET TRUE ;This one's a Z80.
291 baudrt EQU 4Ch ; Baud rate generater (National MM5307)
292 mnport EQU 4Bh ; Comm port data register (Intel 8251)
293 mnprts EQU 4Ah ; Comm port command/status register
294 output EQU 01h ; Transmitter buffer empty flag
295 input EQU 02h ; Reciver buffer full flag
296 TxEmpty EQU 04h ; Transmitter empty flag
297 z80 SET FALSE ; It's really an 8080 [or 8085 ... same thing]
300 IF mmdI ;Morrow MicroDecision - the single-board one
301 mnport EQU 0FEH ;Morrow Printer UART data port
302 mnprts EQU 0FFH ;Morrow Printer UART command/status
303 output EQU 01H ;Output ready bit.
304 input EQU 02H ;Input ready bit.
305 ;Note: Needs terminal definition
306 z80 SET FALSE ;I don't know...
310 osbyte EQU 0FFF4H ; OS entry point
311 osword EQU 0FFF1H ; " " "
312 term EQU 0FFC8H ;Terminal mode OS entry
316 ;Two types of 380Z system
317 IF rm380zm ;[27] MDS - 5 1/4" discs
318 mnport EQU 0C8H ;Modem data port
319 mnprts EQU 0C9H ;Modem status port
322 IF rm380zf ;[32] FDS - 8" discs
323 mnport EQU 0E8H ;Modem data port
324 mnprts EQU 0E9H ;Modem status port
327 IF rm380z ;[32] Common to both systems
328 output EQU 01H ;Transmitter buffer empty
329 input EQU 02H ;Input data available
330 TxEmpty EQU 04h ;Transmitter empty flag
336 mnprts EQU 0dh ; used in sending a break
339 IF mdI ;Morrow Decision I - the big sucker
340 mnport equ 48H ; Modem data port.
341 mnprts equ 4DH ; Modem status port.
342 output equ 20H ; Transmitter empty.
343 input equ 1 ; Input data available.
344 mbase equ 48H ; Base address of Multi I/O port
346 grpsel equ 4FH ; Group select port.
347 rbr equ 48H ; Read Data Buffer.
348 group equ 1 ; Multi I/O Group byte for serial ports.
349 congrp equ 1 ; Serial Port 1 for console
350 mdmgrp equ 3 ; Serial Port 3 for modem.
352 ; Following are needed for baud rate changes...[Toad Hall]
354 dlm equ 49H ; Baud Rate Divisor (Most Sig Bit)
355 dll equ 48H ; Baud Rate Divisor (Least Sig Bit)
356 ier equ 49H ; Interrupt Enable Register
357 lcr equ 4BH ; Line Control Register
358 lsr equ 4DH ; Line Status Register
359 msr equ 4EH ; Modem Status Register
360 dlab equ 80H ; Divisor Latch Access Bit
361 wls0 equ 1 ; Word Length Select Bit 0
362 wls1 equ 2 ; Word Length Select Bit 1 for 8 bit word
363 stb equ 4 ; Stop bit count - 2 stop bits
364 imask equ 0 ; Interrupt mask (all disabled)
365 z80 SET TRUE ; This one's a Z80.
366 ENDIF ;mdI NOTE: needs terminal definition. [Toad Hall]
369 sioac EQU 0FF12H ;SIO channel A register(s) address
370 sioo3 EQU 01000001B ;SIO Write Reg. 3 original setup (?)
371 ;RX 7 bits,synch mode bits 0,RX enable
372 sion3 EQU 11001111B ;SIO Write Reg. 3 KERMIT setup
373 ;RX 8 bits,synch mode bits 0,RX enable
374 sioo4 EQU 01001111B ;SIO Write Reg. 4 original setup (?)
375 ;X16 clock,8 bit synch(ignored),
376 ;2stop bits,par even(on)
377 sion4 EQU 01000100B ;SIO Write Reg. 4 KERMIT setup
378 ;X16 clock,8 bit synch(ignored),
380 sioo5 EQU 10101010B ;SIO Write Reg. 5 original setup (?)
381 ;DTR,TX 7 bits,TX enable,RTS
382 sion5 EQU 11101010B ;SIO Write Reg. 5 KERMIT setup
383 ;DTR,TX 8 bits,TX enable,RTS
384 txclk EQU 0FF30H ;Baud rate generator (CTC) for transmitter
385 rxclk EQU 0FF31H ;Baud rate generator (CTC) for receiver
386 chmask EQU 0F1F2H ;Mask byte address for SIO ch. A reception
387 z80 SET TRUE ;It's got a SIO and a CTC, it must be a Z80
392 mnport EQU 40H ;Modem data port A
393 mnprts EQU 42H ;Modem status/conrtol port A
394 output EQU 04H ;Transmit buffer empty
395 input EQU 01H ;Receive data available
396 z80 SET TRUE ;a good z80, here
401 z80 SET TRUE ; This one's a Z80
405 z80 SET TRUE ;HP-125 uses a Z80
408 IF gener OR cpm3 ; To be truly generic, we must assume 8080.
413 defesc EQU ']'-100O ;The default escape character.
417 defesc EQU '~' ;Vector can't type ']'.
420 IF mikko OR osbrn1 OR lobo
421 defesc EQU '\'-100O ;The default is Control \ -- it's easier B.E.
422 ENDIF;mikko OR osbrn1 OR lobo
425 defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
428 IF bbc OR rm380z OR px8 OR access OR S1008 ;[22] [29]
429 defesc EQU '\'-100O ;Still Control-\ (just ran out of room...)
430 ENDIF ;bbc OR rm380z OR px8 OR access OR s1008[29]
433 defesc EQU '_'-100O ;CTRL-_ (Down-arrow on TRS-80 keyboard)
436 ; Select initial setting for VT-52 emulation flag.
438 IF vt52 ; If console looks like (or is) VT52
439 vtval EQU 0 ; we don't need VT52 emulation
442 ; If none of the above, default to VT52-EMULATION ON.
443 IF NOT (crt OR vt52 OR robin OR dmII OR vt100 OR hp125);[MF]
445 ENDIF;NOT (crt OR vt52 OR robin OR dmII OR vt100 OR hp125)[MF]
448 ; sysxin - system dependent initialisation code, called from SYSINIT
453 ; edit added by OBSchou for C. Lasner. If this dont work, tell me whats
454 ; wrong, as I have no DMII or IBM to play with
456 ; IBM mode fixup program
458 ; This routine must be run before attempting to use KERMIT-80 with half
459 ; duplex KERMIT implementations such as CMS-KERMIT, as the 6120 processor
460 ; will otherwise "swallow" the XON character.
462 ; acknowledgments and limitations.
464 ; This program is based on DECMATE specific implementation details
465 ; provided by Walt Lamia of DEC. It is of course, specific to DECMATE
466 ; implementations of CP/M-80 for DECMATE II, III, III-plus, etc.
468 ; usage consists of merely:
470 ; CP4DMF run this program
471 ; KERMIT80 then run kermit
472 ; <KERMIT-80 commands used normally here, including SET IBM ON>
473 ; CP4DMU run companion program to restore normal XON
475 ; unless CP4DMU is run following KERMIT-80, the normal handling of
476 ; XON/XOFF provided by KERMIT-80 will not work (cold boot is another
481 ; last edit: 12-jun-87 20:00:00 Charles J. Lasner (CJL)
483 ;oboff equ 3fh ; offset of outbyt routine for 6120
484 ;prtctl equ 02h ; port control
485 nocoxon equ 001h ; turn off comm. output XON
487 lxi b,(nocoxon * 100h) + prtctl ; c/prtctl, b/no out. xon
491 ;outbyt has been catered for (in break routine)
494 IF osbrn1 ;(Note now no longer needs code > 4000h as it is already there
495 ; lxi d,ostop ;where we're moving it to
496 ; lxi h,osmove ;what we're moving
497 ; mvi b,osmct ;How many bytes we're moving
499 lda baudrt ; Find out what speed is current
501 mvi a,osbi03 ; assume 300 baud
503 mvi a,osbi12 ; nope, it's 1200.
504 osstr1: sta speed ; save initial speed
505 sta speed+1 ; as 16 bits, to match speed table entries
507 mov e,a ; get initial speed in DE
508 call sysspd ;set up parity etc.
512 mvi a,80h ; Send UART reset [force idle] by setting
513 out baudrt ; bit 7 of baud rate I/O port
514 lxi H,0f0fh ; Clear reset and default to 9600 baud [23]
515 shld speed ; store current speed
517 call sysspd ; set default baud rate
518 mvi a,4Eh ; Set UART mode to async 16x clock, 8 data
519 out mnprts ; bits, no parity, and 1 stop bit
520 mvi a,37h ; Set command to Tx enable, DTR on, Rx enable,
521 out mnprts ; break off, error reset, and RTS on
525 lxi d,modstr ; Set MODE 3
527 mvi a,1 ; Set terminal mode on
529 mvi a,0F2H ; Read current transmit speed
530 lxi h,0FF00H ; .. 3 lsb of ULA register
531 call osbyte ; FX242,0,255
533 ani 7 ; Mask of 3 lsb
535 ; Edit of July 22, 1986 by B Robertson, Aberdeen Univ. Computing Centre.
536 ; Correct bug in sysinit for BBC - reads the initial baud rate at
537 ; start up incorrectly.
540 rar ; Reverse order of 3 lsb
541 rar ; Bit2 now in bit0
544 binit1: ana a ; Set sign bit as appropriate
546 ori 4 ; Bit0 now in bit2
547 binit2: ani 7 ; Mask off unwanted bits
550 xri 7 ; Stored as 2's complement
552 sta speed ; Store 16 bit value
554 mov e,a ; Ensure RX and TX speeds are the same
559 mvi e,11h ;Output ctrl-Q to clear autopaging
565 lxi d,siotbl ;[hh] address of status table
566 mvi c,siolen ;[hh] length of the table
567 siolup: ;[hh] loop here for each command byte
568 ldax d ;[hh] load first byte into A
569 inx d ;[hh] index pointer to next bute
570 sta mnprts ;[hh] send it to status port A
571 sta mnprts+2 ;[hh] and to status port B
572 dcr c ;[hh] decrement the counter
573 jnz siolup ;[hh] loop back for more commands
574 mvi a,05H ;[hh] value for 300 baud
575 sta baudrt ;[hh] starting default for port A
576 sta baudrt+4 ;[hh] and for port B
577 sta speed ;[hh] tell program they're set
578 mvi a,0E4H ;[hh] value for port A
579 sta port ;[hh] tell program we've set this, too
580 mvi a,0D0H ;[hh] port A baud rate value
581 sta port+1 ;[hh] save this as well, for consistancy
585 lxi d,mintbl ;Address of KERMIT Reg values (what)
586 mvi c,minlen ;Length of table (how many)
587 lxi h,sioac ;Send data to ch. A SIO registers (to where)
589 mvi a,0FFH ;Set ch. A mask to use all bits
594 lxi h,96 ;Default 1200 baud modem port speed
595 shld speed ;Store as modem port speed
596 call sysspd ;Initialize the port
597 ENDIF;mdI [Toad Hall]
600 mvi a,01h ; Reset TU-ART
602 mvi a,90h ; Set default baud rate (2400), and 1 stop bit
604 sta speed ; save for status display
610 ; shove the default baud rate (1200) in to the Delphi port address
611 ; for the baud rate generator on port 2, the default port; save this
612 ; value so we can tell what speed is selected.
614 mvi a,07h ;[7] get value for 1200 baud
615 out baudrt ;[7] set it for port 2
616 sta speed ;[7] save for status display
621 lda 0f6a9h ; get baud rate value set by CONFIG
622 sta px8blk+4 ; put into parameter block
623 mov h, a ; initialise global speed indicator
626 lhld 6 ; base of CP/M
627 ; buffer starts at ovlend+8192, immediately after sector buffer
628 ; We must also allow (800h) for the CCP as Kermit exits with a RET
629 lxi d, ovlend+8192+800h ; calc buffer length
631 db 0edh, 52h ; sbc hl, de
637 ;Initialization sequence for Discovery 83U port B
638 ;Sets port to 9600 baud, 8 data bits, 1 stop bit, no parity
639 mvi a,12 ;Register 12
641 mvi a,11 ;Low byte of time constant for 9600
643 mvi a,13 ;Register 13
645 mvi a,0 ;High byte of time constant for 9600
647 mvi a,14 ;Register 14
649 mvi a,3 ;Enable baud rate generator
651 mvi a,11 ;Register 11
653 mvi a,52h ;No Xtal, tclk=rclk=/trxc out=br gen
657 mvi a,44h ;16x clock, 1 stop, no parity
661 mvi a,71h ;rx 8 bit/ch, autoenable, rx enable
665 mvi a,0eah ;tx 8 bit/ch, tx enable, rts
670 IF mikko ;currently for MIKROMIKKO only
671 ; copy command block into memory-mapped SIO.
672 movmik: di ;disable interrupts
673 movmk1: ldax d ;Get a register value
676 dcr c ;Decrement counter
677 jnz movmk1 ;Repeat until done
685 osflag equ 0EF08H ;Osborne 1 Bank-2 flag
687 ; return modem status in A
692 LDA osprts ;Read the status port
697 ; set modem status from A
702 STA osprts ;Write the control port
705 ; read character from modem into A
715 ; output character in A to modem
730 ; List of commands to set up SIO channel A for asynchronous operation.
731 siotbl: DB 18H ; Channel reset
732 DB 18H ; another, in case register 0 wasn't selected
733 DB 04H ; Select register 4
734 DB 44H ; 1 stop bit, clock*16
735 DB 01H ; Select register 1
736 DB 00H ; No interrupts enabled
737 DB 03H ; Select register 3
738 DB 0C1H ; Rx enable, 8 bit Rx character
739 DB 05H ; Select register 5
740 DB 0EAH ; Tx enable, 8 bit Tx character,
742 siolen equ $-siotbl ; length of command list
746 ; command list to set SIO chip back to normal state
753 db 0 ;reselect reg. 0
754 miolen equ $-miotbl ;MikroMikko SIO table length (original values)
756 ; command list to set up SIO chip for operation with Kermit
763 db 0 ;reselect reg. 0
764 minlen equ $-mintbl ;MikroMikko SIO table length (KERMIT values)
769 modstr: db 16h,03h,'$' ; String to put screen into MODE 3
783 rsopen: lxi h, px8blk ; copy px8blk to px8prm
787 mvi b, 10h ; open code
789 rsclose:mvi b, 20h ; close code
791 lxi d, 51h ; offset into BIOS jump table
793 lhld 1 ; start of BIOS
795 xthl ; entry point on stack, px8prm addr in hl
799 db 0, 0, 0, 0, 0 ; the param area is overwritten in rsopen
800 px8blk: dw ovlend+8192 ; buffer address
801 dw 0 ; buffer size - overwritten
802 db 0 ; baud rate - overwritten
804 db 0 ; no parity, it is done internally
806 db 0cfh ; special bits - activate xon/xoff
807 ; The documentation suggests that the xon/xoff bit is bit 4, i.e the pattern
808 ; should be 0efh, but the top bit is omitted from the diagram. I will try
809 ; clearing both bit 4 and bit 5.
813 lxi b,73ffh ;Prepare Data Comm 1 to
814 call bdos ;Transfer eight-bit data
815 lxi d,jbuf ;Point to bios jump-table vector
816 lxi b,7effh ;Set up special subfunction code to
817 call bdos ;Get rdr routine address
818 lhld jbuf+3 ;Remember this address
819 shld readin+1 ;for our eight-bit rdr routine
820 mvi a,1 ;We want to write into the bios jump table
822 lxi h,readin ;Point to our rdr routine (all 8 bits)
823 shld jbuf+3 ;as new RDR routine
824 lxi d,jbuf ;Point to jump vector argument block
825 lxi b,7effh ;Set subfunction code to
826 call bdos ;Substitute our rdr routine in dispatch table
827 lxi h,mapon1 ;Make Data Comm 1 the default port
828 shld port ;at program-start
830 call prtstr ;Print escape sequences to connect
831 ;DAta Comm 1 to rdr/punch
837 ; system-dependent termination processing
838 ; If we've changed anything, this is our last chance to put it back.
842 ; Edited by OBSchou for Charles Lasner. His bug fix now in Kermit-80:
844 ; IBM mode restore program
846 ; This routine must be run after using CP4DMF (and KERMIT-80) to restore
847 ; the normal handling of XON/XOFF; the user may also elect to cold-boot
848 ; the DECMATE instead.
850 ; acknowledgments and limitations.
852 ; This program is based on DECMATE specific implementation details
853 ; provided by Walt Lamia of DEC. It is of course, specific to DECMATE
854 ; implementations of CP/M-80 for DECMATE II, III, III-plus, etc.
856 ; usage consists of merely:
858 ; CP4DMF run xon/xoff disable program
859 ; KERMIT80 then run kermit
860 ; <KERMIT-80 commands used normally here, including SET IBM ON>
861 ; CP4DMU run this program to restore normal XON
863 ; unless CP4DMU is run following KERMIT-80, the normal handling of
864 ; XON/XOFF provided by KERMIT-80 will not work (cold boot is another
869 ; last edit: 12-jun-87 20:00:00 Charles J. Lasner (CJL)
871 coxon equ 000h ; enable comm. output XON
872 ;oboff equ 3fh ; offset of outbyt routine for 6120
873 ;prtctl equ 02h ; port control
876 lxi b,(coxon * 100h) + prtctl ; c/prtctl, b/with out. xon
877 call outbyt ;[OBS] declared elswhere
883 lxi d,miotbl ;Load the adress of original reg values
884 mvi c,miolen ;Length of table
885 lxi h,sioac ;Send data to ch A SIO registers
887 mvi a,07FH ;Set ch A mask to use just 7 bits
892 ;Note - This code was handwritten onto the lising I was sent, with the
893 ; comment that David had just thought of the code, so it was
894 ; not on the listing. If you have problems I suggest you
895 ; comment out these few lines.
899 mvi a,47h ; reset baud rate to 9600
907 mvi a,80h ; Reset (force idle) the 8251 UART via bit 7
908 out baudrt ; of the baud rate generater port
909 mvi a,00h ; and turn off the baud rate generater
914 mvi a,0 ; Turn off terminal mode
923 lxi b,74ffh ;Set subfunction code to
924 call bdos ;Reset Data Comm 1 for 7-bit data
925 lhld readin+1 ;Get original rdr routine address
926 shld jbuf+3 ;and store in jump vector
927 lxi d,jbuf ;Point to jump vector
928 lxi b,7effh ;Set subfunction code to
929 call bdos ;Put original rdr routine back in bios
931 lxi d,mapoff ;Point to escape sequences to
932 call prtstr ;Turn off Data Comm 1/2 mappings
938 ; system-dependent processing for start of CONNECT command
941 IF robin OR trs80 OR cpt85xx ;For Robin/TRS80/CPT-85xx, add some more info
942 lxi d,conmsg ; about obscure key combinations
944 ENDIF;robin OR trs80 OR cpt85xx
946 IF osbrn1 ;*** This is Software dependent ***
947 lhld 1 ;Modify back-arrow code to DELETE
948 mvi l,0 ;Get BIOS-start address
949 lxi d,85H ;Adress for key-code = XX85H
951 mov e,m ;Get it in DE
954 xchg ;Memory pointer to HL
955 mvi m,del ;modify the code
959 conmsg: ; Messages printed when entering transparent (CONNECT) mode:
960 IF robin ; for Robin, control-S key is hidden
961 db ' (Type Left Arrow to send CTRL-S)',cr,lf,'$'
963 IF trs80 ; for TRS-80, the preferred escape key is hidden
964 db ' (Control-_ is the Down-Arrow key on the TRS-80 keyboard)'
967 IF cpt85xx ; for CPT-85xx, some graphics map "funny" to keyboard in CP/M
968 db ' (Use CODE + SHIFT + 1/2 key to generate a Control-\)'
972 ; syscls - system-dependent close routine
973 ; called when exiting transparent session.
977 lhld 1 ;Modify back-arrow code to BACKSPACE
978 mvi l,0 ;Get BIOS address
979 lxi d,85H ;Address for key-code =XX85H
981 mov e,m ;Get it in DE
985 mvi m,bs ;Modify code
989 ; sysinh - help for system-dependent special functions.
990 ; called in response to <escape>?, after listing all the
991 ; system-independent escape sequences.
994 IF robin OR dmII OR cpt85xx OR lobo
995 lxi d,inhlps ; we got options...
996 call prtstr ; print them.
997 ENDIF;robin OR dmII OR cpt85xx OR lobo
999 IF bbc OR rm380z ; some more
1000 lxi d,inhlps ; we got options...
1001 call prtstr ; print them.
1002 ENDIF;[22] bbc OR rm380z
1004 IF px8 OR access OR mmate OR disc ;and more...
1005 lxi d,inhlps ; we got options...
1006 call prtstr ; print them.
1007 ENDIF ;px8 OR access OR mmate OR disc
1012 ;additional, system-dependent help for transparent mode
1013 ; (two-character escape sequences)
1016 IF robin OR dmII OR cpt85xx OR lobo
1017 db cr,lf,'B Transmit a BREAK'
1018 ENDIF;robin OR dmII OR cpt85xx OR lobo
1021 db cr,lf,'B Transmit a BREAK'
1024 IF px8 OR access OR mmate
1025 db cr,lf,'B Transmit a BREAK'
1026 ENDIF ;px8 OR access OR mmate
1029 db cr,lf,'B Transmit a 300ms BREAK'
1030 db cr,lf,'L Transmit a 5 second BREAK'
1034 db cr,lf,'D Drop the line'
1037 db '$' ;[hh] table terminator
1040 ; sysint - system dependent special functions
1041 ; called when transparent escape character has been typed;
1042 ; the second character of the sequence is in A (and in B).
1044 ; non-skip: sequence has been processed
1045 ; skip: sequence was not recognized
1047 sysint: ani 137O ; convert lower case to upper, for testing...
1049 IF robin OR dmII OR cpt85xx OR lobo
1050 cpi 'B' ; send break?
1051 jz sendbr ; yes, go do it. return nonskip when through.
1052 ENDIF;robin OR dmII OR cpt85xx OR lobo
1054 IF bbc OR rm380z ; [22] [25] ... some more
1055 cpi 'B' ; send break?
1056 jz sendbr ; yes, go do it. return nonskip when through.
1057 ENDIF; bbc OR rm380z
1059 IF px8 OR access OR mmate ;[28] [29] and anothers
1060 cpi 'B' ; send break?
1061 jz sendbr ; yes, go do it. return nonskip when through.
1062 ENDIF ; px8 OR access OR mmate [28] [29]
1065 cpi 'D' ;[hh] disconnect?
1066 jz discon ;[hh] yes, go do it. nonskip return when done.
1070 cpi 'B' ;Send short break?
1072 cpi 'L' ;Send long break?
1076 jmp rskp ; take skip return - command not recognized.
1080 IF robin ;Definitions & code to send a BREAK (ungenerically, no other way).
1082 comctl equ 59h ;VT180 communications port
1083 crtctl equ 41h ;VT180 crt port
1085 ;VT180 serial port command bits
1087 txe equ 1 ;transmit enable
1089 rxe equ 4 ;rx enable
1091 rerr equ 10h ;reset error
1093 reset equ 40h ;port reset
1095 ;Send a break to the communications port.
1098 sendbr: lxi h,38500 ;250 ms(?)
1099 lda prtadr ;Get address of selected port
1102 ; OUT C,A ;Want to send to port addressed by C
1103 db 0EDH,079H ;Op code for above instruction
1104 sndbr1: dcx h ;timing loop...
1107 jnz sndbr1 ;...until over
1108 lda prtadr ;Get the address for the port
1110 mvi a,txe+dtr+rxe+rerr+rts ;enable tr/rc, dtr, reset error
1111 ; out c,a ;Z-80 only instruction
1112 db 0EDH,079H ;Op code for above instruction
1113 out contst ;reset ports
1117 IF dmII ;[jd] this added to send break on DECmate
1119 ; DECmate command codes for 6120 I/O processor
1120 oboff equ 3fh ; offset of outbyt routine for 6120
1121 prtctl equ 02h ; port control
1122 brdat equ 06h ; data to tell 6120 to send a break
1123 brdur equ 30 ; duration, 30 = 300 ms.
1125 sendbr: lxi b,(brdat * 100h) + prtctl ; c/prtctl, b/brdat
1127 lxi b,brdur*100h ; b/duration, c/0
1128 ; fall through into outbyt
1130 outbyt: lhld 1 ; get warm boot address
1131 lxi d,oboff ; offset of outbyt routine
1132 dad d ; compute address
1133 pchl ; branch there (a callret)
1137 IF access OR mmate ;[cjc] send break on Kaypro [29]
1138 ; Officially, a "break" is 300 milliseconds of "space" (idle line is
1139 ; "mark"). (or maybe 200 milliseconds; I forget.) The timing isn't
1140 ; usually that critical, but we'll make an attempt, at least. Sending
1141 ; too long a break can cause some modems to hang up.
1144 ; First, make sure the transmitter is really empty. (The SIO sets
1145 ; "transmitter buffer empty" when it can accept another character;
1146 ; the previous character is still being shifted onto the line.
1147 ; Another status bit, "all done", is set to indicate that the
1148 ; transmitter is really idle.
1149 sndbr1: mvi a,1 ; select Read Register 1
1151 in mnprts ; read the contents
1152 ani 1 ; test "all done" flag
1153 jz sndbr1 ; loop until it's nonzero.
1155 ; Next, set the "send break" bit to start the transmitter spacing.
1156 mvi a,5 ; select Write Register 5
1158 mvi a,0FAH ; Tx enable, 8 bit Tx character, Send Break,
1159 out mnprts ; DTR and RTS on.
1161 ; Now, delay for 30 hundredths of a second
1162 mvi a,30 ; delay count
1165 ; Time's up. Put transmitter back in normal state (data byte is the
1166 ; same as the one in siotbl: for Write Register 5) and return.
1167 mvi a,5 ; select Write Register 5
1169 mvi a,0EAH ; Tx enable, 8 bit Tx character,
1170 out mnprts ; DTR and RTS on.
1172 ENDIF;access OR mmate [29]
1174 IF lobo ;[hh] This routine sends a break tone or disconnects a modem
1175 ; (those that respond to it) by setting the DTR line low
1178 sendbr: mvi a,05H ;[hh] write register 5
1179 call outctl ;[hh] send it to control port
1180 mvi a,0FAH ;[hh] value to send break tone
1183 discon: mvi a,05H ;[hh] write register 5
1184 call outctl ;[hh] send it to the control port
1185 mvi a,06AH ;[hh] DTR off and break tone on
1186 sndbr1: call outctl ;[hh] send to control port
1187 mvi a,30 ;[hh] delay count for 300 ms.
1188 call delay ;[hh] wait a while...
1189 mvi a,05H ;[hh] write register 5
1190 call outctl ;[hh] get it's attention
1191 mvi a,0EAH ;[hh] normal 8 bits, DTR on, RTS on, etc.
1192 call outctl ;[hh] restore SIO
1195 outctl: sta mnprts ;[hh]
1199 IF cpt85xx OR rm380z ;[lmj] [22] [25]
1202 ; Ensure that the transmitter has finished sending buffered chars
1203 sndbr1: in mnprts ; get UART status
1204 ani TxEmpty ; everything sent?
1205 jz sndbr1 ; no, wait a bit more
1207 ; Begin sending a break by setting bit in UART command register
1208 mvi a,3Fh ; Set TxEna, DTR, RxEna, SBreak, ErrRst, RTS
1211 ; Wait for 250 milliseconds (using hundredths second delay routine)
1215 ; Resume normal operation by clearing the SendBreak command bit
1216 mvi a,37h ;Set TxEna, DTR, RxEna, ErrRst, RTS
1220 ENDIF;cpt85xx OR rm380z
1223 sendbr: mvi a, 3fh ; set break bit
1226 call delay ; wait 250 msec
1227 mvi a, 37h ; clear break bit
1236 ; Ensure that the transmitter has finished sending buffered chars
1237 sndbr1: mvi a,96h ; get ACIA status
1239 call osbyte ; *FX150,8
1241 ani 2 ; everything sent?
1242 jz sndbr1 ; no, wait a bit more
1244 ; Disable centisecond clock (system VIA) which interferes with break
1245 lxi h,0FE4Eh ; system VIA interrupt enable register
1246 mvi a,40H ; disable timer 1
1247 call wrtiom ; write to I/O processor memory
1249 ; Begin sending a break by setting bit in ACIA control register
1251 lxi h,9F60h ; Set Rxint, Txint, Break, RTS
1252 call osbyte ; *FX 156,96,159
1254 ; Wait for 250 milliseconds (using hundredths second delay routine)
1258 ; Resume normal operation by returning old control byte
1260 mvi h,0 ;Set TxEna, DTR, RxEna, ErrRst, RTS
1261 call osbyte ; *FX 156,oldvalue,0
1263 ; Enable centisecond clock (system VIA)
1264 lxi h,0FE4Eh ; system VIA interrupt enable register
1265 mvi a,0C0H ; enable timer 1
1266 call wrtiom ; write to I/O processor memory
1270 ; Routine to write byte in A to I/O processor memory address
1273 shld parblk ; store address to parameter block
1274 sta parblk+4 ; store data
1275 lxi h,parblk ; load hl with address of param block
1276 mvi a,6 ; write I/O processor memory
1277 call osword ; go do it
1280 parblk: DS 5 ; reserve space for parameter block
1284 ; This is almost an exact copy of the bbI sendbr routine.
1285 ; Modifications to include a long break have been made.
1287 ; Officially, a "break" is 300 milliseconds of "space" (idle line is
1288 ; "mark"). (or maybe 200 milliseconds; I forget.) The timing isn't
1289 ; usually that critical, but we'll make an attempt, at least. Sending
1290 ; too long a break can cause some modems to hang up.
1293 push d ;save d, this may not be necessary, but safe
1294 mvi d,17 ;do short break 17 times (approx. 5 sec.)
1298 mvi d,1 ;On short break, do only once
1299 ; First, make sure the transmitter is really empty. (The SIO sets
1300 ; "transmitter buffer empty" when it can accept another character;
1301 ; the previous character is still being shifted onto the line.
1302 ; Another status bit, "all done", is set to indicate that the
1303 ; transmitter is really idle.
1304 sndbr1: mvi a,1 ; select Read Register 1
1306 in mnprts ; read the contents
1307 ani 1 ; test "all done" flag
1308 jz sndbr1 ; loop until it's nonzero.
1310 ; Next, set the "send break" bit to start the transmitter spacing.
1311 mvi a,5 ; select Write Register 5
1313 mvi a,0FAH ; Tx enable, 8 bit Tx character, Send Break,
1314 out mnprts ; DTR and RTS on.
1316 ; Now, delay for 30*d hundredths of a second
1318 mvi a,30 ; delay count
1320 ; The following has been added to allow doing .03 delay d times
1321 dcr d ; decrement # of times to do loop
1322 jnz sendbr2 ; if not done, do again
1325 ; Time's up. Put transmitter back in normal state (data byte is the
1326 ; same as the one in siotbl: for Write Register 5) and return.
1327 mvi a,5 ; select Write Register 5
1329 mvi a,0EAH ; Tx enable, 8 bit Tx character,
1330 out mnprts ; DTR and RTS on.
1336 ; sysflt - system-dependent filter
1337 ; called with character in E.
1338 ; if this character should not be printed, return with A = zero.
1339 ; preserves bc, de, hl.
1340 ; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
1342 mov a,e ; get character for testing
1344 cpi 'O'-100O ;Control-O's lock keyboard
1345 rnz ; if not control-O, it's ok.
1346 xra a ; don't allow control-O out.
1351 ; mdmflt - modem filter [30]
1352 ; called with character to be sent to printer in E
1353 ; with parity set as appropriate.
1354 ; return with accumulator = 0 do do nothing,
1355 ; <> 0 to send char in E.
1357 mov a,e ;[30] get character to test
1362 ; prtflt - printer filter [30]
1363 ; called with character to be sent to printer in E
1364 ; returns with a = 0 to do nothing
1365 ; a <> 0 to print it.
1367 ; this routine for those printer that automatically insert
1368 ; a lf on cr, or cr for lf. Should this be shifted to
1369 ; the system indep. stuff, in say 4.06?
1371 mov a,e ; [30] get character to test
1376 ; system-dependent processing for BYE command.
1377 ; for lobo, hang up the phone.
1380 call discon ;[hh] force modem to hang up
1385 LINK CPXSY2.ASM ; If m80 then this ignored