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
/
BEEHIVE
/
COMMS
/
ZMP-OV16.ARC
/
ZMOBEE.MAC
< prev
next >
Wrap
Text File
|
1991-02-02
|
16KB
|
932 lines
;-----------------------------------------------------------------------------
;
;
; Overlay for ZMP (Z-Modem Program)
;
; Name ZMO-MB01.Z80
;
; Dated Aug 23, 1988
;
; Written by -
; Ron Murray, c/o Z-Node 62, 061-9-450-0200, Perth, Western Australia.
; Modified for the BBII by Lindsay Allen, sysop, Z-Node 62.
;
;
; Rename subsequent versions as ZMO-MB02.Z80 etc
;
;
; This overlay is set up for a Microbee 128k with a Z8530 SCC.
;
;
;
;-----------------------------------------------------------------------------
;
;
; System-dependent code overlay for ZMODEM
;
;
;
; Insert your own code as necessary in this file. Code contained herein
; has been written in Z80 code for use with M80 or SLR. Assemble as follows:
;
; SLR ZMO-MB01/h
; MLOAD ZMP.COM=ZMODEM.COM,ZMO-MB01.HEX
; or
; M80 =ZMO-MB01.Z80
; RELHEX ZMO-MB01
; MLOAD ZMP.COM=ZMODEM.COM,ZMO-MB01.HEX
;
;
; (Don't use L80 without changing the source for assembly as a
; cseg file.)
;
;-----------------------------------------------------------------------------
;
;
; Notes on modifying this file:
;
; C requires that functions do not change either index register
; (IX or IY), nor the BC register pair. If your overlay requires any of
; these to be changed, ensure they are restored to the 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 contact me for another version. If too many people need
; to do it, we haven't allowed enough room.
;
; Ron Murray 15/8/88
;
;
;
;
;
;
;
;
;
;
;-----------------------------------------------------------------------------
;
; This overlay has been written by Cameron Hutchison to work on a microbee
; with a Z8530 SCC installed. I have no plans in writing one for the standard
; serial port. There is a version of ZMP which has been modified to run on
; a 56k machine using the standard serial port. If you are interested then
; contact me.
;
; I am in sort of direct contact with Ron Murray (the author of ZMP) so if you
; have any suggestions for any improvements or know of any bugs then let me
; know and I will pass it on.
;
; Some of the code and ideas for this overlay has been taken from Tony Ellis's
; BYE510 insert. My thanks go to him.
;
; Cameron Hutchison
;
; I can be contacted on SMUG opus on (02) 476-6396 or via
; netmail at 711/417. I also sometimes usually attend most smug meetings
; (sort of).
;
;-----------------------------------------------------------------------------
.z80
aseg
false equ 0
true equ not false
; User-set variables: ***********
clkspd equ 4 ; Processor clock speed in MHz
debug equ false
overdrive equ 'A'
overuser equ 5
userdef equ 0145h ; origin of this overlay
; This address may change with subsequent
; revisions.
ovsize equ 0400h ; max size of this overlay
if debug
org 100h ; so you can debug it with cebug, zsid, etc
else
org userdef
endif
esc equ 1bh
ctrlq equ 11h
cr equ 0dh
lf equ 0ah
bdos equ 5
; Microbee specific equates ******************************************
mdata equ 06bh
mstata equ 069h
mstatb equ 068h
mdrcv equ 1
mdsnd equ 4
onhook equ 07Fh
online equ 080h
error equ 070h
break equ 0FAh
reset equ 030h
; ******************************************
;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 ; Initialize routine
jp userout ; De-initialize routine
jp getvars
jp setport ; set the serial port
jp spare ; Spare for future modifications
jp spare ; Spare for future modifications
jp spare ; Spare for future modifications
jp spare ; Spare for future modifications
jp spare ; Spare for future modifications
jp spare ; Spare for future modifications
;
; Main code starts here
;
codebgn equ $
;
; Screen print function
scrnpr:
call print
db 'This function not supported.',cr,lf,0
ret
; user initialization routine
userin:
ret
; User de-initialization routine
userout:
ret
; For spare jump vectors
spare:
ret
;Get a character from the modem: return in HL
mchin:
push bc
mchin2:
ld a,(port)
ld c,a
ld a,reset
out (c),a
in a,(c) ; check for char waiting
and mdrcv
jr z,mchin2
ld a,(port+1)
ld c,a
in a,(c) ; read the char
ld l,a ; put in HL
ld h,0
or a ; set/clear Z
pop bc
ret
;Send a character to the modem
mchout:
ld hl,2 ; get the character
add hl,sp
ld a,(hl)
push bc
ld b,a ; save the char
ld a,(port)
ld c,a
mchout2:
in a,(c) ; check for uart ready
and mdsnd
jr z,mchout2
ld a,(port+1)
ld c,a
ld a,b ; char in a
out (c),a ; send it
pop bc
ret ; done
;Test for output ready: return TRUE (1) in HL if ok
mordy:
push bc
ld a,(port)
ld c,a
ld hl,0
in a,(c)
and mdsnd
jr z,mordy1
inc hl
mordy1:
ld a,l ; set/clear Z
or a
pop bc
ret
;Test for character at modem: return TRUE (1) in HL if so
mirdy:
push bc
ld a,(port)
ld c,a
ld hl,0
in a,(c)
and mdrcv
jr z,mirdy1
inc hl
mirdy1:
ld a,l ; set/clear Z
or a
pop bc
ret
;Send a break to the modem: leave empty if your system can't do it
sndbrk:
push bc
ld a,(port)
ld c,a
ld a,5
out (c),a
ld a,break ; FA
out (c),a
ld hl,300 ; 300 msecs
call waithls
ld a,5
out (c),a
ld a,0eah
out (c),a
pop bc
ret
;
;Test UART flags for error: return TRUE (1) in HL if error.
mdmerr:
push bc
ld a,(port)
ld c,a
ld hl,0
in a,(c)
and error
jr z,mdmer2
inc hl
mdmer2:
ld a,l ; set/clear Z
or a
pop bc
ret
;Turn DTR ON
dtron:
push bc
ld a,(port)
ld c,a
ld a,5
out (c),a
ld a,0eah ; DTR and RTS on
out (c),a
pop bc
ret
;Turn DTR OFF
dtroff:
push bc
ld a,(port)
ld c,a
ld a,5
out (c),a
ld a,068h ; DTR and RTS off
out (c),a
pop bc
ret
;Initialise the SCC +++
; The SCC is set up in four steps:
; 1) Reset
; 2) Reg 4 - clock, stop bits, parity
; 3) Reg 5 - dtr, Tx bits, Brk, TxEn, rts
; 4) Reg 3 - Rx bits, RxEn
; leave the bit before the ******
init:
; call dtron
; ret
ld hl,2 ; get parameters
add hl,sp
ex de,hl
call getparm ; in HL
ld (brate),hl ; baud rate
ld a,l
ld (003Ch),a ; save the baud rate in 3C for later as per IMP
call getparm
ld (parity),hl ; parity
call getparm
ld (databits),hl ; data bits
call getparm
ld (stop),hl ; stop bits
; ******
push bc
ld c,mstatb
ld b,6 ; table1end-table1
ld hl,table1
otir
ld a,(port)
cp 068h
jr nz,xt1pa
ld hl,tab1b
ld b,4
otir
jr drob
xt1pa:
ld hl,tab1a
ld b,4
otir
drob:
ld b,14
ld hl,table1+6
otir
dtpa:
ld c,mstata
ld b,4 ; table2end-table2
ld hl,table2
otir
ld a,(port)
cp 068h
jr nz,xt2pa
ld hl,tab2b
ld b,4
otir
jr droa
xt2pa:
ld hl,tab2a
ld b,4
otir
droa:
ld hl,table2+4
ld b,14
otir
susp:
ld a,(port)
ld c,a
ld a,4 ; point to wrt reg 4
out (c),a
ld e,44h ; assume x16, 1 stop, No parity
ld a,(stop) ; set stop bits
cp 2 ; set 2 if required
jr nz,setpar
set 3,e
setpar:
ld a,(parity) ; set parity bits
cp 'O'
jr nz,setpa2
set 0,e ; ODD
jr setpa3
setpa2: cp 'E'
jr nz,setpa3
set 0,e
set 1,e ; EVEN
setpa3: ld a,e
out (c),a ; *** step 2
ld a,5 ; point to wrt reg 5 - dtr, Tx bits, etc
out (c),a
ld e,0EAh ; assume dtr, TX 8 bits, TxEn, rts
ld a,(databits)
cp 7
jr nz,setbi2
res 6,e ; 7 bits
setbi2: ld a,e
out (c),a ; *** step 3
ld a,3 ; point to wrt reg 3
out (c),a
ld e,0C1h ; assume 8 bits
ld a,(databits)
cp 7
jr nz,setbi3
res 7,e ; 7 bits
setbi3: ld a,e
out (c),a ; *** step 4
setbrate:
ld de,(brate) ; get baud rate value (0-10)
dec e
jr z,set300
dec e
dec e
dec e
dec e
jr z,set1200
dec e
jr z,set2400
dec e
jr z,set4800
dec e
jr z,set9600
; Falls through to SET2400 if invalid value (i.e. not supported one)
set2400:
push bc
push de
ld de,002eh
ld bc,028h
jr setbaud
set300:
push bc
push de
ld de,017eh
ld bc,028h
jr setbaud
set1200:
push bc
push de
ld de,005eh
ld bc,028h
jr setbaud
set4800:
push bc
push de
ld de,0016h
ld bc,028h
jr setbaud
set9600:
push bc
push de
ld de,000ah
ld bc,028h
setbaud:
ld a,0bh
out (mstata),a
ld a,c
out (mstata),a
ld a,0dh
out (mstatb),a
ld a,d
out (mstatb),a
ld a,0ch
out (mstatb),a
ld a,e
out (mstatb),a
pop de
pop bc
ld a,(port)
ld c,a
ld a,05h
out (c),a
ld a,0eah
out (c),a
call dtron
pop bc
ret
;
; Set the port. ZMP supplies either 0 or 1 as a parameter. You're on your
; own here -- your system is bound to be different from any other! You may
; implement a software switch on all the modem-dependent routines, or perhaps
; you can have one or two centralised routines for accessing the UARTs and
; modify the code from this routine to select one or the other. (Who said
; there was anything wrong with self-modifying code?). If you have only one
; UART port, or if you don't want to go through all the hassles, just have
; this routine returning with no changes made. Note that ZMP calls this
; routine with both values for the port on initialisation.
;
setport:
ld hl,2 ; get port number
add hl,sp
ex de,hl
call getparm ; in HL (values are 0 and 1)
ld a,h ; 0 - port a
or l ; 1 - port b
jr nz,spb
ld a,69h
ld (port),a
ld a,6bh
ld (port+1),a
ret
spb:
ld a,68h
ld (port),a
ld a,6ah
ld (port+1),a
ret
brate:
dw 6 ; baud rate:
parity:
dw 'N' ; parity
databits:
dw 8 ; data bits
stop:
dw 1 ; stop bits
port:
db 069h ; This is the port used. It can be changed
; from the program
db 06bh ; This is the data port used. Make sure it
; corresponds with the control port or
; anything could happen.
table1:
db 09h
db 0c0h
db 04h
db 044h
db 01h
db 00h
db 09h
db 00h
db 0bh
db 0d6h
db 0eh
db 061h
db 0fh
db 00h
db 0ch
db 02eh and 0ffh
db 0dh
db 02eh shr 8
db 00h
db 030h
table1end:
tab1a:
db 03h
db 0c0h
db 05h
db 060h
tab1b:
db 03h
db 0c1h
db 05h
db 068h
table2:
db 04h
db 044h
db 01h
db 00h
db 0bh
db 028h
db 0eh
db 061h
db 0fh
db 00h
db 0ch
db 06h
db 0dh
db 00h
db 00h
db 038h
db 00h
db 030h
table2end:
tab2a:
db 03h
db 0c1h
db 05h
db 068h
tab2b:
db 03h
db 0c0h
db 05h
db 060h
;****************************************************************************
;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
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
ret
row: ds 2 ; row
col: ds 2 ; column
;Clear screen:
cls:
call print
db 1ah,0
ret
;Inverse video on:
invon:
call print
db esc,')',0
ret
;Inverse video off:
invoff:
call print
db esc,'(',0
ret
;Turn off cursor:
hide:
call print
db esc,'}',0
ret
;Turn on cursor:
show:
call print
db esc,'{',0
ret
;Save cursor position:
savecu:
call print
db esc,'[s',0
ret
;Restore cursor position:
rescu:
call print
db esc,'[u',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 ********************************
; Do not change anything below here.
;Modem character test for 100 ms
mrd:
push bc ; save bc
ld bc,100 ; set limit
mrd1:
call mirdy ; char at modem?
jr nz,mrd2 ; yes, exit
ld hl,1 ; else wait 1ms
call waithlms
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 ; character to E
ld c,2
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
waithls:
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
waithlms:
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
getvars:
ld hl,usevars
ret
usevars:
dw overdrive
dw overuser
if ($ - codebgn) gt ovsize
toobig: jp errval ; Overlay too large!
endif
end