home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
325.lha
/
keys
/
k.asm
< prev
next >
Wrap
Assembly Source File
|
1989-12-26
|
26KB
|
1,252 lines
*------------------------------------------------------------------------------
*
* k.asm - a key macro utility.
*
*------------------------------------------------------------------------------
Section KeyCode,code
******* Included Files *************************************************
INCLUDE "keys.i"
******* Imported *******************************************************
xref _SysBase
xref _DOSBase
xref _IntuitionBase
xref _exit
xref NWPointer ; pointer to NewWindow structure.
xref FreePort
xref _bopen
xref _bclose
xref _bread
xref _bwrite
******* Exported *******************************************************
xdef IHandler
xdef IntRec
xdef ConIOBlock
xdef InpIOBlock
xdef TheTitle
xdef DefinedKeys
xdef StringBuf
xdef AddKey
xdef FileReadChar
xdef _main
*------------------------------------------------------------------------------
_main
;------ Get ready to process input
bsr SetupStuff
0$ move.l OurSigMask(pc),d0
ExecF Wait
;------ We got a signal - Do what we came here for...
;------ If Event is null, wait some more. If it is DOCMD, open
;------ the command window. Any other value is considered to be
;------ a process macro command.
tst.b Event
beq.s 0$
cmp.b #DOCMD,Event
beq.s 2$
1$ ;------ At this point, we have a macro to process. Check the Q
;------ for the next one.
bsr DeQ
beq.s 0$
lea kr_MacStr(a2),a2
bsr InsertString
bra.s 1$ ; Check for another macro.
2$ ;------ Set the current directory to the Initial CLI's.
;------ This has been taken out because this prog crashes
;------ violently if the Initial CLI no longer exists...
; bsr SetDirectory
;------ Get the ptr to the current (frontmost) screen
;------ courtesy of intuitionbase.
move.l _IntuitionBase(pc),a0
move.l ib_FirstScreen(a0),a1
;------ We now have a pointer to the screen structure in a1.
;------ Open a window onto this screen.
bsr OpenTheWindow
;------ Open the console device on this window:
bsr OpenCon
;------ Read Choice and process it
bsr ProcessChoice
;------ All done - close the console device and window.
bsr CloseAll
tst.b KillFlag
beq.s 0$
rts
*------------------------------------------------------------------------------
SetDirectory
;------ Set our directory to the Initial CLI's, so we can find
;------ stuff.
lea CLIName(pc),a1
ExecF FindTask
move.l d0,a0
move.l pr_CurrentDir(a0),d1
DosF CurrentDir
rts
*------------------------------------------------------------------------------
ProcessChoice
move.l sp,ErrorSp
0$ ;------ Prompt for a menu choice and then execute it.
lea ChoicePrompt(pc),a0
bsr PutPrompt
bsr ConReadChar ; get key...
move.b CharBuf,d7
;------ Escape will terminate the window.
cmp.b #27,d7
bne.s 1$
rts
1$ bsr ConWriteChar ; ...echo character
bsr ConReadChar ; ...get another
;------ Do something with the entered choice.
Ucase d7
cmp.b #'K',d7
seq KillFlag
bne.s 2$
rts
2$ cmp.b #'R',d7
bne.s 4$
bsr RemoveKey
bra.s 0$
4$ cmp.b #'D',d7
bne.s 6$
bsr DefineKey
bra.s 0$
6$ cmp.b #'S',d7
bne.s 8$
bsr SaveKeys
bra.s 0$
8$ cmp.b #'L',d7
bne.s 10$
bsr LoadKeys
bra.s 0$
10$ cmp.b #'V',d7
bne.s 12$
bsr ViewKeys
12$ bra.s 0$ ; Bad choice, get another one.
*------------------------------------------------------------------------------
DefineKey
;------ Prompt for the key to define, and then define it!
lea DefinePrompt(pc),a0
bsr PutPrompt
lea StringBuf(pc),a2
bsr ConReadLine
bsr AddKey
move.l a0,d7 ; Any mem free?
bne.s 0$ ; Nope, don't do nothin
UhOh ErNoMem ; Print no mem msg.
0$ lea MacPrompt(pc),a0
bsr PutPrompt
;------ Get the key's definition
move.l d7,a0
lea kr_MacStr(a0),a2
bsr ConReadLine
rts
*------------------------------------------------------------------------------
RemoveKey
;------ Prompt for the key to remove.
lea RemovePrompt(pc),a0
bsr PutPrompt
;------ Get key description.
lea StringBuf(pc),a2
bsr ConReadLine
;------ Convert description to Qualifier/Code form.
lea StringBuf(pc),a2
bsr ConvertCharacter
swap d0
move.w d1,d0
swap d0
bsr LookForKey
bne.s 2$
UhOh ErNoKey
2$ ;------ Remove the key from the list.
bsr DelKey
rts
*------------------------------------------------------------------------------
LoadKeys
lea LoadPrompt(pc),a0
bsr PutPrompt
lea StringBuf(pc),a2
bsr ConReadLine
;------ Attempt to open the file
move.l #StringBuf,d1
move.l #MODE_OLDFILE,d2
move.l #2048,d3
jsr _bopen
move.l d0,d4
bne.s 0$
UhOh ErNoFile
0$ lea LoadingMsg(pc),a0
bsr PutWindowMsg
2$ move.b #' ',d5
lea StringBuf(pc),a2
bsr FileReadItem
beq.s 4$
bsr AddKey
cmpa.l #0,a0
bne.s 3$
move.l d4,d1
jsr _bclose
UhOh ErNoMem
3$ move.b #10,d5
lea kr_MacStr(a0),a2
bsr FileReadItem
bra.s 2$
4$ move.l d4,d1
jsr _bclose
rts
*------------------------------------------------------------------------------
SaveKeys
lea SavePrompt(pc),a0
bsr PutPrompt
lea StringBuf(pc),a2
bsr ConReadLine
;------ Attempt to open the file
move.l #StringBuf,d1
move.l #MODE_NEWFILE,d2
move.l #2048,d3
jsr _bopen
move.l d0,d4
bne.s 0$
UhOh ErNoFile
0$ lea SavingMsg(pc),a0
bsr PutWindowMsg
lea DefinedKeys(pc),a2
2$ move.l kr_Next(a2),a2
cmp.l #0,a2
beq.s 4$
;------ Write the key description.
lea kr_KeyStr(a2),a3
move.b #' ',CharBuf
bsr FileWriteItem
;------ Write the key macro string.
lea kr_MacStr(a2),a3
move.b #10,CharBuf
bsr FileWriteItem
bra.s 2$
4$ move.l d4,d1
jsr _bclose
rts
*------------------------------------------------------------------------------
ViewKeys
ClearWindow
lea ViewPrompt(pc),a0
bsr PutWindowMsg
;------ Resize the window
move.l TheWindow(pc),a0
clr.l d0
move.l #178,d1
IntF SizeWindow
;------ Create an input event so intuition will resize the window
move.w #128,d0
clr.w d1
bsr InsertEvent
;------ Print the macros
lea DefinedKeys(pc),a2
2$ move.l kr_Next(a2),a2
cmp.l #0,a2
beq.s 4$
;------ Write the key description.
lea kr_KeyStr(a2),a0
bsr ConWriteLine
move.b #' ',CharBuf
bsr ConWriteChar
;------ Write the key macro string.
lea kr_MacStr(a2),a0
bsr ConWriteLine
lea CrLf(pc),a0
bsr ConWriteLine
bra.s 2$
4$ bsr ConReadChar
;------ Resize the window again
move.l TheWindow(pc),a0
clr.l d0
move.l #-178,d1
IntF SizeWindow
rts
*------------------------------------------------------------------------------
AddKey
;------ Allocate a structure for a key macro, and link it to the
;------ list. Return its address in a0.
move.l #kr_SIZEOF,d0
move.l #(MEMF_PUBLIC!MEMF_CLEAR!MEMF_CHIP),d1
ExecF AllocMem
tst.l d0
bne.s 0$
suba.l a0,a0
rts
0$ ;------ Add the record to the front of the list
lea DefinedKeys(pc),a0
move.l d0,a1
move.l kr_Next(a0),kr_Next(a1)
move.l a1,kr_Next(a0)
move.l a0,kr_Prev(a1)
tst.l kr_Next(a1)
beq.s 2$
move.l kr_Next(a1),a0
move.l a1,kr_Prev(a0)
2$ ;------ Place the defined key in the record
lea StringBuf(pc),a2
bsr ConvertCharacter
move.w d1,kr_Qual(a1)
move.w d0,kr_Key(a1)
lea StringBuf(pc),a2
lea kr_KeyStr(a1),a0
4$ move.b (a2)+,(a0)+
bne.s 4$
move.l a1,a0
rts
*------------------------------------------------------------------------------
DelKey
;------ Remove the key rec specified by a0 from the key list.
move.l kr_Prev(a0),a1
move.l kr_Next(a0),a2
move.l kr_Next(a0),kr_Next(a1)
cmp.l #0,a2
beq.s 2$
move.l a1,kr_Prev(a2)
2$ move.l a0,a1
move.l #kr_SIZEOF,d0
ExecF FreeMem
rts
*------------------------------------------------------------------------------
LookForKey
;------ Search for the key specified by d0 in the DefinedKey list.
;------ If the key was found, its address will be in a0.
lea DefinedKeys,a0
0$ move.l kr_Next(a0),a0
cmpa.l #0,a0
beq.s 2$
cmp.l kr_Qual(a0),d0
bne.s 0$
moveq #1,d0
2$ rts
*------------------------------------------------------------------------------
FileReadItem
;------ This routine will read either the key def or the macro
;------ def from the file depending on the delimiter.
clr.l d6 ; Keep a character count.
0$ bsr FileReadChar
tst.l d0
beq.s 4$
cmp.b #76,d6
blt.s 1$
move.l d4,d1
jsr _bclose
UhOh ErDefTooLong
1$ cmp.b (a2),d5
beq.s 2$
addq.l #1,a2
addq.l #1,d6
bra.s 0$
2$ clr.b (a2)
moveq #1,d0
4$ rts
*------------------------------------------------------------------------------
FileReadChar
move.l d4,d1
move.l a2,d2
moveq.l #1,d3
jsr _bread
rts
*------------------------------------------------------------------------------
FileWriteItem
;------ Write the item to the file, and the terminator in CharBuf.
;------ a3 points to the item to write.
0$ bsr FileWriteChar
addq.l #1,a3
tst.b (a3)
bne.s 0$
;------ Write the terminator to the file.
lea CharBuf(pc),a3
bsr FileWriteChar
rts
*------------------------------------------------------------------------------
FileWriteChar
;------ Write the character pointed to by a3 to the file (d4).
move.l d4,d1
move.l a3,d2
moveq.l #1,d3
jsr _bwrite
rts
*------------------------------------------------------------------------------
PutPrompt
;------ Put a prompt in the title line, clear the window and
;------ place a prompt character in it. The desired prompt
;------ is in (a0).
bsr PutWindowMsg
ClearWindow
lea PromptStr(pc),a0
bsr ConWriteLine
rts
*------------------------------------------------------------------------------
PutWindowMsg
;------ Put a message in the window's title line. The message consists
;------ of two parts: The window's title, and the specified message.
lea StringBuf(pc),a2
lea TheTitle(pc),a1
0$ move.b (a1)+,(a2)+
bne.s 0$
lea -1(a2),a2
2$ move.b (a0)+,(a2)+
bne.s 2$
;------ Now print the prompt.
lea StringBuf(pc),a1
move.l #-1,a2
move.l TheWindow(pc),a0
IntF SetWindowTitles
rts
*------------------------------------------------------------------------------
ProcessError
bsr PutWindowMsg
bsr ConReadChar
move.l ErrorSp(pc),sp
bra ProcessChoice
rts
*------------------------------------------------------------------------------
EnQ
ExecF Forbid
cmp.w #64,QC ; Full yet?
beq.s 0$
lea CmdQ(pc),a1
addq.b #4,QB+1
move.w QB(pc),d0
move.l a3,0(a1,d0.w)
addq.w #1,QC
0$ ExecF Permit
rts
*------------------------------------------------------------------------------
DeQ
ExecF Forbid
tst.w QC
sne.b d2
beq.s 0$
lea CmdQ(pc),a1
addq.b #4,QF+1
move.w QF,d0
move.l 0(a1,d0.w),a2
subq.w #1,QC
0$ ExecF Permit
tst.b d2
rts
*------------------------------------------------------------------------------
*
* This section contains initialization and termination routines.
*
*------------------------------------------------------------------------------
*------------------------------------------------------------------------------
SetupStuff
;------ Perform the required initialization for console and
;------ input device I/O.
;------ Initialize the queue.
move.w #252,QF
move.w #252,QB
clr.w QC
;------ Fetch our task pointer
move.l _SysBase(pc),a0
move.l ThisTask(a0),OurTask
;------ Allocate a StdIORequest block for console I/O.
bsr AllocIOBlock
move.l d0,ConIOBlock
;------ Allocate a StdIORequest block for input.device I/O.
bsr AllocIOBlock
move.l d0,InpIOBlock
;------ Get a signal for us to use...
bsr AllocSignal
;------ Open the input.device
bsr OpenInputDevice
;------ Set up the interrupt handler node, and tell the input.dev
;------ about it.
bsr SetInputInterrupt
rts
*------------------------------------------------------------------------------
AllocIOBlock
;------ Allocate a STDIO block.
;------ First, create the message port
moveq #-1,d0
ExecF AllocSignal
move.l d0,d2 ; Save this for the moment...
cmp.l #-1,d0 ; Did we get it?
beq.s 0$
;------ Allocate memory for the port:
move.l #(MEMF_PUBLIC!MEMF_CLEAR),d1
move.l #MP_SIZE,d0
LibF AllocMem
tst.l d0 ; Any memory free?
beq.s 2$ ; Nope, exit w/error.
move.l d0,a2 ; Make me a pointer to this...
;------ Set up the port values
move.b #NT_MSGPORT,LN_TYPE(a2) ; type = message port
move.b #PA_SIGNAL,MP_FLAGS(a2) ; signal me...
move.b d2,MP_SIGBIT(a2) ; ...with this signal
move.l OurTask(pc),MP_SIGTASK(a2) ; signal our task
;------ Add the port to the list
lea MP_MSGLIST(a2),a0
NEWLIST a0
;------ Now create the request block
move.l #IOSTD_SIZE,d0
move.l #(MEMF_CLEAR!MEMF_PUBLIC),d1
ExecF AllocMem
tst.l d0 ; Any mem?
beq.s 0$ ; Nope, free the port & exit.
move.l d0,a0
move.b #NT_MESSAGE,LN_TYPE(a0)
move.w #IOSTD_SIZE,MN_LENGTH(a0)
move.l a2,MN_REPLYPORT(a0)
rts
0$ ;------ Free the port
jsr FreePort
bra.s 4$
2$ ;------ Free the signal
move.l d2,d0
LibF FreeSignal
4$ clr.l d0
rts
*------------------------------------------------------------------------------
AllocSignal
;------ Get a signal for us to use, and make it into a signal mask
;------ for the Exec Wait() function.
moveq #-1,d0
ExecF AllocSignal
tst.l d0
beq.s 0$
moveq #1,d1
lsl.l d1,d0
move.l d0,OurSigMask
0$ rts
*------------------------------------------------------------------------------
OpenInputDevice
;------ Umm... open the input.device
clr.l d1 ; Flags
clr.l d0 ; Unit number
lea IDName(pc),a0 ; Input device name
move.l InpIOBlock,a1 ; The IORequest block
ExecF OpenDevice
rts
*------------------------------------------------------------------------------
SetInputInterrupt
;------ Set up the interrupt handler node, and tell the input.dev
;------ to install it.
;------ Note that we set the priority to 51. This magic number
;------ assures us that we will get the event before intuition
;------ because intuition only has a priority of 50.
lea IntRec,a0
clr.l IS_DATA(a0) ; No data...
move.l #IHandler,IS_CODE(a0) ; Point to our handler
move.b #51,LN_PRI(a0) ; Set the priority
;------ Set up the IO request block
move.l InpIOBlock,a1
move.w #IND_ADDHANDLER,IO_COMMAND(a1)
move.l a0,IO_DATA(a1)
;------ Send the bitch!
ExecF DoIO
rts
*------------------------------------------------------------------------------
OpenCon
;------ Open the console device for our window...
move.l ConIOBlock,a1
move.l TheWindow,IO_DATA(a1)
move.l #wd_Size,IO_LENGTH(a1)
lea ConName(pc),a0
clr.l d0
clr.l d1
ExecF OpenDevice
rts
*------------------------------------------------------------------------------
OpenTheWindow
;------ Open the window on the screen pointed to by a1.
move.l NWPointer,a0 ; Snag ptr to NewWindow struct
move.w sc_Flags(a1),d0
and.w #CUSTOMSCREEN,d0
move.l a1,nw_Screen(a0)
move.w d0,nw_Type(a0)
IntF OpenWindow
move.l d0,TheWindow
rts
*------------------------------------------------------------------------------
CloseAll
;------ Close the console device
move.l ConIOBlock,a1
ExecF CloseDevice
;------ Close the window
move.l TheWindow,a0
IntF CloseWindow
rts
*------------------------------------------------------------------------------
*
* This section contains all of the console I/O routines.
*
*------------------------------------------------------------------------------
*------------------------------------------------------------------------------
ConReadChar
;------ Read one character from the console.
move.l ConIOBlock(pc),a1
move.w #CMD_READ,IO_COMMAND(a1)
move.l #1,IO_LENGTH(a1)
move.l #CharBuf,IO_DATA(a1)
ExecF DoIO
rts
*------------------------------------------------------------------------------
ConReadLine
;------ Read a line from the screen and stick it in (a2)
;------ and null-terminate it in the process.
move.l a2,d2 ; Save this address...
moveq.l #1,d3 ; Save character count
0$ ;------ Get a character
bsr ConReadChar
;------ Check for a BACKSPACE character.
cmp.b #BACKSPACE,CharBuf
bne.s 2$
bsr EditBACKSPACE
bra.s 0$
2$ ;------ If we have a CR char, print a newline and return.
cmp.b #RETURN,CharBuf
bne.s 4$
lea CrLf(pc),a0
bsr ConWriteLine
clr.b (a2)
rts
4$ ;------ Increment the buffer pointer and fetch another character.
cmp.w #77,d3
bcc.s 0$
;------ Echo the character.
bsr ConWriteChar
move.b CharBuf,(a2)+
addq.l #1,d3
bra.s 0$
*------------------------------------------------------------------------------
EditBACKSPACE
;------ Edit the BACKSPACE character.
;------ If it is the first character on the line, do nothing.
cmp.l a2,d2
beq.s 0$
;------ Print the backspace, and back up 1 space.
lea BackSpaceStr(pc),a0
bsr ConWriteLine
subq.l #1,a2
subq.l #1,d3
0$ rts
*------------------------------------------------------------------------------
ConWriteChar
;------ Write the character in CharBuf on the screen.
lea CharBuf(pc),a0
moveq.l #1,d0
bra.s ConWrite
*------------------------------------------------------------------------------
ConWriteLine
;------ Put the null terminated string (pointed to by a0) on the
;------ screen.
moveq.l #-1,d0 ; Fall thru to ConWrite...
*------------------------------------------------------------------------------
ConWrite
;------ Print d0 chars of string a0. If d0 is -1, we expect a0 to be
;------ a null-terminated string.
move.l ConIOBlock,a1
move.l a0,IO_DATA(a1)
move.l d0,IO_LENGTH(a1)
move.w #CMD_WRITE,IO_COMMAND(a1)
ExecF DoIO
rts
*------------------------------------------------------------------------------
*
* This section handles the insertion of input events into the event stream.
*
*------------------------------------------------------------------------------
*------------------------------------------------------------------------------
ConvertCharacter
;------ Convert the character pointed to by a2 to an Amiga-useable
;------ qualifier/code pair.
clr.w d0
clr.w d1
lea KeyTable(pc),a0
0$ move.b (a2)+,d0
beq 99$
;------ Test for an escape character.
cmp.b #'\',d0
bne 50$
;------ Process escape character.
move.b (a2)+,d0
;------ Test for left shift
cmp.b #'s',d0
bne.s 2$
bset #L_SHIFT,d1
bra.s 0$
2$ ;------ Test for right shift
cmp.b #'S',d0
bne.s 4$
bset #R_SHIFT,d1
bra 0$
4$ ;------ Test for left alt
cmp.b #'a',d0
bne.s 6$
bset #L_ALT,d1
bra 0$
6$ ;------ Test for right alt
cmp.b #'A',d0
bne.s 8$
bset #R_ALT,d1
bra 0$
8$ ;------ Not a case-sensitive key at this point, make it upper
;------ case...
Ucase d0
;------ Add Control qualifier.
cmp.b #'C',d0
bne.s 10$
bset #CONTROL,d1
bra 0$
10$ ;------ Process Left-Amiga qualifier.
cmp.b #'L',d0
bne.s 16$
bset #L_AMIGA,d1
bra 0$
;------ Process Right-Amiga qualifier.
16$ cmp.b #'R',d0
bne.s 18$
bset #R_AMIGA,d1
bra 0$
18$ ;------ Process Keypad qualifier.
cmp.b #'K',d0
bne.s 24$
;------ The keypad keys present a special case: If the key is between
;------ 0 and 9, set the keypad bit, else don't.
move.b (a2)+,d0
cmp.b #'0',d0
blt.s 20$
bset #KPAD,d1
20$ lea KeypadTable(pc),a0
sub.b #'(',d0
lsl.b #1,d0
move.b 1(a0,d0.w),d0 ; Fetch character code.
rts
24$ ;------ Process Function keys.
cmp.b #'F',d0
bne.s 28$
move.b (a2)+,d0
cmp.b #'1',d0
bne.s 26$
cmp.b #'0',(a2)
bne.s 26$
;------ Process f10
addq.l #1,a2
move.b #('9'+1),d0
26$ add.b #31,d0
rts
28$ ;------ Process Help key
cmp.b #'H',d0
bne.s 30$
move.b #$5f,d0
rts
30$ ;------ Process Cursor keys.
cmp.b #'^',d0
bne.s 50$
move.b (a2)+,d0
Ucase d0
cmp.b #'U',d0
bne.s 32$
move.b #$4c,d0
rts
32$ cmp.b #'D',d0
bne.s 34$
move.b #$4d,d0
rts
34$ cmp.b #'L',d0
bne.s 36$
move.b #$4f,d0
rts
36$ cmp.b #'R',d0
bne.s 38$
move.b #$4e,d0
rts
38$ bra 0$
50$ ;------ Not an escape code, just print the character.
sub.w #27,d0 ; Subtract table base.
lsl.b #1,d0 ; Calc table offset.
move.b 0(a0,d0.w),d2
or.b d2,d1 ; Form character qualifer.
move.b 1(a0,d0.w),d0 ; Fetch character code.
99$ rts
*------------------------------------------------------------------------------
InsertString
;------ Insert the string into the input event stream
bsr ConvertCharacter
beq.s 0$
bsr InsertEvent
bra.s InsertString
0$ rts
*------------------------------------------------------------------------------
InsertEvent
;------ Insert the event into the input stream. The event will be
;------ coded as: code=d0, qualifier=d1
lea MyEventDn(pc),a0
lea MyEventUp(pc),a1
;------ Set up the input event.
move.l a1,ie_NextEvent(a0)
move.b #IECLASS_RAWKEY,ie_Class(a0)
move.w d0,ie_Code(a0)
move.w d1,ie_Qualifier(a0)
clr.w ie_X(a0)
clr.w ie_Y(a0)
clr.l ie_TimeStamp(a0)
clr.l (ie_TimeStamp+4)(a0)
;------ Set up the input event.
clr.l ie_NextEvent(a1)
move.b #IECLASS_RAWKEY,ie_Class(a1)
add.w #128,d0
move.w d0,ie_Code(a1)
move.w d1,ie_Qualifier(a1)
clr.w ie_X(a1)
clr.w ie_Y(a1)
clr.l ie_TimeStamp(a1)
clr.l (ie_TimeStamp+4)(a1)
;------ Set up the IORequest block
move.l InpIOBlock(pc),a1
move.w #IND_WRITEEVENT,IO_COMMAND(a1)
clr.b IO_FLAGS(a1)
move.l #ie_SIZEOF,IO_LENGTH(a1)
move.l a0,IO_DATA(a1)
;------ Send the event
ExecF DoIO
rts
*------------------------------------------------------------------------------
*
* These two routines are input handler related
*
*------------------------------------------------------------------------------
*------------------------------------------------------------------------------
LookupKey
;------ See if input event matches a defined key. a2 points to
;------ input event struct.
;------ First, form search key.
move.w ie_Qualifier(a2),d0
and.w #%111111111,d0 ; don't care about upper bits
;------ Add the keycode to the qualifier, and look it up.
swap d0
move.w ie_Code(a2),d0
bsr LookForKey
beq.s 4$
;------ If we get here, we found the key. EnQ the event, set
;------ Event to DOMAC, and leave.
move.l a0,a3 ; Get macro rec address for queueing
bsr EnQ
move.b #DOMAC,Event
4$ rts
*------------------------------------------------------------------------------
IHandler
;------ When called, we get a pointer to the input-event chain
;------ in a0, and a pointer to our data in a1. We don't need
;------ a1 tho.
movem.l a2/a3/a6,-(sp) ; Save these
move.l a0,a2
clr.b Event
0$ cmp.b #IECLASS_RAWKEY,ie_Class(a2)
bne.s 4$
bsr LookupKey
bne.s 2$
cmp.w #HELPKEY,ie_Code(a2)
bne.s 4$
btst.b #IEQUALIFIERB_LCOMMAND,(ie_Qualifier+1)(a2)
beq.s 4$
move.b #DOCMD,Event ; Indicate: open command window
2$ ;------ This is our event, remove it from the list and signal
;------ our task.
move.l ie_NextEvent(a2),a2
;------ Signal the waiting task.
move.l OurSigMask(pc),d0
move.l OurTask(pc),a1
ExecF Signal
4$ move.l a2,d0 ; Pass return value in d0
movem.l (sp)+,a2/a3/a6
rts
*------------------------------------------------------------------------------
*
* This is the Data section!
*
*------------------------------------------------------------------------------
ConIOBlock ds.l 1 ; Pointer to console.dev IOblock.
InpIOBlock ds.l 1 ; Pointer to input.dev IOblock.
IntRec ds.b IS_SIZE ; The interrupt handler node
MyEventDn ds.b ie_SIZEOF ; My input event structure (key down).
MyEventUp ds.b ie_SIZEOF ; My input event structure (key up).
ErrorSp ds.l 1 ; Stack ptr used for error recovery.
CmdQ ds.w 128 ; Queue for macros.
QF ds.w 1 ; Front of Q pointer.
QB ds.w 1 ; Back of Q pointer.
QC ds.w 1 ; Elements in Q.
DefinedKeys ;------ The first record in the chain
dc.l 0 ; next
dc.l 0 ; prev
dc.w 0 ; key
dc.b 0 ; definition
ds.b 79
OurTask ds.l 1 ; Pointer to our TCB.
OurSigMask ds.l 1 ; Signal mask for our port.
TheWindow ds.l 1 ; Pointer to our window structure.
StringBuf ds.b 160 ; Buffer for reading strings
;------ The following table is used to convert ascii characters to their
;------ keyboard equivalents. We put the qualifier in the first byte, and
;------ the key-code in the second. The table starts with an <escape> character.
KeyTable
;------ Punctuation and digits (<esc> to '@')
dc.w $0045,$0000,$0000,$0000,$0000,$0040,$0101,$012a,$0103
dc.w $0104,$0105,$0107,$002a,$0109,$010a,$0108,$010c,$0038
dc.w $000b,$0039,$003a,$000a,$0001,$0002,$0003,$0004,$0005
dc.w $0006,$0007,$0008,$0009,$0129,$0029,$0138,$000c,$0139
dc.w $013a,$0102
;------ Upper case letters
dc.w $0120,$0135,$0133,$0122,$0112,$0123,$0124,$0125,$0117
dc.w $0126,$0127,$0128,$0137,$0136,$0118,$0119,$0110,$0113
dc.w $0121,$0114,$0116,$0134,$0111,$0132,$0115,$0131
;------ Punctuation
dc.w $001a,$000d,$001b,$0106,$010b,$0000
;------ Lower case letters
dc.w $0020,$0035,$0033,$0022,$0012,$0023,$0024,$0025,$0017
dc.w $0026,$0027,$0028,$0037,$0036,$0018,$0019,$0010,$0013
dc.w $0021,$0014,$0016,$0034,$0011,$0032,$0015,$0031
;------ Punctuation
dc.w $011a,$010d,$011b,$0100,$0046
KeypadTable
;------ Keypad keys starting with '('
dc.w $005a,$005b,$005d,$005e,$0000,$004a,$003c,$005c
dc.w $000f,$001d,$001e,$001f,$002d,$002e,$002f,$003d,$003e
dc.w $003f
CharBuf ds.b 1 ; Buffer for reading characters.
KillFlag ds.b 1 ; 'kill program' flag.
Event ds.b 1 ; 'Type of input event' flag.
cnop 0,2
CrLf dc.b 13,10,0
BackSpaceStr dc.b $9b,$44,$9b,$50,0 ; Back up and delete char.
ClrWindowStr dc.b 12,0
PromptStr dc.b '>',0
TheTitle dc.b 'Keys V1.0 -- ',0
ChoicePrompt dc.b 'Enter: (K)ill, (D)efine, (R)emove, (L)oad, (S)ave, (V)iew',0
DefinePrompt dc.b 'Describe key to Define:',0
RemovePrompt dc.b 'Describe key to Remove:',0
MacPrompt dc.b 'Enter key definition:',0
LoadPrompt dc.b 'Enter file name to Load:',0
SavePrompt dc.b 'Enter file name to Save:',0
ViewPrompt dc.b 'Key listing. Press any key to exit...',0
LoadingMsg dc.b 'Loading...',0
SavingMsg dc.b 'Saving...',0
ErNoMem dc.b 'Error: No memory available',0
ErNoFile dc.b 'Error: File not found',0
ErNoKey dc.b 'Error: Key not defined',0
ErDefTooLong dc.b 'Error: Macro definition exceeds 76 characters',0
ConName dc.b 'console.device',0
IDName dc.b 'input.device',0
CLIName dc.b 'Initial CLI',0
end