home *** CD-ROM | disk | FTP | other *** search
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; ;
- ; WSPATCH.ASM ;
- ; ;
- ; Patch for Wordstar 3.0 running under ;
- ; The Echelon 'Z' System. Modifies ;
- ; Wordstar to use the current terminal ;
- ; characteristics defined in Z3TCAP. ;
- ; ;
- ; Copyright (c) 1985 by Dennis Wright ;
- ; and Echelon, Inc. ;
- ; ;
- ; Contains selected routines from ;
- ; ZCPR3's VLIB. ;
- ; ;
- ; VLIB is Copyrighted by Richard Conn ;
- ; and Echelon Inc. ;
- ; ;
- ; Note: It may be possable to install ;
- ; this patch on other versions of Word- ;
- ; Star if the equates below are changed ;
- ; to agree with versions' addresses. ;
- ; ;
- ; WordStar is a trademark of ;
- ; MicroPro International Corporation ;
- ; ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- MACLIB Z3BASE
- ;
- ; WordStar 3.0 USER1 Patch Addresses from Installation manual.
- ;
- TNAME EQU 0190H ; Terminal name (not documented in manual).
- HITE EQU 0248H ; Number of lines.
- WID EQU 0249H ; Number of columns.
- ERAEOL EQU 026DH ; Erase to end of line.
- LINDEL EQU 0274H ; Delete line.
- LININS EQU 027BH ; Insert line.
- IVON EQU 0284H ; Highlighting on.
- IVOFF EQU 028BH ; Highlighting off.
- DELMIS EQU 02AFH ; Delay for non-cursor set functions.
- TRMINI EQU 0292H ; Terminal init string.
- TRMUNI EQU 029BH ; Terminal de-init string.
- UCRPOS EQU 0264H ; User cursor positioning routine.
- INISUB EQU 02A4H ; User init routine.
- MORPAT EQU 02E0H ; WordStar user patch area.
- PBGMEM EQU 035CH ; Contains beginning of text buffer address.
- OCHAR EQU 0267H ; Contains address of WordStar outchr routine.
- ;
- ; The following equate is the base address of the patch routines.
- ;
- PATCH EQU 7849H ; Get this address from original PBGMEM.
- ;
- ORG UCRPOS ; User-patchable cursor positioning routine.
- JMP XYPOS ; Use VLIB cursor positioning routine.
- ;
- ORG INISUB ; User-patchable init subroutine.
- JMP INIT ; Use patch init routine.
- ;
- ORG MORPAT ; WordStar user patch area.
- INIT: LXI H,Z3ENV ; Point to 'Z' System environment descriptors.
- LXI D,80H
- SHLD ENVPTR ; Save pointer.
- PUSH H ; Save for later.
- DAD D ; Displace to Z3TCAP.
- SHLD VIDPTR ; Save pointer.
- LHLD OCHAR ; Address of WS outchr routine is kept here.
- SHLD COUT1+1 ; Inline modify patch cout to use WS outchr.
- POP H ; Restore env pointer.
- LXI D,47 ; Offset to Z3TCAP crt select byte.
- DAD D
- MOV A,M ; Get it.
- LXI D,2 ; Set offset to crt 0 data area.
- ORA A ; Crt 0?
- JZ GETCRT ; Yes move crt 0 data to WS patch area.
- LXI D,5 ; No, move crt 1 data.
- GETCRT: DAD D ; Offset to selected Z3TCAP crt data area.
- MOV A,M ; Get Z3TCAPs terminal width.
- STA WID ; Patch WS width.
- INX H ; Bump to Z3TCAPs number of lines.
- MOV A,M ; Get number of lines.
- STA HITE ; Patch WS hite.
- XRA A ; Clear following WS patchs.
- STA LINDEL ; Line delete
- STA LININS ; ..and line insert (we don't support these).
- LHLD VIDPTR ; Get Z3TCAP pointer.
- LXI D,22 ; Offset to CE delay.
- DAD D
- MOV A,M ; Get CE delay.
- STA DELMIS ; Patch WS misc delay.
- INX H
- CALL VIDSKP ; Skip past CL string.
- CALL VIDSKP ; Skip past CM string.
- LXI D,ERAEOL ; Point to WS eol string.
- CALL FILL ; Replace with Z3TCAPs eol string.
- LXI D,IVON ; Point to WS turn on highlighting.
- CALL FILL ; Replace with Z3TCAPs string.
- LXI D,IVOFF ; Point to WS turn off highlighting.
- CALL FILL ; Replace with Z3TCAPs string.
- LXI D,TRMINI ; Point to WS terminal init string.
- CALL FILL ; Replace with Z3TCAPs string.
- LXI D,TRMUNI ; Point to WS terminal de-init string.
- CALL FILL ; Replace with Z3TCAPs string.
- CALL NAMIT ; Replace WS terminal name with Z3TCAPs.
- RET ; We're done.
- ;
- ORG PBGMEM ; The beginning of the text memory is
- DW BEGMEM ; ..moved up to accommidate our patch.
- ;
- ORG PATCH ; Extended patch area.
- NAMIT: LHLD VIDPTR ; Point to Z3TCAPs terminal name
- LXI D,TNAME ; ..and WS terminal name.
- MVI C,16 ; Move our 16 bytes.
- NFILL: MOV A,M
- STAX D
- INX H
- INX D
- DCR C
- JNZ NFILL
- XCHG
- NFILL2: MOV A,M ; Pad out the remainder with spaces.
- CPI 0FH ; Till this.
- RZ
- ORA A ; Or zero.
- RZ
- MVI A,20H
- MOV M,A
- INX H
- JMP NFILL2
- ;
- ; This routine moves Z3TCAP data into the WordStar patch area.
- ; Because WordStar requires the number of bytes for each entry
- ; we must count the bytes we patch and place the number at the
- ; beginning of the patch.
- ;
- FILL: PUSH D
- MVI C,-1 ; Set byte counter.
- FIL1: INX D
- MOV A,M ; Replace WS data with Z3TCAPs.
- STAX D
- INX H
- INR C
- ORA A ; Reached end?
- JNZ FIL1
- POP D ; Yes, restore pointer to first byte.
- MOV A,C ; Insert number of bytes in string.
- STAX D
- RET
- ;
- COUT: PUSH H
- PUSH D
- COUT1: CALL 0000H ; This is inline modified by the INIT.
- POP D ; Routine to call WordStars outchr
- POP H ; ..routine.
- RET
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; The following routines are from VLIB by Richard Conn.
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; GOTO XY (From VLIB)
- ; HL = Row/Col, with Home=0/0
- ; Return with A=0 and Zero Flag Set if not done
- ;
- XYPOS: MOV D,L ; Swap row & column
- MOV E,H ; ..for vlib
- XCHG
- GOTOXY: PUSH B ; Save regs
- PUSH D
- PUSH H
- LHLD VIDPTR ; Pt to environment
- MOV A,M ; No terminal?
- CPI ' '+1
- JC ERR
- LXI D,15H ; Pt to CM delay
- DAD D
- MOV A,M ; Get it
- STA CMDELAY ; Save it
- INX H ; Pt to CL string
- INX H
- CALL VIDSKP ; Skip CL string
- MOV A,M ; Get first char of CM string
- ORA A ; If no string, error
- JZ ERR
- XCHG ; DE=address of CM string
- POP H ; Get coordinates in HL
- PUSH H
- CALL GXY ; Output xy string with delay
- LDA CMDELAY ; Pause
- CALL VIDELAY
- POP H ; Done
- POP D
- POP B
- XRA A ; Return NZ
- DCR A
- RET
- ERR: POP H ; Done
- POP D
- POP B
- XRA A ; Return Z
- RET
- ;
- ; GOTOXY (From VLIB)
- ; On input, H=Row and L=Column to Position To (0,0 is Home)
- ; On input, DE=address of CM string
- ;
- GXY: XRA A ; Set row/column
- STA RCORDER ; Row before column
- STA RCBASE ; Add 0 to base
- ;
- ; Cycle thru string
- ;
- GXYLOOP:LDAX D ; Get next char
- INX D ; Pt to next
- ORA A ; Done?
- RZ
- CPI '%' ; Command?
- JZ GXYCMD
- CPI '\' ; Escape?
- JZ GXYESC
- CALL COUT ; Send char
- JMP GXYLOOP
-
- ;
- ; Escape - output following byte literally
- ;
- GXYESC: LDAX D ; Get next char
- CALL COUT ; Output literally
- INX D ; Pt to next
- JMP GXYLOOP
- ;
- ; Interpret next character as a command character
- ;
- GXYCMD: LDAX D ; Get command char
- INX D ; Pt to next
- CPI 'd' ; %d
- JZ GXYOUT1
- CPI '2' ; %2
- JZ GXYOUT2
- CPI '3' ; %3
- JZ GXYOUT3
- CPI '.' ; %.
- JZ GXYOUT4
- CPI '+' ; %+v
- JZ GXYOUT5
- CPI '>' ; %>xy
- JZ GXYGT
- CPI 'r' ; %r
- JZ GXYREV
- CPI 'i' ; %i
- JZ GXYINC
- CALL COUT ; Output char if nothing else
- JMP GXYLOOP
- ;
- ; Set row/col home to 0,0
- ;
- GXYINC: MVI A,1 ; Set rcbase to 1
- STA RCBASE
- JMP GXYLOOP
- ;
- ; Reverse order of output to column then row (default is row then column)
- ;
- GXYREV: MVI A,1 ; Set column and row order
- STA RCORDER
- JMP GXYLOOP
- ;
- ; Command: >xy
- ; If value of row/col is greater than x, add y to it
- ;
- GXYGT: CALL GETVAL ; Get value
- MOV C,A ; Save value
- LDAX D ; Get value to test
- INX D ; Pt to next
- CMP C ; If carry, value>x
- JNC GXYGT1
- LDAX D ; Get value to add
- ADD C
- CALL PUTVAL ; Put value back
- GXYGT1: INX D ; Pt to next
- JMP GXYLOOP ; Resume
- ;
- ; Command: +n
- ; Add n to next value and output
- ;
- GXYOUT5:LDAX D ; Get value to add
- INX D ; Pt to next
- MOV B,A ; Save in B
- CALL GETVAL ; Get value
- ADD B ; Add in B
- CALL COUT ; Output value
- RCMARK: LDA RCORDER ; Mark output
- ORI 80H
- STA RCORDER
- JMP GXYLOOP
- ;
- ; Command: .
- ; Output next value
- ;
- GXYOUT4:CALL GETVAL ; Get value
- CALL COUT ; Output value
- JMP RCMARK
- ;
- ; Command: 3
- ; Output next value as 3 decimal digits
- ;
- GXYOUT3:CALL GETVAL ; Get value
- MVI B,100 ; Output 100's
- MVI C,1 ; Leading zeroes
- CALL DIGOUT
- GXYOT3: MVI B,10 ; Output 10's
- MVI C,1 ; Leading zeroes
- GXYOT2: CALL DIGOUT
- ADI '0' ; Output 1's
- CALL COUT
- JMP RCMARK
- ;
- ; Command: 2
- ; Output next value as 2 decimal digits
- ;
- GXYOUT2:CALL GETVAL ; Get value
- JMP GXYOT3
- ;
- ; Command: d
- ; Output next value as n decimal digits with no leading zeroes
- ;
- GXYOUT1:CALL GETVAL ; Get value
- MVI B,100 ; Output 100's
- MVI C,0 ; No leading zeroes
- CALL DIGOUT
- MVI B,10 ; Output 10's
- MVI C,0 ; No leading zeroes
- JMP GXYOT2
- ;
- ; Return next value in A
- ;
- GETVAL: LDA RCORDER ; Get order flag
- ORA A ; Already output the first value?
- JM GETVAL2
- ANI 1 ; Look at lsb
- JZ GETVALR ; If 0, row first
- GETVALC:LDA RCBASE ; Get base offset
- ADD L ; Get column
- RET
- ;
- GETVALR:LDA RCBASE ; Get base offset
- ADD H ; Get row
- RET
- ;
- GETVAL2:ANI 1 ; Look at lsb
- JZ GETVALC
- JMP GETVALR
- ;
- ; Store A as next value
- ;
- PUTVAL: MOV C,A ; Save value
- LDA RCORDER ; Get order flag
- ORA A ; Already output the first value?
- JM PUTVAL2
- ANI 1 ; Look at lsb
- JZ PUTVALR ; If 0, row first
- PUTVALC:MOV L,C ; Set column
- RET
- ;
- PUTVALR:MOV H,C ; Set row
- RET
- ;
- PUTVAL2:ANI 1 ; Look at lsb
- JZ PUTVALC
- JMP PUTVALR
- ;
- ; Output A as decimal digit char
- ; B=Quantity to Subtract from A, C=0 if no leading zero
- ;
- DIGOUT: PUSH D ; Save DE
- MVI D,'0' ; Char
- DECOT1: SUB B ; Subtract
- JC DECOT2
- INR D ; Increment char
- JMP DECOT1
- ;
- DECOT2: ADD B ; Add back in
- PUSH PSW ; Save result
- MOV A,D ; Get digit
- CPI '0' ; Zero?
- JNZ DECOT3
- MOV A,C ; Get zero flag
- ORA A ; 0=no zero
- JZ DECOT4
- DECOT3: MOV A,D ; Get digit
- CALL COUT ; Print it
- DECOT4: POP PSW ; Get A
- POP D ; Restore DE
- RET
- ;
- ; GXY Buffers
- ;
- RCORDER:DS 1 ; 0=row/col, else col/row
- RCBASE: DS 1 ; 0=org is 0,0, else org is 1,1
- CMDELAY:DS 1 ; Number of milliseconds to delay for CM
- ;
- ; VIDELAY pauses for the number of milliseconds indicated by the A
- ; register. VIDELAY assumes a ZCPR3 environment and uses it to determine
- ; processor speed.
- ;
- VIDELAY:PUSH PSW ; Save regs
- PUSH B
- PUSH D
- PUSH H
- MOV C,A ; Save count in C
- ORA A ; No delay?
- JZ DONE
- LHLD ENVPTR ; Pt to environment
- LXI D,2BH ; Offset to processor speed
- DAD D
- MOV A,M ; Get processor speed
- ORA A ; Zero?
- JNZ VID1
- MVI A,4 ; Assume 4 MHz
- VID1: MOV B,A ; Processor speed in B
- VID2: PUSH B ; Delay 1 ms
- CALL DELAY
- POP B
- DCR C ; Count down
- JNZ VID2
- DONE: POP H ; Restore regs
- POP D
- POP B
- POP PSW
- RET
- ;
- ; Delay 1 ms at Clock speed
- ;
- DELAY: CALL DEL1 ; Delay 1 ms at 1MHz
- DCR B ; Count down clock speed
- JNZ DELAY
- RET
- ;
- ; Delay 1 ms at 1MHz
- ;
- DEL1: MVI C,20 ; 20 loops of 51 cycles each ~ 1000 cycles
- DEL1A: XTHL ; 18 cycles
- XTHL ; +18 = 36 cycles
- DCR C ; + 5 = 41 cycles
- JNZ DEL1A ; +10 = 51 cycles
- RET
- ;
- ; VIDSKP - Skip over video string pted to by HL; pt to byte after string
- ;
- VIDSKP: MOV A,M ; Get next char
- INX H ; Pt to next
- ORA A ; Done if zero
- RZ
- CPI '\' ; Literal value?
- JNZ VIDSKP ; Continue if not
- INX H ; Pt to after literal value
- JMP VIDSKP
- ;
- ; ZCPR3 Pointer save area
- ;
- VIDPTR: DS 2 ; First byte of termcap entry
- ENVPTR: DS 2 ; 'Z' System environment package.
- ;
- BEGMEM EQU $
- ;
- END