home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
MODEMS
/
ZMODEM
/
ZMO-H805.Z80
< prev
next >
Wrap
Text File
|
2000-06-30
|
19KB
|
743 lines
TITLE System-dependent installation overlay for ZMP
SUBTTL Author: Ron Murray
; System-dependent installation overlay for ZMP
; Author: Ron Murray
; Name ZMPOVH89.Z80
; Dated Nov 11, 1988
; Written by - Ron Murray, c/o Z-Node 62, 061-9-450-0200
; Perth, Western Australia.
; Modified by - Ted May, 116B Laval St., Vanier, Ont., Canada
; (613)741-0862
; for the H89-H19 terminal
; with a Hays compatable 2400 baud modem
; (US Robotics Courier 2400)
; 89/04/12 - Modified to ZMP v1.5 - George Conover
; Modified to ZMP v1.4 standard Ron Murray Nov 11, 88
; Modified to ZMP v1.3 standard Ron Murray Oct 11, 88
; Modified to ZMP v1.2 standard Ron Murray Sept 15, 88
;
;-----------------------------------------------------------------------
;
; 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 programs.
; Assemble as follows:
; SLR ZMO-MH01/h
; MLOAD ZMP.COM=ZMODEM.COM,ZMO-MH01.HEX
; or
; M80 =ZMO-MH01.Z80
; RELHEX ZMO-MH01
; MLOAD ZMP.COM=ZMODEM.COM,ZMO-MH01.HEX
; (Don't use L80 without changing the source for assembly as a CSEG
; file.)
;-----------------------------------------------------------------------
; Code contained herein has been written in Z80 code for use with M80.
; Once assembled, convert to hex with RELHEX and use MLOAD to overlay it
; over the main ZMPX.COM file to produce your very own ZMP.COM.
;-----------------------------------------------------------------------
; Notes on modifying this file:
; Hi-Tech C requires that functions do not change either index register
; (IX or IY). If your overlay requires either of these to be changed, ensure
; they are restored to their original values on return.
; Since collecting parameters from C functions can be tricky, only change
; the parts marked 'Insert your own code here'. Do NOT modify the jump
; table at the start. Do NOT modify the entry/exit sections of each
; function. Do NOT pass 'GO'. Do NOT collect $200.
; Apart from defining modem functions, this file also defines terminal
; characteristics. Most have been set up for ADM-3A (with a few of my own
; additions). Modify to suit your own terminal. An inline print routine
; is provided for printing strings in the usual way: usage is
; CALL PRINT
; DEFB 'required string',0
; Don't forget to set your clock speed at the clkspd variable.
; If you find your overlay exceeds the maximum size (currently 0400h),
; you will have to re-compile the whole thing. Good luck. You might try
; informing us if you need to do this: if too many people need to do it, we
; haven't allowed enough room.
; Ron Murray Aug 15, 88
;-----------------------------------------------------------------------
NO EQU 0
YES EQU NOT NO
CLKSPD EQU 2 ; Processor clock speed in MHz
DEBUG EQU NO ; 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
;-----------------------------------------------------------------------
; NOT user-set variables
USERDEF EQU 0145H ; Origin of this overlay. This address
; should not change with subsequent
; revisions.
MSPEED EQU 003CH ; Location of current baud rate.
OVSIZE EQU 0400H ; Maximum 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
; The following define the H8/89 SIO Modem Port addresses...
DPORT EQU 0D8H ; Data port (base port)
LSPDIV EQU DPORT ; LSP baud rate divisor if DLAB set
IENREG EQU DPORT+1 ; Interupt Enable register
MSPDIV EQU DPORT+1 ; MSP baud rate divisor if DLAB set
IIDREG EQU DPORT+2 ; Interrupt identification register (r/o)
LCPORT EQU DPORT+3 ; Line Control register
MCPORT EQU DPORT+4 ; Modem Control register
LSPORT EQU DPORT+5 ; Line Status register
MSPORT EQU DPORT+6 ; Modem Status register
; Line Control (LCPORT) bits - - - - - - - - - - - - - - - - -
WLS0 EQU 00000001B ; Word length select 0
WLS1 EQU 00000010B ; Word length select 1
STB EQU 00000100B ; Stop bit select
PEN EQU 00001000B ; Parity Enable (0 for disabled)
PES EQU 00010000B ; Even parity select (0 for odd)
SPE EQU 00100000B ; Stick parity
BRKS EQU 01000000B ; Break set (set break)
DLAB EQU 10000000B ; Divisor Latch Access Bit
; Modem Control (MCPORT) bits - - - - - - - - - - - - - - - - -
MCBASE EQU 00000000B ; Basic setup: no DTR or RTS
DTR EQU 00000001B ; Data Terminal Ready
RTS EQU 00000010B ; Request To Sent
OUT1 EQU 00000100B ; Aux Output #1
OUT2 EQU 00001000B ; Aux Output #2
TSTLP EQU 00010000B ; Sets 8250 Test Loop condition
; Line Status (LSPORT) bits - - - - - - - - - - - - - - - - - -
DAV EQU 00000001B ; Data Available (and bit to test)
ORUN EQU 00000010B ; Overrun Error (rec'd was char overwritten
RPERR EQU 00000100B ; Parity Error
FERR EQU 00001000B ; Framing Error (checks for valid stop bit)
BRKD EQU 00010000B ; Break Detect
TBMT EQU 00100000B ; Transmit Buffer Empty (and bit to test)
TSRE EQU 01000000B ; Transmit Shift Register Empty (r/o)
; Modem Status (MSPORT) bits - - - - - - - - - - - - - - - - - -
DCTS EQU 00000001B ; Delta Clear To Send
DDSR EQU 00000010B ; Delta Data Set Ready
TERI EQU 00000100B ; Trailing Edge Ring Indicator
DRLSD EQU 00001000B ; Delta Receive Line Signal Detect
CTS EQU 00010000B ; Clear To Send
DSR EQU 00100000B ; Data Set Ready
RDET EQU 01000000B ; Ring Detect
RLSD EQU 10000000B ; Carrier Detect
RESET EQU 00000001B ; Output Reset Code
; Baud rate divisor values - - - - - - - - - - - - - - - - - - -
BD110 EQU 1047 ; 110 bps
BD300 EQU 384 ; 300 bps
BD450 EQU 256 ; 450 bps
BD600 EQU 192 ; 600 bps
BD710 EQU 162 ; 710 bps
BD1200 EQU 96 ; 1200 bps
BD2400 EQU 48 ; 2400 bps
BD4800 EQU 24 ; 4800 bps
BD9600 EQU 12 ; 9600 bps
BD19200 EQU 6 ; 19,200 bps
BD38400 EQU 3 ; 38,400 bps
BD57600 EQU 2 ; 57,600 bps
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;Jump table for the overlay: do NOT change this
JUMPTAB:
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 ; 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
JP SPARE ; spares for later use
; Main code starts here
VERSN: DEFB '===> Ver. 1.5.1520.24.11.88.ZMPOVL <==='
; 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
; (It is not necessary to test for status)
MCHIN:
; <== Insert your own code here
IN A,(DPORT) ; to get the character in A
; <== End of your own code
LD L,A ; put in HL
LD H,0
OR A ; set/clear Z
RET
;Send a character to the modem
MCHOUT:
LD HL,2 ; get the character
ADD HL,SP
LD A,(HL) ; in A
; <== Insert your own code here
OUT (DPORT),A
; <== 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 ; Assume that the Transmit Buffer is full
IN A,(LSPORT) ; Get Line Status
AND TBMT ; Is the Transmit Buffer Empty?
JR Z,TB.BUSY ; No, skip
LD L,1 ; Yes, HL = 1 (TRUE)
TB.BUSY: ; <== 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 ; Assume that no data is available
IN A,(LSPORT) ; Get Line Status
AND DAV ; Is Data Available?
JR Z,NO.DAV ; No, skip
LD L,1 ; Yes, HL = 1 (TRUE)
NO.DAV: ; <== 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
; This routine sends a 300 ms Break Tone and sets DTR low for the
; same length of time to disconnect the modem at both ends
XOR A ; Clear reg A to
OUT (MCPORT),A ; Set DTR and RTS low
LD A,BRKS ; Set Break Tone
OUT (LCPORT),A ; to go to 'break' level
LD HL,300 ; wait 300 ms
CALL WAITHLMS
DSP EQU $+1 ; Inline code modification (data, stop, parity)
LD A,WLS0+WLS1 ; Set 8 data bits, 1 stop bit, no parity
OUT (LCPORT),A
LD A,DTR ; Set DTR for proper Modem output level
OUT (MCPORT),A
; to restore
; <== 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 ; Set HL = FALSE (0)
; <== End of your own code
LD A,L ; set/clear Z
OR A
RET
;Turn DTR (and optionally RTS) ON.
DTRON:
; <== Insert your own code here
LD A,DTR ; Set DTR
OUT (MCPORT),A
; <== End of your own code
RET
;Turn DTR ( and RTS?) OFF
DTROFF:
; <== Insert your own code here
XOR A ; Clear reg A to
OUT (MCPORT),A ; Set DTR and RTS low
; <== 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
CALL GETPARM
LD (STOP),HL ; stop bits
; <== Insert your own code here
DI ; Disable CPU Interrupts
LD A,(BRATE) ; A = Baud rate number (see table below)
CP 11+1 ; Allow speeds to 57,600 bps
JR NC,BADRATE ; Skip if invalid baud rate
LD (MSPEED),A ; else save for current BRATE
LD E,A
LD D,0 ; DE = Baud rate number
LD HL,BAUD.RATES ; HL -> Start of baudrate divisor table
ADD HL,DE ; Add it twice, each
ADD HL,DE ; Divisor value occupies two bytes
LD A,(HL) ; HL -> Desired divisor value, load HL
INC HL ; indirect through HL [(HLIHL)]
LD H,(HL)
LD L,A ; HL = Divisor value
LD A,D ; A = 0
OUT (IENREG),A ; Disable 8250 interrupts
LD A,DLAB ; Set DLAB so we can use the baud rates
OUT (LCPORT),A ; divisors
LD A,L ; A = LSP of divisor
OUT (LSPDIV),A ; Write divisor's "LSP"
LD A,H ; A = MSP of divisor
OUT (MSPDIV),A ; Write divisor's "MSP"
LD A,(DATA) ; Get data bits count (7 or 8)
CP 7 ; Is it 7 data bits?
LD A,10B ; Assume it is
JR Z,IS7BITS ; Yes, skip
LD A,11B ; No, is 8 data bits, A = 11B
IS7BITS:
LD D,A ; Save data bits
LD A,(STOP) ; Get number of desired stop bits (1 or 2)
CP 1 ; Want one stop bit?
LD A,0 ; Assume so
JR Z,ONE.STOP ; Yes, skip
LD A,100B ; No, set bit 2 - 2 stop bits wanted
ONE.STOP:
OR D ; OR in data bits info
LD D,A ; and save data bits and stop bit info
LD A,(PARITY) ; Get desired parity indicator (N, E or O)
LD E,A ; and save it for possible later use
CP 'N' ; Want no parity?
LD A,D ; Assume so, A = data, stop, and parity (D,S,P)
JR Z,HAVE.BITS ; Yes, skip
LD A,E ; Get back desired parity indicator
CP 'E' ; Want Even parity?
LD A,PEN+PES ; Assume so, set even parity
OR D ; and OR in data bits and stop bit info
JR Z,HAVE.BITS ; Yes, skip
LD A,PEN ; No, has to be Odd parity, set it
OR D ; and OR in data bits and stop bit info
HAVE.BITS:
LD (DSP),A ; Set it for resetting after disconnect
OUT (LCPORT),A ; Set desired word, stop and parity
LD A,DTR ; Set DTR for proper MODEM operation
OUT (MCPORT),A
BADRATE: ; Skips above to here if baud rate bad
EI ; Restore CPU interrupts
; using values below
; <== End of your own code
RET
STOP: DEFW 1 ; Stop bits (will be 1 or 2)
PARITY: DEFW 'N' ; Parity (will be 'N', 'E' or 'O')
DATA: DEFW 8 ; Data bits (will be 7 or 8)
BRATE: DEFW 6 ; 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
;-----------------------------------------------------------------------
; Baud rate divisor table
BAUD.RATES:
DEFW BD110 ; 0 - 110 baud
DEFW BD300 ; 1 - 300
DEFW BD450 ; 2 - 450
DEFW BD600 ; 3 - 600
DEFW BD710 ; 4 - 710
DEFW BD1200 ; 5 - 1,200
DEFW BD2400 ; 6 - 2,400
DEFW BD4800 ; 7 - 4,800
DEFW BD9600 ; 8 - 9,600
DEFW BD19200 ; 9 - 19,200
DEFW BD38400 ; 10 - 38,400
DEFW BD57600 ; 11 - 57,600
;
; Set the port. ZMP supplies either 0 or 1 as a parameter.
;
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
;****************************************************************************
;Video terminal sequences: these are for ADM-3A: Modify as you wish
;Cursor addressing: (modified for H19/89)
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
DEFB ESC,'Y',0 ; H19/89 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: DEFS 2 ; row
COL: DEFS 2 ; column
;Clear screen:
CLS:
CALL PRINT
DEFB ESC,'E',0
RET
;Inverse video on:
INVON:
CALL PRINT
DEFB ESC,'p',0
RET
;Inverse video off:
INVOFF:
CALL PRINT
DEFB ESC,'q',0
RET
;Turn off cursor:
HIDE:
CALL PRINT
DEFB ESC,'x5',0
RET
;Turn on cursor:
SHOW:
CALL PRINT
DEFB ESC,'y5',0
RET
;Save cursor position:
SAVECU:
CALL PRINT
DEFB ESC,'j',0
RET
;Restore cursor position:
RESCU:
CALL PRINT
DEFB ESC,'k',0
RET
;****************************************************************************
;Service modem interrupt:
MINT:
RET ; my system doesn't need this
;Initialise interrupt vectors:
INVEC:
RET ; ditto
;De-initialise interrupt vectors:
DINVEC:
RET ; ditto
;****************** End of user-defined code ********************************
; Don't change anything below this point. We needed some assembly language
; stuff for speed, and this seemed like a good place to put it.
;Modem character test for 100 ms
MRD:
PUSH BC ; save bc
LD BC,100 ; set limit
MRD1:
CALL MIRDY ; 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
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:
DEFW OVERDRIVE ; OVR etc. drive/user
DEFW OVERUSER
IF ($ - JUMPTAB) GT OVSIZE
TOOBIG: JP ERRVAL ; Overlay too large!
ENDIF
END