Title REDEF - Key mapping util. ; Greg Louis, 830330:0832 .z80 .comment " This program, when run, installs itself in 'safe memory' and reads in a set of key definitions from its standard input. The program supports I/O redirection via subroutines init and getc: if the command line reads REDEF string to be substituted^C (for example, Xexample^C would cause the word example to be input every time an uppercase X was pressed). CR and LF characters following the control-C will be ignored (you can't redefine either of those keys), but CR and LF may be included in the substitution string. For more examples, look at file Z80.DFN which contains redefinitions for the more common M80 opcodes and pseudo-ops. Once the program finishes its execution the redefinitions are in place and will apply until either a cold boot is performed or the keystroke sequence ` (hex 60,3) is typed. The character ` (hex 60) acts as an escape character to allow entry of an other- wise 'redefined' key, e.g. `X if X has been redefined and the text needs an X in it. The routines declared as external will be found in the TOOLS.ARC toolbox. To get this program running, alter the memory equates below to suit your memory map, assemble with M80, link with your version of TOOLS.REL (full source is in TOOLS.ARC on the Mississauga RCP/M System One) and enjoy. " ext init,movel,getc ext remark,error goloc equ 0f540h ; Resident part of program maxloc equ 0f5d0h ; Upper limit (hardware dependent) maxsec equ 8 ; Maximum redefinition file size ptrs equ 0f100h ; Start of safe memory table equ 0f140h ; Start of redefinitions cseg start: jp instal ; Around the resident part code: ; Install-time address of resident part .phase goloc ; Run-time address of resident part freept: ds 1 ; Number (0-31) of first free pointer indef: ds 1 ; Flag true if input from a definition pntr: ds 2 ; Where in definition jtbl: ds 2 ; Storage for BIOS jump table addr const: ld a,(indef) ; Replacement console status routine or a ; Always ready if reading from defn. ret nz oconst: jp $-$ ; Jump to old constat routine oconin: jp $-$ ; Old conin routine conin: ld a,(indef) ; Replacement conin or a jr nz,give ; If in defn., read from table keyin: call oconin ; Get a keypress ld b,a ; save it ld a,(freept) ; get pointer count ld e,a ld a,b ; get the keypress cp '`' ; check for escape character jr z,esckey ; ..which needs special processing cp ' ' ; can't be redef if ctrl char ret c sub 32 ; get ordinal key number ld d,a ld hl,ptrs+1 ; begin looking for redef. key ckptr: ld a,(hl) and 63 ; key number is lower 6 bits cp d jr z,stdef ; if found, start definition or a ; empty entry? ld a,b ; get original key back in case ret z ; send it along if so dec e ; end of table? ret z ; send original key if so inc hl ; point to next entry inc hl jr ckptr ; and round again ; Got a redefined key stdef: ld a,0ffh ld (indef),a ; flag definition being read ld a,(hl) ; get high bits + key number dec hl ld e,(hl) ; and low bits rlca ; rotate address bits to rlca ; ..positions 0 and 1 and 3 ; isolate them ld d,a ; de now has 10-bit table address ld hl,table ; add it to base add hl,de jr give+3 ; ..and use the result as the first give: ld hl,(pntr) ; pointer to char to give ld a,(hl) ; get it inc hl ; point to next char ld (pntr),hl ; save the pointer ld b,a ; save the char ld a,(hl) ; get the one that will be next cp 3 ; check for end of string ld a,b ; get back the current char ret nz ; send it along unless we're done xor a ; clear the 'in definition' flag ld (indef),a ld a,b ; get back the current char ret ; Process escape (`) key esckey: call oconin ; get another keypress cp 3 ; was it ETX, ie should we cancel? ret nz ; use the second keypress if not ETX ld hl,(oconst+1) ; Cancel out: ex de,hl ; ..restore original BIOS jumps ld hl,(jtbl) ld (hl),e ; ..constat inc hl ld (hl),d ex de,hl ld hl,(oconin+1) ex de,hl inc hl inc hl ld (hl),e ;.. and conin inc hl ld (hl),d jr oconin ;.. and jump to old conin. ephase equ $ if ephase ge maxloc .printx "Code too long" endif .dephase instal: call init ; Set up redirection if wanted ld hl,(1) ; Find BIOS jump table inc hl inc hl inc hl inc hl inc hl ; high byte of CONIN jmp ld a,(hl) and 0f0h ; look at which 4k block ld l,a ld a,h ; Same block as BIOS jump table? and 0f0h cp l jp z,moveit call error ; Bomb out if REDEF done already db 'Type `^C; REDEF ' ; ..Test for this may have to be db 'already loaded!',0 ; ..altered depending on mem map ; Put the resident code in place moveit: ld hl,code ld de,goloc ld bc,instal-code call movel ; Read the definition file call remark db 'Reading ' db 'redefinitions...' db 13,10,0 ld hl,table ld de,maxsec shl 7 ; Max bytes rdlop: call getc cp 0dh ; Ignore leading CR or LF jr z,rdlop cp 0ah jr z,rdlop rdlop0: ld (hl),a ; Save char cp 1ah ; Was it ctl-Z? jr z,eofl ; End of input if so dec de ; Mem full? ld a,d or e jr z,eofl ; End of input if so ld a,(hl) inc hl cp 3 ; End of definition? jr z,rdlop ; Skip CR or LF if so call getc ; ..else don't skip jr rdlop0 ; done reading, construct pointer table eofl: ld (hl),1ah ; Make sure end is marked ld de,table ld hl,ptrs ld bc,0 ; Byte counter xor a ld (freept),a ; Entry counter ld (indef),a ; In-definition flag ptlop: ld a,(de) ; Get byte inc bc ; count it cp 1ah ; done if ctrl-Z jp z,rdy ld a,(freept) ; error if more than 32 entries cp 32 jp z,err inc a ; count new entry ld (freept),a ld (hl),c ; save low 8 bits inc hl ld a,(de) ; get byte again inc de sub 32 ; make it key number (6 bits) ld (hl),a ; save temporarily ld a,b ; get bits 8 and 9 of table rrca ; ..addr and rotate to rrca ; ..positions 14 and 15 and 0c0h or (hl) ; or in the 6-bit char ld (hl),a ; complete the pointer entry inc hl skplop: ld a,(de) inc de inc bc ; skip and count cp 1ah ; end of entries? jp nz,skpl1 ld a,3 ; mark end of string ld (de),a call remark db 'Last entry ' db 'truncated',0 jp rdy ; and quit skpl1: cp 3 ; end of string? jr nz,skplop ; keep lookin if not jp ptlop ; else start new pointer err: call remark db 'Too many entries: ' db 'stop at 32',0 ; ready to go rdy: ld hl,(1) inc hl inc hl inc hl inc hl ; low byte of constat ld (jtbl),hl ; save for cancel routine ld e,(hl) ; get and install original inc hl ; ..constat addr ld d,(hl) ex de,hl ld (oconst+1),hl ex de,hl inc hl inc hl ld e,(hl) ; ..and conin addr inc hl ld d,(hl) ex de,hl ld (oconin+1),hl ; ..in resident code ex de,hl ld de,conin ; Install new conin ld (hl),d dec hl ld (hl),e dec hl dec hl ld de,const ; ..and constat ld (hl),d dec hl ld (hl),e ; ..in BIOS jump table call error ; Not really an error db 'Redefinitions ' ; ..Issues message and quits db 'installed',0 end start