home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
beehive
/
zcat
/
z3key14.lbr
/
Z3KEYRCP.ZZ0
/
Z3KEYRCP.Z80
Wrap
Text File
|
1991-01-31
|
18KB
|
790 lines
; SYSTEM SEGMENT: Z3KEY.RCP
; WRITTEN BY: ARNOLD BAILEY
;
; PROGRAM: Z3KEYRCP.Z80
; AUTHOR: ARNOLD BAILEY
; VERSION: 1.4
; DATE: 25 JAN 86
; PREVIOUS VERSIONS: 1.0, 1.1, 1.2, 1.3
; VERSION 1.4 IMPROVED INSTALLATION FOR USERS
; VERSION 1.3 ADDS FULL SUPERSHIFT KEY ABILITY. AND COMPILED KEY DEFINITION
; INPUTS WITH Z3KEY.COM
;
; VERSION 1.2 ADDS ABILITY TO DISPLAY THE KEY DEFINITIONS BY THE USE OF THE
; KEYS COMMMAND.
;
; VERSION 1.1 ADDS CONTROLLED EXPANSION RATE OF MACROS TO PREVENT PROGRAMS
; THAT CLEAR INCOMING CHARACTERS UPON ENTRY FROM THROWING AWAY THE REST OF
; A MACRO EXPANSION.
;
VERSION EQU 14
;
; ZKEYRCP IS A RESIDENT COMMAND PROCESSOR FOR ZCPR3. IT PROVIDES THE
; FOLLOWING FUNCTIONS:
;
; 1. ALLOWS ON THE FLY RE-DEFINITION OF THE KEYBOARD. EVEN WHILE IN
; A PROGRAM.
;
; 2. ALLOWS DEFINING A KEY AS THE GENERATOR OF A MACRO STRING.
;
; 3. USER DEFINIED LEADIN KEY FOR USE OF MULTI CHARACTER FUNCTION KEYS.
;
; 4. VARIABLE DELAY ALLOWS THE LEADIN KEY TO BE USED AS A SUPER SHIFT KEY.
;
; 5. CASE FLAG CAN AUTOMATICALLY UPCASE ANY CHARACTER AFTER THE LEADIN
; CHARACTER.
;
; 6. Z3KEY.COM UTILITY ALLOWS RE-DEFINITION OF THE ATTENTION KEY, LEADIN
; KEY, DELAY, CASE FLAG, AND SAVING A SET OF DEFINITIONS TO A DISK FILE.
;
;
;
; GLOBAL LIBRARY WHICH DEFINES ADDRESSES FOR ZKEYRCP
;
*INCLUDE Z3BASE.LIB ; USE BASE ADDRESSES
*INCLUDE Z3KEYRCP.LIB ;INITIALIZATION DEFINITIONS
;
CTRLC EQU 'C'-'@'
TAB EQU 09H
LF EQU 0AH
FF EQU 0CH
CR EQU 0DH
CTRLX EQU 'X'-'@'
;
WBOOT EQU BASE+0000H ; CP/M WARM BOOT ADDRESS
UDFLAG EQU BASE+0004H ; USER NUM IN HIGH NYBBLE, DISK IN LOW
BDOS EQU BASE+0005H ; BDOS FUNCTION CALL ENTRY PT
TFCB EQU BASE+005CH ; DEFAULT FCB BUFFER
FCB1 EQU TFCB ; 1ST AND 2ND FCBS
FCB2 EQU TFCB+16
TBUFF EQU BASE+0080H ; DEFAULT DISK I/O BUFFER
TPA EQU BASE+0100H ; BASE OF TPA
;
; SYSTEM ENTRY POINT
;
ORG RCP
DB 'Z3RCP' ; FLAG FOR PACKAGE LOADER
;
; **** COMMAND TABLE FOR RCP ****
; THIS TABLE IS RCP-DEPENDENT!
;
; THE COMMAND NAME TABLE IS STRUCTURED AS FOLLOWS:
;
; CTABLE:
; DB 'CMNDNAME' ; TABLE RECORD STRUCTURE IS
; DW CMNDADDRESS ; 8 CHARS FOR NAME AND 2 BYTES FOR ADR
; ...
; DB 0 ; END OF TABLE
;
CNSIZE EQU 5 ; NUMBER OF CHARS IN COMMAND NAME
DB CNSIZE ; SIZE OF TEXT ENTRIES
CTAB:
DB 'H ' ; HELP FOR RCP
DW CLIST
CTAB1:
DB 'KEY+ ' ;CLEAR SCREEN COMMMAND
DW KEYON
DB 'KEY- '
DW KEYOFF
DB 'CASE+'
DW CASEON
DB 'CASE-'
DW CASEOFF
DB 'KSTAT'
DW STATUS
IF KEYDEF
DB 'KEYS '
DW KEYS
ENDIF
DB 0
;
; THE KEY DEFINITION BUFFER AND VARIABLES MUST FOLLOW HERE SO THAT THE
; Z3KEY.COM UTILITY CAN FIND THEM PROPERLY.
;
ID DB 'Z3KEY' ;IDENTIFIER TO Z3KEY UTILITY
NAME DB ' ',0 ;NAME OF RCP STORED HERE WHEN DEFINITION SAVED
CASEFLG: ;IF NOT ZERO THEN ALL CHAR AFTER LEADIN WILL
DB UPCASE ;BE UPPERCASE
DELAY: DW DELAYCNT ;DELAY FOR FUNCTION KEY SECOND CHAR
INSFLG: DB 00H ;FLAG TO INDICATE WHETHER INSTALLED OR NOT
EXRATE: DB EXPRATE ;COUNT FOR CONST CALLS BEFORE CHARACTER SENT
KTSIZE DW KEYTBLS ;LENGTH OF TABLE
ATTN: ;ATTENTION CHAR TO SIGNAL DEFINITION INPUT
DB ATTNCHAR
LEADIN: ;LEAD IN CHARACTER FOR FUNCTION KEYS
KEYTBL:
DB LEADCHR,LEADCHR+128,0
;DOUBLE CHARACTER DEFINES SINGLE LEADIN AS
;LEADIN CHARACTER
DS TABLESIZE
;RESERVE BLANK SPACE FOR TABLE
KEYEND:
DB 0,0 ;GUARD BYTES JUST IN CASE
KEYTBLS: EQU KEYEND-KEYTBL ;KEY TABLE SIZE
;
; BANNER NAME OF RCP
;
RCP$NAME:
DB 'Z3KEY '
DB [VERSION/10]+'0','.',[VERSION MOD 10]+'0'
DB RCPID,0DH,0AH,0AH
DB ' KEY+ activates key definitions',0DH,0AH
DB ' KEY- deactivates key definitions',0DH,0AH,0AH
DB ' KEY- must be run before loading a new RCP',0DH,0AH
DB 0
;
; COMMAND LIST ROUTINE
;
CLIST:
LD HL,NAME
CALL PRINT1
CALL CRLF
LD HL,RCP$NAME ; PRINT RCP NAME
CALL PRINT1
LD HL,CTAB1 ; PRINT TABLE ENTRIES
LD C,1 ; SET COUNT FOR NEW LINE
CLIST1:
LD A,(HL) ; DONE?
OR A
RET Z
DEC C ; COUNT DOWN
JR NZ,CLIST1A
CALL CRLF ; NEW LINE
LD C,4 ; SET COUNT
CLIST1A:
LD DE,ENTRYNAME ; COPY COMMAND NAME INTO MESSAGE BUFFER
LD B,CNSIZE ; NUMBER OF CHARS
CLIST2:
LD A,(HL) ; COPY
LD (DE),A
INC HL ; PT TO NEXT
INC DE
DJNZ CLIST2
INC HL ; SKIP TO NEXT ENTRY
INC HL
PUSH HL ; SAVE PTR
LD HL,ENTRYMSG ; PRINT MESSAGE
CALL PRINT1
POP HL ; GET PTR
JR CLIST1
CRLF: LD A,0DH
CALL CONOUT
LD A,0AH
;
; CONSOLE OUTPUT ROUTINE
;
CONOUT:
PUSH HL ; SAVE REGS
PUSH DE
PUSH BC
PUSH AF
AND 7FH ; MASK MSB
LD E,A ; CHAR IN E
LD C,2 ; OUTPUT
CALL BDOS
POP AF ; GET REGS
POP BC
POP DE
POP HL
RET
;
; PRINT STRING [TERMINATED IN 0 OR MSB SET] AT RETURN ADDRESS
;
PRINT:
EX (SP),HL ; GET ADDRESS
CALL PRINT1
EX (SP),HL ; PUT ADDRESS
RET
;
; PRINT STRING [TERMINATED IN 0 OR MSB SET] PTED TO BY HL
;
PRINT1:
LD A,(HL) ; DONE?
INC HL ; PT TO NEXT
OR A ; 0 TERMINATOR
RET Z
CALL CONOUT ; PRINT CHAR
RET M ; MSB TERMINATOR
JR PRINT1
;
; CLIST MESSAGES
;
ENTRYMSG:
DB ' ' ; COMMAND NAME PREFIX
ENTRYNAME:
DS CNSIZE ; COMMAND NAME
DB 0 ; TERMINATOR
;
; UCASE UPCASES CHARACTER IN A
;
UCASE:
AND 7FH ; MASK OUT MSB
CP 'a' ; LOWER-CASE A
RET C
CP 'z'+1 ; GREATER THAN LOWER-CASE Z?
RET NC
AND 5FH ; CAPITALIZE
RET
;
; **** RCP ROUTINES ****
; ALL CODE FROM HERE ON IS RCP-DEPENDENT!
;
;
; MESSAGE STRINGS
;
KEYMSG:
DB 'Key: ',0 ;KEY PROMPT
EQMSG:
DB ' = ',0 ;EQUAL STRING
FULLMSG:
DB ' Key Table Full, Press any Key ',0
CMESGON:
DB ' Upcase function is on.',0DH,0AH,0
KMESGON:
DB ' Z3KEY is active.',0DH,0AH,0
KMESGOFF:
DB ' Z3KEY is inactive.',0DH,0AH,0
CMESGOFF:
DB ' Upcase function is off.',0DH,0AH,0
OLDWBOOT:
JP 0000H ;STORAGE FOR ORIGINAL BIOS JUMP TABLE
OLDCONST:
JP 0000H
OLDCONIN:
JP 0000H
OLDCONOUT:
JP 0000H
NEWTBL: JP NEWCONST ;THIS JUMP TABLE WILL BE MOVED TO
JP NEWCONIN ;OVERLAY AT CONST TO REDIRECT CONSOLE IO
;TO THE RCP
SENDFLG: ;FLAG TO SHOW THAT A DEFINITION IS BEING SENT
DB 00H
ENTRYPTR: ;POINTER TO A FOUND ENTRY IN THE TABLE
DW KEYTBL ;USED TO CLEAR ENTRIES
DEFPTR: ;POINTER TO NEXT CHAR TO BE SENT
DW KEYTBL ;INITIALLY POINTS TO THE START OF THE KEYTABLE
LNLEN DB 0 ;STORAGE FOR DEFINITION LINE LENGTH
EXCOUNT DB EXPRATE ;COUNTER FOR EXPANSION RATE
INBUFS: EQU 5 ;SIZE OF INPUT BUFFER FOR FUNCTION KEYS
INBUF: ;INPUT BUFFER FOR FUNCTION KEYS
DS INBUFS ;INITIALIZED TO ZERO
IF KEYDEF
KEYS:
LD DE,KEYTBL+3
KS4: LD B,14H
KS0: CALL CRLF
KS1:
LD A,(DE)
OR A
JP M,KS2
RET Z
CP ' '
JR NC,KS6
LD A,'^'
CALL CONOUT
LD A,(DE)
ADD A,40H
KS6:
CALL CONOUT
INC DE
JR KS1
KS2:
LD HL,EQMSG
CALL PRINT1
KS3:
PUSH BC
CALL SNDMSG
POP BC
DJNZ KS0
KS5:
LD C,06H
PUSH DE
LD E,0FFH
CALL BDOS
POP DE
OR A
JR Z,KS5
JR KS4
ENDIF
KEYOFF LD A,(INSFLG) ;TURNS OFF THE KEY TRANSLATION AND
OR A ;UNPATCHES THE BIOS TABLE
JR Z,KO1 ;MUST BE RUN BEFORE A NEW RCP IS LOADED
LD DE,(WBOOT+1) ;TO AVOID TRASHING THE BIOS POINTERS
LD HL,OLDWBOOT
LD BC,12
LDIR
XOR A
LD (INSFLG),A
KO1: LD HL,KMESGOFF
JR S2
KEYON: ;REDIRECTS CONSOLE IO TO THE RCP
LD A,(INSFLG) ;SEE IF ALREADY ACTIVE
OR A
JR NZ,KN1 ;RETURN IMMEDIATELY IF NOT 0
LD HL,(WBOOT+1) ;POINT TO PRESENT BIOS TABLE
LD DE,OLDWBOOT ;POINT TO STORAGE AREA
LD BC,12 ;LENGTH OF TABLE
LDIR ;MOVE TO STORAGE
LD HL,(WBOOT+1) ;POINT TO PRESENT BIOS TABLE
LD BC,3 ;ADD 3 TO POINT TO CONST
ADD HL,BC
EX DE,HL ;PUT IN DE
LD HL,NEWTBL ;POINT TO NEW JUMP TABLE
LD BC,6 ;LOAD LENGTH
LDIR ;MOVE NEW TABLE TO BIOS
LD A,0FFH ;TURN ON INSTALLED FLAG
LD (INSFLG),A
KN1:
LD HL,NAME ;DISPLAY NAME OF THIS VERSION OF Z3KEY
CALL PRINT1
CALL CRLF
LD HL,RCP$NAME ;DISPLAY HELP MENU
JR S2
CASEON: ;TURNS ON THE CASE TRANSLATION FLAG
LD A,0FFH
LD (CASEFLG),A
LD HL,CMESGON
JR S2
CASEOFF: ;TURNS OFF TTHE CASE TRANSLATION FLAG
XOR A
LD (CASEFLG),A
LD HL,CMESGOFF
JR S2
STATUS: ;DISPLAYS PRESENT STATUS OF INSTALLED RCP
LD A,(INSFLG)
OR A
LD HL,KMESGON
JR NZ,S1
LD HL,KMESGOFF
S1: CALL PRINT1
LD HL,CMESGON
LD A,(CASEFLG)
OR A
JR NZ,S2
LD HL,CMESGOFF
S2: JP PRINT1
NEWCONST: ;NEW CONSOLE STATUS ROUTINE
LD A,(SENDFLG) ;SEE IF FLAG SET
OR A
JP Z,OLDCONST ;IF ZERO THEN CHECK THE CONSOLE
LD A,(EXCOUNT) ;GET EXPANSION COUNT
OR A ;SET FLAGS
JR Z,NS1 ;SKIP IF ZERO
DEC A
LD (EXCOUNT),A ;STORE THE NEW COUNT
XOR A ;ZERO A
RET ;RET NO CHARACTER AVAILABLE YET
NS1: LD A,0FFH ;CHARACTER AVAILABLE HERE FIRST
RET ;SO FLAG IT AND RETURN
NEWCONIN: ;NEW CONSOLE INPUT ROUTINE
PUSH HL ;SAVE THE REGISTERS
PUSH DE
PUSH BC
LD A,(SENDFLG) ;SEE IF FLAG SET
OR A
JR NZ,SENDNXT ;IF NOT ZERO THEN SEND NEXT CHAR OF DEFINITION
LD HL,INBUF ;POINT TO INBUF FOR GETKEY
CALL GETKEY ;GET THE CHARCTER OR FUNCTION KEY
LD A,(INBUF) ;GET FIRST CHAR
LD BC,(ATTN) ;GET ATTENTION CHAR
CP C
JP Z,GETDEF ;IF ATTENTION CHAR THEN GET A KEY DEFINITION
CALL FINDKEY ;ELSE SEARCH THE KEY TABLE RETURNS CHAR IN A
NC1:
IF KEYDEF
AND 7FH
ENDIF
POP BC
POP DE
POP HL
RET
SENDNXT: ;SENDS NEXT CHARACTER OF A MACRO KEY
LD A,(EXRATE) ;GET EXPANSION RATE COUNT
LD (EXCOUNT),A ;RESET COUNT
LD HL,(DEFPTR) ;GET POINTER TO NEXT CHARACTER
LD B,(HL) ;MOVE CHARACTER TO A
INC HL ;INCREMENT THE POINTER
LD (DEFPTR),HL
LD A,(HL) ;GET NEXT CHAR
LD (SENDFLG),A ;STORE IN FLAG
LD A,B ;MOVE THE CHAR TO A
JR NC1 ;AND EXIT
GETKEY: ;GETS A KEY FROM CONSOLE AND STORES IT AT HL
;HL RETURNS POINTING TO 0 AT END OF STRING
PUSH HL
CALL OLDCONIN ;ELSE GET CHARACTER FROM CONSOLE
POP HL
LD (HL),A
INC HL
LD BC,(LEADIN) ;LOAD LEADIN CHARACTER TO C
CP C ;SEE IF CHARACTER IS LEADIN CHARACTER
CALL Z,CHKLEADIN ;IF SO THEN CHECK FOR REST OF CHARACTERS
LD (HL),0 ;OTHERWISE NO NEED FOR INBUF SO 0
RET
CHKLEADIN: ;CHECKS FOR MORE CHARACTERS AFTER A LEADIN
;CHARACTER IF NONE ARRIVE WHITHIN THE PERIOD
;DEFINED BY DELAY IT TERMINATES THE INPUT
LD BC,(DELAY) ;LOAD DELAY COUNT
XOR A ;ZERO A REGISTER
CP B ;IS B ZERO
JR NZ,CL1 ;IF NOT THEN CONTINUE
CP C ;SEE IF C IS ALSO 0
JR NZ,CL1 ;IF 0 THEN TREAT AS SUPERSHIFT KEY
PUSH HL ;SAVE POINTER
CALL GETCHAR ;GET NEXT CHARACTER
POP HL ;RETRIEVE POINTER
LD (HL),A
LD BC,(LEADIN)
CP C
RET Z
INC HL
RET
CL1:
PUSH BC ;SAVE REGISTERS
PUSH HL
CALL OLDCONST ;SEE IF NEXT CHARACTER AVAILABLE YET
OR A ;SET FLAGS
JR Z,WAIT ;IF NOT THEN WAIT A TICK
CALL GETCHAR
POP HL ;RETRIEVE POINTER
LD (HL),A ;STORE NEXT CHARACTER IN INBUF
INC HL
POP BC ;CLEANUP STACK
JR CHKLEADIN ;SEE IF MORE CHARACTERS
WAIT:
POP HL ;RETRIEVE REGISTERS
POP BC
DEC BC ;DECREMENT THE DELAY COUNT
CP B ;A IS ZERO SO SEE IF B IS
JR NZ,CL1 ;IF NOT 0 THEN LOOP
CP C ;IF B WAS 0 SEE IF C IS
JR NZ,CL1 ;LOOP IF NOT 0
RET
;
; GETCHAR GET A CHARACTER FROM THE OLD CONIN ROUTINE AND APPLIES THE UP CASE IF
; THE CASE FLAG IS SET
;
GETCHAR:
CALL OLDCONIN ;ELSE GET THE CHARACTER
LD B,A
LD A,(CASEFLG)
OR A
LD A,B
CALL NZ,UCASE
RET
;
; FINDKEY LOCATES A KEY DEFINITION IN THE TABLE FROM THE STRING POINTED TO
; BY DE. RETURNS WITH THE ENTRY'S ADDRESS IN ENTRYPTR, A CONTAINS THE FIRST
; CHARACTER OF THE DEFINITION,DEFPTR POINTS TO SECOND CHARACTER OF DEFINITION
; SENDFLG IS SET IF MORE CHARACTERS TO SEND FROM THE DEFINITION
;
FINDKEY: ;INBUF CONTAINS THE KEY CHAR TO BE MATCHED
LD DE,INBUF
SCAN: ;ENTER HERE WITH DE PRESET
LD BC,KEYTBLS ;LOAD SIZE OF KEY TABLE
LD HL,KEYTBL ;POINT TO BEGINNING OF KEY TABLE
PUSH DE ;SAVE POINTER TO THE INPUT STRING
KEYCOMP:
LD A,(DE) ;GET CHAR FROM INBUF
INC DE ;POINT TO NEXT INBUF CHAR
OR A ;END OF INBUF CHARACTERS?
JR Z,FOUND ;IF SO THEN FOUND
CPI ;COMPARE INBUF CHAR WITH TABLE
JR Z,KEYCOMP ;IF MATCH THEN CHECK NEXT CHARACTER
POP DE ;IF NOT THEN GET START OF KEY
PUSH DE ;AND SAVE IT AGAIN
XOR A ;FIND A=0 WHICH BEGINS A DEFINITION
CPIR ;SEARCH UNTIL 0 FOUND OR END OF TABLE
JP PO,NOFIND ;IF BC=0 THEN END OF TABLE REACHED
CP (HL) ;SEE IF CHARACTER AFTER THE ZERO IS ALSO A ZERO
JR Z,NOFIND ;DOUBLE ZERO MARKS END OF DEFINED TABLE
LD (ENTRYPTR),HL ;SAVE POINTER TO BEGINNING OF ENTRY
JR KEYCOMP
FOUND:
POP DE
LD B,(HL) ;GET FIRST CHARACTER
INC HL ;POINT TO NEXT CHAR
FND1:
LD (DEFPTR),HL ;STORE POINTER TO NEXT CHAR OF TRANSLATION
LD A,(HL) ;LOAD SECOND CHAR
LD (SENDFLG),A ;STORE IN FLAG IF NON ZERO THEN MORE TO SEND
LD A,B ;MOVE FIRST CHAR TO A
RET
NOFIND:
POP HL ;NOT FOUND SO GET CHARACTERS FROM INPUT BUFFER
LD B,(HL)
INC HL
JR FND1
PRTCHR: ;SEND CHARACTER IN A TO CONSOLE
PUSH HL
PUSH DE
PUSH BC
PUSH AF
LD C,A
CALL OLDCONOUT
POP AF
POP BC
POP DE
POP HL
RET
SNDMSG: ;SEND MESSAGE POINTED TO BY DE TO CONSOLE
;INCREMENTS LNLEN SO MESSAGE CAN BE ERASED
LD A,(DE) ;GET CHAR
IF KEYDEF
AND 7FH
ENDIF
INC DE
OR A ;SET FLAGS
RET Z ;RETURN IF END OF STRING
CP ' ' ;CHECK IF LESS THAN SPACE CHARACTER
JR NC,SM1 ;JUMP IF >= TO SPACE
ADD A,40H ;ADD OFFSET TO PROPER CHARACTER
LD B,A ;SAVE CHARACTER
LD A,'^' ;LOAD '^' SYMBOL FOR CONTROL CHARACTERS
CALL PRTCHR
LD A,(LNLEN) ;INCREMENT THE LINE LENGTH
INC A
LD (LNLEN),A ;SAVE NEW VALUE BACK
LD A,B
SM1:
CALL PRTCHR ;SEND CHARACTER
LD A,(LNLEN) ;INCREMENT THE LINE LENGTH
INC A
LD (LNLEN),A
JR SNDMSG ;LOOP TIL DONE
;
; FINDS END OF KEY TABLE. RETURNS END OF TABLE IN HL OR SENDS TABLE FULL
; MESSAGE. BC CONTAINS SPACE REMAINING IN TABLE
;
FINDEND:
LD HL,KEYTBL ;POINT TO BEGINNING OF TABLE
LD BC,KEYTBLS ;LOAD SIZE OF TABLE
FE1: XOR A ;SEARCH FOR 0 IN TABLE
CPIR ;SEARCH UNTIL 0 FOUND OR END OF TABLE
JP PO,TBLFULL ;IF BC=0 THEN END OF TABLE REACHED
CP (HL) ;SEE IF CHAR AFTER THE ZERO IS ALSO A ZERO
RET Z ;DOUBLE ZERO MARKS END OF DEFINED TABLE
JR FE1 ;OTHERWISE KEEP LOOKING
;
;GETDEF PROMPTS FOR KEY DEFINITION AND PLACES IT AT THE END OF THE TABLE
;DELETES PREVIOUS MATCHING DEFINITION IF FOUND
;
GETDEF:
XOR A
LD (LNLEN),A ;ZERO LENGTH OF LINE COUNTER
LD DE,KEYMSG ;POINT TO KEY PROMPT
CALL SNDMSG ;SEND THE MESSAGE
CALL FINDEND ;RETURNS WITH HL POINTING TO END OF KEY TABLE
OR A ;IF A ZERO THEN ROOM REMAINS IN TABLE
LD A,0AH ;LINEFEED
JP NZ,NC1 ;IF NOT ZERO THEN EXIT
PUSH HL ;SAVE STARTING ADDRESS
CALL GETKEY ;GET KEY TO BE DEFINED
POP DE ;RETRIEVE STARTING ADDRESS
PUSH HL ;SAVE POINTER TO NEXT CHAR OF DEFINITION
PUSH DE ;SAVE STARTING ADDRESS AGAIN
LD BC,(ATTN) ;MOVE ATTN CHARACTER TO C REGISTER
LD A,(DE) ;GET FIRST CHARACTER OF KEY BEING DEFINED
CP C ;SEE IF IT'S THE ATTENTION CHARACTER
JR NZ,GD3 ;IF NOT THEN SKIP NEXT
POP DE
POP DE ;CLEAN UP STACK
JR ERASE ;ERASE AND SEND THE ATTENTION CHARACTER
GD3:
CALL SNDMSG ;DISPLAY KEY TO BE DEFINED
LD DE,EQMSG ;POINT TO EQUAL MESSAGE
CALL SNDMSG ;SEND MESSAGE
POP DE ;RETRIEVE STARTING ADDRESS
PUSH DE ;SAVE IT AGAIN
CALL SCAN ;SEARCH TABLE FOR KEY POINTED TO BY DE
POP BC ;RETRIEVE STARTING ADDRESS OF KEY
LD A,(ENTRYPTR) ;GET LOW BYTE OF POINTER TO FOUND KEY DEF
CP C ;SEE IF ENTRY POINTER AND BC MATCH
JR NZ,GD0 ;IF NO MATCH THEN ENTRYPTR POINTS TO PREV DEF
LD A,(ENTRYPTR+1) ;GET HIGH BYTE
CP B ;CHECK HIGH BYTE
GD0: CALL NZ,DELDEF ;IF NO MATCH THEN DELETE OLD DEFINITION
POP HL ;IF THEY MATCH THEN THIS IS A NEW DEF
GD1:
PUSH HL ;SAVE POINTER TO NEXT CHAR OF DEF
CALL GETKEY ;GET CHAR OF DEFINITION
POP DE ;POP STARTING POSITION TO DE
LD B,A
IF KEYDEF
OR 80H
LD (DE),A ;STORE CHARACTER WITH HIGH BIT SET
ENDIF
LD A,(ATTN) ;GET ATTENTION CHAR
CP B ;SEE IF ATTENTION CHAR
LD A,08H ;LOAD BS TO BE RETURNED BY ERASE IF CALLED
JR Z,ERASE ;IF SO THEN QUIT
CALL SNDMSG ;DISPLAY CHAR
PUSH HL ;SAVE POINTER
EX DE,HL ;MOVE TO DE
LD HL,KEYEND ;LOAD END OF TABLE
CCF ;CLEAR CARRY FLAG
SBC HL,DE ;CALCULATE REMAINING SPACE
POP HL ;RETRIEVE NEXT POSITION
JR NC,GD1 ;SPACE REMAINS SO GET ANOTHER CHAR
;
;TBLFULL SENDS THE TABLE FULL MESSAGE WHEN CALLED
;
TBLFULL:
LD DE,FULLMSG
CALL SNDMSG
LD C,07
CALL OLDCONOUT
TF2: CALL OLDCONST
OR A
JR Z,TF2
CALL OLDCONIN
ERASE: ;ERASE A MESSAGE SENT BY SNDMSG
PUSH AF ;SAVE CHARACTER TO BE OUTPUT ON RETURN
LD A,(LNLEN)
LD B,A
PUSH BC
LD A,08H
CALL SNDX
POP BC
PUSH BC
LD A,' '
CALL SNDX
POP BC
DEC BC
LD A,08H
CALL SNDX
XOR A
LD (DE),A
LD (SENDFLG),A
POP AF ;RETRIEVE FINAL CHARACTER
JP NC1 ;EXIT THROUGH END OF NEWCONIN
SNDX:
CALL PRTCHR
DJNZ SNDX
RET
DELDEF: ;DELETE DEFINITION POINTED TO BY ENTRYPTR
POP HL ;CLEAN UP STACK
POP DE
PUSH HL ;SAVE RETURN ADDRESS
LD HL,(ENTRYPTR) ;LOAD POSITION OF ENTRY TO DELETE
EX DE,HL
LD HL,KEYEND ;LOAD ADDRESS OF TABLE END
CCF ;CLEAR CARRY FLAG
SBC HL,DE ;GET LENGTH OF REMAINING TABLE
PUSH HL ;MOVE RESULT TO BC
POP BC ;SIZE OF BLOCK TO SEARCH
LD HL,(ENTRYPTR) ;POINT TO START OF DEFINITION TO DELETE
XOR A ;LOOK FOR ZERO AT END OF DEFINITION
CPIR
LD DE,(ENTRYPTR) ;DESTINATION OF BLOCK MOVE
LDIR ;MOVE TABLE UP
CALL FINDEND ;FIND NEW END OF TABLE
DEC HL ;MOVE BACK ONE SPACE
INC BC
POP DE
PUSH HL
PUSH DE
RET
;
; SIZE ERROR TEST
;
IF [$ GT [RCP+RCPS*128]]
SIZERR EQU NOVALUE
ENDIF
;
; END Z3KEY.RCP
;
END