home *** CD-ROM | disk | FTP | other *** search
- ; PROGRAM: ZMO-CP05.Z80
- ; AUTHOR: Bruce Dudley
- ; VERSION: 1.5
- ; DATE: 19 Sept, 1988
- ;-----------------------------------------------------------------------
- ; This overlay is set up for an Amstrad CPC6128 under CPM Plus,
- ; with a Zenith Z19/Z29 terminal emulation and a Z80SIO and 8253
- ; counter.
- ;-----------------------------------------------------------------------
- ; 89/04/12 - Modified to ZMP v1.5 - George Conover
- ; 89/03/15 - Removed the beginning remarks to make the file
- ; smaller. If you need the remarks there are in the
- ; file ZMP-BLNK.Z80 - George Conover
- ; 89/03/14 - Modified to ZMP v1.4 - George Conover
- ; 88/10/12 - Modified to ZMP v1.3 - Ron Murray
- ; 88/09/15 - Modified to ZMP v1.2 - Ron Murray
- ; 88/08/28 - First version of this file - Bruce Dudley
- ;
- ; Written by -
- ; Ron Murray, c/o Z-Node 62, 061-9-450-0200, Perth, Western Australia.
- ;-----------------------------------------------------------------------
- ;
- NO EQU 0
- YES EQU NOT NO
- ;
- ; User-set variables
- ;
- CLKSPD EQU 4 ; Processor clock speed in MHz
- ;
- DEBUG EQU NO
-
- ;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
- ; ; may change with subsequent revisions
- MSPEED EQU 05CH ; 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 ; DEBUG
- ;
- ESC EQU 1BH
- CTRLQ EQU 11H
- CR EQU 0DH
- LF EQU 0AH
- BDOS EQU 5
- ;
- ; Amstrad CPC6128 specific equates
- ;
- MDATA EQU 0FADCH ; Data port
- MSTAT EQU 0FADDH ; Status port
- RDA EQU 0 ; Received data available
- TBE EQU 2 ; Tx ready
- ONHOOK EQU 7FH
- ONLINE EQU 80H
- ERROR EQU 70H
- BREAK EQU 0F8H
- ;
- ; 8253 Counter equates
- ;
- CTCONT EQU 0FBDFH ; Control register of the 8253
- CTC0 EQU 0FBDCH ; Counter # 0 of the 8253
- CTC1 EQU 0FBDDH ; Counter # 1 of the 8253
- ;
- ;-----------------------------------------------------------------------
- ;
- ; Main code starts here
- ;
- ;Jump table for the overlay: do NOT change this
- ;
- CODEBGN EQU $
- ;
- 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
- ;
- SPARE: RET
- ;
- ;-----------------------------------------------------------------------
- ;
- ; Screen print function
- ;
- SCRNPR: DS 0
- ;
- ; <== Insert your own code here
- ;
- CALL PRINT
- DB 'This function not supported.',CR,LF
- DB 0
- ;
- ; <== End of your own code
- ;
- RET
- ;
- ; Get a character from the modem: return in HL
- ;
- MCHIN: PUSH BC
- ;
- ; <== Insert your own code here
- ;
- LD BC,MSTAT
- ;
- MCHIN2: IN A,(C) ; Check for char waiting
- BIT RDA,A
- JR Z,MCHIN2
- LD BC,MDATA
- IN A,(C) ; Read the character
- ;
- ; <== End of your own code
- ;
- LD L,A ; Put in HL
- LD H,0
- OR A ; Set/clear Z
- POP BC
- RET
- ;
- ; Send a character to the modem
- ;
- MCHOUT: LD HL,2 ; Get the character
- ADD HL,SP
- LD A,(HL)
- ;
- ; <== Insert your own code here
- ;
- PUSH BC
- PUSH AF ; Save the character
- LD BC,MSTAT
- ;
- MCHOUT2:IN A,(C) ; Check for UART ready
- BIT TBE,A
- JR Z,MCHOUT2
- POP AF ; Character in a
- LD BC,MDATA
- OUT (C),A ; Send it
- POP BC
- ;
- ; <== End of your own code
- ;
- RET ; Done
- ;
- ; Test for output ready: return YES (1) in HL if ok
- ;
- MORDY: DS 0
- ;
- ; <== Insert your own code here
- ;
- PUSH BC
- LD BC,MSTAT
- LD HL,0
- IN A,(C)
- BIT TBE,A ; Transmit buffer empty
- JR Z,MORDY1
- INC HL
- ;
- MORDY1: DS 0
- ;
- ; <== End of your own code
- ;
- POP BC
- LD A,L ; Set/clear Z
- OR A
- RET
- ;
- ;-----------------------------------------------------------------------
- ;
- ; Test for character at modem: return YES (1) in HL if so
- ;
- MIRDY: DS 0
- ;
- ; <== Insert your own code here
- ;
- PUSH BC
- LD BC,MSTAT
- LD HL,0
- IN A,(C)
- BIT RDA,A ; Received data available
- JR Z,MIRDY1
- INC HL
- ;
- MIRDY1: DS 0
- ;
- ; <== End of your own code
- ;
- POP BC
- 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: DS 0
- ;
- ; <== Insert your own code here
- ;
- PUSH BC
- LD BC,MSTAT
- LD A,5
- OUT (C),A
- LD A,BREAK ; F8h
- OUT (C),A
- LD HL,300 ; A 300 mS break
- CALL WAITHLMS
- LD A,5
- OUT (C),A
- LD A,ONLINE ; 68h
- OUT (C),A
- LD A,3
- OUT (C),A
- LD A,0E1H ; E1h
- OUT (C),A
- POP BC
- ;
- ; <== End of your own code
- ;
- RET
- ;
- ; Test UART flags for error: return YES (1) in HL if error.
- ;
- MDMERR: DS 0
- ;
- ; <== Insert your own code here
- ;
- PUSH BC
- LD BC,MSTAT
- LD HL,0
- IN A,(C)
- AND A,ERROR
- JR Z,MDMER2
- INC HL
- ;
- MDMER2: DS 0
- ;
- ; <== End of your own code
- ;
- POP BC
- LD A,L ; Set/clear Z
- OR A
- RET
- ;
- ; Turn DTR ON
- ;
- DTRON: DS 0
- ;
- ; <== Insert your own code here
- ;
- PUSH BC
- LD BC,MSTAT
- LD A,5
- OUT (C),A
- LD A,(COMBYT) ; Get the one we used last time
- OR A,ONLINE ; 80h - set bit 7 high
- LD (COMBYT),A ; Save it for next time
- OUT (C),A ; Go
- POP BC ;
- ;
- ; <== End of your own code
- ;
- RET
- ;
- ; Turn DTR OFF
- ;
- DTROFF: DS 0
- ;
- ; <== Insert your own code here
- ;
- PUSH BC
- LD BC,MSTAT
- LD A,5
- OUT (C),A
- LD A,(COMBYT) ; Get the one we used last time
- AND ONHOOK ; 7Fh - clear bit 7
- LD (COMBYT),A ; Save it for next time
- OUT (C),A ; Go
- POP BC
- ;
- ; <== End of your own code
- ;
- RET
- ;
- ; Initialise the SIO +++
- ; The SIO is set up in four steps:
- ;
- ; 1) Reset
- ; 2) Reg 4 - clock, stop bits, parity
- ; 3) Reg 5 - dtr, Tx bits, Brk, TxEn, rts
- ; 4) Reg 3 - Rx bits, RxEn
- ;
- INIT: LD HL,2 ; Get parameters
- ADD HL,SP
- EX DE,HL
- CALL GETPARM ; In HL
- LD (BRATE),HL ; Baud rat
- CALL GETPARM
- LD (PARITY),HL ; Parity
- CALL GETPARM
- LD (DATA),HL ; Data bits
- CALL GETPARM
- LD (STOP),HL ; Stop bits
- ;
- ; <== Insert your own code here, using values below
- ;
- PUSH BC
- LD BC,MSTAT
- LD A,0
- OUT (C),A ; Point to reg 0
- LD A,18H ; Reset
- OUT (C),A ; *** step 1
- LD A,4 ; Point to wrt reg 4
- OUT (C),A
- LD E,44H ; Assume x16, 1 stop, No parity
- LD A,(STOP) ; Set stop bits
- CP 2 ; Set 2 if required
- JR NZ,SETPAR
- LD A,08H ; 0000 1000
- OR E
- LD E,A
- ;
- SETPAR: LD A,(PARITY) ; Set parity bits
- CP 'O'
- JR NZ,SETPA2
- LD D,01H ; 0000 0001 ODD
- JR SETPA3
- ;
- SETPA2: CP 'E'
- JR NZ,SETPA4
- LD D,03H ; 0000 0011 EVEN
- ;
- SETPA3: LD A,E
- OR A,D
- LD E,A
- ;
- SETPA4: LD A,E
- OUT (C),A ; *** step 2
- LD A,5 ; Point to wrt reg 5 - dtr, Tx bits, etc
- OUT (C),A
- LD E,0EAH ; Assume dtr, TX 8 bits, TxEn, rts
- LD A,(DATA)
- CP 7
- JR NZ,SETBI2
- LD D,0BFH ; 1011 1111 7 bits
- LD A,E
- AND A,D
- LD E,A
- ;
- SETBI2: LD A,E
- OUT (C),A ; *** step3
- LD A,3 ; Point to wrt reg 3
- OUT (C),A
- LD E,0C1H ; Assume 8 bits
- LD A,(DATA)
- CP 7
- JR NZ,SETBI3
- LD D,07FH ; 0111 1111 7 bits
- LD A,E
- AND A,D
- LD E,A
- ;
- SETBI3: LD A,E
- OUT (C),A ; *** step 4
- ;
- SETBRATE:
- PUSH IX ; Save IX
- LD DE,(BRATE) ; Get baud rate value (0-10)
- LD IX,BRVAL
- ADD IX,DE
- ADD IX,DE ; IX now points to the 2-byte value
- LD A,(IX) ; If zero,
- OR (IX+1)
- JR Z,SETBRX ; It's not valid
- LD BC,CTCONT
- LD A,36H
- OUT (C),A
- LD BC,CTC0
- LD A,(IX)
- OUT (C),A ; Low byte
- LD A,(IX+1)
- OUT (C),A ; High byte
- LD BC,CTCONT
- LD A,76H
- OUT (C),A
- LD BC,CTC1
- LD A,(IX)
- OUT (C),A ; Low byte
- LD A,(IX+1)
- OUT (C),A ; High byte
- LD A,(BRATE) ; Tell ZMP it's valid
- LD (MSPEED),A
- ;
- SETBRX: POP IX
- POP BC
- ;
- ; <== End of your own code
- ;
- RET
- ;
- BRATE: DW 5 ; Baud rate
- PARITY: DW 'N' ; Parity
- DATA: DW 8 ; Data bits
- STOP: DW 1 ; Stop bits
- COMBYT: DB 0EAH ; Save here
- ;
- ; Values for 8253 control reg for each baud rate: 0 if invalid
- ;
- BRVAL: DW 470H ; 110 0
- DW 1A1H ; 300 1
- DW 116H ; 450 2
- DW 0D0H ; 600 3
- DW 0B0H ; 710 4
- DW 068H ; 1200 5
- DW 034H ; 2400 6
- DW 01AH ; 4800 7
- DW 00DH ; 9600 8
- DW 007H ; 19200 9
- DW 0 ; 38400 10
- DW 0 ; 57600 11
- DW 0 ; 76800 12
- DW 0 ; 115200 13
- ;
- ; 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 Zenith Z19/Z29: 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 column
- ;
- CALL PRINT
- DB ESC,'Y',0 ; Leadin
- LD A,(ROW) ; Row first
- ADD A,' ' ; Add offset
- CALL COUT
- LD A,(COL) ; Sane for column
- ADD A,' '
- CALL COUT
- ;
- ; <== End of your own code
- ;
- RET
- ;
- ROW: DS 2 ; Row
- COL: DS 2 ; Column
- ;
- ; Clear screen
- ;
- CLS: CALL PRINT
- DB ESC,'E',ESC,'H',0
- RET
- ;
- ; Inverse video on
- ;
- INVON: CALL PRINT
- DB ESC,'p',0
- RET
- ;
- ; Inverse video off
- ;
- INVOFF: CALL PRINT
- DB ESC,'q',0
- RET
- ;
- ; Turn off cursor
- ;
- HIDE: CALL PRINT
- DB ESC,'f',0
- RET
- ;
- ; Turn on cursor
- ;
- SHOW: CALL PRINT
- DB ESC,'e',0
- RET
- ;
- ; Save cursor position
- ;
- SAVECU: CALL PRINT
- DB ESC,'j',0
- RET
- ;
- ; Restore cursor position
- ;
- RESCU: CALL PRINT
- DB ESC,'k',0
- RET
- ;
- ;-----------------------------------------------------------------------
- ;
- ; Service modem interrupt
- ;
- MINT: RET
- ;
- ; Initialise interrupt vectors
- ;
- INVEC: RET
- ;
- ; De-initialise interrupt vectors
- ;
- DINVEC: RET
- ;
- ; User-defined entry routine: leave empty if not used
- ;
- USERIN: RET
- ;
- ; User-defined exit routine: leave empty if not used
- ;
- USEROUT: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 1 ms
- 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 registers
- 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
- ;
- ; 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 low
- INC HL
- LD D,(HL) ; Then hihi
- 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 is too large
- ENDIF
- ;
- END