******************************************************************************* * * KeyMenu.asm V1.03 02 Mar 1991 * * * Usage: * KeyMenu QUIT * KeyMenu ? * KeyMenu [] * Where is one or more of the following: * -i info about KeyMenu's current configuration * -b toggle Intuition pointer blanking default=OFF * -t toggle clearing of RMBTRAP flag in windows default=OFF * -q# # = qualifier key(s) to supplement move keys default=Right Shift * -p# # = input handler priority in decimal default=51 * -a# # = hex keycode of ACTIVATION key default=Right ALT * -e# # = hex keycode of ESCAPE key default=ESC * -s# # = hex keycode of SELECT key default=Return * -l# # = hex keycode of LEFT key default=Cursor left * -r# # = hex keycode of RIGHT key default=Cursor right * -u# # = hex keycode of UP key default=Cursor up * -d# # = hex keycode of DOWN key default=Cursor down * * * This program serves as the user interface to the KeyMenu-Handler. It is * used to install the KeyMenu-Handler, change it's configuration at any time * or remove the handler from the system. This program is completely * re-entrant (pure). * * * Modification History: * * Date By Modification * -------- -------------------- -------------------------------------- * 09/09/89 Ken Lowther Initial release, V1.01 * * 09/13/89 Ken Lowther V1.02 - Added qualifier option to allow * changing the qualifier key that can be * used with the movement keys. * * 09/30/89 Ken Lowther V1.02 - This program no longer creates a * process for the keymenu-handler module. * * 03/02/91 Ken Lowther V1.03 - Re-installed intuition pointer * blanking option. * ******************************************************************************* nolist include "macros.i" include "exec/types.i" include "exec/strings.i" include "exec/nodes.i" include "exec/ports.i" include "exec/execbase.i" include "exec/ables.i" include "exec/interrupts.i" include "exec/memory.i" include "exec/lists.i" include "exec/io.i" include "devices/input.i" include "devices/inputevent.i" include "intuition/intuition.i" include "libraries/dos.i" include "libraries/dosextens.i" include "keymenu-handler.i" include "keymenu.i" list nomlist kmw equr a4 ; keymenu workarea register gbl equr a5 ; handler global register ******************************************************************************* * * * Miscellaneous equates * * * ******************************************************************************* keynamesmax equ (keynamesend-keynames)/2 ; maximum keycode in keynames ; table kmportl equ kmportend-kmport ; port name length quitwordl equ quitwordend-quitword nomeml equ nomemend-nomem cseg public main near code ******************************************************************************* * * * main * * * * This is the main routine of keymenu. It is where execution begins. * * Here we perform the following functions. * * 1) Initialize program * * 2) parse the runtime command line and report errors if any. * * 3) determine what work is to be done and call the appropriate * * routines to do it. * * 4) perform program cleanup and exit. * * * * Input Registers: * * a0 - command line address * * d0 - command line length * * * * Output Registers: * * d0 - amigados return code * * * ******************************************************************************* main movem.l mainregs,-(sp) ; save entry registers *-----------------------------------------------------------------------------* * go initialize, exit if initialization fails * *-----------------------------------------------------------------------------* jsr init ; go initialize bne mainexit ; initialization failed, branch *-----------------------------------------------------------------------------* * parse the runtime command, exit if errors * *-----------------------------------------------------------------------------* jsr parse ; go parse the runtime command bne maincleanup ; parser failed, branch *-----------------------------------------------------------------------------* * determine what is to be done * *-----------------------------------------------------------------------------* lea kmport(pc),a1 ; point to handler's port name Call FindPort ; go see if it exists tst.l d0 ; does port exist ? bne main010 ; yes, branch *-----------------------------------------------------------------------------* * handler doesn't exist, create it * *-----------------------------------------------------------------------------* jsr create ; go create handler beq maincleanup ; branch if unable to create it main010 bset.b #FLAGB_exists,kmw_flags(kmw) ; indicate port exists move.l d0,gbl ; setup handler global register main015 btst.b #FLAGB_quit,kmw_flags(kmw) ; was 'quit' specified ? beq main020 ; no, branch *-----------------------------------------------------------------------------* * quit was specified, stop the handler and exit * *-----------------------------------------------------------------------------* jsr quit ; yes, get rid of handler bra maincleanup ; get out main020 btst.b #FLAGB_exists,kmw_flags(kmw) ; does handler exist ? beq maincleanup ; no, branch *-----------------------------------------------------------------------------* * process any runtime parameters that may have been given * *-----------------------------------------------------------------------------* jsr params ; yes, go process any runtime params *-----------------------------------------------------------------------------* * do cleanup and exit. * *-----------------------------------------------------------------------------* maincleanup move.l kmw_dosbase(kmw),a1 ; get dos library base Call CloseLibrary ; close it move.l kmw,a1 ; get work area address move.l #kmw_size,d0 ; get size of work area Call FreeMem ; go free the work area mainexit movem.l (sp)+,mainregs ; restore registers clr.l d0 ; set return code for dos rts ; return to caller mainregs reg d1-d7/a0-a6 ; registers saved by main ******************************************************************************* * * * init * * * * This routine performs the following initialization tasks: * * 1) opens the dos library * * 2) gets std output file handle * * 3) allocates and initializes our workarea * * * * Input Registers: * * a0 - command line address * * d0 - command line length * * * * Output Registers: * * a4 - workarea address * * a6 - exec library base * * d0 - return code (0=initialization successful) * * * ******************************************************************************* init move.l AbsExecBase,a6 ; setup exec library base move.l a0,a3 ; save command line address move.l d0,d3 ; save command line length *-----------------------------------------------------------------------------* * Open DOS Library * *-----------------------------------------------------------------------------* lea doslib(pc),a1 ; point to library name moveq.l #0,d0 ; we don't care what version Call OpenLibrary ; go open the library move.l d0,a5 ; save library base for use later beq init_err1 ; openlibrary failed - can't tell ; user - just exit *-----------------------------------------------------------------------------* * Get STD Output File Handle * *-----------------------------------------------------------------------------* Call Output,a5 ; get file handle for screen move.l d0,a2 ; save output file handle beq init_err ; if no handle was returned - branch *-----------------------------------------------------------------------------* * Allocate our workarea * *-----------------------------------------------------------------------------* move.l #kmw_size,d0 ; set size of area to allocate move.l #MEMF_CLEAR,d1 ; indicate type of memory Call AllocMem ; go get it move.l d0,kmw ; setup our workarea register bne init010 ; if allocate was successful, branch move.l a2,d1 ; get file handle lea nomem(pc),a0 ; get error message address move.l a0,d2 move.l #nomeml,d3 ; get error message length Call Write,a5 ; write error message bra init_err ; go cleanup *-----------------------------------------------------------------------------* * Initialize our workarea * *-----------------------------------------------------------------------------* init010 move.l a5,kmw_dosbase(kmw) ; save dos base address move.l a2,kmw_filehandle(kmw) ; save output file handle move.l a3,kmw_cmd(kmw) ; save runtime command address move.w d3,kmw_cmd_length(kmw) ; save runtime command length move.b #-1,kmw_AKey(kmw) ; initialize to null keys move.b #-1,kmw_DKey(kmw) move.b #-1,kmw_SKey(kmw) move.b #-1,kmw_UpKey(kmw) move.b #-1,kmw_DownKey(kmw) move.b #-1,kmw_LeftKey(kmw) move.b #-1,kmw_RightKey(kmw) move.b #handlerpri,kmw_handlerpri(kmw) ; default handler priority bra init_ok ; initialized ok - return *-----------------------------------------------------------------------------* * Failed to get Output File Handle * *-----------------------------------------------------------------------------* init_err move.l a5,a1 ; get dos library base Call CloseLibrary ; close it *-----------------------------------------------------------------------------* * Couldn't initialize for whatever reason - set return code * *-----------------------------------------------------------------------------* init_err1 moveq.l #1,d0 ; indicate failure bra initexit ; get out *-----------------------------------------------------------------------------* * initialized ok - set return code * *-----------------------------------------------------------------------------* init_ok clr.l d0 ; indicate success *-----------------------------------------------------------------------------* * Common return point * *-----------------------------------------------------------------------------* initexit rts ; return ******************************************************************************* * * * changekey * * * * This routine is called to change a keymenu configuration key from one * * value to another and print a message documenting the change. * * * * Input Registers: * * a0 - address of keymenu's global area for the key being changed * * a1 - address of text describing the key being changed * * d0 - new key value to be used (-1 = no change) * * * * Output Registers: * * none * * * ******************************************************************************* changekey movem.l ckregs,-(sp) ; save registers cmp.b #-1,d0 ; was a new value given ? beq changekeyexit ; no, branch clr.l d1 ; clear work register move.b (a0),d1 ; get old value of key move.l d0,d2 ; get new key value asl.w #1,d2 ; multiply by 2 lea keynames(pc),a3 ; get address of key names table lea keyval(pc),a2 ; get address of key value table move.w d0,-(sp) ; pass new key value move.w (a3,d2.w),d2 ; get disp of new key name pea (a2,d2.w) ; pass addr of new key name move.l d1,d2 ; get old key value asl.w #1,d2 ; multiply by 2 move.w d1,-(sp) ; pass old key value move.w (a3,d2.w),d2 ; get disp of old key name pea (a2,d2.w) ; pass address of old key name move.l a1,-(sp) ; pass text of key being changed move.b d0,(a0) ; update keymenu's global area lea changemsg(pc),a0 ; get format string address jsr printf ; go print change message add.l #16,sp ; adjust stack pointer changekeyexit movem.l (sp)+,ckregs rts ; return to caller ckregs reg d0-d2/a0-a3 ******************************************************************************* * * * params * * * * This routine processes any runtime params that may have been given * * to change keymenu's configuration. Also, messages are produced * * indicating any changes that are made. * * * * Input Registers: * * a4 - keymenu workarea address (kmw) * * a5 - handler global area * * * * Output Registers: * * none * * * ******************************************************************************* params clr.l d0 *-----------------------------------------------------------------------------* * Change any of the various keys that keymenu uses. * *-----------------------------------------------------------------------------* move.b kmw_AKey(kmw),d0 ; load parameter lea gb_AKey(gbl),a0 ; point to global area lea akey(pc),a1 ; text for change message jsr changekey ; go change the key if necessary move.b kmw_DKey(kmw),d0 ; load parameter lea gb_DKey(gbl),a0 ; point to global area lea dkey(pc),a1 ; text for change message jsr changekey ; go change the key if necessary move.b kmw_SKey(kmw),d0 ; load parameter lea gb_SKey(gbl),a0 ; point to global area lea skey(pc),a1 ; text for change message jsr changekey ; go change the key if necessary move.b kmw_UpKey(kmw),d0 ; load parameter lea gb_UpKey(gbl),a0 ; point to global area lea upkey(pc),a1 ; text for change message jsr changekey ; go change the key if necessary move.b kmw_DownKey(kmw),d0 ; load parameter lea gb_DownKey(gbl),a0 ; point to global area lea downkey(pc),a1 ; text for change message jsr changekey ; go change the key if necessary move.b kmw_LeftKey(kmw),d0 ; load parameter lea gb_LeftKey(gbl),a0 ; point to global area lea leftkey(pc),a1 ; text for change message jsr changekey ; go change the key if necessary move.b kmw_RightKey(kmw),d0 ; load parameter lea gb_RightKey(gbl),a0 ; point to global area lea rightkey(pc),a1 ; text for change message jsr changekey ; go change the key if necessary btst.b #FLAGB_trap,kmw_flags(kmw) ; was rmbtrap option specified ? beq params025 ; ; no, branch *-----------------------------------------------------------------------------* * Change the clear RMBTRAP option * *-----------------------------------------------------------------------------* lea info4(pc),a0 ; point to message text bchg.b #FLAGB_Clear_rmbtrap,gb_flags(gbl) ; invert the bit beq params010 ; was off, now on, branch pea nowoff(pc) ; indicate now off bra params020 params010 pea nowon(pc) ; indicate now on params020 jsr printf ; go tell what we did addq.l #4,sp ; adjust stack pointer params025 btst.b #FLAGB_Qual,kmw_flags(kmw) ; was a qualifier(s) specified ? beq params026 ; no, branch *-----------------------------------------------------------------------------* * Change qualifier(s) * *-----------------------------------------------------------------------------* move.b kmw_Qual(kmw),gb_Qual(gbl) ; update global area jsr printqual ; go print new keys params026 btst.b #FLAGB_blankp,kmw_flags(kmw) ; was blank pointer option ; given ? beq params030 ; no, branch *-----------------------------------------------------------------------------* * Change the blank intuition pointer option * *-----------------------------------------------------------------------------* lea info5(pc),a0 ; point to message text bchg.b #FLAGB_Blank_pointer,gb_flags(gbl) ; invert the bit beq params027 ; was off, now on, branch pea nowoff(pc) ; indicate now off bra params028 params027 pea nowon(pc) ; indicate now on params028 jsr printf ; go tell what we did addq.l #4,sp ; adjust stack pointer params030 btst.b #FLAGB_info,kmw_flags(kmw) ; was info asked for ? beq params110 ; no, branch *-----------------------------------------------------------------------------* * print info about keymenu's configuration * *-----------------------------------------------------------------------------* lea info1(pc),a0 ; point to message text pea kmport(pc) ; put portname address on the stack jsr printf ; go print it addq.w #4,sp ; adjust stack move.b gb_AKey(gbl),d0 ; load key's value lea akey(pc),a1 ; point to text describing the key jsr printkey ; print info message move.b gb_DKey(gbl),d0 lea dkey(pc),a1 jsr printkey move.b gb_SKey(gbl),d0 lea skey(pc),a1 jsr printkey move.b gb_UpKey(gbl),d0 lea upkey(pc),a1 jsr printkey move.b gb_DownKey(gbl),d0 lea downkey(pc),a1 jsr printkey move.b gb_RightKey(gbl),d0 lea rightkey(pc),a1 jsr printkey move.b gb_LeftKey(gbl),d0 lea leftkey(pc),a1 jsr printkey jsr printqual ; go print key qualifier(s) lea info5(pc),a0 ; point to message text btst.b #FLAGB_Blank_pointer,gb_flags(gbl) ; blank pointer option on ? beq params070 ; no, branch pea on(pc) ; pass 'on' text to printf bra params080 params070 pea off(pc) ; pass 'off' text to printf params080 jsr printf ; print the message addq.l #4,sp ; adjust the stack pointer lea info4(pc),a0 ; point to message text btst.b #FLAGB_Clear_rmbtrap,gb_flags(gbl) ; is clear rmbtrap on ? beq params090 ; no, branch pea on(pc) ; pass 'on' text to printf bra params100 params090 pea off(pc) ; pass 'off' text to printf params100 jsr printf ; print the message addq.l #4,sp ; adjust the stack pointer params110 rts ; return to caller ******************************************************************************* * * * printkey * * * * This routine is called to print the configured value of a key * * * * Input Registers: * * a1 - address of text describing the key being changed * * d0 - key value * * * * Output Registers: * * none * * * ******************************************************************************* printkey movem.l pkregs,-(sp) ; save registers clr.l d1 ; clear work register move.l d0,d2 ; get key value asl.w #1,d2 ; multiply by 2 lea keynames(pc),a3 ; get address of key names table lea keyval(pc),a2 move.w d0,-(sp) ; pass key value move.w (a3,d2.w),d2 pea (a2,d2.w) move.l a1,-(sp) ; pass text of key being changed lea info2(pc),a0 ; get format string address jsr printf ; go print change message add.l #10,sp ; adjust stack pointer printkeyexit movem.l (sp)+,pkregs rts ; return to caller pkregs reg d0-d2/a0-a3 ******************************************************************************* * * * printqual * * * * This routine is called to print the configured key qualifier(s) * * * * Input Registers: * * a5 - address of keymenu global area * * * * Output Registers: * * none * * * ******************************************************************************* printqual movem.l pqregs,-(sp) ; save registers lea info3(pc),a0 ; get format string address jsr printf ; go print the string lea none(pc),a0 tst.b gb_Qual(gbl) ; are there any qualifiers beq pq030 ; no, branch moveq.l #7,d1 ; set number of bits pq010 btst.b d1,gb_Qual(gbl) ; is qualifier present ? beq pq015 ; no, branch move.l d1,d2 asl.w #1,d2 ; multiply by 2 lea qualnames(pc),a3 ; get address of qualifier names lea keyval(pc),a2 move.w (a3,d2.w),d2 pea (a2,d2.w) lea info3a(pc),a0 ; get format string address jsr printf ; go print key name addq.l #4,sp ; adjust stack pointer pq015 dbra d1,pq010 pq020 lea info3end(pc),a0 pq030 jsr printf ; print end of the message printqualexit movem.l (sp)+,pqregs rts ; return to caller pqregs reg d0-d2/a0-a3 ******************************************************************************* * * * quit * * * * This routine stops the input handler and frees all its remaining * * resources in the following manner: * * 1) signal the handler that we are stopping. * * 2) wait for handler to signal back that it is ready to stop * * 3) remove the handlers port and tell the input device to stop * * passing events to the handler. * * 4) unload the handler's segment * * * * Input Registers: * * a4 - keymenu work area (kmw) * * a5 - handler global area (gbl) * * * * Output Registers: * * none * * * ******************************************************************************* quit btst.b #FLAGB_exists,kmw_flags(kmw) ; does handler exist ? beq quit020 ; no, branch lea remove(pc),a0 ; get removing message address jsr printf ; go write removing message *-----------------------------------------------------------------------------* * Signal the input handler that we intend to stop * *-----------------------------------------------------------------------------* sub.l a1,a1 ; setup to find our task Call FindTask ; go get our task pointer move.l d0,gb_task(gbl) ; save our task pointer moveq.l #-1,d0 ; setup to allocate a signal Call AllocSignal ; go allocate one move.b d0,gb_tasksignum(gbl) ; save signal number move.l #SIGBREAKF_CTRL_C,d0 ; set signal mask move.l gb_handtask(gbl),a1 ; get task to signal Call Signal ; signal the handler task to stop *-----------------------------------------------------------------------------* * Wait for the handler to signal us that it's ok to stop * *-----------------------------------------------------------------------------* clr.l d0 clr.l d1 move.b gb_tasksignum(gbl),d1 bset.l d1,d0 ; create wait mask Call Wait ; wait for handler to signal us clr.l d0 move.b gb_tasksignum(gbl),d0 ; get allocated signal number Call FreeSignal ; go free the signal *-----------------------------------------------------------------------------* * remove the handler's port and tell input device to remove us from * * the handler list * *-----------------------------------------------------------------------------* move.l gbl,a1 ; get handler's port Call RemPort ; remove it from the public eye moveq.l #IND_REMHANDLER,d0 ; indicate we want to remove handler jsr tellinputdevice ; go tell it to the input.device bne quit010 ; if removed, branch lea handlererr(pc),a0 ; get error message address jsr printf ; go tell user bra quit020 *-----------------------------------------------------------------------------* * Unload the handler's segment and tell user everything ok. * *-----------------------------------------------------------------------------* quit010 move.l gb_Segment(gbl),d1 ; get segment address Call UnLoadSeg,kmw_dosbase(kmw) ; get rid of it lea ok(pc),a0 ; get message address jsr printf ; write it *-----------------------------------------------------------------------------* * cleanup remaining resources * *-----------------------------------------------------------------------------* quit020 jsr cleanup rts ; return to caller ******************************************************************************* * * * parse * * * * This routine parses the command line setting flags and keyvalues in * * our work area indicating what options were given when we were invoked.* * * * Input Registers: * * a4 - keymenu work area (kmw) * * * * Output Registers: * * d0 - return code (0=parsing successful) * * * ******************************************************************************* parse movem.l parseregs,-(sp) ; save registers clr.l d2 ; clear length register move.w kmw_cmd_length(kmw),d2 ; get runtime command length subq.w #1,d2 ; reduce by 1 for dbra instr beq parseexit ; no command to parse, branch move.l kmw_cmd(kmw),a2 ; get runtime command pointer *-----------------------------------------------------------------------------* * Upshift the entire runtime command * *-----------------------------------------------------------------------------* parse010 move.b (a2,d2.w),d0 ; get character cmp.b #'a',d0 ; within lowercase range ? blt parse012 ; no, branch cmp.b #'z',d0 bgt parse012 and.b #$5f,d0 ; upshift the character parse012 move.b d0,(a2,d2.w) ; put it back dbra d2,parse010 ; loop through entire command clr.l d2 ; clear index register *-----------------------------------------------------------------------------* * Scan runtime command searching for valid option specifiers * *-----------------------------------------------------------------------------* parse015 cmp.b #'-',(a2,d2.w) ; option specifier ? bne parse065 ; no, branch addq.w #1,d2 ; bump index cmp.b #'A',(a2,d2.w) ; change activation key ? bne parse020 ; no, branch lea kmw_AKey(kmw),a3 ; yes, load result area address bra parsekey ; go get new keyvalue parse020 cmp.b #'E',(a2,d2.w) ; change escape key ? bne parse025 ; no, branch lea kmw_DKey(kmw),a3 ; yes, load result area address bra parsekey ; go get new keyvalue parse025 cmp.b #'S',(a2,d2.w) ; change select key ? bne parse030 ; no, branch lea kmw_SKey(kmw),a3 ; yes, load result area address bra parsekey ; go get new keyvalue parse030 cmp.b #'U',(a2,d2.w) ; change up key ? bne parse035 ; no, branch lea kmw_UpKey(kmw),a3 ; yes, load result area address bra parsekey ; go get new keyvalue parse035 cmp.b #'D',(a2,d2.w) ; change down key ? bne parse040 ; no, branch lea kmw_DownKey(kmw),a3 ; yes, load result area address bra parsekey ; go get new keyvalue parse040 cmp.b #'L',(a2,d2.w) ; change left key ? bne parse045 ; no, branch lea kmw_LeftKey(kmw),a3 ; yes, load result area address bra parsekey ; go get new keyvalue parse045 cmp.b #'R',(a2,d2.w) ; change right key ? bne parse050 ; no, branch lea kmw_RightKey(kmw),a3 ; yes, load result area address *-----------------------------------------------------------------------------* * A keyvalue specifier has been found, check its validity and * * if valid save it for use later. If invalid, issue a message * * and quit. * *-----------------------------------------------------------------------------* parsekey clr.l d4 ; indicate hex numbers jsr parsevalue ; go parse the value bne parse_keyerror ; bad value, branch cmp.w #keynamesmax,d0 ; is value within range ? bgt parse_keyerror ; no, branch lea keynames(pc),a1 asl.w #1,d0 cmp.w #-1,(a1,d0.w) ; is this a valid keyvalue ? beq parse_keyerror ; no, branch asr.w #1,d0 move.l d3,d2 ; adjust index move.b d0,(a3) ; save keyvalue bra parse015 ; go check for end of command parse050 cmp.b #'T',(a2,d2.w) ; toggle rmbtrap option ? bne parse054 ; no, branch bset.b #FLAGB_trap,kmw_flags(kmw) ; set indicator parse052 addq.w #1,d2 ; bump index bra parse015 ; loop for next character parse054 cmp.b #'B',(a2,d2.w) ; toggle blank pointer option ? bne parse055 ; no, branch bset.b #FLAGB_blankp,kmw_flags(kmw) ; set indicator bra parse052 ; bump index & check next character parse055 cmp.b #'I',(a2,d2.w) ; configuration info wanted ? bne parse057 ; no, branch bset.b #FLAGB_info,kmw_flags(kmw) ; set indicator bra parse052 parse057 cmp.b #'Q',(a2,d2.w) ; qualifier key(s) ? bne parse060 ; no, branch moveq.l #1,d4 ; indicate decimal number jsr parsevalue ; go parse the value bne parse_qualerror ; bad value, branch cmp.w #255,d0 ; within range ? bgt parse_qualerror ; no, branch move.b d0,kmw_Qual(kmw) ; save qualifier bset.b #FLAGB_Qual,kmw_flags(kmw) ; indicate option specified move.l d3,d2 ; adjust index bra parse015 parse060 cmp.b #'P',(a2,d2.w) ; handler priority option ? bne parse_optionerror ; no, bad option specified, branch moveq.l #1,d4 ; indicate decimal number jsr parsevalue ; go parse the value bne parse_prierror ; bad value, branch cmp.w #255,d0 ; is it within range ? bgt parse_prierror ; no, branch move.l d3,d2 ; adjust index move.b d0,kmw_handlerpri(kmw) ; save priority move.w d0,-(sp) ; pass pri value lea primsg(pc),a0 ; get format string address jsr printf ; go print change message addq.l #2,sp ; adjust stack pointer bra parse015 *-----------------------------------------------------------------------------* * Print 'HELP' information ? * *-----------------------------------------------------------------------------* parse065 cmp.b #'?',(a2,d2.w) ; help wanted ? bne parse070 ; no, branch lea help1(pc),a0 ; address of message jsr printf ; go write it lea help2(pc),a0 ; address of message jsr printf ; go write it lea help3(pc),a0 ; address of message jsr printf ; go write it lea help4(pc),a0 ; address of message jsr printf ; go write it lea help4a(pc),a0 ; address of message jsr printf ; go write it lea help5(pc),a0 ; address of message jsr printf ; go write it lea help6(pc),a0 ; address of message jsr printf ; go write it lea help6a(pc),a0 ; address of message jsr printf ; go write it lea help7(pc),a0 ; address of message pea akey(pc) ; text describing key jsr printf ; go write it addq.l #4,sp ; adjust stack pointer lea help8(pc),a0 ; address of message pea dkey(pc) ; text describing key jsr printf ; go write it addq.l #4,sp ; adjust stack pointer lea help9(pc),a0 ; address of message pea skey(pc) ; text describing key jsr printf ; go write it addq.l #4,sp ; adjust stack pointer lea help10(pc),a0 ; address of message pea leftkey(pc) ; text describing key jsr printf ; go write it addq.l #4,sp ; adjust stack pointer lea help11(pc),a0 ; address of message pea rightkey(pc) ; text describing key jsr printf ; go write it addq.l #4,sp ; adjust stack pointer lea help12(pc),a0 ; address of message pea upkey(pc) ; text describing key jsr printf ; go write it addq.l #4,sp ; adjust stack pointer lea help13(pc),a0 ; address of message pea downkey(pc) ; text describing key jsr printf ; go write it addq.l #4,sp ; adjust stack pointer bra parse_error ; get out *-----------------------------------------------------------------------------* * 'QUIT'ting KeyMenu * *-----------------------------------------------------------------------------* parse070 lea quitword(pc),a0 lea (a2,d2.w),a1 move.w #quitwordl-1,d0 parse072 cmp.b (a0)+,(a1)+ ; 'QUIT' ? bne parse075 ; no, branch dbra d0,parse072 ; loop control bset.b #FLAGB_quit,kmw_flags(kmw) ; set indicator add.w #quitwordl,d2 ; bump index bra parse015 ; loop for next option *-----------------------------------------------------------------------------* * White space or end of command ? * *-----------------------------------------------------------------------------* parse075 cmp.b #' ',(a2,d2.w) ; white space ? bne parse080 ; no, branch addq.w #1,d2 ; yes, bump index bra parse015 ; loop for next character parse080 cmp.b #LF,(a2,d2.w) ; are we at the end of the command ? bne parse_optionerror ; no, branch bra parseok ; yes, branch *-----------------------------------------------------------------------------* * Print 'Invalid key value specified' message * *-----------------------------------------------------------------------------* parse_keyerror jsr showerror ; go list the command and show where ; the error occurred lea keyerror(pc),a0 ; get address of message text jsr printf ; go write it bra parse_error ; take error exit *-----------------------------------------------------------------------------* * Print 'Invalid handler priority specified' message * *-----------------------------------------------------------------------------* parse_prierror jsr showerror ; go list the command and show where ; the error occurred lea prierror(pc),a0 ; get address of message text jsr printf ; go write it bra parse_error ; take error exit *-----------------------------------------------------------------------------* * Print 'Invalid qualifier(s) specified' message * *-----------------------------------------------------------------------------* parse_qualerror jsr showerror ; go list the command and show where ; the error occurred lea qualerror(pc),a0 ; get address of message text jsr printf ; go write it bra parse_error ; take error exit *-----------------------------------------------------------------------------* * Print 'Invalid/Unknown option specified' message * *-----------------------------------------------------------------------------* parse_optionerror jsr showerror ; go list the command and show where ; the error occurred lea opterror(pc),a0 ; get address of message text jsr printf ; go write it *-----------------------------------------------------------------------------* * Some kind of parsing error occured, set return code * *-----------------------------------------------------------------------------* parse_error moveq.l #1,d0 bra parseexit *-----------------------------------------------------------------------------* * parsed ok - set return code * *-----------------------------------------------------------------------------* parseok moveq.l #0,d0 *-----------------------------------------------------------------------------* * Common return point * *-----------------------------------------------------------------------------* parseexit movem.l (sp)+,parseregs ; restore registers rts ; return to caller parseregs reg d1-d4/a0-a3 ******************************************************************************* * * * parsevalue * * * * This routine parses ascii values and converts them to binary. * * * * Input Registers: * * a4 - keymenu work area (kmw) * * d2 - displacement into command where option containing value * * starts. * * d4 - 0 = ascii numbers are in hex, 1 = ascii numbers are decimal * * * * Output Registers: * * d0 - binary value * * d4 - 0 = parsed ok, 1 = parse error * * * ******************************************************************************* parsevalue addq.w #1,d2 ; bump index move.l d2,d3 ; use temporary index clr.l d0 ; clear accumulator clr.l d1 ; clear work register parseval010 move.b (a2,d3.w),d1 cmp.b #'0',d1 ; within decimal range ? blt parseval015 ; no, branch cmp.b #'9',d1 bgt parseval015 sub.b #'0',d1 ; make binary bra parseval020 parseval015 tst.l d4 ; hex number ? bne parseval025 ; no, branch cmp.b #'A',d1 ; within hex alpha range ? blt parseval025 ; no, branch cmp.b #'F',d1 bgt parseval025 sub.b #'A'-10,d1 ; make binary parseval020 tst.l d4 ; hex number ? beq parseval023 ; yes, branch mulu #10,d0 ; multiply accumulator by 10 bra parseval024 parseval023 asl.w #4,d0 ; multiply accumulator by 16 parseval024 add.w d1,d0 ; add current digit addq.w #1,d3 ; bump accumulator bra parseval010 ; loop for next char parseval025 cmp.b #' ',d1 ; end of value ? beq parseval030 ; yes, branch cmp.b #LF,d1 ; end of command ? beq parseval030 ; yes, branch bra parse_valerror ; no, error, branch parseval030 cmp.w d2,d3 ; was anything parsed ? bne parse_valok ; no, branch parse_valerror moveq.l #1,d4 ; indicate error bra parse_valend ; go to common return parse_valok clr.l d4 ; indicate value ok parse_valend rts ; return to caller ******************************************************************************* * * * showerror * * * * This routine displays the runtime command with a caret symbol * * underneath the portion of the command that caused the parsing error. * * * * Input Registers: * * a4 - keymenu work area (kmw) * * d2 - displacement into command where caret symbol should go * * * * Output Registers: * * none * * * ******************************************************************************* showerror movem.l showerrorregs,-(sp) ; save registers move.l kmw_cmd(kmw),a0 ; message text pointer clr.l d0 move.w kmw_cmd_length(kmw),d0 ; message text length jsr putmessage ; go write the command text clr.l d3 ; clear counter moveq.l #1,d0 ; set length of text to write lea kmw_buffer(kmw),a0 ; get address of buffer move.b #' ',(a0) ; put blank in buffer showerr010 cmp.w d2,d3 ; have we reached the displacement ? bge showerr015 ; yes, branch jsr putmessage ; go write a blank addq.w #1,d3 ; bump counter bra showerr010 ; loop showerr015 move.b #'^',(a0) ; put ^ in buffer jsr putmessage ; go write it move.b #LF,(a0) ; put linefeed in buffer jsr putmessage ; go write it movem.l (sp)+,showerrorregs ; restore registers rts showerrorregs reg d3 ******************************************************************************* * * * printf * * * * This routine is called to print a formatted message substituting data * * into the message from parameters (passed on the stack) using 'C'-like * * formatting characters. The calling routine is responsible for placing * * the datastream parameters on the stack and then adjusting the stack * * after execution of this routine. It is assumed that the parameters * * are located 4 bytes beyond the current stack pointer upon entry to * * this routine. * * * * Input Registers: * * a0 - address of format string * * a3 - address of current position in buffer * * a4 - workarea address * * * * Output Registers: * * none. * * * ******************************************************************************* printf lea 4(sp),a1 ; get datastream address movem.l printfregs,-(sp) ; save registers lea putchar(pc),a2 ; point to routine to build buffer lea kmw_buffer(kmw),a3 ; point to buffer Call RawDoFmt ; go format the buffer lea kmw_buffer(kmw),a0 ; point to buffer move.l a0,a1 ; save buffer start move.l #kmw_bsize-1,d0 ; get maximum size of buffer printf010 move.b (a1),(a1)+ ; scan buffer for end dbeq d0,printf010 ; loop til end sub.l a0,a1 ; compute size of datastream move.l a1,d0 ; setup for putmessage jsr putmessage ; go write the message movem.l (sp)+,printfregs ; restore registers rts printfregs reg a2/a3 ******************************************************************************* * * * putmessage * * * * This routine writes a message to the standard output device * * * * Input Registers: * * a0 - address of message text to write * * a4 - keymenu work area (kmw) * * d0 - length of message text to write * * * * Output Registers: * * none * * * ******************************************************************************* putmessage movem.l putmessageregs,-(sp) ; save registers move.l a0,d2 ; message text move.l d0,d3 ; text length move.l kmw_filehandle(kmw),d1 ; output file handle Call Write,kmw_dosbase(kmw) ; go write the message movem.l (sp)+,putmessageregs ; restore registers rts putmessageregs reg d0-d3/a0 ******************************************************************************* * * * putchar * * * * This routine is called by the 'RawDoFmt' exec function to put each * * character of a formatted datastring into an output buffer. The * * printf routine is used to pass the address of this routine to exec. * * * * Input Registers: * * d0 - character to be put into a buffer * * a3 - address of current position in buffer * * * * Output Registers: * * a3 - incremented to next position in buffer * * * ******************************************************************************* putchar move.b d0,(a3)+ ; put character into buffer rts ; return to caller ******************************************************************************* * * * create * * * * This routine loads the keymenu-handler code and adds it as an input * * handler to the input.device, if possible * * * * Input Registers: * * a4 - workarea address * * * * Output Registers: * * d0 - handler global area/null if unable to load/add handler * * * ******************************************************************************* create btst.b #FLAGB_quit,kmw_flags(kmw) ; was 'quit' specified ? bne create_err ; yes, keymenu not running, branch *-----------------------------------------------------------------------------* * Allocate handler global area * *-----------------------------------------------------------------------------* move.l #gb_size,d0 ; set size of area to allocate move.l #MEMF_CLEAR+MEMF_PUBLIC,d1; indicate type of memory Call AllocMem ; go get it move.l d0,gbl ; setup our global area register bne create015 ; if allocate was successful, branch create010 lea nomem(pc),a0 ; get error message address jsr printf ; go write error message bra create_err ; go cleanup *-----------------------------------------------------------------------------* * Initialize global area * *-----------------------------------------------------------------------------* create015 move.b #ralt_down,gb_AKey(gbl) move.b #esc_down,gb_DKey(gbl) move.b #return_down,gb_SKey(gbl) move.b #CURSORUP,gb_UpKey(gbl) move.b #CURSORDOWN,gb_DownKey(gbl) move.b #CURSORLEFT,gb_LeftKey(gbl) move.b #CURSORRIGHT,gb_RightKey(gbl) move.b #IEQUALIFIER_RSHIFT,gb_Qual(gbl) move.l gbl,gb_handler+IS_DATA(gbl) moveq.l #blank_pointer_size,d0 ; set size of area to allocate move.l #MEMF_CLEAR+MEMF_CHIP,d1 ; indicate type of memory Call AllocMem ; go get it move.l d0,gb_blank_ptr(gbl) ; save pointer data address bne create020 ; if allocate was successful, branch create018 jsr cleanup ; go release everything bra create010 *-----------------------------------------------------------------------------* * begin installing keymenu handler * *-----------------------------------------------------------------------------* create020 lea install(pc),a0 ; get install message address jsr printf ; go write install message move.b #PA_SIGNAL,gb_Port+MP_FLAGS(gbl) ; setup message port move.b #0,gb_Port+LN_PRI(gbl) move.b #NT_MSGPORT,gb_Port+LN_TYPE(gbl) move.l #kmportl,d0 ; size of port name move.l #MEMF_PUBLIC,d1 ; set type of memory to get Call AllocMem ; go allocate it move.l d0,gb_Port+LN_NAME(gbl) ; save its address beq create018 ; branch if allocation failed move.l d0,a0 ; get destination address lea kmport(pc),a1 ; get address of port name move.w #kmportl-1,d1 ; get length of area to move create030 move.b (a1,d1.w),(a0,d1.w) ; copy port name dbra d1,create030 ; loop through port name lea gb_Port+MP_MSGLIST(gbl),a0 ; get address of message list NEWLIST a0 ; initialize it *-----------------------------------------------------------------------------* * Open Intuition Library * *-----------------------------------------------------------------------------* lea intuitionlib(pc),a1 ; point to library name moveq.l #0,d0 ; we don't care what version Call OpenLibrary ; go open the library move.l d0,gb_IBase(gbl) ; save lib base for handler's use bne create040 ; openlibrary successful, branch jsr cleanup ; go release everything lea interr(pc),a0 ; get error message address jsr printf ; go write error message bra create_err ; take error exit *-----------------------------------------------------------------------------* * Load 'Keymenu-handler' segment * *-----------------------------------------------------------------------------* create040 lea handlerpath(pc),a0 ; use library path first move.l a0,d1 Call LoadSeg,kmw_dosbase(kmw) ; try to load the segment move.l d0,gb_Segment(gbl) ; save segment pointer bne create050 ; if loaded, branch lea handlername(pc),a0 ; use current directory move.l a0,d1 Call LoadSeg,kmw_dosbase(kmw) ; try load again move.l d0,gb_Segment(gbl) ; save segment pointer bne create050 ; if loaded, branch lea loaderr(pc),a0 ; get format string address pea handlername(pc) ; setup datastream jsr printf ; go print the message addq.l #4,sp ; adjust stack pointer jsr cleanup ; go release everything bra create_err ; take error exit *-----------------------------------------------------------------------------* * Add message port so that we can get access later. * *-----------------------------------------------------------------------------* create050 move.l gbl,a1 ; get port address Call AddPort ; add the port to the system sub.l a1,a1 ; setup to find our task Call FindTask ; go get our task pointer move.l d0,gb_task(gbl) ; save our task pointer moveq.l #-1,d0 ; setup to allocate a signal Call AllocSignal ; go allocate one move.b d0,gb_tasksignum(gbl) ; save signal number move.l gb_Port+LN_NAME(gbl),d1 moveq.l #procpri,d2 ; process priority move.l gb_Segment(gbl),d3 ; process code segment move.l #procstack,d4 ; process stack size Call CreateProc,kmw_dosbase(kmw) ; go create the process clr.l d0 clr.l d1 move.b gb_tasksignum(gbl),d1 bset.l d1,d0 ; create wait mask Call Wait ; wait for handler to signal us *-----------------------------------------------------------------------------* * Add handler to input.device * *-----------------------------------------------------------------------------* clr.l d0 move.b gb_tasksignum(gbl),d0 ; get allocated signal number Call FreeSignal ; go free the signal number move.b #handlerpri,gb_handler+LN_PRI(gbl) moveq.l #IND_ADDHANDLER,d0 ; indicate we want to add handler jsr tellinputdevice ; go tell it to the input.device bne create060 ; if added, branch bset.b #FLAGB_quit,kmw_flags(kmw) ; indicate that we want out lea handlererr(pc),a0 ; get error message address jsr printf ; go tell user bra create_ok ; take normal exit create060 lea handlerok(pc),a0 ; get format string address pea kmport(pc) ; put portname address on stack jsr printf ; go print 'ok' message addq.l #4,sp ; adjust stack pointer create_ok move.l gbl,d0 ; pass back address of global area bra createexit create_err move.l #0,d0 ; indicate no handler createexit rts ; return to caller ******************************************************************************* * * * tellinputdevice * * * * This routine is called to open the input.device, send a command to * * it and then close it. * * * * Input Registers: * * d0 - function to be sent to the input.device * * a4 - keymenu workarea address (kmw) * * a5 - handler global area * * * * * * Output Registers: * * d0 - return code (non-zero=success) * * * ******************************************************************************* tellinputdevice movem.l tidregs,-(sp) ; save registers move.l d0,d3 ; save function for use later moveq.l #-1,d2 ; default to good return *-----------------------------------------------------------------------------* * Create a port to communicate with the input.device * *-----------------------------------------------------------------------------* moveq.l #-1,d0 ; setup to allocate a signal Call AllocSignal ; go allocate one move.l d0,d6 ; save signal number for later use move.l #MP_SIZE,d0 ; size of port move.l #MEMF_PUBLIC+MEMF_CLEAR,d1 ; set type of memory to get Call AllocMem ; go allocate a message port move.l d0,d4 ; save its address bne tid010 ; if allocated ok, branch clr.l d2 ; set bad return code bra tid070 ; go free resources tid010 move.l d4,a2 move.b #NT_MSGPORT,LN_TYPE(a2) ; initialize the port move.b #PA_SIGNAL,MP_FLAGS(a2) move.b gb_tasksignum(gbl),MP_SIGBIT(a2) sub.l a1,a1 Call FindTask ; go find our task move.l d0,MP_SIGTASK(a2) lea MP_MSGLIST(a2),a0 NEWLIST a0 *-----------------------------------------------------------------------------* * Create a standard IO block * *-----------------------------------------------------------------------------* move.l #IOSTD_SIZE,d0 ; size of std request move.l #MEMF_CLEAR+MEMF_PUBLIC,d1 ; set type of memory Call AllocMem ; go allocate it move.l d0,d5 ; save its address bne tid020 ; branch if allocated ok clr.l d2 ; set bad return code bra tid060 ; go free resources tid020 move.l d5,a3 move.b #NT_MESSAGE,LN_TYPE(a3) move.l d4,MN_REPLYPORT(a3) move.w #IOSTD_SIZE,MN_LENGTH(a3) *-----------------------------------------------------------------------------* * Open input device * *-----------------------------------------------------------------------------* lea inputdevice(pc),a0 ; point to device name clr.l d0 ; unit 0 move.l d5,a1 ; inputblock clr.l d1 ; flags Call OpenDevice ; go open the input device tst.l d0 ; open ok ? beq tid030 ; yes, branch clr.l d2 ; set bad return code bra tid050 ; go free resources *-----------------------------------------------------------------------------* * Issue request to input device * *-----------------------------------------------------------------------------* tid030 move.w d3,IO_COMMAND(a3) ; set function in inputblock lea gb_handler(gbl),a0 ; get address of handler data move.l a0,IO_DATA(a3) ; put it in the inputblock move.l a3,a1 Call DoIO ; issue the I/O tst.l d0 ; was I/O successful ? beq tid040 ; yes, branch clr.l d2 ; no, set bad return code *-----------------------------------------------------------------------------* * Close the input device * *-----------------------------------------------------------------------------* tid040 move.l d5,a1 Call CloseDevice ; close the input device *-----------------------------------------------------------------------------* * Delete the input block * *-----------------------------------------------------------------------------* tid050 move.l #IOSTD_SIZE,d0 ; get size of standard request move.l d5,a1 ; get pointer to block Call FreeMem ; go deallocate memory *-----------------------------------------------------------------------------* * Delete the input port * *-----------------------------------------------------------------------------* tid060 move.l #MP_SIZE,d0 ; get size of port move.l d4,a1 ; get pointer to port Call FreeMem ; go deallocate the port *-----------------------------------------------------------------------------* * Free the signal associated with the port * *-----------------------------------------------------------------------------* tid070 clr.l d0 move.b gb_tasksignum(gbl),d0 Call FreeSignal ; go free the signal *-----------------------------------------------------------------------------* * Set return code and exit * *-----------------------------------------------------------------------------* move.l d2,d0 movem.l (sp)+,tidregs ; restore registers rts ; return to caller tidregs reg a2-a3/d2-d5 ******************************************************************************* * * * cleanup * * * * This routine frees resources that have been allocated or acquired * * during execution. * * * * Input Registers: * * a4 - keymenu work area (kmw) * * a5 - keymenu handler global area * * * * Output Registers: * * none * * * ******************************************************************************* cleanup *-----------------------------------------------------------------------------* * Close Intuition Library * *-----------------------------------------------------------------------------* move.l gb_IBase(gbl),d0 ; get intuition library base beq cleanup070 ; branch if not open move.l d0,a1 Call CloseLibrary ; close it *-----------------------------------------------------------------------------* * Deallocate port name area * *-----------------------------------------------------------------------------* cleanup070 move.l gb_Port+LN_NAME(gbl),d0 ; get port name area address beq cleanup080 ; branch if no area move.l d0,a1 move.l #kmportl,d0 ; get size of area Call FreeMem ; go free it *-----------------------------------------------------------------------------* * Deallocate blank pointer chip memory * *-----------------------------------------------------------------------------* cleanup080 move.l gb_blank_ptr(gbl),d0 ; get blank pointer area address beq cleanup090 ; branch if no area move.l d0,a1 move.l #blank_pointer_size,d0 ; get size of area Call FreeMem ; go free it *-----------------------------------------------------------------------------* * Deallocate handler global area * *-----------------------------------------------------------------------------* cleanup090 move.l gbl,a1 ; get global area address move.l #gb_size,d0 ; get size of work area Call FreeMem ; go free it rts ******************************************************************************* * * * Miscellaneous constants * * * ******************************************************************************* doslib DOSNAME ; library names intuitionlib INTUITIONNAME inputdevice dc.b 'input.device',0 portname kmport kmportend handlerpath dc.b 'L:' handlername dc.b 'KeyMenu-Handler',0 install dc.b 'Installing KeyMenu, ',0 remove dc.b 'Removing KeyMenu, ',0 nomem dc.b 'Unable to allocate work area, Aborted',LF,0 nomemend interr dc.b 'Unable to open Intuition library',LF,0 loaderr dc.b 'Unable to find %s',LF,0 handlererr dc.b 'Handler error',0 handlerok dc.b 'ok. %s, PUBLIC DOMAIN.',LF,0 ok dc.b 'ok',LF,0 help1 dc.b 'Usage: KeyMenu ' quitword dc.b 'QUIT' quitwordend dc.b LF,0 help2 dc.b ' KeyMenu []',LF,0 help3 dc.b ' Where is one or more of the following:',LF,0 help4 dc.b " -i = info about KeyMenu's current settings",LF,0 help4a dc.b ' -b = toggle Intuition pointer blanking',LF,0 help5 dc.b ' -q# = key qualifier(s) in decimal',LF,0 help6 dc.b ' -t = toggle clear RMBTRAP flag option',LF,0 help6a dc.b ' -p# = input handler priority in decimal',LF,0 help7 dc.b ' -a# = %s',LF,0 help8 dc.b ' -e# = %s',LF,0 help9 dc.b ' -s# = %s',LF,0 help10 dc.b ' -l# = %s',LF,0 help11 dc.b ' -r# = %s',LF,0 help12 dc.b ' -u# = %s',LF,0 help13 dc.b ' -d# = %s',LF,0 akey dc.b 'ACTIVATION key',0 dkey dc.b 'ESCAPE key',0 skey dc.b 'SELECT key',0 leftkey dc.b 'LEFT key',0 rightkey dc.b 'RIGHT key',0 upkey dc.b 'UP key',0 downkey dc.b 'DOWN key',0 keyerror dc.b 'Invalid key value',LF,0 prierror dc.b 'Invalid handler priority',LF,0 qualerror dc.b 'Invalid qualifier(s)',LF,0 opterror dc.b 'Invalid/unknown option',LF,0 changemsg dc.b '%s: %s (%x) changed to %s (%x)',LF,0 primsg dc.b 'Input handler priority is %d',LF,0 nowoff dc.b 'now ' off dc.b 'OFF',0 nowon dc.b 'now ' on dc.b 'ON',0 info1 dc.b '%s Configuration:',LF,0 info2 dc.b '%14s is %s (%x)',LF,0 info3 dc.b 'Key qualifier(s):',0 info3a dc.b ' %s ',0 none dc.b ' None' info3end dc.b LF,0 info4 dc.b 'Clear RMBTRAP option is %s',LF,0 info5 dc.b 'Blank Intuition Pointer option is %s',LF,0 ******************************************************************************* * * * Key Value Table * * * * Contains text descriptions of the various keys supported. * * Entries are variable length null terminated strings. This table * * is indexed by the keynames table. The order of the entries in * * this table is not significant. * * * ******************************************************************************* keyval ; this label must be first key00 dc.b '`',0 key01 dc.b '1',0 key02 dc.b '2',0 key03 dc.b '3',0 key04 dc.b '4',0 key05 dc.b '5',0 key06 dc.b '6',0 key07 dc.b '7',0 key08 dc.b '8',0 key09 dc.b '9',0 key0a dc.b '0',0 key0b dc.b '-',0 key0c dc.b '=',0 key0d dc.b '\',0 key0f dc.b 'Numeric Pad 0',0 key10 dc.b 'Q',0 key11 dc.b 'W',0 key12 dc.b 'E',0 key13 dc.b 'R',0 key14 dc.b 'T',0 key15 dc.b 'Y',0 key16 dc.b 'U',0 key17 dc.b 'I',0 key18 dc.b 'O',0 key19 dc.b 'P',0 key1a dc.b '[',0 key1b dc.b ']',0 key1d dc.b 'Numeric Pad 1',0 key1e dc.b 'Numeric Pad 2',0 key1f dc.b 'Numeric Pad 3',0 key20 dc.b 'A',0 key21 dc.b 'S',0 key22 dc.b 'D',0 key23 dc.b 'F',0 key24 dc.b 'G',0 key25 dc.b 'H',0 key26 dc.b 'J',0 key27 dc.b 'K',0 key28 dc.b 'L',0 key29 dc.b ';',0 key2a dc.b "'",0 key2d dc.b 'Numeric Pad 4',0 key2e dc.b 'Numeric Pad 5',0 key2f dc.b 'Numeric Pad 6',0 key31 dc.b 'Z',0 key32 dc.b 'X',0 key33 dc.b 'C',0 key34 dc.b 'V',0 key35 dc.b 'B',0 key36 dc.b 'N',0 key37 dc.b 'M',0 key38 dc.b ',',0 key39 dc.b '.',0 key3a dc.b '/',0 key3c dc.b 'Numeric Pad .',0 key3d dc.b 'Numeric Pad 7',0 key3e dc.b 'Numeric Pad 8',0 key3f dc.b 'Numeric Pad 9',0 key40 dc.b 'Space Bar',0 key41 dc.b 'Backspace',0 key42 dc.b 'Tab',0 key43 dc.b 'Numeric Pad Enter',0 key44 dc.b 'Return',0 key45 dc.b 'Escape',0 key46 dc.b 'Delete',0 key4a dc.b 'Numeric Pad -',0 key4c dc.b 'Cursor up',0 key4d dc.b 'Cursor down',0 key4e dc.b 'Cursor right',0 key4f dc.b 'Cursor left',0 key50 dc.b 'F1',0 key51 dc.b 'F2',0 key52 dc.b 'F3',0 key53 dc.b 'F4',0 key54 dc.b 'F5',0 key55 dc.b 'F6',0 key56 dc.b 'F7',0 key57 dc.b 'F8',0 key58 dc.b 'F9',0 key59 dc.b 'F10',0 key5f dc.b 'Help',0 key60 dc.b 'Left Shift',0 key61 dc.b 'Right Shift',0 key62 dc.b 'Caps Lock',0 key63 dc.b 'Control',0 key64 dc.b 'Left Alt',0 key65 dc.b 'Right Alt',0 key66 dc.b 'Left Amiga',0 key67 dc.b 'Right Amiga',0 ******************************************************************************* * * * Key Name Table * * * * Ordered by keycode. Each entry consists of a word displacement * * into the keyval table. Entries for unsupported keycodes contain * * a negative displacement. * * * * * ******************************************************************************* keynames dc.w key00-keyval dc.w key01-keyval dc.w key02-keyval dc.w key03-keyval dc.w key04-keyval dc.w key05-keyval dc.w key06-keyval dc.w key07-keyval dc.w key08-keyval dc.w key09-keyval dc.w key0a-keyval dc.w key0b-keyval dc.w key0c-keyval dc.w key0d-keyval dc.w -1 dc.w key0f-keyval dc.w key10-keyval dc.w key11-keyval dc.w key12-keyval dc.w key13-keyval dc.w key14-keyval dc.w key15-keyval dc.w key16-keyval dc.w key17-keyval dc.w key18-keyval dc.w key19-keyval dc.w key1a-keyval dc.w key1b-keyval dc.w -1 dc.w key1d-keyval dc.w key1e-keyval dc.w key1f-keyval dc.w key20-keyval dc.w key21-keyval dc.w key22-keyval dc.w key23-keyval dc.w key24-keyval dc.w key25-keyval dc.w key26-keyval dc.w key27-keyval dc.w key28-keyval dc.w key29-keyval dc.w key2a-keyval dc.w -1 dc.w -1 dc.w key2d-keyval dc.w key2e-keyval dc.w key2f-keyval dc.w -1 dc.w key31-keyval dc.w key32-keyval dc.w key33-keyval dc.w key34-keyval dc.w key35-keyval dc.w key36-keyval dc.w key37-keyval dc.w key38-keyval dc.w key39-keyval dc.w key3a-keyval dc.w -1 dc.w key3c-keyval dc.w key3d-keyval dc.w key3e-keyval dc.w key3f-keyval dc.w key40-keyval dc.w key41-keyval dc.w key42-keyval dc.w key43-keyval dc.w key44-keyval dc.w key45-keyval dc.w key46-keyval dc.w -1 dc.w -1 dc.w -1 dc.w key4a-keyval dc.w -1 dc.w key4c-keyval dc.w key4d-keyval dc.w key4e-keyval dc.w key4f-keyval dc.w key50-keyval dc.w key51-keyval dc.w key52-keyval dc.w key53-keyval dc.w key54-keyval dc.w key55-keyval dc.w key56-keyval dc.w key57-keyval dc.w key58-keyval dc.w key59-keyval dc.w -1 dc.w -1 dc.w -1 dc.w -1 dc.w -1 dc.w key5f-keyval qualnames dc.w key60-keyval dc.w key61-keyval dc.w key62-keyval dc.w key63-keyval dc.w key64-keyval dc.w key65-keyval dc.w key66-keyval keynamesend dc.w key67-keyval public create end