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
/
ZMO-BB06.Z80
< prev
next >
Wrap
Text File
|
1991-02-02
|
15KB
|
734 lines
;-----------------------------------------------------------------------------
;
;
; Overlay for ZMP (Z-Modem Program)
;
; Name ZMO-BBxx.Z80
;
; Dated 18 Sep 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.
; Modified to 1.4 standard, SIO init order changed, mdmerr fixed.
; Modified to ZMP v1.5 standard rjm 25/3/89
;
;
; Rename subsequent versions as ZMO-BBxx.Z80 etc
;
;
; This overlay is set up for a BigBoardII using port B.
; Uses a Z80SIO and Z80CTC.
;
;
;-----------------------------------------------------------------------------
;
;
; 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-BBxx/h
; MLOAD ZMP.COM=ZMPX.COM,ZMO-BBxx.HEX
; or
; M80 =ZMO-BBxx.Z80
; RELHEX ZMO-BBxx
; MLOAD ZMP.COM=ZMPX.COM,ZMO-BBxx.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
;
;
;
;
;
;
;
;
;
;
;-----------------------------------------------------------------------------
false equ 0
true equ not false
; User-set variables: ***********
clkspd equ 4 ; Processor clock speed in MHz
debug equ false
;Set the following two equates to the drive and user area which will
; contain zmp's .OVR files, .CFG file and .FON file. Set both to zero
; to locate them on the drive from which zmp is invoked.
overdrive equ 'H' ; Drive to find overlays on. Range is 'A'-'P'
overuser equ 15 ; User area to find overlays
userdef equ 0145h ; origin of this overlay
; This address may change with subsequent
; revisions.
ovsize equ 0400h ; max size of this overlay
.z80 ; use z80 code
aseg ; absolute
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
; BBII specific equates ******************************************
mdata equ 082h
mdctl equ 083h
rda equ 0
tbe equ 2
ctc equ 88h
mode equ 47h
onhook equ 7Fh
online equ 80h
error equ 70h
break equ 0F8h
reset equ 30h
; ******************************************
;-------------------------------------------------------------------------
; Main code starts here
codebgn equ $
;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 ; set port (1 or 2)
; 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
jp spare ; spare for later use
spare: ret
;-------------------------------------------------------------------------
;Screen print function
scrnpr:
; <== Insert your own code here
call print
db 'This function not supported.',cr,lf,0
; <== End of your own code
ret
;Get a character from the modem: return in HL
mchin:
push bc
; <== Insert your own code here
mchin2:
in a,(mdctl) ; check for char waiting
bit rda,a
jr z,mchin2
in a,(mdata) ; read the char
; <== End of your own code
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)
; <== Insert your own code here
push bc
ld b,a ; save the char
mchout2:
in a,(mdctl) ; check for uart ready
bit tbe,a
jr z,mchout2
ld a,b ; char in a
out (mdata),a ; send it
pop bc
; <== End of your own code
ret ; done
;Test for output ready: return TRUE (1) in HL if ok
mordy:
; <== Insert your own code here
ld hl,0
in a,(mdctl)
bit tbe,a ; transmit buffer empty
jr z,mordy1
inc hl
mordy1:
; <== End of your own code
ld a,l ; set/clear Z
or a
ret
;Test for character at modem: return TRUE (1) in HL if so
mirdy:
; <== Insert your own code here
ld hl,0
in a,(mdctl)
bit rda,a ; received data available
jr z,mirdy1
inc hl
mirdy1:
; <== End of your own code
ld a,l ; set/clear Z
or a
ret
;Send a break to the modem: leave empty if your system can't do it
sndbrk:
; <== Insert your own code here
ld a,5
out (mdctl),a
ld a,break ; F8
out (mdctl),a
ld hl,01 ; a 1 second break
call wait1s
ld a,5
out (mdctl),a
ld a,online ; 68
out (mdctl),a
ld a,3
out (mdctl),a
ld a,0E1h
out (mdctl),a ; E1
; <== End of your own code
ret
;
;Test UART flags for error: return TRUE (1) in HL if error.
mdmerr:
; <== Insert your own code here
ld hl,0 ; assume no error
ld a,1 ; select RR1
out (mdctl),a
in a,(mdctl) ; read it
and error ; mask out the other bits
jr z,noerr
ld a,38h ; error reset (latches)
out (mdctl),a
inc hl ; tell ZMP that we have an error
noerr:
; <== End of your own code
ld a,l ; set/clear Z
or a
ret
;Turn DTR ON
dtron:
; <== Insert your own code here
ld a,5
out (mdctl),a
ld a,(combyt) ; get the one we used last time
or a,online ; 80h - set bit 7 high
ld (combyt),a ; save it for next time
out (mdctl),a ; go
; <== End of your own code
ret
;Turn DTR OFF
dtroff:
; <== Insert your own code here
ld a,5
out (mdctl),a
ld a,(combyt) ; get the one we used last time
and onhook ; 7Fh - clear bit 7
ld (combyt),a ; save it for next time
out (mdctl),a ; go
; <== End of your own code
ret
;Initialise the SIO +++
; The SIO is set up in four steps:
; 1) Reset
; 2) Reg 4 - clock, stop bits, parity
; 3) Reg 3 - Rx bits, RxEn
; 4) Reg 5 - dtr, Tx bits, Brk, TxEn, rts
init:
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 (data),hl ; data bits
call getparm
ld (stop),hl ; stop bits
; <== Insert your own code here
; using values below
push bc
ld a,0
out (mdctl),a ; point to reg 0
ld a,18h ; reset
out (mdctl),a ; *** step 1
ld a,4 ; point to wrt reg 4
out (mdctl),a
ld e,44h ; assume x16, 1 stop, No parity
ld a,(stop) ; get stop bit setting
cp 2 ; need 2 ?
jr nz,setpar ; no - 1 stop bit already set
set 3,e ; yes - set 2 stop bits
setpar:
ld a,(parity) ; set parity bits
cp 'O' ; want ODD parity ?
jr nz,setpa2 ; no
set 0,e ; yes - set ODD parity
jr setpa3 ; parity set so skip setpa2
setpa2: cp 'E' ; want EVEN parity ?
jr nz,setpa3 ; no - "NONE" already set
set 0,e ; yes - set EVEN parity
set 1,e ;
setpa3: ld a,e
out (mdctl),a ; *** step 2
ld a,3 ; point to wrt reg 3
out (mdctl),a
ld e,0C1h ; assume 8 Rx data bits
ld a,(data) ; get required setting
cp 7 ; seven ?
jr nz,setbi3 ; no - eight Rx data bits already set
res 7,e ; set 7 Rx data bits
setbi3: ld a,e
out (mdctl),a ; *** step 3
ld a,5 ; point to wrt reg 5 - dtr, Tx bits, etc
out (mdctl),a
ld e,0EAh ; assume dtr, Tx 8 bits, TxEn, rts
ld a,(data) ; number of Tx data bits required
cp 7 ; seven ?
jr nz,setbi2 ; no
res 6,e ; yes - set 7 Tx data bits
setbi2: ld a,e
out (mdctl),a ; *** step 4
setbrate:
ld a,mode ; 47h
out (ctc),a ; select the correct timer and mode of the CTC
ld de,(brate) ; get baud rate value (0-10)
ld hl,brval
add hl,de
ld a,(hl)
out (ctc),a
pop bc
ret
brate: dw 6 ; baud rate:
parity: dw 'N' ; parity
data: dw 8 ; data bits
stop: dw 1 ; stop bits
combyt: db 0EAh ; save it here
;Values for Z80CTC control reg for each baud rate: 0 if invalid
brval:
db 0 ; 110 0
db 80h ; 300 1
db 0 ; 450 2
db 40h ; 600 3
db 0 ; 710 4
db 20h ; 1200 5
db 10h ; 2400 6
db 08h ; 4800 7
db 04h ; 9600 8
db 02h ; 19200 9
;
; 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)
; <== Insert your own code here
; <== End of your own code
ret
port: ds 1
;*****************************************************************************
;My system needs a BIOS call to access the UART. If yours doesn't, you don't
; need anything here. Otherwise write your own.
calmod:
; not required for most computers
;****************************************************************************
;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 esc,'*',0
ret
;Inverse video on:
invon:
call print
db esc,'G4',0
ret
;Inverse video off:
invoff:
call print
db esc,'G0',0
ret
;Turn off cursor:
hide:
; call print
; db esc,'.1',0
ret
;Turn on cursor:
show:
; call print
; db esc,'.3',0
ret
;Save cursor position:
savecu:
ret
;Restore cursor position:
rescu:
ret
;User-defined entry routine: leave empty if not used
userin:
ret
;User-defined exit routine: leave empty if not used
userout:
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.
mrd:
push af
push bc
ld hl,1 ; "character waiting"
ld bc,7600 ; empirical value, found by timing tests
mrd1:
in a,(mdctl) ; check for char waiting
bit rda,a
jr nz,mrd2
dec bc
ld a,b
or c
jr nz,mrd1
ld hl,0 ; "no character"
mrd2:
pop bc
pop af
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
wait1s:
push de
wait10:
ld de,6667 * clkspd
wait11:
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,wait11 ; 150 T-states per loop
dec hl
ld a,h
or l
jr nz,wait11
pop de
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
wait1ms:
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,uservars
ret
ds ($ or 0Fh) - $ + 1,0
db 'OVERLAYS',0
uservars:
dw overdrive ; all integer
dw overuser
ds ovsize + codebgn - $,0
if ($ - codebgn) gt ovsize
toobig: jp errval ; Overlay too large!
endif
end