mirror of https://github.com/wwarthen/RomWBW.git
17 changed files with 2218 additions and 4 deletions
@ -0,0 +1,18 @@ |
|||||
|
@echo off |
||||
|
setlocal |
||||
|
|
||||
|
set TOOLS=..\..\..\Tools |
||||
|
|
||||
|
set PATH=%TOOLS%\zx;%PATH% |
||||
|
|
||||
|
set ZXBINDIR=%TOOLS%\cpm\bin\ |
||||
|
set ZXLIBDIR=%TOOLS%\cpm\lib\ |
||||
|
set ZXINCDIR=%TOOLS%\cpm\include\ |
||||
|
|
||||
|
zx Z80ASM -ZMO-RW01/H || exit /b |
||||
|
zx MLOAD25 -ZMP.COM=ZMPX.COM,ZMO-RW01 || exit /b |
||||
|
|
||||
|
copy /Y zmp.com ..\..\..\Binary\Apps\ || exit /b |
||||
|
copy /Y *.ovr ..\..\..\Binary\Apps\ || exit /b |
||||
|
copy /Y *.hlp ..\..\..\Binary\Apps\ || exit /b |
||||
|
copy /Y zmp.doc ..\..\..\Doc\ || exit /b |
||||
@ -0,0 +1,7 @@ |
|||||
|
@echo off |
||||
|
setlocal |
||||
|
|
||||
|
if exist zmp.com del zmp.com |
||||
|
if exist *.hex del *.hex |
||||
|
if exist *.lst del *.lst |
||||
|
if exist *.zip del *.zip |
||||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,862 @@ |
|||||
|
;----------------------------------------------------------------------------- |
||||
|
; |
||||
|
; Overlay for ZMP (Z-Modem Program) |
||||
|
; |
||||
|
; Name ZMO-RW01.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 ZMP v1.5 standard rjm 25/3/89 |
||||
|
; |
||||
|
; ZMO-RW01.Z80 ROMWBW version using HBIOS and https://github.com/mecparts/zmp version of zmodem |
||||
|
; Databits, stop bit, parity setting not supported. |
||||
|
; All i/o is through the hbios. |
||||
|
; Timing delay calcuations based on hbios reported cpu speed. |
||||
|
; Console is assumed to be current hbios CIO console |
||||
|
; Only 1 port is supported by this version of zmp. |
||||
|
; Port setting supports 2 port, port A is CIO 1, port B is CIO 2 |
||||
|
; This overlay is compatible with Ron Murray's original ZMP15 which support two ports. |
||||
|
; Teraterm users may need to change the ZmodemWinSize value to 1024 in teraterm.ini file. |
||||
|
; |
||||
|
;----------------------------------------------------------------------------- |
||||
|
; |
||||
|
; |
||||
|
; 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 10 ; 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 0 ; Drive to find overlay files on ('A'-'P') |
||||
|
overuser equ 0 ; User area to find files |
||||
|
; |
||||
|
; Initial ROMWBW CIO device |
||||
|
; |
||||
|
initdev equ 1 ; Second CIO device on system |
||||
|
; |
||||
|
; Initial baud rate code |
||||
|
; |
||||
|
initbr equ 10 ; Refer to "baudtbl" table below - brate column |
||||
|
; |
||||
|
;------------------------------------------------------------------------------ |
||||
|
|
||||
|
|
||||
|
; 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 |
||||
|
jp setport ; set port (0 or 1) |
||||
|
|
||||
|
; 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 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: leave empty if not needed |
||||
|
; |
||||
|
; Get the cpu speed reported by romwbw hbios and calculate |
||||
|
; the three required loop counter values for timing. |
||||
|
; |
||||
|
; outerva (outv) |
||||
|
; innerval (inv) |
||||
|
; millisv (msv) |
||||
|
|
||||
|
userin: |
||||
|
ld a,-1 ; force re-init |
||||
|
ld (mspeed),a |
||||
|
|
||||
|
push bc |
||||
|
ld bc,0f8f0h ; get clock speed in l |
||||
|
rst 08 |
||||
|
; |
||||
|
; outerval equ (clkspd / 10) + 1 |
||||
|
; |
||||
|
push hl ; save clock speed |
||||
|
ld h,0 |
||||
|
ld c,10 |
||||
|
call div_hl_c ; result in hl |
||||
|
ld a,l |
||||
|
inc a |
||||
|
ld (outv),a |
||||
|
; |
||||
|
; innerval equ (6667 / outerval) * clkspd |
||||
|
; |
||||
|
ld c,a |
||||
|
ld hl,6667 |
||||
|
call div_hl_c ; result in hl |
||||
|
; |
||||
|
ex de,hl |
||||
|
pop hl ; recall clock |
||||
|
ld a,l ; save |
||||
|
push af ; clock speed |
||||
|
|
||||
|
call mult_a_de |
||||
|
ld (inv),hl |
||||
|
|
||||
|
; |
||||
|
; ld de,39 * clkspd |
||||
|
; |
||||
|
pop af ; recall clock speed |
||||
|
ld de,39 |
||||
|
call mult_a_de |
||||
|
ld (msv),hl |
||||
|
; |
||||
|
pop bc |
||||
|
ret |
||||
|
|
||||
|
outv: ds 1 ; outer value |
||||
|
inv: ds 2 ; inner value |
||||
|
msv: ds 2 ; millisec value |
||||
|
; |
||||
|
; maths helpers |
||||
|
; |
||||
|
mult_a_de: ; https://wikiti.brandonw.net/index.php?title=Z80_Routines:Math:Multiplication |
||||
|
ld c, 0 |
||||
|
ld h, c |
||||
|
ld l, h |
||||
|
add a, a ; optimised 1st iteration |
||||
|
jr nc,$+4 |
||||
|
ld h,d |
||||
|
ld l,e |
||||
|
ld b,7 |
||||
|
_loop2: |
||||
|
add hl,hl |
||||
|
rla |
||||
|
jr nc,$+4 |
||||
|
add hl,de |
||||
|
adc a,c |
||||
|
djnz _loop2 ; result in ahl |
||||
|
ret |
||||
|
; |
||||
|
div_hl_c: ; https://wikiti.brandonw.net/index.php?title=Z80_Routines:Math:Division |
||||
|
xor a |
||||
|
ld b,16 |
||||
|
_loop1: |
||||
|
add hl, hl |
||||
|
rla |
||||
|
jr c,$+5 |
||||
|
cp c |
||||
|
jr c,$+4 |
||||
|
sub c |
||||
|
inc l |
||||
|
djnz _loop1 ; result in hl |
||||
|
ret |
||||
|
|
||||
|
; User-defined exit routine: leave empty if not needed |
||||
|
userout: |
||||
|
|
||||
|
ret |
||||
|
|
||||
|
|
||||
|
;Get a character from the modem: return in HL |
||||
|
mchin: |
||||
|
push bc |
||||
|
; <== Insert your own code here |
||||
|
push de |
||||
|
ld b,00h |
||||
|
ld hl,port |
||||
|
ld c,(hl) |
||||
|
rst 08 |
||||
|
|
||||
|
ld a,e |
||||
|
pop de |
||||
|
; <== 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 |
||||
|
ld e,a |
||||
|
ld b,01h |
||||
|
ld hl,port |
||||
|
ld c,(hl) |
||||
|
rst 08 |
||||
|
; <== 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 b,03h |
||||
|
ld hl,port |
||||
|
ld c,(hl) |
||||
|
rst 08 |
||||
|
ld h,0 |
||||
|
or a |
||||
|
jr z,modrdy1 |
||||
|
ld a,1 |
||||
|
modrdy1: |
||||
|
ld l,a |
||||
|
; <== 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 |
||||
|
push bc |
||||
|
ld b,02h |
||||
|
ld hl,port |
||||
|
ld c,(hl) |
||||
|
rst 08 |
||||
|
or a |
||||
|
jr z,mirdy1 |
||||
|
ld a,1 |
||||
|
mirdy1: |
||||
|
ld l,a |
||||
|
ld h,0 |
||||
|
pop bc |
||||
|
|
||||
|
; <== 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 hl,300 ; wait 300 mS |
||||
|
call waithlms |
||||
|
|
||||
|
; <== 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 |
||||
|
|
||||
|
; <== End of your own code |
||||
|
ld a,l ; set/clear Z |
||||
|
or a |
||||
|
ret |
||||
|
|
||||
|
|
||||
|
|
||||
|
;Turn DTR ON |
||||
|
dtron: |
||||
|
; <== Insert your own code here |
||||
|
|
||||
|
; <== End of your own code |
||||
|
ret |
||||
|
|
||||
|
|
||||
|
|
||||
|
;Turn DTR OFF |
||||
|
dtroff: |
||||
|
; <== Insert your own code here |
||||
|
|
||||
|
|
||||
|
; <== End of your own 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 |
||||
|
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) |
||||
|
|
||||
|
|
||||
|
; <== Insert your own code here |
||||
|
; using values below |
||||
|
call print |
||||
|
db cr,lf,cr,lf,'Initializing CIO device ...',cr,lf,0 |
||||
|
|
||||
|
ld a,(port) ; get device type |
||||
|
ld c,a |
||||
|
ld b,06h |
||||
|
rst 08 |
||||
|
or a ; check if valid |
||||
|
jr nz,initerr |
||||
|
|
||||
|
ld a,(brate) ; get baud rate to set |
||||
|
ld c,a |
||||
|
ld b,0 |
||||
|
ld hl,baudtbl |
||||
|
add hl,bc |
||||
|
ld a,(hl) ; convert to encoded hbios |
||||
|
cp a,-1 |
||||
|
jr z,initerr |
||||
|
|
||||
|
push af |
||||
|
ld a,(port) ; get line characteristics |
||||
|
ld c,a |
||||
|
ld b,05h |
||||
|
rst 08 |
||||
|
ld a,d ; mask out exisitng |
||||
|
and 11100000b ; replace with rate |
||||
|
ld d,a |
||||
|
pop af |
||||
|
or d |
||||
|
ld d,a |
||||
|
|
||||
|
ld b,04h ; set new |
||||
|
ld a,(port) ; speed |
||||
|
ld c,a |
||||
|
rst 08 |
||||
|
or a |
||||
|
jr nz,initerr |
||||
|
|
||||
|
call print |
||||
|
db 'CIO device initialized: ',0 |
||||
|
ld a,(port) |
||||
|
add a,'0'-1 |
||||
|
call cout |
||||
|
call print |
||||
|
db cr,lf,0 |
||||
|
|
||||
|
ld a,(brate) |
||||
|
ld (mspeed),a ; don't forget to load mspeed with the |
||||
|
; current brate value if the new rate is |
||||
|
; valid. See table of values below. |
||||
|
; <== End of your own code |
||||
|
ret |
||||
|
initerr: |
||||
|
call print |
||||
|
db 'Unable to initialize CIO device: ',0 |
||||
|
ld a,(port) |
||||
|
add a,'0'-1 |
||||
|
call cout |
||||
|
call print |
||||
|
db cr,lf,0 |
||||
|
|
||||
|
ret |
||||
|
|
||||
|
;-------------------------------------------------------------------------- |
||||
|
stop: dw 1 ; stop bits |
||||
|
parity: dw 'N' ; parity |
||||
|
data: dw 8 ; data bits |
||||
|
brate: dw initbr ; baud rate: |
||||
|
;-------------------------------------------------------------------------- |
||||
|
;Values of brate for each baud rate |
||||
|
; |
||||
|
; hb encode baud rate brate |
||||
|
; |
||||
|
baudtbl: |
||||
|
db -1 ; 110 0 not supported |
||||
|
db 2 ; 300 1 |
||||
|
db 17 ; 450 2 |
||||
|
db 3 ; 600 3 |
||||
|
db -1 ; 710 4 not supported |
||||
|
db 4 ; 1200 5 |
||||
|
db 5 ; 2400 6 |
||||
|
db 6 ; 4800 7 |
||||
|
db 7 ; 9600 8 |
||||
|
db 8 ; 19200 9 |
||||
|
db 9 ; 38400 10 |
||||
|
db 24 ; 57600 11 |
||||
|
db 10 ; 76800 12 |
||||
|
|
||||
|
; |
||||
|
; 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 |
||||
|
|
||||
|
inc l ; l = cio 1 or cio 2 |
||||
|
push hl |
||||
|
ld b,06h ; test if a valid cio |
||||
|
ld c,l |
||||
|
rst 08 |
||||
|
pop hl |
||||
|
or a |
||||
|
ld a,l |
||||
|
ld (port),a |
||||
|
jr nz,seterr |
||||
|
push hl |
||||
|
call print |
||||
|
db 'Setting CIO device: ',0 |
||||
|
pop hl |
||||
|
|
||||
|
ld a,l |
||||
|
add a,'0'-1 |
||||
|
call cout |
||||
|
call print |
||||
|
db cr,lf,0 |
||||
|
ret |
||||
|
seterr: |
||||
|
push hl |
||||
|
call print |
||||
|
db 'Unable to set CIO device: ',0 |
||||
|
pop hl |
||||
|
ld a,l |
||||
|
add a,'0'-1 |
||||
|
call cout |
||||
|
call print |
||||
|
db cr,lf,0 |
||||
|
; <== End of your own code |
||||
|
ret |
||||
|
|
||||
|
port: db initdev ; zmp port 0 = cio 1, zmp port 1 = cio 2 |
||||
|
|
||||
|
;**************************************************************************** |
||||
|
;Video terminal sequences: these are for VT-100: Modify as you wish |
||||
|
;Cursor addressing: |
||||
|
cursadd: |
||||
|
ld hl,2 ; get parameters |
||||
|
add hl,sp |
||||
|
ex de,hl |
||||
|
call getparm ; in HL |
||||
|
inc hl |
||||
|
ld (row),hl ; row |
||||
|
call getparm |
||||
|
inc hl |
||||
|
ld (col),hl ; column |
||||
|
; <== Insert your own code here |
||||
|
; using values in row and col |
||||
|
call print |
||||
|
db esc,'[',0 |
||||
|
ld a,(row) ; row first |
||||
|
call cursconv |
||||
|
ld a,';' |
||||
|
call cout |
||||
|
ld a,(col) ; same for column |
||||
|
call cursconv |
||||
|
ld a,'H' |
||||
|
call cout |
||||
|
; <== end of your own code |
||||
|
ret |
||||
|
|
||||
|
cursconv: |
||||
|
ld b,a |
||||
|
xor a |
||||
|
ca1: |
||||
|
add a,1 |
||||
|
daa |
||||
|
djnz ca1 |
||||
|
ld (num),a |
||||
|
and 0f0h |
||||
|
jr z,ca2 |
||||
|
srl a |
||||
|
srl a |
||||
|
srl a |
||||
|
srl a |
||||
|
or '0' |
||||
|
call cout |
||||
|
ca2: |
||||
|
ld a,(num) |
||||
|
and 0fh |
||||
|
or '0' |
||||
|
call cout |
||||
|
ret |
||||
|
|
||||
|
row: ds 2 ; row |
||||
|
col: ds 2 ; column |
||||
|
num: ds 1 |
||||
|
|
||||
|
;Clear screen: |
||||
|
cls: |
||||
|
call print |
||||
|
db esc,"[H",esc,"[2J",0 |
||||
|
ret |
||||
|
|
||||
|
;Inverse video on: |
||||
|
invon: |
||||
|
call print |
||||
|
db esc,"[7m",0 |
||||
|
ret |
||||
|
|
||||
|
;Inverse video off: |
||||
|
invoff: |
||||
|
call print |
||||
|
db esc,"[m",0 |
||||
|
ret |
||||
|
|
||||
|
;Turn off cursor: |
||||
|
hide: |
||||
|
call print |
||||
|
db esc,'[?25l',0 |
||||
|
ret |
||||
|
|
||||
|
;Turn on cursor: |
||||
|
show: |
||||
|
call print |
||||
|
db esc,'.3',0 |
||||
|
ret |
||||
|
|
||||
|
;Save cursor position: |
||||
|
savecu: |
||||
|
call print |
||||
|
db esc,'[7',0 |
||||
|
ret |
||||
|
|
||||
|
;Restore cursor position: |
||||
|
rescu: |
||||
|
call print |
||||
|
db esc,'[8',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 |
||||
|
; Display A in hex |
||||
|
prthexbyte: |
||||
|
push af |
||||
|
push de |
||||
|
call hexascii |
||||
|
ld a,d |
||||
|
call cout |
||||
|
ld a,e |
||||
|
call cout |
||||
|
pop de |
||||
|
pop af |
||||
|
ret |
||||
|
|
||||
|
hexascii: |
||||
|
ld d,a |
||||
|
call hexconv |
||||
|
ld e,a |
||||
|
ld a,d |
||||
|
rlca |
||||
|
rlca |
||||
|
rlca |
||||
|
rlca |
||||
|
call hexconv |
||||
|
ld d,a |
||||
|
ret |
||||
|
|
||||
|
hexconv: |
||||
|
and 0fh |
||||
|
add a,90h |
||||
|
daa |
||||
|
adc a,40h |
||||
|
daa |
||||
|
ret |
||||
|
|
||||
|
;****************** 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 |
||||
|
ld b,01h |
||||
|
ld c,80h |
||||
|
ld e,a |
||||
|
rst 08 |
||||
|
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 a,(outv) ; was ld b,outerval |
||||
|
ld b,a |
||||
|
wait11: |
||||
|
ld de,(inv) ; was 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,(msv) ; was 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 |
||||
|
|
||||
@ -0,0 +1,573 @@ |
|||||
|
;----------------------------------------------------------------------------- |
||||
|
; |
||||
|
; Sample Overlay for ZMP (Z-Modem Program) |
||||
|
; |
||||
|
; Name ZMO-BLNK.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 ZMP v1.5 standard rjm 25/3/89 |
||||
|
; |
||||
|
; |
||||
|
;----------------------------------------------------------------------------- |
||||
|
; |
||||
|
; |
||||
|
; 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 |
||||
|
|
||||
|
;------------------------------------------------------------------------------ |
||||
|
|
||||
|
|
||||
|
; 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 |
||||
|
jp setport ; set port (0 or 1) |
||||
|
|
||||
|
; 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 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: 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 |
||||
|
; <== Insert your own code here |
||||
|
|
||||
|
|
||||
|
; <== 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 |
||||
|
|
||||
|
|
||||
|
; <== End of your own code |
||||
|
ret ; done |
||||
|
|
||||
|
;Test for output ready: return TRUE (1) in HL if ok |
||||
|
mordy: |
||||
|
; <== Insert your own code here |
||||
|
|
||||
|
; <== 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 |
||||
|
|
||||
|
|
||||
|
; <== 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 hl,300 ; wait 300 mS |
||||
|
call waithlms |
||||
|
|
||||
|
; <== End of your own code |
||||
|
ret |
||||
|
; |
||||
|
;Test UART flags for error: return TRUE (1) in HL if error. |
||||
|
mdmerr: |
||||
|
; <== Insert your own code here |
||||
|
|
||||
|
; <== End of your own code |
||||
|
ld a,l ; set/clear Z |
||||
|
or a |
||||
|
ret |
||||
|
|
||||
|
|
||||
|
|
||||
|
;Turn DTR ON |
||||
|
dtron: |
||||
|
; <== Insert your own code here |
||||
|
|
||||
|
; <== End of your own code |
||||
|
ret |
||||
|
|
||||
|
|
||||
|
|
||||
|
;Turn DTR OFF |
||||
|
dtroff: |
||||
|
; <== Insert your own code here |
||||
|
|
||||
|
|
||||
|
; <== End of your own 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 |
||||
|
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) |
||||
|
|
||||
|
|
||||
|
; <== Insert your own code here |
||||
|
; using values below |
||||
|
ld (mspeed),a ; don't forget to load mspeed with the |
||||
|
; current brate value if the new rate is |
||||
|
; valid. See table of values below. |
||||
|
; <== End of your own code |
||||
|
ret |
||||
|
;-------------------------------------------------------------------------- |
||||
|
|
||||
|
stop: dw 1 ; stop bits |
||||
|
parity: dw 'N' ; parity |
||||
|
data: dw 8 ; data bits |
||||
|
brate: dw 7 ; baud rate: |
||||
|
|
||||
|
;-------------------------------------------------------------------------- |
||||
|
;Values of brate for each baud rate |
||||
|
; |
||||
|
; baud rate brate |
||||
|
; |
||||
|
; 110 0 |
||||
|
; 300 1 |
||||
|
; 450 2 |
||||
|
; 600 3 |
||||
|
; 710 4 |
||||
|
; 1200 5 |
||||
|
; 2400 6 |
||||
|
; 4800 7 |
||||
|
; 9600 8 |
||||
|
; 19200 9 |
||||
|
; 38400 10 |
||||
|
; 57600 11 |
||||
|
; 76800 12 |
||||
|
|
||||
|
; |
||||
|
; 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 |
||||
|
|
||||
|
|
||||
|
;**************************************************************************** |
||||
|
;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 1ah,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 |
||||
|
|
||||
|
;**************************************************************************** |
||||
|
|
||||
|
;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 |
||||
|
|
||||
@ -0,0 +1,256 @@ |
|||||
|
ZMP Overlay Update Information |
||||
|
|
||||
|
This file contains information on updating ZMP overlays designed for |
||||
|
previous versions to the current version. Newer versions appear first in |
||||
|
this file. |
||||
|
|
||||
|
Updates to ZMP14 Overlays for use with ZMP15. |
||||
|
--------------------------------------------- |
||||
|
|
||||
|
The changes required here are associated with ZMP15's ability to access |
||||
|
either of two UART ports, if available on the specific machine. One entry |
||||
|
needs to be added to the jump table, and an extra routine needs to be added |
||||
|
to set which port is in use. Lines which must be added to the overlay have |
||||
|
an asterisk at the beginning. |
||||
|
|
||||
|
1. Add an entry to the jump table. |
||||
|
|
||||
|
Add the following instruction at the end of the jump table, after the |
||||
|
'jp getvars' instruction and before the spare jumps: |
||||
|
|
||||
|
* jp setport ; Set the modem port being used |
||||
|
|
||||
|
2. Add the setport routine. |
||||
|
|
||||
|
The following routine should be added into the code. A good place is |
||||
|
immediately following the UART init code. |
||||
|
|
||||
|
*; |
||||
|
*; 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 twice -- once for each port value -- 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 |
||||
|
* |
||||
|
|
||||
|
End of changes ZMP14 --> ZMP15. |
||||
|
|
||||
|
-- Ron Murray |
||||
|
25/3/89 |
||||
|
|
||||
|
=============================================================================== |
||||
|
|
||||
|
Updates to ZMP13 Overlays for use with ZMP14. |
||||
|
--------------------------------------------- |
||||
|
|
||||
|
Some changes need to be made to accommodate the user-specification |
||||
|
of drive/user area for the .OVR files. Changes need to be made in three |
||||
|
places in your overlay (asterisks at the start of lines indicate which lines |
||||
|
should be added): |
||||
|
|
||||
|
1. Specify the required drive/user area. |
||||
|
|
||||
|
Add the following section after the mspeed equate: |
||||
|
|
||||
|
*;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 |
||||
|
|
||||
|
2. Add to the jump table |
||||
|
|
||||
|
Add the following instruction at the end of the jump table, after the |
||||
|
'jp userout' instruction and before the spare jumps: |
||||
|
|
||||
|
* jp getvars ; get system variables |
||||
|
|
||||
|
|
||||
|
3. Add code at the end to get the system variables: |
||||
|
|
||||
|
Add the following code just in front of the overlay size test: |
||||
|
|
||||
|
*;Get address of user-defined variables |
||||
|
* |
||||
|
*getvars: |
||||
|
* ld hl,uservars |
||||
|
* ret |
||||
|
* |
||||
|
*uservars: |
||||
|
* dw overdrive ; .OVR etc. drive/user |
||||
|
* dw overuser |
||||
|
* |
||||
|
|
||||
|
End of ZMP14 overlay modifications. |
||||
|
|
||||
|
-- Ron Murray, 20/11/88 |
||||
|
|
||||
|
=============================================================================== |
||||
|
|
||||
|
Updates to ZMP12 Overlays for use with ZMP13. |
||||
|
--------------------------------------------- |
||||
|
|
||||
|
There have been very few changes made to the overlay structure in ZMP13. |
||||
|
Some shuffling of module orders has allowed the origin to be set at 0145 hex, |
||||
|
and here it should stay (unless I fiddle with the startup code -- MOST |
||||
|
unlikely!). So, set your 'userdef' equate to 0145h and you should be able to |
||||
|
leave it there. |
||||
|
There is also a bug fix which should be installed in all overlays. |
||||
|
|
||||
|
1. Fix a bug in the wait routines |
||||
|
|
||||
|
Two routines in the user overlays are misnamed. You would expect wait1s |
||||
|
to pause for one second, and wait1ms to pause for one millisecond, wouldn't |
||||
|
you? Well they don't. Blame it on a lack of sleep on my part. They actually |
||||
|
pause for a number of seconds (milliseconds) in hl. I suggest renaming them |
||||
|
to waithls amd waithlms. The main consequence of this has been the pause in |
||||
|
the middle of the 'send break' routine: there was originally a ld hl, 1 before |
||||
|
the call to wait1s, but it got lost somewhere along the way. In any case, one |
||||
|
second is probably too long for this, and I suggest you change it to |
||||
|
|
||||
|
ld hl, 300 ; wait 300 mS |
||||
|
call waithlms |
||||
|
|
||||
|
There are two faults in the waithls (formerly wait1s) routine. The first |
||||
|
is a misplaced jr instruction that caused waits of more than 1 second to be |
||||
|
much longer than intended. The other concerns z80 machines with a clock speed |
||||
|
greater than 9 MHz: these will cause 16-bit overflow in the ld de,6667 |
||||
|
instruction. (It had never occurred to me that anyone would have a z80 running |
||||
|
at this speed!). Both these faults can be solved by replacing the whole |
||||
|
waithls routine with the following: |
||||
|
|
||||
|
;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 |
||||
|
|
||||
|
; End of changes to waithls routine |
||||
|
|
||||
|
The remaining changes concern baud rates. Firstly, ZMP13 will reject a |
||||
|
selected baud rate if the machine is not capable of it. It does this by |
||||
|
determining if the value in mspeed (location 3c hex) has changed. Thus if |
||||
|
you modify your overlay to only change 003ch (mspeed) if the new baud rate |
||||
|
is valid, then incorrect baud rates cannot be selected. No code is given for |
||||
|
this as all overlays are different. Note that the only penalty for not making |
||||
|
this change is that all baud rates are accepted, whether valid or not. Older |
||||
|
overlays always set mspeed to the new value. |
||||
|
In response to numerous requests (well, actually, two), ZMP13 will accept |
||||
|
speeds of 38400, 57600 and 76800 baud. This means that it accepts the numbers |
||||
|
for these -- mspeed values are 10, 11 and 12 respectively. If you think that |
||||
|
you can get your machine to actually work at these speeds, then go ahead. But |
||||
|
don't blame me if it doesn't work. (Personally, I doubt if successful |
||||
|
transfers in both directions with a 4 MHz machine can be done at much over |
||||
|
4800 baud. But don't let me stop you.) |
||||
|
|
||||
|
-- Ron Murray |
||||
|
11/10/88 |
||||
|
|
||||
|
|
||||
|
End of changes ZMP12 --> ZMP13 |
||||
|
=============================================================================== |
||||
|
|
||||
|
Updates to ZMP11 Overlays for ZMP12. |
||||
|
------------------------------------ |
||||
|
|
||||
|
Some additions to the jump table have been made to allow for user-defined |
||||
|
routines to be executed on entry/exit from ZMP. Modify your overlay as |
||||
|
follows: |
||||
|
|
||||
|
1. Adding to the jump table |
||||
|
|
||||
|
Add the following code to the end of the jump table after the line: |
||||
|
|
||||
|
jp mswait ; wait milliseconds (Last entry of old table) |
||||
|
|
||||
|
==> Insert this stuff |
||||
|
jp userin ; user-defined entry routine |
||||
|
jp userout ; user-defined exit routine |
||||
|
|
||||
|
;Spare jumps for compatibility with future versions |
||||
|
jp spare ; spares for later use |
||||
|
jp spare ; spares for later use |
||||
|
jp spare ; spares for later use |
||||
|
jp spare ; spares for later use |
||||
|
jp spare ; spares for later use |
||||
|
==> End of inserted jump codes |
||||
|
|
||||
|
2. Adding the 'spare' code |
||||
|
|
||||
|
The following code can be added anywhere. A good idea is to put the |
||||
|
'spare:' label in front of an existing ret instruction. |
||||
|
|
||||
|
spare: |
||||
|
ret |
||||
|
|
||||
|
3. Adding the user routines |
||||
|
|
||||
|
Add the following code to your overlay. Anywhere will do. The code |
||||
|
you put in here depends on what you want to do. |
||||
|
|
||||
|
;User-defined entry routine: leave empty if not used |
||||
|
userin: |
||||
|
ret |
||||
|
|
||||
|
;User-defined exit routine: leave empty if not used |
||||
|
userout: |
||||
|
ret |
||||
|
|
||||
|
End of changes ZMP11 --> ZMP12 |
||||
|
=============================================================================== |
||||
|
|
||||
|
|
||||
@ -0,0 +1,24 @@ |
|||||
|
1 1 0 0 0 360 |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
AT! |
||||
|
ATV1Q0DT |
||||
|
! |
||||
|
CONNECT |
||||
|
BUSY |
||||
|
NO CARRIER |
||||
|
NO ANSWER |
||||
|
ERROR |
||||
|
~+++~~ATH! |
||||
|
15 30 |
||||
|
5 N 8 1 |
||||
|
1400 512 F 5 50 |
||||
|
|
||||
@ -0,0 +1,389 @@ |
|||||
|
** ZMP Documentation ** |
||||
|
|
||||
|
1. Introduction. |
||||
|
|
||||
|
ZMP is a communications/file transfer program for CP/M which |
||||
|
performs Xmodem, Xmodem-1k (often erroneously called Ymodem), |
||||
|
true Ymodem and Zmodem file transfer protocols. Although tested |
||||
|
with Z80DOS, ZRDOS and CP/M 2.2, there seems to be no reason why |
||||
|
it shouldn't work with CP/M 3 as well. The only requirements are |
||||
|
a Z80 processor (sorry about that!), a computer running CP/M in |
||||
|
one of its various guises, with at least 45k of TPA (but the more |
||||
|
the better!), and a modem. |
||||
|
When you try to pack this many features into one program, |
||||
|
you end up with a pretty large file. The big problem occurs when |
||||
|
file transfers are attempted: unless you have at least 4-8k of |
||||
|
buffer size, you might as well use xmodem protocol. The approach |
||||
|
taken in ZMP is to use overlays for various functions, accepting |
||||
|
the time taken to load these from disk. Thus performance will |
||||
|
vary depending on your disk setup: if you have a hard disk and a |
||||
|
fast processor you will likely not notice the difference. If, on |
||||
|
the other hand, you are running a Commodore 128 with CP/M on a |
||||
|
1571 drive, there is no physical reason why ZMP won't work, but |
||||
|
you might consider investing in a book to read while the overlays |
||||
|
load. (A suitable book to read might be a computer catalogue!). |
||||
|
The curious amongst you may notice that the beginning of the |
||||
|
ZMPX.COM file has the magic 'Z3ENV' string, but don't let this |
||||
|
fool you into thinking that you don't need to add terminal |
||||
|
characteristics into the overlay if you have a ZCPR3 system. It |
||||
|
has proved possible to persuade this particular C compiler to |
||||
|
access ZCPR3's environment descriptor, but not for ZMP. Yet. |
||||
|
Perhaps later. In the meantime, the startup code is there for it. |
||||
|
In order to produce a program which would work with most |
||||
|
CP/M systems, the Zmodem protocol performed by ZMP is fairly |
||||
|
simple. The transmit section uses 'Full Streaming with Reverse |
||||
|
Interrupt', as Chuck Forsberg calls it in his description of the |
||||
|
Zmodem protocol. The receive section uses 'Segmented Streaming'. |
||||
|
This means that, if your system can do serial I/O and disk I/O at |
||||
|
the same time, ZMP does not take advantage of the faster transfer |
||||
|
rate which this capability provides. Since, however, I can't |
||||
|
write and listen at the same time, and neither can my computer, |
||||
|
and neither can the vast majority of CP/M computers, it seemed |
||||
|
the best approach to take. Segmented Streaming means that the |
||||
|
receive program tells the transmit program how big its buffer is. |
||||
|
The transmit program then sends just that much data, then waits |
||||
|
for an acknowledge from the receiver. We have encountered some |
||||
|
Zmodem programs which send too much data in this case: errors |
||||
|
will appear if this happens, but the protocol should recover and |
||||
|
the file will be received intact (we hope!). |
||||
|
The string which ZMP passes to the receiving program to |
||||
|
interrupt in case of errors is likewise simple. Basically it |
||||
|
causes the receiving program to send a control-C character and |
||||
|
then wait for one second. The receiver will then send its ZRPOS |
||||
|
string, by which time ZMP, as the transmitter, should be ready to |
||||
|
receive it. |
||||
|
|
||||
|
|
||||
|
2. Customisation. |
||||
|
|
||||
|
ZMP must be customised to suit your system. This involves |
||||
|
overlaying the un-installed copy of ZMP.COM (contained in this |
||||
|
library as ZMPX.COM) with a user-written installation overlay. |
||||
|
Some hints on writing this are given below; there is a blank |
||||
|
overlay file in this library, or you may be able to obtain one |
||||
|
for your computer from the same place you got this library. |
||||
|
This value is set at 0145 hex, and should stay there permanently. |
||||
|
See the notes in this document, and also the ZMP-OVL.UPD file, |
||||
|
for more details on how to set up your overlay. |
||||
|
Once the installation overlay is written, assemble it with |
||||
|
M80 (or SLR or whatever), use RELHEX to create a .HEX file, and |
||||
|
use MLOAD to overlay it over the ZMPX.COM file to produce your |
||||
|
very own ZMP.COM. |
||||
|
|
||||
|
3. Operation. |
||||
|
|
||||
|
The following files must be on the same disk and user area, |
||||
|
which must be specified in your customisation overlay: |
||||
|
|
||||
|
ZMCONFIG.OVR -- the configuration overlay |
||||
|
ZMINIT.OVR -- the initialisation overlay |
||||
|
ZMTERM.OVR -- the terminal overlay |
||||
|
ZMXFER.OVR -- the file transfer overlay |
||||
|
ZMP.HLP -- the help file (recommended). |
||||
|
|
||||
|
Start the program with ZMP. The screen should clear, then a |
||||
|
title message is printed, then ZMP enters terminal mode. You may |
||||
|
type escape-H for help at this point. When you first run the |
||||
|
program, the first thing you need to do is to enter the |
||||
|
configuration overlay (type escape-C) and set all the defaults |
||||
|
and others to suit your system as required. If you don't know |
||||
|
whether to change something or not, it's probably better to leave |
||||
|
it alone. When you exit the configuration program, answer 'Y' to |
||||
|
the 'Make changes permanent' question. ZMP.FON and ZMP.CFG will |
||||
|
be produced on your disk, in the same drive/user area as the |
||||
|
above files. |
||||
|
|
||||
|
Operation of the program is controlled by escape sequences |
||||
|
entered in terminal mode. Escape-H gives you a list of options. |
||||
|
Most of these are self-explanatory, but they will be summarized |
||||
|
here. |
||||
|
|
||||
|
B - Send Break to modem. |
||||
|
If your overlay has been set up to send a break command |
||||
|
to your UART, this command will perform this function. (Some |
||||
|
remote systems may require a break sent to them to interrupt |
||||
|
Zmodem transfers). |
||||
|
|
||||
|
C - Configure system. |
||||
|
This function is designed to set system defaults, save |
||||
|
phone numbers etc. Changing baud rates etc. for a particular |
||||
|
call are better handled with the escape-L option. If you |
||||
|
answer Y or y to the 'make changes permanent?' question, the |
||||
|
new configuration will be saved in a ZMP.CFG file, and the |
||||
|
phone numbers in a ZMP.FON file for later use. The .CFG file |
||||
|
is read, if it exists, when ZMP is first started. |
||||
|
|
||||
|
D - Get disk Directory. |
||||
|
Gets a directory of the current drive and user area. |
||||
|
Change to another with the escape-F command, described |
||||
|
below. The directory will be sorted and will include |
||||
|
filesizes unless you have so many files on the current |
||||
|
drive/user area that there is insufficient memory available |
||||
|
to sort them. In this case an unsorted directory, without |
||||
|
file sizes, will be printed. |
||||
|
|
||||
|
F - Disk/File operations. |
||||
|
This command is used to change the current drive/user |
||||
|
area, to reset a disk in the current drive, and to view, |
||||
|
erase, print or rename files. There are also options to give |
||||
|
a directory of the current drive/user area, and to supply a |
||||
|
new filename for the capture file. This filename may specify |
||||
|
a different drive/user area than the current one. If capture |
||||
|
mode is on, the status line printed when terminal mode is |
||||
|
entered will state the capture file name. |
||||
|
|
||||
|
H - Get Help. |
||||
|
Prints the ZMP.HLP file. You may then either type CR to |
||||
|
return to terminal mode, or enter the required function key. |
||||
|
|
||||
|
I - Initiate phone call. |
||||
|
Reads the ZMP.FON file, if any, and prints it. You have |
||||
|
four seconds after typing ESC I, during which you may enter |
||||
|
the letter corresponding to the required number, in which |
||||
|
case ZMP will dial it without printing a list. Otherwise the |
||||
|
full phone list will be printed, and you will be asked which |
||||
|
number you want. Enter the identifying letter of the number |
||||
|
you wish to call. You can also enter numbers not in the |
||||
|
list. Multiple numbers can be called by entering them separ- |
||||
|
ated with commas. Dialling will then commence, and will |
||||
|
continue until one of the numbers answers, or until you |
||||
|
abort the process with the escape key. Note that the baud |
||||
|
rate used for the call is that in the .FON file for that |
||||
|
number, or the current one if a new number is entered. This |
||||
|
function works best if the strings in the .CFG file have |
||||
|
been set up for your modem, and the initialisation string |
||||
|
sent to the modem sets it into verbose mode for status |
||||
|
messages (ATV1). |
||||
|
|
||||
|
K - Display Keyboard macros. |
||||
|
The configuration option allows up to ten macro keys to |
||||
|
be defined, and these are recalled by typing escape followed |
||||
|
by the numbers 0 to 9. This function prints the current |
||||
|
assignments. |
||||
|
|
||||
|
L - Change Line settings. |
||||
|
This function allows temporary changes of baud rate, |
||||
|
stop bits, and data bits. There is also an option to operate |
||||
|
terminal mode in full duplex (locally typed characters are |
||||
|
sent but not displayed on the screen), half duplex (locally |
||||
|
typed characters are sent and also displayed on the screen), |
||||
|
or echo mode (as for half duplex, but received characters |
||||
|
are echoed to the remote system as well as being displayed). |
||||
|
Don't have two computers talking to each other in echo mode |
||||
|
unless you're bored. There are also options to allow/dis- |
||||
|
allow control characters above CR to be displayed in term- |
||||
|
inal mode, to strip the parity bit in terminal mode, and to |
||||
|
re-initialise the currently selected UART and modem at the |
||||
|
current baud rate. |
||||
|
Like IMP, ZMP uses location 003C hex to store a value |
||||
|
corresponding to the present baud rate. Then, if you leave |
||||
|
ZMP and later re-enter, it checks location 003C. If it |
||||
|
contains a legal value, then that baud rate is set for you, |
||||
|
otherwise it sets the default baud rate as selected in the |
||||
|
.CFG file. |
||||
|
|
||||
|
M - Toggle capture mode in Memory. |
||||
|
Received characters will be saved in a buffer and saved |
||||
|
in a file named 'ZMP.LOG' when the buffer fills or when the |
||||
|
command is entered again. A control-S/control-Q sequence is |
||||
|
sent to the remote computer while the buffer is being saved |
||||
|
in an attempt to stop it sending more data. |
||||
|
|
||||
|
P - Toggle Printer. |
||||
|
This is similar to the 'M' command, except incoming |
||||
|
characters are sent to the printer. This functions best if |
||||
|
your system performs the BIOS 'List Status' function |
||||
|
correctly. |
||||
|
|
||||
|
Q - Quit the program. |
||||
|
Obvious. You will be asked if this is really what you |
||||
|
want. Any entry other than N or n will exit to CP/M. |
||||
|
|
||||
|
R - Receive a file. |
||||
|
You will be asked which protocol you wish to use. The |
||||
|
default is ZMODEM. The <X>modem option will allow either |
||||
|
128-byte blocks (standard XMODEM) or 1k blocks (XMODEM-1k), |
||||
|
since this is decided by the transmit end. If an attempt is |
||||
|
made to receive a file which has the same name as a file on |
||||
|
the current drive/user area, the current one will be renamed |
||||
|
to .BAK and the new one will then be received normally. |
||||
|
(However, see below for the transfer resumption feature in |
||||
|
ZMP v1.5 and above). |
||||
|
Note that the byte count on the screen is not kept up- |
||||
|
to-date on Zmodem receive. This is because the data arrives |
||||
|
non-stop and there is simply no time available with non- |
||||
|
interrupt driven computers to update the screen. An update |
||||
|
is performed if errors occur, and when the computer pauses |
||||
|
to write to the disk. |
||||
|
Starting with version 1.4, Zmodem file receive will |
||||
|
commence automatically upon receipt of the sender's ZRQINIT |
||||
|
string. Thus all you need to do is have the sender initiate |
||||
|
the transfer, select the drive and user area you wish |
||||
|
the file(s) to be received on, and wait.. |
||||
|
ZMP v1.5 adds the ability to resume an interrupted |
||||
|
Zmodem transfer. If a Zmodem receive attempt fails (either |
||||
|
because of manual cancellation or massive errors), you will |
||||
|
be asked if you wish to save the portion of the file already |
||||
|
received. If not, it will be erased. If so, and a subsequent |
||||
|
Zmodem receive attempt would result in a file of the same |
||||
|
name, you are asked if you wish to resume the transfer. If |
||||
|
you do, transfer will start at the end of the file. |
||||
|
Otherwise the old file will be renamed to .BAK as before. |
||||
|
Since this feature is a function of the receiver, it should |
||||
|
work with any Zmodem implementation which conforms |
||||
|
reasonably closely to Chuck Forsberg's standard. It has been |
||||
|
tested with ZMP and RZMP, and I would like to hear of any |
||||
|
programs with which it doesn't work. No attempt is made to |
||||
|
determine if the files are the same up to the commencement |
||||
|
point: the Zmodem protocol provides two ways in which this |
||||
|
may be determined (file date and CRC), but neither has yet |
||||
|
been implemented in ZMP. |
||||
|
|
||||
|
S - Send a file. |
||||
|
Operation is similar to the receive function. |
||||
|
Additional options available are ASCII send and the |
||||
|
capability of distinguishing between normal Xmodem and |
||||
|
Xmodem-1k. In Ymodem and Zmodem modes, wildcard filenames |
||||
|
and multiple filenames are allowed. Multiple filenames |
||||
|
should be entered separated by spaces. In all cases, files |
||||
|
on different drives/user areas may be specified by supplying |
||||
|
a zcpr3-style du: prefix (e.g. C7:NEATPROG.WOW). |
||||
|
Byte count information is displayed in Zmodem mode on |
||||
|
transmit. This causes noticeable breaks between packets, but |
||||
|
it is felt that this is outweighed by the usefulness of the |
||||
|
information. ZMP's Zmodem mode is capable of CRC-32 opera- |
||||
|
tion, although CRC-16 mode is used if the receiver is incap- |
||||
|
able of CRC-32. Some other terminal programs, however, do |
||||
|
strange things when faced with a receiving program which |
||||
|
claims it can do CRC-32 (we have encountered one for the |
||||
|
Amiga which exhibits this problem). If this happens, the |
||||
|
esc-L menu and the configuration overlay have an option to |
||||
|
disable CRC-32. |
||||
|
|
||||
|
X - Hangup. |
||||
|
This function causes the modem to disconnect from the |
||||
|
phone line, by momentarily dropping DTR. |
||||
|
|
||||
|
Y - Print screen. |
||||
|
Allows the current screen to be dumped to printer. Note |
||||
|
that this must be supported in the overlay: most terminals |
||||
|
are incapable of this function. The standard overlay prints |
||||
|
'This function not supported.'. If you can make it work on |
||||
|
your system, good luck! |
||||
|
|
||||
|
Z - Clear screen. |
||||
|
Allows the screen to be cleared. Useful if it fills |
||||
|
with rubbish. |
||||
|
|
||||
|
|
||||
|
4. Other information. |
||||
|
|
||||
|
a) ZMP at higher baud rates. |
||||
|
When I first produced ZMP, I was more interested in |
||||
|
producing a universal Zmodem program than anything else. |
||||
|
Originally (several C compilers ago!) I had difficulty get- |
||||
|
ting it to work even at 300 baud, and so little thought was |
||||
|
given to accommodate higher transmission speeds. In partic- |
||||
|
ular, there is a "designed-in" bug/feature which would prob- |
||||
|
ably preclude ZMP working at much over 4800 baud. The prob- |
||||
|
lem is in the user overlay, in the mrd: routine. The requ- |
||||
|
irement here is to have a routine which returns either when |
||||
|
a character is available at the modem (in which case we |
||||
|
return TRUE), or 100 mS has elapsed (in which case we return |
||||
|
FALSE). The catch is that I used 100 x 1 mS waits, between |
||||
|
which we test for a character. A little calculation will |
||||
|
show that a 9600 baud character will take a little over 1 mS |
||||
|
to transfer, and 19200 baud characters take half this time. |
||||
|
Thus we are practically guaranteed to miss characters at |
||||
|
19200 baud, and even 9600 baud characters leave little |
||||
|
processing timeto spare. Two possible ways to overcome this |
||||
|
are: |
||||
|
|
||||
|
i) Make the wait time shorter. Thus we could wait 1000 x |
||||
|
100 uS periods instead. This, however, makes the actual |
||||
|
wait time more unpredictable, since subroutine |
||||
|
call/return times are comparable to the wait time. It |
||||
|
also just puts off the evil day. |
||||
|
|
||||
|
ii) Use a hardware timer to determine whether 100 mS has |
||||
|
elapsed. This is the preferred approach. Thus the mrd: |
||||
|
routine would loop continuously, exiting when either |
||||
|
there was a character at the modem or when the hardware |
||||
|
timer expired. An embryo CP/M-68K version of ZMP using |
||||
|
this approach has proved capable of reliable transfers |
||||
|
at 19,200 baud (although one must admit that it IS |
||||
|
running a 68010 at 10 MHz!). |
||||
|
|
||||
|
I would like to hear from anyone who has had any |
||||
|
success with either of these two approaches. |
||||
|
|
||||
|
5. Acknowledgements. |
||||
|
|
||||
|
ZMP was developed from Hal Maney's Heath-specific HMODEM II. |
||||
|
I would like to thank Hal for writing HMODEM: CP/M users have |
||||
|
been without ZMODEM capability for far too long. As requested in |
||||
|
the source file, acknowledgement is given to him therein. |
||||
|
Appreciations also go to the authors of the Hi-Tech C compiler, |
||||
|
which proved to be capable of producing fast and compact code for |
||||
|
Z80 machines. |
||||
|
ZMP in its various incarnations is refined by suggestions |
||||
|
from you, the user. In particular, I would like to thank Mike |
||||
|
Allen, Richard Kopplin and Fred Haines for their invaluable |
||||
|
suggestions. I may sometimes be a little slow at implementation, |
||||
|
but I usually get there eventually! Fred Haines has also kindly |
||||
|
offered to be the U.S. collection point for bug reports, |
||||
|
suggestions etc. His address appears at the bottom of this |
||||
|
document, and he'll forward them to me via what he calls 'U.S. |
||||
|
Snail'. I will try and respond using what I call 'Australia |
||||
|
Pest'. |
||||
|
I would also like to thank Lindsay Allen, sysop of Z-Node |
||||
|
62. His name was removed from the original zmp11 title screen at |
||||
|
his own request, since I had done most of the work in modifying |
||||
|
Hmodem to work on other machines. Without Lindsay's encouragement |
||||
|
at difficult times, suggestions as to how to go about |
||||
|
recalcitrant procedures, and experience in file transfers, ZMP |
||||
|
would not have been produced. Thank you. |
||||
|
|
||||
|
|
||||
|
6. Finally... |
||||
|
The files contained in this library are placed in the public |
||||
|
domain. Just don't sell it, claim you wrote it, or do anything |
||||
|
similar that might annoy me. Above all, don't bother trying to |
||||
|
sue me if it doesn't work, or you tripped over the disk, or |
||||
|
anything similar. I haven't distributed the source files partly |
||||
|
due to the size of them, partly due to the fact that compilation |
||||
|
is messy (several modifications were needed to "standard" library |
||||
|
functions!), and partly due to the fact that there's still work |
||||
|
to do on them. Besides, I feel a certain fatherly feeling towards |
||||
|
ZMP, having spent most of my spare time for the last four months |
||||
|
working on it. So here's the deal: I will continue to support ZMP |
||||
|
(and RZMP) until I get sick of it. This could take an unknown |
||||
|
amount of time! At that point, I will release the sources into |
||||
|
the RCP/M community, and you may make of them what you will. |
||||
|
ZMP has a remote system relative, called RZMP. This allows |
||||
|
Zmodem transfers to and from remote systems. It should be |
||||
|
available from the same place from which you obtained ZMP. |
||||
|
I have also produced an extremely cut-down version of ZMP |
||||
|
which runs under CP/M-68K, currently running quite well as a |
||||
|
single .68K file (no overlays!) on a system with 128k bytes of |
||||
|
memory. If there is enough interest from CP/M-68k users (are |
||||
|
there any??), I could be persuaded to upgrade this version to the |
||||
|
point where it could be released. |
||||
|
Comments and suggestions are welcome. Bug reports are not so |
||||
|
welcome, but we'd like them anyway! Send either to: |
||||
|
|
||||
|
Z-Node 62 |
||||
|
Perth, Western Australia |
||||
|
(061+) 09-450-0200 |
||||
|
(Soon to be on FidoNet) |
||||
|
|
||||
|
U.S. users may send reports/comments to: |
||||
|
|
||||
|
Fred Haines, |
||||
|
733 North King's Road, Apt. 356 |
||||
|
Los Angeles, California 90069 |
||||
|
|
||||
|
-- Ron Murray |
||||
|
26th March, 1989 |
||||
|
te systems. It should be |
||||
|
available from the same place fr |
||||
@ -0,0 +1,21 @@ |
|||||
|
Virtual Altair altair 8 N 8 1 0 |
||||
|
_________________ _________________ 9 N 8 1 0 |
||||
|
_________________ _________________ 9 N 8 1 0 |
||||
|
_________________ _________________ 9 N 8 1 0 |
||||
|
_________________ _________________ 9 N 8 1 0 |
||||
|
_________________ _________________ 9 N 8 1 0 |
||||
|
_________________ _________________ 9 N 8 1 0 |
||||
|
heatwave heatwave 8 N 8 1 0 |
||||
|
_________________ _________________ 9 N 8 1 0 |
||||
|
_________________ _________________ 9 N 8 1 0 |
||||
|
_________________ _________________ 9 N 8 1 0 |
||||
|
Level 29 bbs.fozztexx.com 8 N 8 1 0 |
||||
|
_________________ _________________ 9 N 8 1 0 |
||||
|
_________________ _________________ 9 N 8 1 0 |
||||
|
_________________ _________________ 9 N 8 1 0 |
||||
|
Particles BBS particles 8 N 8 1 0 |
||||
|
_________________ _________________ 9 N 8 1 0 |
||||
|
_________________ _________________ 9 N 8 1 0 |
||||
|
_________________ _________________ 9 N 8 1 0 |
||||
|
_________________ _________________ 9 N 8 1 0 |
||||
|
|
||||
@ -0,0 +1,13 @@ |
|||||
|
ZMP is a communications/file transfer program for CP/M which |
||||
|
performs Xmodem, Xmodem-1k (often erroneously called Ymodem), |
||||
|
true Ymodem and Zmodem file transfer protocols. |
||||
|
|
||||
|
This library contains an un-installed ZMP.COM (called |
||||
|
ZMPX.COM) and five .OVR files. There is also a file called |
||||
|
ZMP-OVL.UPD which describes the changes which need to be made to |
||||
|
the user-written overlay to allow it to operate with this version |
||||
|
of ZMP. YOU need to read this one!! |
||||
|
|
||||
|
Details of changes made to this version are in the ZMPxx.NEW |
||||
|
file. |
||||
|
|
||||
@ -0,0 +1,20 @@ |
|||||
|
Commands: Precede with ESC: |
||||
|
|
||||
|
B Send break to modem |
||||
|
C Configure system |
||||
|
D Get disk directory |
||||
|
F File operations, change/reset disk |
||||
|
H Get instructions |
||||
|
I Initiate phone call (dial) |
||||
|
K Display keyboard macros |
||||
|
L Change line parameters (baud rate, full/half duplex/echo, UART settings) |
||||
|
M Toggle memory capture mode |
||||
|
P Toggle printer |
||||
|
Q Quit |
||||
|
R Receive a file |
||||
|
S Send a file |
||||
|
X Hangup |
||||
|
Y Print screen |
||||
|
Z Clear local screen |
||||
|
|
||||
|
|
||||
@ -0,0 +1,29 @@ |
|||||
|
Version 1.5+/- of ZMP now compiles and links with v3.09 of |
||||
|
Hi Tech C and fixes a few things that had niggled at me for |
||||
|
awhile (some, a few decades): |
||||
|
|
||||
|
* Datestamps transferred in Y/Zmodem transfers. |
||||
|
* Fixed long filename conversions on Y/Zmodem transfers. |
||||
|
* Fixed issues displaying baud rate and send times when the |
||||
|
baud rate is > 19.2K. |
||||
|
* Removed superfluous CR sent to the remote end when a |
||||
|
connection was established, which was a pita when connecting to |
||||
|
a Linux box. |
||||
|
* In keyboard macros, ! translates to a CR now, not CR/LF. |
||||
|
* \ escapes ! and ~ so those literal characters can be used in |
||||
|
keyboard macros. |
||||
|
* Long distance access code has been removed. |
||||
|
* Quick dialing letters limited to A-T. |
||||
|
|
||||
|
This version, based on the version of the source code in |
||||
|
ZMP-SRC.LBR, is missing a few things that made it into the later |
||||
|
version in ZMP15.LBR. So, to quote the original author, |
||||
|
|
||||
|
"As always, ensure that you erase your .CFG file and make a |
||||
|
new one with the config option. There have again been changes to |
||||
|
the format of this file." |
||||
|
|
||||
|
June 7, 2021 |
||||
|
|
||||
|
This ROMWBW version is an extract of https://github.com/mecparts/zmp/bin |
||||
|
as at Aug 23rd, 2021. |
||||
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue