; 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