home *** CD-ROM | disk | FTP | other *** search
- 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