; MODMON.MAC vers. 1.0 ; ; Written September 26, 1982 ; by ; Ken Stephenson ; 5 Laurel Wood Dr. ; Lawrenceville, N.J. 08648 ; ; This program provides customized character redefinition ; for the Keytronics Word Processor keyboard operating ; with the DRC Big Board computer. The program allows ; definition of up to 16 functions which are executed ; directly in interupt status upon closure of the appropriate ; keyboard key. Presently, two functions have been implemented: ; 1) closure of cntl, shift, and key 69 will interupt the ; program which is presently executing and print out the ; processor register values which were in effect at the time ; of interupt. Control is then returned to the interupted ; program which will continue executing. 2) closure of cntl, ; shift, and key 70 will have the same effect as function 1 ; except that the function will reboot instead of returning ; to the interupted program. These two functions are useful ; for debugging and graceful exits from infinite loops. ; .z80 ; This program loads at 100h like a normal CPM program. ; The keyboard interupt program section then relocates to ; reside immediately above the PFM monitor. The character ; translation table is relocated immediately below the ; monitor variable area ( ff00 - ffffh ). The translation ; table will permanently occupy this area, even as updates ; are made to the interupt program. In this way, user ; programs operating in low memory can modify the table to ; suit their requirements, and will not have to be changed ; if updates are made to the interupt program. ; ; prgdst equ 0f7e8h ;interupt prog will relocate to here datdst equ 0feb2h ;translation table will relocate ;to here ptchlc equ 0f49ah ;patch into monitor at this location sploc equ 0ff35h ;stack pointer is stored here pnext equ 0f3ech ;monitor ascii output routine eot equ 04h ;end of text marker cr equ 0dh lf equ 0ah put4hs equ 0f3cdh ;monitor hex output routine boot equ 0 ; ; program relocation ; ld bc,pend-pstart ;number of bytes to relocate ld hl,pstart ;start address of code to reloc ld de,prgdst ;relocated code goes here ldir ;move code ; ; translation table relocation ; ld bc,dend-dstart ;number of bytes to relocate ld hl,dstart ;start address of data to reloc ld de,datdst ;relocated data goes here ldir ;move data ; ; prepare to patch monitor ; ld a,0c3h ;jump instruction into reg a ld hl,prgdst ;jump address di ;no interupts while patching monitor ld (ptchlc),a ;store jump instruction ld (ptchlc+1),hl ;store jump address ei ret ;back to cpm ; ; ; keyboard interupt routine begins in monitor and ; jumps to here ; pstart: .phase prgdst ;assemble code to run above PFM ; cp 20h ;is character a control char? jp c,cntlch ;jump if yes cp 80h ;not cntl; is char asci? jp nc,bit7 ;jump if not asci ; nrmret: defb 2ah,59h,0ffh ;this is instruction ld hl,(pinvec) ;which was overwritten in the ;monitor patch jp 0f49dh ;return to monitor ; ; arrive here if character is control char cntlch: ld bc,ctldat ;bc points to character ;translation table ckchr: ld h,0 ;character value is ld l,a ;offset to translation value add hl,bc ld a,(hl) ;get translated character ckspec: cp 0f0h ;values above f0h will get ;special treatment jp nc,specl jr nrmret ;if not special, return to monitor ; ; arrive here if character has bit 7 set bit7: cp 201Q ;key 71, shift or cntl-shift is 201Q jr nz,e1 ld a,(k71s) ;get translated value jr ckspec ;check for special character ; e1: cp 221Q ;key 71, unshift or cntl jr nz,e2 ;jump if not 221Q ld a,(k71u) ;get translated value jr ckspec ;check for special character ; e2: cp 254Q ;all other bit 7 keys, but cntl-shift jr nc,e3 ;jump if >= 254Q sub 241Q ;generate table offset value ld bc,ctlshf jp ckchr ;go get translated char ; e3: cp 274Q ;all other bit7 keys, but cntl jr nc,e4 ;jump if >= 274Q sub 261Q ;generate table offset value ld bc,ctl jp ckchr ;go get translated char ; e4: cp 354Q ;all other bit 7 keys, but shifted jr nc,e5 ;jump if >= 354Q sub 341Q ;generate table offset value ld bc,shift jp ckchr ;go get translated char ; e5: sub 361Q ;to arrive here, must be unshifted ld bc,unshft jp ckchr ;go get translated char ; ; ; arrive here for special characters. that is, characters ; with values greater than 0f0h indicate that special ; processing is to take place in the keyboard routine. ; ; Presently, two special characters are implemented: 0feh ; and 0ffh. For 0feh, the contents of the z80 registers ; prior to interupt are displayed on the screen . Instead of ; returning to the keyboard routine, return is directly ; to the interupted program. The function for 0ffh is ; the same except that, instead of returning to the ; interupted program, a warm boot is performed. These two ; functions allow limited debugging and a graceful exit ; from infinite loops. ; char: defs 1 ;place to store character regsto: defs 12 ;place to store register values ; specl: ld (char),a ;remember character pop hl ;hl now has value of af prior to intrp ld (regsto),hl ;keep old af at regsto pop hl ;hl now has value of bc prior to intrp ld (regsto+2),hl ;keep old bc at regsto+2 pop hl ;hl now has value of de prior to intrp ld (regsto+4),hl ;keep olf de at regsto+4 pop hl ;hl now has value of hl prior to intrp ld (regsto+6),hl ;keep old hl at regsto+6 ld hl,(sploc) ;hl now has value of stk ptr prior ;to interupt ld (regsto+10),hl ;keep old stk ptr at regsto+10 ld sp,hl ;make old stk ptr new stk ptr ;so that we can return to program pop hl ;hl now has value of program counter ;at point of interupt ld (regsto+8),hl ;keep old pc at regsto+8 ; now comes tricky part ; we want to use display routines but we cannot if we ; are in interupt status. Therefore, we will push our ; present location onto the stack so that when we execute ; a return-from-interupt, we will return to our present ; location. ld hl,rtnloc ;hl contains our desired rtn location push hl ;put rtn location onto stack ei ;enable interupts reti ;return from interupt rtnloc: call pnext ;we are back! print message defb cr,lf defm ' intrp at ' defb eot ld hl,(regsto+8) ;hl contains pc at point of interupt call put4hs ;print pc on screen call pnext ;print message defb cr,lf defm ' af ' defb eot ld hl,(regsto) ;hl contains af at point of interupt call put4hs call pnext ;print message defb cr,lf defm ' bc ' defb eot ld hl,(regsto+2) ;hl contains bc at point of interupt call put4hs call pnext defb cr,lf defm ' de ' defb eot ld hl,(regsto+4) ;hl contains de at point of interupt call put4hs call pnext defb cr,lf defm ' hl ' defb eot ld hl,(regsto+6) ;hl contains hl at point of interupt call put4hs call pnext defb cr,lf defm ' sp ' defb eot ld hl,(regsto+10) ;hl contains stk ptr at pnt of intrp call put4hs call pnext defb cr,lf,eot ld a,(char) ;restore character to a cp 0ffh ;test for reboot char jp z,boot ;boot if yes ld hl,(regsto+8) ;otherwise, restore all reg for ;return to interupted program push hl ;push desired prog counter onto stack ld hl,(regsto) ;cannot load af directly from push hl ;memory, so do it in two steps pop af ld bc,(regsto+2) ;bc is easier ld de,(regsto+4) ;load de ld hl,(regsto+6) ;finally,restore hl ret ;return to interupted program ; ; .dephase ; pend: ;end of program ; dstart: ;start of data section .phase datdst ;locate immediately ;below monitor variables ; ; CHARACTER TRANSLATION TABLE ; ; Customized to the Keytronics Word Processor Keyboard ; ; The following redefinitions are made to incoming ; control characters: ; ; change cntl-j to cntl-z ; " cntl-y to cntl-s ; " cntl-z to cntl-x ; " cntl-l to \ (5ch). Keytronics does'nt have \ otherwise ; " cntl-w to | (7ch). " " " | " ; " cntl-k to ~ (7eh). " " " ~ " ; ; ctldat: defb 0,1,2,3,4,5,6,7,8,9,1ah,7eh,5ch,13,14,15 defb 16,17,18,19,20,21,22,7ch,24,13h,18h,27,28,29,30,31 ; ; use bit 7 keys as a numeric keypad when unshifted ; k71u: defm '0' k71s: defm '?' ;key 71 shifted is not presently used ; unshft: defm '1234567890.' shift: defm '???????????' ctl: defm '???????????' ctlshf: defm '?????????' defb 0feh,0ffh ;make these two keys special ; ; end translation table ; .dephase dend: ; end 100h ;link as cpm com file