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-XER2.Z80
< prev
next >
Wrap
Text File
|
1991-02-02
|
18KB
|
726 lines
;-----------------------------------------------------------------------------
;
; Overlay for ZMP (Z-Modem Program)
;
; Name ZMO-XER2.Z80
;
; Dated Sep 14, 1988
;
; Written by -
; Ron Murray, c/o Z-Node 62, 061-9-450-0200, Perth, Western Australia.
;
; Modified to ZMP v1.2 standard rjm 15/9/88
; Modified to ZMP v1.3 standard rjm 11/10/88
; Modified to ZMP v1.4 standard rjm 20/11/88
;
; Modified to Xerox ZMP v1.2 S.V. Hovater Houston Z-Node 713-937-8886
; Modified to Xerox ZMP v1.4 Foster Schucker PO Box 385 Eagle PA 19480
; Added parity, 7 and 8 bit data selection and Screen Print
;
; Last Modification January 7, 1989
;
;-----------------------------------------------------------------------------
;
;
; 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-xx01/h
; MLOAD ZMP.COM=ZMODEM.COM,ZMO-xx01.HEX
; or
; M80 =ZMO-xx01.Z80
; RELHEX ZMO-xx01
; MLOAD ZMP.COM=ZMODEM.COM,ZMO-xx01.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).
; If your overlay requires either 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. Examples provided are 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 ; to allow debugging of overlay with Z8E etc.
;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
;------------------------------------------------------------------------------
; Modem vars for Xerox UART
PORT equ 04H ; Xerox Serial Port (data or status)
MDCTL1 equ PORT+2 ; Modem control port
MDDATP equ PORT ; Modem data port
MDRCV equ 01H ; Modem receive ready bit
MDSND equ 04H ; Modem send ready bit
MDTXE equ 01H ; Modem send buffer empty, holding buffer empty
BRPORT equ 00H ; 8116 timer port for baudrate selection
;------------------------------------------------------------------------------
; NOT user-set variables
userdef equ 0145h ; origin of this overlay
; This address should not change with
; subsequent revisions.
mspeed equ 03ch ; location of current baud rate.
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
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
; 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
;
; Main code starts here
;
;Screen print function
scrnpr:
; <== Insert Xerox specific code here
in a,(01CH) ; get current value of system port
push af ; save it so we can come back
res 7,a ; turn on the system ROM
out (01CH),a ; and zap the pio
call 0F045H ; call screen print
pop af ; back to the real world
out (01CH),a ; zap pio again
; <== End of Xerox specific code
spare:
ret
; User-defined entry routine: leave empty if not needed
userin:
ret
; User-defined exit routine: leave empty if not needed
userout:
ret
;Get a character from the modem: return in HL
mchin:
push bc
; <== Inserted Xerox specific code here
in a,(MDDATP) ; get character in A
; <== End of Xerox specific 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)
; <== Inserted Xerox specific code here
push bc
ld c,a
mchout1:
in a,(MDCTL1)
and MDSND
jr z,mchout1
ld a,c
out (MDDATP),a
pop bc
; <== End of Xerox specific code
ret ; done
;Test for output ready: return TRUE (1) in HL if ok
mordy:
; <== Inserted Xerox specific code here
in a,(MDCTL1)
and MDTXE
jr z,mordy1
ld l,1
ld h,0
mordy1:
; <== End of Xerox specific code
ld a,l ; set/clear Z
or a
ret
;Test for character at modem: return TRUE (1) in HL if so
mirdy:
; <== Inserted Xerox specific code here
in a,(MDCTL1)
and MDRCV
jr z,mirdy1
ld l,1
jr mirdy2
mirdy1:
ld l,0
mirdy2:
ld h,00H
; <== End of Xerox specific 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:
; <== Inserted Xerox specific code here
ld a,5
out (MDCTL1),a ; Send to the status port
ld a,(WORD5)
set 4,a ; DTR Normal, send break tone
out (MDCTL1),a
ld hl,600 ; wait 600 ms
call waithlms
ld a,5 ; Restore normal operation
out (MDCTL1),a
ld a,(WORD5) ; Get orginal value of WORD5
out (MDCTL1),a
; <== End of Xerox specific code
ret
;
;Test UART flags for error: return TRUE (1) in HL if error.
mdmerr:
; <== Inserted Xerox specific code here
ld a,010H ; register 0, reset interupts ; <== End of Xerox specific code
out (MDCTL1),a
in a,(MDCTL1)
; <== End of Xerox specific code
ld a,l ; set/clear Z
or a
ret
;Turn DTR on
dtron:
; <== Inserted Xerox specific code here
ld a,05H
out (MDCTL1),a
ld a,(WORD5) ; Get UART WORD 5
set 7,a ; DTR ON
ld (WORD5),a ; save it for later
out (MDCTL1),a
; <== End of Xerox specific code
ret
;Turn DTR and RTS off
dtroff:
; <== Inserted Xerox specific code here
ld a,05H
out (MDCTL1),a
ld a,(WORD5) ; Get UART WORD 5
res 7,a ; DTR off
res 1,a ; RTS off also for the modem
ld (WORD5),a ; save it for later
out (MDCTL1),a
; <== End of Xerox specific code
ret
;Initialise the uart
init:
ld hl,2 ; get parameters
add hl,sp
ex de,hl
call getparm ; in HL
ld (brate),hl ; baud rate
ld a,l ; only one byte
ld (mspeed),a
call getparm
ld (parity),hl ; parity
call getparm
ld (data),hl ; data bits (BINARY 7 or 8)
call getparm
ld (stop),hl ; stop bits (BINARY 1 or 2)
; <== Inserted Xerox specific code here
; using values below
push bc
;----- Register 0
ld a,0 ; select register 0
out (MDCTL1),a
ld a,018H ; Throw out of mode
out (MDCTL1),a
;----- Register 4
ld a,04H ; select register 4
out (MDCTL1),a
; First set up stop bits
ld a,(stop)
cp 1
jp z,onestop ; One stop bit?
ld a,08H
ld (stopmask),a ; Must be two stop bits
jp parityck ; Ok look at parity
onestop:
ld a,04H
ld (stopmask),a ; set for one stop bit
parityck:
ld a,(parity) ; Now the parity bit
cp 'N' ; None?
jp z,noparity ;
cp 'O' ; Odd parity?
jp z,oddparity ;
ld a,03H
ld (parmask),a ; Ok make it even parity
jp load4
noparity:
ld a,00
ld (parmask),a ;
jp load4
oddparity:
ld a,01H
ld (parmask),a ;
load4:
ld b,040H ; x16 cloc rate
ld a,(parmask) ; Parity
or b
ld b,a
ld a,(stopmask) ; Stop bits
or b
out (MDCTL1),a
;----- Register 3
ld a,03H ; select register 3
out (MDCTL1),a
ld a,(data) ; Number of bits in word
cp 8 ; 8 bits?
jp z,eightbitrec ;
ld b,040H ; Must be 7 data bits
jp load3
eightbitrec:
ld b,0C0H ; set for 8
load3: ld a,01H ; Enable receiver
or b ; Mash them
out (MDCTL1),a
;----- Register 5
ld a,05H ; select register 5
out (MDCTL1),a
ld a,(data) ; Number of bits in word
cp 8 ; 8 bits?
jp z,eightbitxmit ;
ld b,0A0H ; Must be 7 data bits
jp load5
eightbitxmit:
ld b,0E0H ; set for 8
load5: ld a,0AH ; set RTS
or b ; Mash them
ld (WORD5),a ; Save for later
out (MDCTL1),a
;----- Timer setup
ld b,0 ; Ok, now set the baud rate
ld a,(mspeed)
cp 1
jp z,S300
cp 5
jp z,S1200
cp 6
jp z,S2400
cp 7
jp z,S4800
cp 8
jp z,S9600
cp 9
jp z,S19200
jp S1200 ;did not find one, default is 1200
S300: ld b,BD300
jp loaded
S1200: ld b,BD1200
ld a,5
jp loaded
S2400: ld b,BD2400
ld a,6
jp loaded
S4800: ld b,BD4800
jp loaded
S9600: ld b,BD9600
jp loaded
S19200: ld b,BD19200
loaded:
ld (brate),a ; set up brate and mspeed
ld (mspeed),a
ld a,b
out (BRPORT),a
pop bc
; <== End of Xerox specific code
ret
;--------------------------------------------------------------------------
stop: dw 1 ; stop bits
stopmask: db 4 ; one stop bit
parity: dw 'N' ; parity
parmask: db 0 ; no parity
data: dw 8 ; data bits
brate: dw 7 ; baud rate:
WORD5: db 0EAH ; Uart WORD 5 storage
;--------------------------------------------------------------------------
;Values of brate for each baud rate
;
; baud rate brate
;
; 110 0
; 300 1
BD300 equ 5 ; timer number
; 450 2
; 600 3
; 710 4
; 1200 5
BD1200 equ 7 ; timer number
; 2400 6
BD2400 equ 10 ; timer number
; 4800 7
BD4800 equ 12 ; timer number
; 9600 8
BD9600 equ 14 ; timer number
; 19200 9
BD19200 equ 15 ; timer number
; 38400 10
; 57600 11
; 76800 12
;
;****************************************************************************
;Video terminal sequences: these are for Xerox 820
;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
; <== Inserted Xerox specific code here
; using values in row and col
call print
db esc,'=',0 ; leadin
ld a,(row) ; row first
add a,' ' ; add offset
call cout
ld a,(col) ; same for column
add a,' '
call cout
; <== end of Xerox specific code
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,'z',0
ret
;Turn on cursor:
show:
call print
db esc,'v',0
ret
;Save cursor position:
savecu:
ret
;Restore cursor position:
rescu:
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
;Get address of user-defined variables
getvars:
ld hl,uservars
ret
uservars:
dw overdrive ; .OVR etc. drive/user
dw overuser
if ($ - codebgn) gt ovsize
toobig: jp errval ; Overlay too large!
endif
end