home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
KERMIT
/
CP411SRC.ARK
/
cpxsys.asm
< prev
next >
Wrap
Assembly Source File
|
1991-04-23
|
41KB
|
1,387 lines
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