home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
beehive
/
utilitys
/
cop12.arc
/
COP12.MAC
< prev
next >
Wrap
Text File
|
1991-08-11
|
13KB
|
357 lines
TITLE COP - Console Output Processor
SUBTTL Author: Mike Freeman 9-May-89
;
;Copyright 1989 by Michael Freeman; 301 N.E. 107th Street;
;Vancouver, Wa 98685; Telephone (206)574-8221
;Permission is hereby granted to use and/or modify this code and its
;accompanying documentation as long as such modified code and/or
;documentation is not distributed without the permission, either in
;writing or electronically, of the copyright-holder. Commercial use and/or
;sale of this program, its code and/or documentation is strictly
;prohibited except that a blind person may use the program in his/her
;place of employment in order to facilitate his/her work. Notwithstanding
;the foregoing, any of these provisions which may be deemed to be in
;violation of the copyright of Mr. Hastwell-Batten are null and void.
; The code which relocates the program to high-memory (just below the CCP)
; is copyrighted 1982, 1984 by John Hastwell-Batten of Australia.
;
; This program relocates itself into high memory just below the CCP.
; It then acts as a preprocessor for characters destined for Console output.
; A string of repeated characters may be displayed as one or more
; occurrences of the character, the maximum number of which is specified by
; the user. For example, a string of five asterisks may be displayed
; as one, two, three, four or five asterisks, depending upon the user's
; preference. Characters may be suppressed from Console output altogether.
; A maximum of 40 such characters (together with their display-counts)
; may be specified. A display-count of 0 for a character is interpreted
; as meaning that the character should be suppressed.
;This is useful for blind computer users employing Braille output devices
;or voice synthesizers to access the computer screen. Ruled lines of
;equals signs (=) or asterisk borders (*), used by the; sighted to
;prettify and/or clarify their computer output can be tamed.
; In addition, with Space-compression enabled, <tab> characters
; are displayed as spaces and multiple spaces are displayed as a single
; space. This should help those who read the computer screen with
; Braille output devices or Optacons.
;
; To install the RSX, just run COP. It will ask for characters to be
; compressed/suppressed (see COP.DOC) and if Space-compression is desired.
; COP then exits to the CCP.
; To remove the RSX, just run COP again.
;
; To compile/link COP using M80/L80:
; Obtain a copy of RELOC23.LBR and extract the files RELOC.ABS,
; RELOC.REL and RELOC.COM
; Extract RELOC.SUB from this archive
; Compile COPxx.MAC:
; A>M80 =COPxx.MAC
; Making sure all files are on drive A (or the default drive if
; you've modified your CCP/SUBMIT/XSUB accordingly, type:
; A>SUBMIT RELOC COPxx -
; The result will be a copy of COPxx.COM (where xx is version-number)
; This .COM-file is ready for execution
;
.Z80 ;Use Zilog mnemonics
;
; BDOS EQUATES
;
WBT EQU 0H ;Warm-boot to CP/M
BDOS EQU 05H ;Jump to BDOS
WSC EQU 09H ;Write String to Console
RSC EQU 0AH ;Read String from Console
RDS EQU 0DH ;Reset Disk System
;
; ASCII equates
;
CR EQU 0DH ;<cr>
LF EQU 0AH ;<lf>
;
; Miscellaneous symbols
;
CHBLEN EQU 40 ;Length of character processing buffer
;
SUBTTL Revision History
;
;Version Description
;
;1.0 Initial Release 01/15/89
;1.1 Maintainence release 04/01/89; fixed a bug wherein Warm-boot
; and BDOS addresses were not being restored during
; warm-boots after installation of COP. This prevented
; removal of COP after running DDT. Thanks to Howard
; Goldstein of New Haven, CT, for pointing out this one.
;1.2 ;Program enhanced 05/09/89
; Implemented ability to specify the maximum number of
; times repeated characters are to be displayed (previously
; always showed only one time); also implemented
; space/tab compression
;
SUBTTL Main program
;
DSEG ;Data segment
;
$MEMRY:: ;Here for L80 to put address of
DEFW 0 ;First Free Location in memory
JP START ;Vector to start of program after relocation
;$MEMRY and the vector to START **MUST**
;be in the order here shown in order for
;the relocator module to relocate
;this program to high-memory (see
;RELOC.DOC from RELOC23.LBR)
;
; Here after program has been relocated
;
START: LD IX,(BDOS+1) ;Point to vector into BDOS
LD A,(IX+3) ;Get 1st byte beyond jump
CP 'C' ;If COP not already present,
JR NZ,INITOK ;Go set things up
LD A,(IX+4) ;COP possibly here, get next character
CP 'O' ;If COP not here,
JR NZ,INITOK ;Go set things up
LD A,(IX+5) ;COP may still be present, get next char
CP 'P' ;If COP not present,
JR NZ,INITOK ;Go init things, else
PUSH IX ;Save register IX
LD DE,FINMSG ;Type termination message
LD C,WSC ;...
CALL BDOS ;...
POP IX ;Restore register IX
LD IY,(WBT+1) ;Point into BIOS dispatch table
LD E,(IX+9) ;Get real CP/M Console output routine address
LD D,(IX+10) ;...
LD (IY+10),E ;and restore real Console output address
LD (IY+11),D ;...
LD L,(IX+1) ;Get real BDOS address
LD H,(IX+2) ;...
LD (BDOS+1),HL ;and restore it
LD L,(IX+6) ;Get real CP/M warm-boot address
LD H,(IX+7) ;...
LD (IY+1),L ;and restore it
LD (IY+2),H ;...
JP WBT ;and exit to CP/M
;Here to initialize various pointers and buffers
INITOK: LD DE,HELLO ;Type sign-on message
LD C,WSC ;...
CALL BDOS ;...
INITOK0:LD DE,CHRMSG ;Now ask user for characters
LD C,WSC ;to be compressed/suppressed
CALL BDOS ;...
LD DE,CONBUF ;Get user's characters to be
LD C,RSC ;compressed/suppressed
CALL BDOS ;...
LD DE,CONBUF+2 ;Point to Console buffer
LD IX,CHRBUF ;and character buffer
INIT0: LD A,(DE) ;Get a character to process
OR A ;Done yet?
JR Z,INIT2 ;Yes
INC DE ;Increment Console buffer pointer
LD (IX),A ;and store character
LD (IX+CHRCNT),0 ;Zap character counter for this character
LD A,(DE) ;Get next character
INC DE ;...
CP '(' ;If start of display-count,
JR Z,INIT1 ;All is well, else
INIT0A: LD DE,FMTERR ;Complain to the user
LD C,WSC ;about his/her lousy typing
CALL BDOS ;...
JR INITOK0 ;and ask again
INIT1: CALL DECIN ;Get display-count
CP ')' ;If not terminated by ")",
JR NZ,INIT0A ;Complain again
LD (IX+DSPCNT),L ;Remember display-count (low-order 8 bits)
LD A,(CHBCNT) ;Increment count of chars to process
INC A ;...
LD (CHBCNT),A ;...
INC IX ;Increment character pointer
JR INIT0 ;and look for more characters
INIT2: LD DE,SPCMSG ;Ask about space-compression
LD C,WSC ;...
CALL BDOS ;...
LD DE,CONBUF ;Get user's answer
LD C,RSC ;...
CALL BDOS ;...
LD A,(CONBUF+1) ;Did user want space-compression?
OR A ;...
JR Z,INIT3 ;No
LD A,(CONBUF+2) ;Get answer (only 1st char counts)
CP 'Y' ;If "yes",
JR Z,INIT2A ;Set space-compression
CP 'Y'+20H ;...
JR NZ,INIT3 ;...
INIT2A: LD A,0FFH ;Set space-compression
LD (SPCFLG),A ;...
INIT3: LD IX,(WBT+1) ;Point into BIOS jump table
LD (BTADR),IX ;and remember it
LD L,(IX+1) ;Get real CP/M warm-boot address
LD H,(IX+2) ;...
LD (WBTADR),HL ;and remember for later
LD L,(IX+10) ;Get address of Console output routine
LD H,(IX+11) ;...
LD (JPCONO+1),HL ;and remember for later
LD HL,CONOUT ;Substitute our own routine
LD (IX+10),L ;...
LD (IX+11),H ;...
LD HL,(BDOS+1) ;Get BDOS entry address
LD (JPBDOS+1),HL ;and remember it
LD HL,JPBDOS ;Substitute our own branch
LD (BDOS+1),HL ;...
EX (SP),HL ;Get CP/M's CCP address
LD (CPMRET),HL ;and remember it
EX (SP),HL ;Restore HL-return address
LD HL,NWBOOT ;Use our own warm-boot routine
LD (IX+1),L ;...
LD (IX+2),H ;...
LD DE,INIMSG ;Say COP is installed
LD C,WSC ;...
JP BDOS ;and return to CP/M CCP
;
;DECIN - Get decimal number from Console buffer CONBUF and place it in HL
;Terminates on non-numeric character (left in A)
;
DECIN: LD HL,0 ;Zero result
DECIN0: LD A,(DE) ;Get character
INC DE ;and increment character pointer
CP '0' ;If not numeric,
RET C ;Return with terminator in A
CP '9'+1 ;...
RET NC ;...
LD B,H ;Save result
LD C,L ;...
ADD HL,HL ;Multiply interim result by ten
ADD HL,HL ;...
ADD HL,HL ;...
ADD HL,BC ;...
ADD HL,BC ;...
AND 0FH ;Make character binary digit
LD B,0 ;Put in BC
LD C,A ;...
ADD HL,BC ;Put digit into the result
JR DECIN0 ;Get all digits
;
HELLO: DEFB CR,LF,'Console Output Processor Version 1.2'
DEFB ' 9-May-89'
DEFB CR,LF,'Copyright 1989 by Michael Freeman'
DEFB CR,LF,'Program Relocation Module copyright 1984 by '
DEFB 'John Hastwell-Batten',CR,LF,'$' ;Sign-on message
CHRMSG: DEFB CR,LF,'Characters>$';Prompt
FINMSG: DEFB CR,LF,'Removing Console Output Processor',CR,LF,'$'
;Termination message
INIMSG: DEFB CR,LF,'Console Output Processor is installed'
DEFB CR,LF,'$' ;Installation announcement
;
SPCMSG: DEFB CR,LF,'Space-compression (Y or N)[N]? $';Space-comp message
;
FMTERR: DEFB CR,LF,'? Format error -- Please try again!!',CR,LF,'$'
;
CONBUF: DEFB 255,0 ;Console input buffer
REPT 256 ;...
DEFB 0 ;...
ENDM ;...
;
; Console Output Processor RSX begins here
;
JPBDOS: DEFB 0C3H,0,0 ;Vector to BDOS
;
DEFB 'COP' ;Identifying characters
;
WBTADR: DEFW 0 ;Holds address of CP/M's warm-boot routine
JPCONO: JP $-$ ;Holds jump to Console output routine
BTADR: DEFW 0 ;Holds address of BIOS jump to boot
CPMRET: DEFW 0 ;Holds return address of CCP
;
WBTMSG: DEFB CR,LF,'Console Output Processor active',CR,LF,'$'
;Warm-boot message
;
CHBCNT: DEFB 0 ;# of characters to check
CHRBUF: ;Character buffer
.PHASE 0
DEFS CHBLEN ;Reserve space for buffer
DSPCNT: DEFS CHBLEN ;Number of times to display chars
CHRCNT: DEFS CHBLEN ;Number of times chars have been displayed
.DEPHASE
;
LSTCHR: DEFB 0 ;Holds last character processed
SPCFLG: DEFB 0 ;0FFH means space-compression
;
CPMSTK: DEFW 0 ;Holds CP/M's stack pointer
DEFS 32 ;Local stack
LOCSTK: ;...
;
;CONOUT - Console Output Routine
;Preserves all registers
;
CONOUT: LD (CPMSTK),SP ;Save current stack pointer
LD SP,LOCSTK ;Use local stack
PUSH AF ;Save AF-IY
PUSH BC ;...
PUSH DE ;...
PUSH HL ;...
PUSH IX ;...
PUSH IY ;...
LD A,(SPCFLG) ;Is space-compression in effect?
INC A ;...
JR NZ,CONOU2 ;No
LD A,(LSTCHR) ;Get last character processed
LD E,A ;and salt it away for checking
LD A,C ;Get current character in process
CP 09H ;If a tab,
JR NZ,CONOU3 ;...
LD A,20H ;Make it a space
LD C,A ;...
CONOU3: LD (LSTCHR),A ;and make it last character processed
CP 20H ;If character is not a space,
JR NZ,CONOU2 ;Process normally, else
CP E ;If previous character was a space,
JR Z,CONOUX ;Don't type anything
CONOU2: LD A,(CHBCNT) ;Get # of chars to be compressed/suppressed
OR A ;Any there?
JR Z,CCOUT ;No, type current character and return
LD B,A ;Put in B to loop over chars
LD IX,CHRBUF ;Point to character buffer
CONOU0: LD A,(IX) ;Get a character of interest
CP C ;Is current character this one?
JR NZ,CONOU1 ;No, check next buffer character
LD A,(IX+DSPCNT) ;Get # of times char should be shown
OR A ;Is character to be suppressed?
JR Z,CONOUX ;Yes, don't type it
LD D,A ;Save display count
INC D ;Increment it by one
LD A,(IX+CHRCNT) ;Get # times char has been typed
INC A ;and increment it
LD (IX+CHRCNT),A ;...
CP D ;Should we display the character?
JR C,CCOUT ;Yes, type it
JR CONOUX ;No, suppress it
CONOU1: LD (IX+CHRCNT),0 ;This char hasn't been seen
INC IX ;Increment buffer pointer
DJNZ CONOU0 ;Go thru character buffer
CCOUT: CALL JPCONO ;Type character in C to Console
CONOUX: POP IY ;Restore registers
POP IX ;...
POP HL ;...
POP DE ;...
POP BC ;...
POP AF ;...
LD SP,(CPMSTK) ;Restore original stack pointer
RET ;and return
;
;NWBOOT - Substitute warm-boot routine
;
NWBOOT: LD SP,WBTSTK ;Use our own stack
LD HL,(BTADR) ;Restore address in BIOS jumping to warm-boot
LD (WBT+1),HL ;...
LD HL,JPBDOS ;Reset our BDOS entry vector
LD (BDOS+1),HL ;...
LD C,RDS ;Reset disk system
CALL BDOS ;...
LD DE,WBTMSG ;Type warm-boot message
LD C,WSC ;to tell user COP RSX is loaded
CALL BDOS ;...
LD HL,(CPMRET) ;Get CCP entry address
JP (HL) ;and go to CCP
;
DEFS 16 ;Boot stack
WBTSTK: ;...
;
END START ;End of program