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
/
MODEMS
/
ZMODEM
/
ZMO-KP12.ZZ0
/
ZMO-KP12.Z80
Wrap
Text File
|
2000-06-30
|
18KB
|
696 lines
;
; Overlay to ZMP (Z-Modem Program), for the Kaypro CP/M computers.
; (Z80 SIO and 8116 baudrate generator.)
;
; Name: zmo-kp07.z80
;
; Dated: 10 April 1989
;
; Written by -
; Ron Murray, c/o Z-Node 62, 061-9-450-0200, Perth, Western Australia.
; kp07 - April 89. Updated "my" 06 (which had been a simple change of
; video code from Duerr's 05) to run on ZMP version 1.5.
; This version does not implement the dual port option. If
; any Kaypro owner has use of this option (it would have to
; take over the serial printer port), drop me a "line."
; In addition, the equate for RTS/CTS has been set at 'false'
; for the COM file included with this file. Tests have suggested
; that the Kaypro 2X/4/10/1 series' problems with dropping char-
; acters in terminal mode have to do with the inability of the
; Z80 to perform both its video and CPU functions in those machines
; at baud rates above 1200. The character dropping does not
; affect the quality of non-ASCII file transfers.
; Michael Broschat, GEnie address: M.BROSCHAT; also,
; Adam's RiBBS: Seattle WA area (206) 882-3684
; KP05 - Nov. 24, 88. Updated for ZMP version 1.4 (overlay drive/user
; equates). Added conditional to check RTS/CTS signals.
; Bill Duerr, GEnie ID: B.DUERR
; DKUG RBBS [313] 772-0522
;
; KP04 - Oct. 22, 88. Updated to allow program to be reentered properly,
; for 8-N-1 only -- still problems with even/odd parity.
; Bill Duerr, GEnie ID: B.DUERR
; DKUG RBBS [313] 772-0522
;
; KP03 - Oct. 12, 88 Modified to ZMP v1.3 standard rjm
;
;
; Insert your own code as necessary in this file. Code contained herein
; has been written in Z80 code for use with M80. Once assembled,
; convert to hex with RELHEX and use MLOAD to overlay it over the main
; ZMPX.COM file to produce your very own ZMP.COM.
;
; Notes on modifying this file:
; Hi-Tech C requires that functions do not change either index register
; (IX or IY). If your overlay requires either of these to be changed, ensure
; they are restored to their original values on return.
; Since collecting parameters from C functions can be tricky, only change
; the parts marked 'Insert your own code here'. Do NOT modify the jump
; table at the start. Do NOT modify the entry/exit sections of each
; function. Do NOT pass 'GO'. Do NOT collect $200.
; Apart from defining modem functions, this file also defines terminal
; characteristics. Most have been set up for ADM-3A (with a few of my own
; additions). Modify to suit your own terminal. An inline print routine
; is provided for printing strings in the usual way: usage is
;
; call print
; db 'required string',0
;
; Don't forget to set your clock speed at the clkspd variable.
;
; If you find your overlay exceeds the maximum size (currently 0400h),
; you will have to re-compile the whole thing. Good luck. You might try
; informing us if you need to do this: if too many people need to do it, we
; haven't allowed enough room.
;
; Ron Murray 15/8/88
;
;
false equ 0
true equ not false
;
; If the following equate is set to true, code will be added to set
; the RTS modem signal, telling the modem not to send any characters
; till RTS is reset, and also to check CTS if characters may be sent.
; This allows the Kaypro screen to keep up with the characters sent
; over the modem lines at higher speeds. (The modem must be able to
; recognize RTS and set CTS for this to work.)
;
rtscts equ false
;
;Set the following two equates to the drive and user area which will contain
; ZMP's .OVR files, .CFG file, .FON file and .HLP file. Set both to zero
; (null) to locate them on the drive from which ZMP was invoked.
overdrive equ 'A' ; Drive to find overlay files on ('A'-'P')
overuser equ 0 ; User area to find files
;------------------------------------------------------------------------------
;User-set variables:
clkspd equ 4 ; Processor clock speed in MHz
mspeed equ 003ch ; Current baud rate: as used by BYE etc
; This MUST be the same as Mspeed in
; ZMP.H
dport equ 04h ; Kaypro SIO data port
sport equ dport+2 ; Modem control port
mdrcv equ 01h ; Modem receive ready
mdsnd equ 04h ; Modem send ready bit
mdtxe equ 01h ; Modem send buffer empty, holding buffer empty
rsterr equ 30h ; Reset parity and overrun flags - register 0
reg1ins equ 0 ; No interrupts - register 1
reg3ins equ 0c1h ; 8 Rx bits, Rx enable
reg4ins equ 44h ; 16X baud rate, 1 stop bit, no parity
reg5ins equ 0eah ; 8 Tx bits, Tx enable, RTS, DTR
bauda equ 00h ; 8116 port for baudrate
rstsio equ 18h ; Reset the SIO
dcd equ 08h ; Data Carrier Detect
dtr equ 80h ; Data Terminal Ready
rts equ 02h ; Request to send
cts equ 20h ; Clear to send
brk equ 10h ; SIO Break
sioerr equ 70h ; SIO error
userdef equ 00145h ; origin of this overlay: get this value
; from the .SYM file produced when ZMP.COM
; is linked
ovsize equ 0400h ; max size of this overlay
org userdef
esc equ 1bh
ctrlq equ 11h
cr equ 0dh
lf equ 0ah
bdos equ 5
;Jump table for the overlay: do NOT change this
jump_tab:
jp scrnpr ; screen print
jp mrd ; modem read with timeout
jp mchin ; get a character from modem
jp mchout ; send a character to the modem
jp mordy ; test for tx buffer empty
jp mirdy ; test for character received
jp sndbrk ; send break
jp cursadd ; cursor addressing
jp cls ; clear screen
jp invon ; inverse video on
jp invoff ; inverse video off
jp hide ; hide cursor
jp show ; show cursor
jp savecu ; save cursor position
jp rescu ; restore cursor position
jp mint ; service modem interrupt
jp invec ; initialise interrupt vectors
jp dinvec ; de-initialise interrupt vectors
jp mdmerr ; test uart flags for error
jp dtron ; turn DTR on
jp dtroff ; turn DTR OFF
jp init ; initialise uart
jp wait ; wait seconds
jp mswait ; wait milliseconds
jp userin ; user-defined entry routine
jp userout ; user-defined exit routine
jp getvars ; get system variables
jp setport ; choose one of two (not implemented)
; Spare jumps for compatibility with future versions
jp spare ; spare for later use
jp spare ; spare for later use
jp spare ; spare for later use
jp spare ; spare for later use
jp spare ; spare for later use
; Main code starts here
;
codebgn equ $
;
;Screen print function
scrnpr:
; <== Insert your own code here
call print
db 'This function not supported.',cr,lf,0
; <== End of your own code
spare:
ret
; User-defined entry routine
userin:
ret
; User-defined exit routine
userout: ; Leave RTS off
if rtscts
ld a,05h ; Select register 5
out (sport),a ; Send to the status port
ld a,(reg5) ; Get register 5 settings
and 255-rts ; Turn off RTS
out (sport),a ; Send to the status port
endif ; rtscts
ret
;Get a character from the modem: return in HL
; It is not necessary to test for status
mchin:
;-- Code added specific to Kaypro
in a,(dport) ; get the character in A
;
; This routine checks parity, and if parity is not "none", strips high bit.
; This is needed, even if the filter is turned on, because CONNECT message
; is not filtered.
;
ld l,a ; Save in L
ld a,(parity) ; Check parity
cp 'N' ; No parity?
ld a,l ; Get the character back
jr z,mchin1 ; Bypass following kludge
and 7fh
ld l,a ; put in HL
mchin1:
if rtscts
ld a,05h ; Select register 5
out (sport),a ; Send to the status port
ld a,(reg5) ; Get register 5 settings
and 255-rts ; Turn off RTS
out (sport),a ; Send to the status port
endif ; rtscts
;-- End of this block of machine specific code
ld a,l ; get character from HL
ld h,0
or a ; set/clear Z
ret
;Send a character to the modem
mchout:
ld hl,2 ; Get the character
add hl,sp
ld a,(hl) ; in A
;-- Code added specific to Kaypro
out (dport),a ; Put the character to the serial port
;-- End of this block of machine specific code
ret ; done
;Test for output ready: return TRUE (1) in HL if ok
mordy:
;-- Code added specific to Kaypro
ld hl,0 ; Assume not ready
;
if rtscts
ld a,10h ; Reset register 0
out (sport),a ; Send to the status port
in a,(sport) ; read status port
and cts ; Is clear to send up
jr z,mordy1 ; Branch if not clear to send
endif ; rtscts
;
ld a,10h ; Reset register 0
out (sport),a ; Send to the status port
in a,(sport) ; Read status port
and mdsnd ; Isolate transmit empty bit
jr z,mordy1 ; Branch if not ready
inc hl ; otherwise set HL to indicate ready
mordy1:
;-- End of this block of machine specific code
ld a,l
or a ; set/clear Z
ret
;Test for character at modem: return TRUE (1) in HL if so
mirdy:
;-- Code added specific to Kaypro
ld a,05h ; Select register 5
out (sport),a ; Send to the status port
ld a,(reg5) ; Get register 5 settings
or rts ; Turn on RTS
out (sport),a ; Send to the status port
ld hl,0 ; Assume not ready
ld a,10h ; Reset register 0
out (sport),a ; Send to the status port
in a,(sport) ; Get the status
and mdrcv ; Isolate receive ready bit
jr z,mirdy1 ; Branch if not ready
inc hl ; otherwise set HL to indicate ready
mirdy1:
;-- End of this block of machine specific code
ld a,l
or a ; set/clear Z
ret
;Send a break to the modem: leave empty if your system can't do it
sndbrk:
;-- Code added specific to Kaypro
ld a,5 ; Select register 5
out (sport),a ; Send to the status port
ld a,(reg5) ; Get parameters for register 5
or brk ; Set the break tone
out (sport),a ; Send to the status port
;-- End of this block of machine specific code
ld hl,300
call waitms ; wait 300 mS
;-- Code added specific to Kaypro
ld a,5 ; Select register 5
out (sport),a ; Send to the status port
ld a,(reg5) ; Restore register 5 settings
out (sport),a ; Send to the status port
;-- End of this block of machine specific code
ret
;Test UART flags for error: return TRUE (1) in HL if error
mdmerr:
;-- Code added specific to Kaypro
ld hl,0 ; Assume no error
ld a,011h ; Select read register 1
out (sport),a ; Send to the status port
in a,(sport) ; Get error status
and sioerr ; Mask all but error bits
ret z ; Return zeor in HL if no error
inc hl ; Otherwise set HL to indicate error
ret ; Return
;Turn DTR (and optionally RTS) ON.
dtron:
;-- Code added specific to Kaypro
ld a,05h ; Select register 5
out (sport),a ; Send to the status port
ld a,(reg5) ; Get register 5 settings
out (sport),a ; Send to the status port
;-- End of this block of machine specific code
ret
;Turn DTR ( and RTS?) OFF
dtroff:
;-- Code added specific to Kaypro
ld a,05h ; Select register 5
out (sport),a ; Send to the status port
ld a,(reg5) ; Get register 5 settings
and 255-dtr ; Turn off DTR
out (sport),a ; Send to the status port
;-- End of this block of machine specific code
ret
;Initialise the UART
init:
ld hl,2 ; get parameters
add hl,sp
ld a,(hl) ; get lo
ld (mspeed),a ; save in baud rate low memory
inc hl
inc hl ; bump for next
ld a,(hl) ; get lo
and 5Fh ; Convert to upper case
ld (parity),a ; parity
inc hl
inc hl ; bump for next
ld a,(hl) ; get lo
and 0fh ; Make sure binary
ld (data),a ; Save data bits
cp 7 ; but 7 if required
ld a,reg5ins ; 8 Tx bits, Tx enable, RTS, DTR
jr nz,setbs
ld a,reg5ins-040h ; Turn bit off
setbs:
ld (reg5),a
inc hl
inc hl ; bump for next
ld a,(hl) ; get lo
and 0fh ; Make sure binary
ld (stop),a ; stop bits
; <== Insert your own code here
;-- Code added specific to Kaypro
ld a,10h ; Reset register 0
out (sport),a ; Send to the status port
in a,(sport) ; read status port
and DCD ; Is carrier up
jr nz,initr ; Branch if carrier already there
ld A,0 ; Select register 0
out (sport),a ; Send to status port
ld a,rstsio ; Reset SIO - 18h
out (sport),a ; Send to status port
;
ld A,4 ; Select register 4
out (sport),a ; Send to status port
ld a,(parity) ; do parity
ld e,003h ; assume even parity
cp 'E' ; even?
jr z,setstop ; yes
ld e,001h ; try odd
cp 'O'
jr z,setstop
ld e,0 ; Indicate no parity
setstop:
ld a,(stop) ; set stop bits
cp 2
ld a,reg4ins ; 16X baud rate, 1 stop bit, no parity
jr nz,onestop
or 00ch ; set bits 2 and 3
onestop:
or e ; put parity bits in the register
;
out (sport),a ; Send to status port
;
ld a,3 ; Select register 3
out (sport),a ; Send to status port
;
ld a,(data) ; get data bits parameter field
cp 7 ; is 7 required
ld a,reg3ins ; 8 Rx bits, Rx enable
jr nz,setbr
and 07fh
setbr:
out (sport),a ; Set Rx bits
ld a,5 ; Select register 5
out (sport),a ; Send to status port
ld a,(reg5) ; Get register 5 settings
out (sport),a ; Set tx bits
;
ld a,1 ; Select register 1
out (sport),a
ld a,reg1ins ; No interrupts
out (sport),a ; Send to status port
;
ld a,(mspeed) ; set baud rate: get index
ld hl,brval
ld e,a ; rate to DE
ld d,0
add hl,de
ld a,(hl) ; get baud rate value
out (bauda),a
; <== End of your own code
initr: ret
;
; Baud rate factors, output to bauda to select baud rate
;
bd10 equ 02h ; 110 baud rate 0
bd30 equ 05h ; 300 baud rate 1
bd12 equ 07h ; 1200 baud rate 5
bd24 equ 0ah ; 2400 baud rate 6
bd48 equ 0ch ; 4800 baud rate 7
bd96 equ 0eh ; 9600 baud rate 8
bd19k equ 0fh ; 19.2k baud rate 9
;Values for control reg for each baud rate: 0 if invalid
brval:
; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
db 00,01,00,00,00,07,10,12,14,15
; <== End of your own code
ret
brate: db 6,0 ; baud rate:
; 0 = 110 baud 1 = 300 baud 2 = 450 baud
; 3 = 600 baud 4 = 710 baud 5 = 1200 baud
; 6 = 2400 baud 7 = 4800 baud 8 = 9600 baud
; 9 = 19200 baud
parity: db 'N',0 ; parity (will be 'N', 'E' or 'O')
data: db 8,0 ; data bits (will be 7 or 8)
stop: db 1,0 ; stop bits (will be 1 or 2)
reg5: db reg5ins
;****************************************************************************
;Video terminal sequences: these are for ADM-3A: Modify as you wish
;Cursor addressing:
cursadd:
ld hl,2 ; get parameters
add hl,sp
ex de,hl
call getparm ; in HL
ld (row),hl ; row
call getparm
ld (col),hl ; column
; <== Insert your own code here
; using values in row and col
call print
db esc,'=',0 ; ADM-3A leadin
ld a,(row) ; row first
add a,' ' ; add offset
call cout
ld a,(col) ; sane for column
add a,' '
call cout
; <== end of your own code
ret
row: ds 2 ; row
col: ds 2 ; column
;Clear screen:
cls:
call print
db 01ah,0
ret
;Inverse video on:
invon:
call print
db esc,'B','0',esc,'B','1',0
ret
;Inverse video off:
invoff:
call print
db esc,'C','0',esc,'C','1',0
ret
;Turn off cursor:
hide:
call print
db esc,'C','4',0
ret
;Turn on cursor:
show:
call print
db esc,'B','4',0
ret
;Save cursor position:
savecu:
call print
defb esc,'B','6',0
ret
;Restore cursor position:
rescu:
call print
defb esc,'C','6',0
ret
;****************************************************************************
;Service modem interrupt:
mint:
ret ; my system doesn't need this
;Initialise interrupt vectors:
invec:
ret ; ditto
;De-initialise interrupt vectors:
dinvec:
ret ; ditto
;****************** End of user-defined code ********************************
; Don't change anything below this point. We needed some assembly language
; stuff for speed, and this seemed like a good place to put it.
;Modem character test for 100 ms
mrd:
push bc ; save bc
ld bc,100 ; set limit
mrd1:
call mirdy ; character at modem?
jr nz,mrd2 ; yes, exit
ld hl,1 ; else wait 1ms
call waitms
dec bc ; loop till done
ld a,b
or c
jr nz,mrd1
ld hl,0 ; none there, result=0
xor a
mrd2:
pop bc
ret
; Inline print routine: destroys A and HL
print:
ex (sp),hl ; get address of string
ploop:
ld a,(hl) ; get next
inc hl ; bump pointer
or a ; done if zero
jr z,pdone
call cout ; else print
jr ploop ; and loop
pdone:
ex (sp),hl ; restore return address
ret ; and quit
;
;Output a character in A to the console
;
cout:
push bc ; save regs
push de
push hl
ld e,a ; Save the character to E for BDOS routine
ld c,2 ; BDOS conout routine
call bdos ; print it
pop hl
pop de
pop bc
ret
;Wait(seconds)
wait:
ld hl,2
add hl,sp
ex de,hl ; get delay size
call getparm
; fall thru to..
;Wait seconds in HL
waits:
push bc ; save bc
push de ; de
push ix ; and ix
ld ix,0 ; then point ix to 0
; so we don't upset memory-mapped i/o
;Calculate values for loop constants. Need to have two loops to avoid
; 16-bit overflow with clock speeds above 9 MHz.
outerval equ (clkspd / 10) + 1
innerval equ (6667 / outerval) * clkspd
wait10:
ld b,outerval
wait11:
ld de,innerval
wait12:
bit 0,(ix) ; time-wasters
bit 0,(ix)
bit 0,(ix) ; 20 T-states each
bit 0,(ix)
bit 0,(ix)
bit 0,(ix)
dec de
ld a,e
ld a,d
or e
jr nz,wait12 ; 150 T-states per inner loop
djnz wait11 ; decrement outer loop
dec hl ; ok, decrement count in hl
ld a,h
or l
jr nz,wait10
pop ix ; done -- restore ix
pop de ; de
pop bc ; and bc
ret
;Wait milliseconds
mswait:
ld hl,2
add hl,sp
ex de,hl ; get delay size
call getparm
; fall thru to..
;Wait milliseconds in HL
waitms:
push de
w1ms0:
ld de,39 * clkspd
w1ms1:
dec de
ld a,d
or e
jr nz,w1ms1
dec hl
ld a,h
or l
jr nz,w1ms0
pop de
ret
;Get next parameter from (de) into hl
getparm:
ex de,hl ; get address into hl
ld e,(hl) ; get lo
inc hl
ld d,(hl) ; then hi
inc hl ; bump for next
ex de,hl ; result in hl, address still in de
ret
;Get address of user-defined variables
getvars:
ld hl,uservars
ret
uservars:
dw overdrive ; .OVR etc. drive/user
dw overuser
setport:
ret
if ($ - codebgn) gt ovsize
toobig: jp errval ; Overlay too large!
endif
end