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
/
ZSYS
/
SIMTEL20
/
ZSIG
/
WMZ3PAT.ASM
< prev
next >
Wrap
Assembly Source File
|
2000-06-30
|
10KB
|
483 lines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; WMPATCH.ASM ;
; ;
; Patch for Word-Master 1.07 to use with ;
; the Echelon 'Z' System. This patch causes ;
; WordMaster to use the current terminal ;
; characteristics defined in Z3TCAP. ;
; ;
; Copyright (c) 1985 by Dennis Wright and ;
; Echelon, Inc. ;
; ;
; Contains selected ZCPR3 VLIB routines. ;
; ;
; VLIB is copyrighted by Richard Conn and ;
; Echelon, Inc. ;
; ;
; WordMaster is a trademark of MicroPro ;
; International. ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
MACLIB Z3BASE
;
; WordMaster 1.07 Patch Addresses
;
CLRSCRN EQU 0180H ; Clearscreen routine
HITE EQU 01B9H ; Number of lines
WID EQU 01BAH ; Number of columns
EREOL EQU 01BBH ; Erase to end of line
NOVIO EQU 01BDH ; No video i/o board
DELCLR EQU 01C1H ; Delay after clear screen
DELCUS EQU 01C1H
DELERE EQU 01C3H ; Delay for non-cursor set functions
TCURSOR EQU 0196H ; User cursor positioning routine
PBEGMEM EQU 01B7H ; Contains beginning of text buffer address
SPEC EQU 29B8H ; Get this address from PBEGMEM
OUTCHR EQU 01EFH ; Output character routine.
START EQU 0269H ; Start of Word-Master Version 1.07
;
ORG 100H
JMP INIT ; Goto our init routine
;
ORG CLRSCRN
CALL CLS
LXI H,0
JMP XYPOS ; Put cursor at 0, 0
;
ORG TCURSOR ; User-patchable cursor positioning routine.
JMP XYPOS ; Use our own cursor positioning routine.
;
ORG PBEGMEM
DW BEGMEM
;
ORG SPEC ; Added patch area
INIT: LXI H,Z3ENV ; Point to the ZCPR3 environment
LXI D,80H
SHLD ENVPTR ; Save pointer
PUSH H ; Save for later
DAD D ; Displace to Z3TCAP
SHLD VIDPTR ; Save pointer
XRA A
LXI H,DELCLR
MOV M,A
INX H
MOV M,A
INX H
MOV M,A
POP H ; Restore env pointer
LXI D,47 ; Offset to CRT select byte
DAD D
MOV A,M ; Get it.
LXI D,2
ORA A ; Crt 0?
JZ GETCRT ; Yes move crt 0 data to wm patch area
LXI D,5 ; No, move crt 1 data
GETCRT: DAD D
MOV A,M ; Get tcap width
STA WID ; Patch wm width
INX H
MOV A,M ; Get tcap number of lines
STA HITE ; Patch wm hite
LHLD VIDPTR ; Get tcap pointer
LXI D,22 ; Offset to ce delay
DAD D
MOV A,M ; Get ce delay
STA DELERE ; Patch wm delay after erase to eol
INX H
CALL VIDSKP ; Skip past cl string
CALL VIDSKP ; Skip past cm string
LXI D,EREOL ; Point to wm eol string
PUSH H
MVI C,-1
CNTEOL: MOV A,M ; Get tcap byte count for eol
INX H
INR C
ORA A
JNZ CNTEOL
POP H
MOV A,C
CPI 3 ; More than 2 bytes?
JNC INIT1 ; If so don't use it
CALL FILL ; No, patch with tcaps eol string
JMP INIT2
INIT1: XRA A ; Tell wm to simulate eol
STAX D
INIT2: MVI A,0FFH ; Set no video i/o
STA NOVIO
JMP START ; We're done
;
FILL: MOV A,M ; Replace wm data with ours
ORA A
RZ
STAX D
INX H
INX D
JMP FILL
;
COUT: PUSH H
PUSH D
CALL OUTCHR
POP D
POP H
RET
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; The following routines are from VLIB by Richard Conn.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Clear Screen
; Return with A=0 and Zero Flag Set if not done
;
CLS: PUSH H ; Save regs
PUSH D
LHLD VIDPTR ; Pt to environment
MOV A,M ; No terminal?
CPI ' '+1
JC CLSERR
LXI D,14H ; Pt to cls delay
DAD D
MOV D,M ; Get it
INX H ; Pt to cls string
INX H
INX H
MOV A,M ; Get first char of string
ORA A ; If no string, error
JZ CLSERR
CALL VIDOUT ; Output string with delay
POP D ; Done
POP H
XRA A ; Return NZ
DCR A
RET
;
CLSERR: POP D ; Done
POP H
XRA A ; Return Z
RET
;
; VIDOUT - Output video string pted to by HL
; Output also a delay contained in the D register
;
VIDOUT: MOV A,M ; Get next char
ORA A ; Done if zero
JZ VIDO2
INX H ; Pt to next
CPI '\' ; Literal value?
JNZ VIDO1
MOV A,M ; Get literal char
INX H ; Pt to after it
VIDO1: CALL COUT ; Output char
JMP VIDOUT
VIDO2: MOV A,D ; Output delay
JMP VIDELAY ; Output delay
;
; GOTO XY (From VLIB)
; HL = Row/Col, with Home=1/1
; 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 (1,1 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 1,1 rather than 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
;
BEGMEM EQU $
;
END