*	SetPWkeys
*	1991 by Preben Nielsen
*
*
*HISTORY
*          Made with Hisoft V2.12
*
*  V1.0   20-Apr-91: The program has now existed for a long time, but I
*                    don't remember exactly when I started on it.
*  V1.1   07-May-91: Modified it to accommodate 3 new functions.
*         08-May-91: Modified it to accommodate 2 new functions.
*                    Added arrow-images.
*         11-May-91: Located an error. The correct number of hotkeys
*                    didn't get saved to file (oops).
*         14-May-91: Added string-gadgets to control handler-priority and
*                    mouse speed/threshold.
*         15-May-91: Added string-gadgets to control screen/mouse blanking.
*  V2.0   18-May-91: Now uses Workbench 2.x colors.
*         19-May-91: Help, I just found out that my "TellInputDevice"
*                    routine trashes memory-address 0 because it didn't
*                    do a "NewList" on its Message-port. It didn't cause
*                    any problems most of the time, but it has now been
*                    cured.

	OPT O+
	OPT O1+			; Tells when a branch could be optimised to short
	OPT i+			; Tells when '#' is probably missing

		incdir		"AsmInc:"
		include		"exec/exec_lib.i"
		include		"exec/io.i"
		include		"exec/memory.i"
		include		"exec/interrupts.i"
		include		"devices/input.i"
		include		"libraries/dos_lib.i"
		include		"libraries/dosextens.i"
		include		"graphics/graphics_lib.i"
		include		"graphics/gfxbase.i"
		include		"graphics/text.i"
		include		"intuition/intuition.i"
		include		"intuition/intuition_lib.i"
		include		"PWkeys.i"

POPSCREEN			; If this is defined then the screen will
				; pop up from below
CUSTOMCOLORS			; If you remove this then it uses WB-colors

PLANES			=1	; Bitplanes on screen
SWDIFF			=10	; Difference between screen and window y-coords

FUNCTEXTS		=KeyFuncNumber+3
GADTEXTS		=13
MSGTEXTS		=14

TITLE			=0
NOFILE			=-1
READERROR		=-2
WRITEERROR		=-3
GOODREAD		=-4
GOODWRITE		=-5
NOHANDLER		=-6
CANTREMOVE		=-7
CANTINSTALL		=-8
IMPORTOK		=-9
EXPORTOK		=-10
DUPLICATES		=-11
WRONGPRI		=-12
NOERRORS		=-13

KEYMASK			=$FF

SELECTEDBOX		=0
GHOSTEDBOX		=1

Prepare		MACRO
		IFC		'\1','Exec_Call'
		movea.l		4.W,A6
		ENDC
		IFC		'\1','Intuition_Call'
		movea.l		IntBase(DB),A6
		ENDC
		IFC		'\1','Gfx_Call'
		movea.l		GraphBase(DB),A6
		ENDC
		IFC		'\1','Dos_Call'
		movea.l		DosBase(DB),A6
		ENDC
		ENDM
CallLib		MACRO
		jsr		_LVO\1(A6)
		ENDM
Call		MACRO
		bsr		\1
		ENDM
Push		MACRO		Push <reg list | all>
		IFC		'\1','all'
		movem.l		D0-D7/A0-A6,-(SP)
		ENDC
		IFNC		'\1','all'
		movem.l		\1,-(SP)
		ENDC
		ENDM
Pop		MACRO		Pop <reg list | all>
		IFC		'\1','all'
		movem.l		(SP)+,D0-D7/A0-A6
		ENDC
		IFNC		'\1','all'
		movem.l		(SP)+,\1
		ENDC
		ENDM
rAPtr		MACRO		Name
DefSiz		set		DefSiz+4
DefPtr		set		DefPtr-4
\1		=		DefPtr
		ENDM
rLong		MACRO		Name
DefSiz		set		DefSiz+4
DefPtr		set		DefPtr-4
\1		=		DefPtr
		ENDM
rWord		MACRO		Name
DefSiz		set		DefSiz+2
DefPtr		set		DefPtr-2
\1		=		DefPtr
		ENDM
rByte		MACRO		Name
DefSiz		set		DefSiz+1
DefPtr		set		DefPtr-1
\1		=		DefPtr
		ENDM
rStorage	MACRO		Name,Size	;def storage
DefSiz		set		DefSiz+\2
DefPtr		set		DefPtr-\2
\1		=		DefPtr
		ENDM
rEVEN		MACRO				;word boundary
		IFNE		DefPtr&1
DefPtr		set		DefPtr-1
DefSiz		set		DefSiz+1
		ENDC
		ENDM
rStart		MACRO				;def var section
DefPtr		set		0
DefSiz		set		0
		ENDM
rEnd		MACRO				;def var section
RelSize		=		DefSiz
		ENDM
rAlloc		MACRO
		link		DB,#-RelSize
		ENDM
rFree		MACRO				;De-allocate storage
		unlk		DB
		ENDM
rClear		MACRO				;reset all variables
		movem.l		D0/A0,-(SP)
		move.w		#RelSize-1,D0
		move.l		DB,A0
rClr.\@		clr.b		-(A0)
		dbf		D0,rClr.\@
		movem.l		(SP)+,D0/A0
		ENDM
Gadget		MACRO
		dc.l		\1
		dc.w		\2,\3,\4,\5,\6,\7,\8
		ENDM
Gadget2		MACRO
		dc.l		\1,\2,\3,\4,\5
		dc.w		\6
		dc.l		\7
		ENDM
Border		MACRO
		dc.w		\1,\2
		dc.b		\3,\4,\5,\6
		dc.l		\7,\8
		ENDM
Image		MACRO
		dc.w		\1,\2,\3,\4,\5
		dc.l		\6
		dc.b		\7,\8
		dc.l		\9
		ENDM
IntuiText	MACRO
		dc.b		\1,\2,\3,0
		dc.w		\4,\5
		dc.l		TxtAttr,\6,\7
		ENDM
Detach		MACRO		; Detach <'process name'>,stacksize,processpri
		SECTION		MultiSplit,CODE
Start		Prepare		Exec_Call
		suba.l		A1,A1
		CallLib		FindTask		; Find us
		move.l		D0,A0
		tst.l		pr_CLI(A0)
		bne.S		SegSplit
		jmp		ProcessStart		; from WorkBench
SegSplit	link		A4,#-100
		CallLib		Forbid			; From Dos
		lea		DName(PC),A1
		CallLib		OldOpenLibrary
		move.l		D0,D5
		beq		6$
		move.l		Start-4(PC),A1
		move.l		A1,D3
		moveq		#0,D6			; Number of segments
		moveq		#ML_SIZE,D7		; Size of memory to allocate
		move.l		SP,A0
1$		move.l		A1,D0			; Count segments and make MemEntries on the stack
		beq.S		2$
		adda.l		A1,A1
		adda.l		A1,A1
		subq.l		#4,A1
		move.l		A1,(A0)+		; MemList -> ml_me[0].me_Addr	= Segment
		move.l		(A1),(A0)+		; MemList -> ml_me[0].me_Length	= Length
		move.l		4(A1),A1
		addq.w		#1,D6
		addq.w		#ME_SIZE,D7
		bra.S		1$
2$		move.l		D7,D0
		move.l		#MEMF_PUBLIC|MEMF_CLEAR,D1
		CallLib		AllocMem		; Allocate Memlist
		move.l		D0,A2
		tst.l		D0
		beq.S		5$
		move.w		D6,ML_NUMENTRIES(A2)	; MemList -> ml_NumEntries = number of segments
		move.l		SP,A0
		lea		ML_ME(A2),A1
		move.l		D7,D0
		sub.w		#ML_SIZE+1,D0
3$		move.b		(A0)+,(A1)+
		dbf		D0,3$
		move.l		#ProcessName,D1
		moveq		#\3,D2			; Priority
		move.l		#\2,D4			; Stacksize
		move.l		D5,A6
		CallLib		CreateProc
		Prepare		Exec_Call
		move.l		D0,A0
		tst.l		D0
		beq.S		4$
		lea		-pr_MsgPort(A0),A0	; Now we have process
		not.l		pr_CLI(A0)		; All MY programs will now think they were started from the CLI
		lea		TC_MEMENTRY(A0),A0
		move.l		A2,A1
		CallLib		AddTail			; AddTail(&Process->pr_Task.tc_MemEntry,&MemList->ml_Node);
		lea		Start-4(PC),A1
		clr.l		(A1)			; Split the segments
		bra.S		5$
4$		move.l		A2,A1			; CreateProc failed. Can't do anything then
		move.l		D7,D0
		CallLib		FreeMem
5$		move.l		D5,A1
		CallLib		CloseLibrary
6$		CallLib		Permit
		unlk		A4
		moveq		#0,D0
		rts
DName		dc.b		'dos.library',0
ProcessName	dc.b		\1,0			; CreateProc makes a copy of this name
		SECTION		ProcessCode,CODE
ProcessStart
		ENDM

DB		EQUR		A4

InitProcess	Detach		<'SetPWkeys Process'>,4000,0
		rAlloc					; Allocate memory for variables
		rClear					; Clear the memory
		Prepare		Exec_Call
		suba.l		A1,A1
		CallLib		FindTask		; Find us
		move.l		D0,PProcess(DB)
		movea.l		D0,A2
		tst.l		pr_CLI(A2)
		bne.S		GetLibs
WBenchStartup	lea		pr_MsgPort(A2),A0
		CallLib		WaitPort		; wait for a message
		lea		pr_MsgPort(A2),A0
		CallLib		GetMsg			; then get it
		move.l		D0,WBenchMsg(DB)	; save it for later reply
GetLibs		lea		DosName(PC),A1
		CallLib		OldOpenLibrary
		move.l		D0,DosBase(DB)
		beq		Error
		lea		GfxName(PC),A1
		CallLib		OldOpenLibrary
		move.l		D0,GraphBase(DB)
		beq.S		Error
		lea		IntName(PC),A1
		CallLib		OldOpenLibrary
		move.l		D0,IntBase(DB)
		beq.S		Error
		Prepare		Intuition_Call
		lea		NewS(PC),A0
	IFD POPSCREEN
		move.l		GraphBase(DB),A1
		move.w		gb_NormalDisplayRows(A1),ns_TopEdge(A0)
		ori.w		#SCREENBEHIND,ns_Type(A0)
	ENDC
		CallLib		OpenScreen
		move.l		D0,DScreen(DB)
		beq.S		Error
		moveq		#sc_ViewPort,D1
		add.l		D0,D1
		move.l		D1,ScrVp(DB)
		moveq		#sc_RastPort,D1
		add.l		D0,D1
		move.l		D1,Rp(DB)

	IFD CUSTOMCOLORS
		Prepare		Gfx_Call
		move.l		ScrVp(DB),A0
		lea		ColorTable(PC),A1
		moveq		#2,D0
		CallLib		LoadRGB4
	ENDC
		Prepare		Intuition_Call
		lea		NewW(PC),A0
		move.l		DScreen(DB),nw_Screen(A0)
		CallLib		OpenWindow
		move.l		D0,DWindow(DB)
		movea.l		D0,A0
		beq.S		Error
		move.l		wd_UserPort(A0),Up(DB)
		Call		SetAPen1
		bra.S		Main

Exit
Error
FreeWindow	Prepare		Intuition_Call
		move.l		DWindow(DB),D0
		beq.S		FreeScreen
	IFD POPSCREEN
		Call		PushScreen
	ENDC
		move.l		DWindow(DB),A0
		CallLib		CloseWindow
FreeScreen	move.l		DScreen(DB),D0
		beq.S		FreeIntuition
		movea.l		D0,A0
		CallLib		CloseScreen
FreeIntuition	Prepare		Exec_Call
		move.l		IntBase(DB),D0
		beq.S		FreeGraphics
		movea.l		D0,A1
		CallLib		CloseLibrary
FreeGraphics	move.l		GraphBase(DB),D0
		beq.S		FreeDos
		movea.l		D0,A1
		CallLib		CloseLibrary
FreeDos		move.l		DosBase(DB),D0
		beq.S		ReplyWB
		movea.l		D0,A1
		CallLib		CloseLibrary
ReplyWB		move.l		WBenchMsg(DB),D2
		beq.S		AllDone
		CallLib		Forbid
		movea.l		D2,A1
		CallLib		ReplyMsg		; Reply WBenchMessage if we are started from WB
AllDone		rFree
		moveq		#0,D0
		rts

Main		Prepare		Intuition_Call

		move.w		#FFx1+74,D0
		moveq		#FFy1+13,D1
		move.l		Rp(DB),A0
		lea		UArrowImage(PC),A1
		CallLib		DrawImage

		moveq		#FFx1,D0
		moveq		#FFy1,D1
		move.l		Rp(DB),A0
		lea		WFuncBorder(PC),A1
		CallLib		DrawBorder
		move.w		#FFx2,D0
		moveq		#FFy2,D1
		move.l		Rp(DB),A0
		lea		SFuncBorder(PC),A1
		CallLib		DrawBorder
		move.w		#FFx3,D0
		moveq		#FFy3,D1
		move.l		Rp(DB),A0
		lea		MFuncBorder(PC),A1
		CallLib		DrawBorder

		moveq		#0,D0
		moveq		#KY-5,D1
		move.l		Rp(DB),A0
		lea		KeybBorder(PC),A1
		CallLib		DrawBorder
		moveq		#TITLE,D0
		Call		WriteMsg
		Call		WriteTexts
		Call		DrawKeys
		Call		SetAPen0
		lea		ReturnKey2(PC),A2
		move.w		Box_x(A2),D2
		add.w		Box_Width(A2),D2
		move.w		Box_y(A2),D3
		move.w		D2,D0
		move.w		D3,D1
		move.l		Rp(DB),A1
		CallLib		Move
		move.w		D2,D0
		move.w		D3,D1
		subq.w		#1,D1
		add.w		Box_Height(A2),D1
		move.l		Rp(DB),A1
		CallLib		Draw
		subq.w		#1,D2
		move.w		D2,D0
		move.w		D3,D1
		addq.w		#1,D1
		move.l		Rp(DB),A1
		CallLib		Move
		move.w		D2,D0
		move.w		D3,D1
		add.w		Box_Height(A2),D1
		subq.w		#1,D1
		move.l		Rp(DB),A1
		CallLib		Draw
		Call		SetAPen1

		Call		DoImport
		cmp.w		#IMPORTOK,D0		; Did we find handler ?
		beq.S		1$

		Call		ClearFunctions		; No we didn't !
		Call		ClearKeyboard
		Call		SetStrings
		lea		Funcs(PC),A0
		bset		#SELECTEDBOX,Box_Flags(A0)
		move.l		A0,CurFunc(DB)
		Call		FillKeyboard
		Call		FillFunctions
1$
	IFD POPSCREEN
		Call		PopScreen		; Bring screen up
	ENDC
EventLoop	tst.w		Quit(DB)
		bne		Exit
		movea.l		Up(DB),A0
		Prepare		Exec_Call
		CallLib		WaitPort
GetNextMsg	Call		GetAMessage
		beq.S		EventLoop
		move.l		Class(DB),D0
		cmpi.w		#GADGETUP,D0
		beq.S		DoGadget
		cmpi.w		#GADGETDOWN,D0
		beq.S		DoGadget
		cmpi.w		#MOUSEBUTTONS,D0
		beq		DoMouse
		bra.S		GetNextMsg

	IFD POPSCREEN
MOVESTEP	=10
PopScreen	Prepare		Intuition_Call
		move.l		DScreen(DB),A0
		CallLib		ScreenToFront
		moveq		#-MOVESTEP,D2
		move.l		DScreen(DB),A0
		move.w		sc_TopEdge(A0),D1
		Call		PScreen
		rts

PushScreen	moveq		#MOVESTEP,D2
		move.l		GraphBase(DB),A0
		move.w		gb_NormalDisplayRows(A0),D1
		move.l		DScreen(DB),A0
		sub.w		sc_TopEdge(A0),D1
		Prepare		Intuition_Call
		Call		PScreen
		move.l		DScreen(DB),A0
		CallLib		ScreenToBack
		rts

* Call: D1 = y-coordinates to move screen
*       D2 = delta-y
PScreen		ext.l		D1
		move.w		D1,D3
		divu		#MOVESTEP,D1
		swap		D1
		sub.w		D1,D3
		tst.w		D2
		bpl.S		1$
		neg.w		D1
1$		tst.w		D1
		beq.S		4$
		bra.S		3$
2$		move.w		D2,D1
3$		moveq		#0,D0
		move.l		DScreen(DB),A0
		CallLib		MoveScreen
4$		sub.w		#MOVESTEP,D3
		bge.S		2$
		rts
	ENDC

* A gadget was selected
DoGadget
GJ		movea.l		IAddress(DB),A1
		move.w		gg_GadgetID(A1),D0	; GadgetID is offset from GJ
		jsr		GJ(PC,D0.W)
		bra		GetNextMsg


* User clicked the 'Check' gadget
DoCheck		move.l		CurFunc(DB),A0
		Call		KeysToFunc
		Call		SortKeys
		moveq		#DUPLICATES,D7
		Call		FindDuplicates
		bge.S		1$
		Call		GetStrings
		move.l		D0,D7
		bmi.S		1$
		moveq		#NOERRORS,D7
1$		move.l		D7,D0
		Call		WriteMsg
DoGadgets	rts

DoQuit		not.w		Quit(DB)
		rts

* User clicked the 'Import' gadget
* Returns error-code in D0 !!!
DoImport	Prepare		Exec_Call
		CallLib		Forbid
		lea		PWkeysPortName(PC),A1
		CallLib		FindPort
		move.l		D0,D2
		CallLib		Permit
		moveq		#NOHANDLER,D7
		tst.l		D2
		beq.S		1$
		move.l		D0,A0			; Handler was installed
		move.l		ihs_Interrupt+IS_DATA(A0),A0
		lea		TBuf(DB),A1
		move.w		#pw_SIZE,D0		; Copy keydefinition from the
		Call		MemCopy			; handlers memory
		clr.l		pw_MWaitTime(A1)
		clr.l		pw_SWaitTime(A1)
		Call		ClearFunctions
		Call		ClearKeyboard
		Call		UnsortKeys
		Call		InitFuncs
		Call		SetStrings
		lea		Funcs(PC),A0
		bset		#SELECTEDBOX,Box_Flags(A0)
		move.l		A0,CurFunc(DB)
		Call		FillKeyboard
		Call		FillFunctions
		moveq		#IMPORTOK,D7
1$		move.l		D7,D0
		Call		WriteMsg
		rts

* User clicked the 'Export' gadget
DoExport	move.l		CurFunc(DB),A0
		Call		KeysToFunc
		Call		SortKeys
		moveq		#DUPLICATES,D7
		Call		FindDuplicates
		bge.S		2$
		Call		MakeMasks
		Call		CountKeys
		Call		GetStrings
		move.l		D0,D7
		bmi.S		2$
		Prepare		Exec_Call
		CallLib		Forbid
		lea		PWkeysPortName(PC),A1
		CallLib		FindPort
		move.l		D0,D2
		CallLib		Permit
		moveq		#NOHANDLER,D7
		tst.l		D2
		beq.S		2$
		move.l		D2,A2
		move.l		A2,A0
		moveq		#IND_REMHANDLER,D0
		moveq		#CANTREMOVE,D7
		Call		TellInputDevice
		bne.S		2$
		lea		TBuf(DB),A0
		move.b		pw_Pri(A0),ihs_Interrupt+LN_PRI(A2)	; HandlerBlock.HInterrupt.is_Node.ln_Pri = PRI;
		move.l		ihs_Interrupt+IS_DATA(A2),A1
		move.w		#pw_SIZE,D0		; Copy keydefinition into the
		Call		MemCopy			; PWkeys-handler memory
		move.l		A2,A0
		moveq		#IND_ADDHANDLER,D0
		moveq		#EXPORTOK,D7
		Call		TellInputDevice
		beq.S		2$
		Prepare		Exec_Call
		move.l		ihs_MemEntry(A2),A0
		CallLib		FreeEntry
		moveq		#CANTINSTALL,D7
2$		move.l		D7,D0
		Call		WriteMsg
		rts

* User clicked the 'Undo' gadget
DoUndo		Call		ClearKeyboard
		move.l		CurFunc(DB),A0
		Call		FillKeyboard
		rts

* User clicked the 'Clear' gadget
DoClear		Call		ClearKeyboard
		rts

* User clicked the 'Save' gadget
DoSave		move.l		CurFunc(DB),A0
		Call		KeysToFunc
		Call		SortKeys
		moveq		#DUPLICATES,D7
		Call		FindDuplicates
		bge.S		2$
		Call		MakeMasks
		Call		CountKeys
		Call		GetStrings
		move.l		D0,D7
		bmi.S		2$
		Prepare		Dos_Call
		lea		FBuffer(PC),A0
		move.l		A0,D1
		move.l		#MODE_NEWFILE,D2
		moveq		#NOFILE,D7
		CallLib		Open
		move.l		D0,FHandle(DB)
		beq.S		1$
		move.l		D0,D1
		lea		TBuf(DB),A0
		move.l		A0,D2
		move.l		#pw_SIZE,D3
		moveq		#WRITEERROR,D7
		CallLib		Write
		cmp.l		D0,D3
		bne.S		1$
		moveq		#GOODWRITE,D7
1$		move.l		FHandle(DB),D1
		beq.S		2$
		CallLib		Close
2$		move.l		D7,D0
		Call		WriteMsg
		rts

* User clicked the 'Load' gadget
DoLoad		Prepare		Dos_Call
		lea		FBuffer(PC),A0
		move.l		A0,D1
		move.l		#MODE_OLDFILE,D2
		moveq		#NOFILE,D7
		CallLib		Open
		move.l		D0,FHandle(DB)
		beq.S		1$
		move.l		D0,D1
		lea		TBuf(DB),A0
		move.l		A0,D2
		move.l		#pw_SIZE,D3
		moveq		#READERROR,D7
		CallLib		Read
		cmp.l		D0,D3
		bne.S		1$
		lea		TBuf(DB),A0
		movem.l		(A0),D0-D1
		movem.l		PWkVersionID(PC),D2-D3
		cmp.l		D0,D2
		bne.S		1$
		cmp.l		D1,D3
		bne.S		1$
		Call		ClearFunctions
		Call		ClearKeyboard
		Call		UnsortKeys
		Call		InitFuncs
		Call		SetStrings
		lea		Funcs(PC),A0
		bset		#SELECTEDBOX,Box_Flags(A0)
		move.l		A0,CurFunc(DB)
		Call		FillKeyboard
		Call		FillFunctions
		moveq		#GOODREAD,D7
1$		move.l		FHandle(DB),D1
		beq.S		2$
		CallLib		Close
2$		move.l		D7,D0
		Call		WriteMsg
		rts

* The user pressed/released a mousebutton
DoMouse		cmpi.w		#SELECTDOWN,Code(DB)
		bne		DoM
		move.w		Qual(DB),D0
		andi.w		#SHIFT,D0
		beq.S		DoLB
* Perhaps the user clicked on a qualifier-key with RMB
DoRB		cmp.w		#KY-SWDIFF,MouseY(DB)
		blt		DoSelFunc
		Call		WhichKey
		bmi		DoM
		tst.w		KeyBox_Qual(A0)		; Is it a qual-key ?
		beq		DoM
		btst		#SELECTEDBOX,Box_Flags(A0)
		beq.S		1$
		btst		#GHOSTEDBOX,Box_Flags(A0)
		bne.S		1$
		Call		RawInvert		; Key was raw
		move.l		#-1,CurCode(DB)
1$		Call		QualInvert
		bra		DoM
* Perhaps the user clicked on a key with LMB
DoLB		cmp.w		#KY-SWDIFF,MouseY(DB)
		blt.S		DoSelFunc
		Call		WhichKey
		bmi		DoM
		move.l		CurCode(DB),D0
		move.l		A0,CurCode(DB)
		tst.l		D0
		bmi.S		5$
		lea		ReturnKey1(PC),A1	; Treat the two
		lea		ReturnKey2(PC),A2	; parts of the
		cmp.l		A1,A0			; RETURN-key as
		beq.S		1$			; if they were
		cmp.l		A2,A0			; one
		bne.S		3$
1$		cmp.l		A1,D0
		beq.S		2$
		cmp.l		A2,D0
		bne.S		3$
2$		move.l		A0,D0

3$		cmp.l		A0,D0
		beq.S		4$
		move.l		D0,A0			; Changed key
		Call		RawInvert
		move.l		CurCode(DB),A0
		bra.S		5$
4$		move.l		#-1,CurCode(DB)		; Unselected a key
5$		btst		#SELECTEDBOX,Box_Flags(A0)
		beq.S		6$
		btst		#GHOSTEDBOX,Box_Flags(A0)
		beq.S		6$
		Call		QualInvert		; Key was qual
6$		Call		RawInvert
		bra.S		DoM
* Perhaps the user clicked on a function
DoSelFunc	Call		WhichFunc
		bmi.S		DoM
		move.l		CurFunc(DB),A1
		cmp.l		A0,A1			; If the function is already selected
		beq.S		1$			; then this is click is a 'UNDO' click
		move.l		A0,CurFunc(DB)
		move.l		A1,A0
		Call		KeysToFunc		; Save the selected keys
		btst		#GHOSTEDBOX,Box_Flags(A0)
		beq.S		3$
		Call		RawInvert
		Call		QualInvert
		bset		#GHOSTEDBOX,Box_Flags(A0)
		bra.S		4$
3$		Call		RawInvert		; Unselect function
4$		move.l		CurFunc(DB),A0
		btst		#GHOSTEDBOX,Box_Flags(A0)
		beq.S		2$
		Call		QualInvert
2$		Call		RawInvert		; Select function
1$		Call		ClearKeyboard
		move.l		CurFunc(DB),A0
		Call		FillKeyboard
DoM		bra		GetNextMsg

* THE INVERT FUNCTONS ONLY PRESERVES A0
* Complements a key with a pattern
* Call: A0 = box
QualInvert	Push		A0
		bchg		#GHOSTEDBOX,Box_Flags(A0)
		movea.l		Rp(DB),A1
		move.l		#Mask,rp_AreaPtrn(A1)
		move.b		#2,rp_AreaPtSz(A1)
		bra.S		RI2
* Complements a key
* Call: A0 = box
RawInvert	cmp.l		#ReturnKey1,A0
		beq.S		1$
		cmp.l		#ReturnKey2,A0
		bne.S		RI
1$		Push		A0
		lea		ReturnKey1(PC),A0
		Call		RI
		lea		ReturnKey2(PC),A0
		Call		RI
		Pop		A0
		rts
RI		Push		A0
RI2		bchg		#SELECTEDBOX,Box_Flags(A0)
		move.l		A0,A2
		Prepare		Gfx_Call
		Call		SetDrMd2
		move.w		Box_x(A2),D0
		move.w		Box_y(A2),D1
		move.w		D0,D2
		move.w		D1,D3
		addq.w		#1,D0
		addq.w		#1,D1
		add.w		Box_Width(A2),D2
		add.w		Box_Height(A2),D3
		subq.w		#1,D2
		subq.w		#1,D3
		movea.l		Rp(DB),A1
		CallLib		RectFill
		Call		SetDrMd1
		movea.l		Rp(DB),A1
		clr.l		rp_AreaPtrn(A1)
		clr.b		rp_AreaPtSz(A1)
		Pop		A0
		rts

* Finds the selected function box (if any)
* Return: If D0=-1 then couldn't find anything, else A0=FuncBox
WhichFunc	lea		Funcs(PC),A0
		bra.S		WFK
* Finds the selected key (if any)
* Return: If D0=-1 then couldn't find anything, else A0=KeyBox
WhichKey	lea		Keys(PC),A0
WFK		move.w		MouseX(DB),D6
		move.w		MouseY(DB),D7
		add.w		#SWDIFF,D7
1$		move.w		Box_y(A0),D1
		bmi.S		3$
		cmp.w		D1,D7
		blt.S		2$
		add.w		Box_Height(A0),D1
		cmp.w		D1,D7
		bgt.S		2$
		move.w		Box_x(A0),D0
		cmp.w		D0,D6
		blt.S		2$
		add.w		Box_Width(A0),D0
		cmp.w		D0,D6
		bgt.S		2$
		moveq		#0,D0
		bra.S		4$
2$		add.l		#FKeyBox_SIZE,A0
		bra.S		1$
3$		moveq		#-1,D0
4$		rts

* Draw all the keys
DrawKeys	lea		Keys(PC),A2
DL		Prepare		Gfx_Call
1$		move.w		Box_x(A2),D0
		bmi		3$
		move.w		Box_y(A2),D1
		move.l		Rp(DB),A1
		CallLib		Move
		move.w		Box_x(A2),D0
		move.w		Box_y(A2),D1
		add.w		Box_Width(A2),D0
		move.l		Rp(DB),A1
		CallLib		Draw
		move.w		Box_x(A2),D0
		move.w		Box_y(A2),D1
		add.w		Box_Width(A2),D0
		add.w		Box_Height(A2),D1
		move.l		Rp(DB),A1
		CallLib		Draw
		move.w		Box_x(A2),D0
		move.w		Box_y(A2),D1
		add.w		Box_Height(A2),D1
		move.l		Rp(DB),A1
		CallLib		Draw
		move.w		Box_x(A2),D0
		move.w		Box_y(A2),D1
		move.l		Rp(DB),A1
		CallLib		Draw
		lea		StrBuf(PC),A0
		move.b		KeyBox_Char(A2),(A0)
		beq.S		2$
		move.w		Box_x(A2),D0
		addq.w		#7,D0
		move.w		Box_y(A2),D1
		addq.w		#8,D1
		move.l		Rp(DB),A1
		CallLib		Move
		lea		StrBuf(PC),A0
		moveq		#1,D0
		move.l		Rp(DB),A1
		CallLib		Text
2$		add.l		#FKeyBox_SIZE,A2
		bra		1$
3$		rts

* Call: A0 = FuncBox
FillFunctions	Call		KeysToFunc
		Push		A2
		lea		Funcs(PC),A2
		bclr		#GHOSTEDBOX,Box_Flags(A2)	;Just loaded new file, first item needs to be selected
		Pop		A2
* hilites/unhilites all functions with the 'SELECTEDBOX/GHOSTEDBOX' flag set
RefreshFunc	Push		D0-D3/A0-A2/A6
		lea		Funcs(PC),A2
		bra.S		RFK
* Call: A0 = FuncBox
FillKeyboard	Call		FuncToKeys
* hilites/unhilites all keys with the 'SELECTEDBOX'/'GHOSTEDBOX' flag set
RefreshKeys	Push		D0-D3/A0-A2/A6
		lea		Keys(PC),A2
RFK
1$		move.w		Box_x(A2),D0
		bmi.S		5$
		btst		#SELECTEDBOX,Box_Flags(A2)
		beq.S		4$
		move.l		A2,A0
		btst		#GHOSTEDBOX,Box_Flags(A2)
		beq.S		2$
		Call		QualInvert
		bset		#GHOSTEDBOX,Box_Flags(A2)
		bra.S		3$
2$		Call		RawInvert
3$		bset		#SELECTEDBOX,Box_Flags(A2)
4$		add.l		#FKeyBox_SIZE,A2
		bra.S		1$
5$		Pop		D0-D3/A0-A2/A6
		rts

* Clears all hilite-flags in the 'Funcs' array
ClearFunctions	move.l		CurFunc(DB),A0		; This is because the selected
		bclr		#GHOSTEDBOX,Box_Flags(A0); can be both selected and ghosted
		Call		RefreshFunc
		Push		A2
		lea		Funcs(PC),A2
		bra.S		CFK
* Clears all hilite-flags in the 'Keys' array
ClearKeyboard	Call		RefreshKeys
		move.l		#-1,CurCode(DB)
		Push		A2
		lea		Keys(PC),A2
CFK	* Clears all hilite-flags in the 'Keys/Funcs' array
1$		tst.w		Box_x(A2)
		bmi.S		2$
		bclr		#SELECTEDBOX,Box_Flags(A2)
		bclr		#GHOSTEDBOX,Box_Flags(A2)
		add.l		#FKeyBox_SIZE,A2
		bra.S		1$
2$		Pop		A2
		rts

* Call: A0 = FuncBox
* Collects all hilite-flags in the 'Keys' array
KeysToFunc	Push		D0-D2/A0-A2
		move.l		FuncBox_HotKey(A0),A1
		move.w		#U_CODE,D1
		moveq		#0,D2
		lea		Keys(PC),A2
1$		move.w		Box_x(A2),D0
		bmi.S		4$
		btst		#SELECTEDBOX,Box_Flags(A2)
		beq.S		3$
		btst		#GHOSTEDBOX,Box_Flags(A2)
		bne.S		2$
		move.w		KeyBox_Code(A2),D1
		bra.S		3$
2$		or.w		KeyBox_Qual(A2),D2
3$		add.l		#FKeyBox_SIZE,A2
		bra.S		1$
4$		cmp.w		#U_CODE,D1
		bne.S		5$
		bset		#GHOSTEDBOX,Box_Flags(A0)	; If no code then function has to be ghosted
		moveq		#U_QUAL,D2			; If no code then no qualifier
5$		move.w		D1,HotKey_Code(A1)
		move.w		D2,HotKey_Qual(A1)
		Pop		D0-D2/A0-A2
		rts

* Call: A0 = FuncBox
* Set all hilite-flags in the 'Keys' array
FuncToKeys	Push		D0/A0/A2
		move.l		FuncBox_HotKey(A0),A0
		lea		Keys(PC),A2
1$		move.w		Box_x(A2),D0
		bmi.S		4$
		move.w		KeyBox_Code(A2),D0
		cmp.w		HotKey_Code(A0),D0
		bne.S		2$
		move.l		A2,CurCode(DB)
		bset		#SELECTEDBOX,Box_Flags(A2)
		bra.S		3$
2$		move.w		KeyBox_Qual(A2),D0
		and.w		HotKey_Qual(A0),D0
		beq.S		3$
		bset		#SELECTEDBOX,Box_Flags(A2)
		bset		#GHOSTEDBOX,Box_Flags(A2)
3$		add.l		#FKeyBox_SIZE,A2
		bra.S		1$
4$		Pop		D0/A0/A2
		rts

* Makes some masks
MakeMasks	Push		D0-D4/A0-A2
		lea		TBuf+pw_KeyDefs(DB),A2
		moveq		#0,D0
		moveq		#-2,D2			; Code
ml		cmp.w		#KeyFuncNumber,D0
		bge.S		5$
		moveq		#0,D1			; Number
		moveq		#0,D3			; Qual
1$		move.l		D0,D4			; 'OR' qualifiers for all hotkeys with this code
		add.w		D1,D4
		cmp.w		#KeyFuncNumber,D4
		bge.S		2$
		mulu		#HotKey_SIZE,D4
		lea		0(A2,D4),A0
		cmp.w		HotKey_Code(A0),D2
		bne.S		2$
		addq.l		#1,D1
		or.w		HotKey_Qual(A0),D3
		bra.S		1$
2$		tst.w		D3
		bne.S		4$
		move.w		#KEYMASK,D3
		bra.S		4$
3$		move.l		D0,D4			;Store the 'OR'ed qualifiers in all hotkeys with this code
		mulu		#HotKey_SIZE,D4
		lea		0(A2,D4),A1
		move.w		D3,HotKey_QMask(A1)
		addq.l		#1,D0
4$		dbf		D1,3$
		move.w		HotKey_Code(A0),D2
		bra.S		ml
5$		Pop		D0-D4/A0-A2
		rts

InitFuncs	Push		D0/A0-A2
		lea		Funcs(PC),A2
1$		move.w		Box_x(A2),D0
		bmi.S		2$
		move.l		FuncBox_HotKey(A2),A0
		bclr		#SELECTEDBOX,Box_Flags(A2)
		bclr		#GHOSTEDBOX,Box_Flags(A2)
		cmp.w		#U_CODE,HotKey_Code(A0)
		bne.S		3$
		bset		#SELECTEDBOX,Box_Flags(A2)
		bset		#GHOSTEDBOX,Box_Flags(A2)
3$		add.l		#FKeyBox_SIZE,A2
		bra.S		1$
2$		Pop		D0/A0-A2
		rts

* Finds first pair of duplicates (HotKeys must be sorted)
* Return: D0 != -1 means D0 and D1 are the same (and not undefined)
FindDuplicates	Push		A2
		lea		TBuf+pw_KeyDefs+HotKey_SIZE(DB),A2
		moveq		#KeyFuncNumber,D0
		bra.S		3$
1$		move.l		-HotKey_SIZE+HotKey_ID(A2),D1
		cmp.l		HotKey_ID(A2),D1
		bne.S		2$
		cmp.l		#(U_CODE<<16)|U_QUAL,D1
		bne.S		4$
2$		addq.l		#HotKey_SIZE,A2
3$		dbf		D0,1$	
		moveq		#-1,D0
		bra.S		5$
4$		moveq		#0,D0
		moveq		#0,D1
		move.b		HotKey_Func(A2),D0
		move.b		-HotKey_SIZE+HotKey_Func(A2),D1
5$		Pop		A2
		tst.l		D0
		rts

* Counts the number of defined hotkeys (HotKeys must be sorted)
* Return: D0 = count
CountKeys	Push		D0-D2/A2
		lea		TBuf+pw_KeyDefs(DB),A2
		moveq		#0,D0
		moveq		#KeyFuncNumber,D1
		bra.S		2$
1$		move.w		HotKey_Code(A2),D2
		cmp.w		#U_CODE,D2
		beq.S		3$
		addq.l		#1,D0
		addq.l		#HotKey_SIZE,A2
2$		dbf		D1,1$
3$		move.w		D0,TBuf+pw_KeyNum(DB)
		Pop		D0-D2/A2
		rts

SetStrings	Push		D0-D2/A0-A2/A6
		moveq		#0,D0
		move.b		PWkPri(PC),D0
		lea		PBuffer(PC),A0
		Call		BinToStr
		moveq		#0,D0
		move.b		PWkMouseAccel(PC),D0
		lea		SBuffer(PC),A0
		Call		BinToStr
		moveq		#0,D0
		move.b		PWkMouseThresh(PC),D0
		lea		TBuffer(PC),A0
		Call		BinToStr
		moveq		#0,D0
		move.l		PWkMTimeout(PC),D0
		lea		MouseBuffer(PC),A0
		Call		BinToStr
		moveq		#0,D0
		move.l		PWkSTimeout(PC),D0
		lea		ScreenBuffer(PC),A0
		Call		BinToStr
		moveq		#5,D0
		lea		Gad10(PC),A0
		movea.l		DWindow(DB),A1
		suba.l		A2,A2
		Prepare		Intuition_Call
		CallLib		RefreshGList
		Pop		D0-D2/A0-A2/A6
		rts

GetStrings	Push		D1-D2/A0-A2/A6
		moveq		#WRONGPRI,D2
		lea		PBuffer(PC),A0
		Call		StrToBin
		cmp.w		#127,D0
		bgt.S		1$
		move.b		D0,TBuf+pw_Pri(DB)
		lea		SBuffer(PC),A0
		Call		StrToBin
		move.b		D0,TBuf+pw_Accel(DB)
		lea		TBuffer(PC),A0
		Call		StrToBin
		move.b		D0,TBuf+pw_Thresh(DB)
		lea		MouseBuffer(PC),A0
		Call		StrToBin
		move.l		D0,TBuf+pw_MTimeout(DB)
		lea		ScreenBuffer(PC),A0
		Call		StrToBin
		move.l		D0,TBuf+pw_STimeout(DB)
		moveq		#0,D2
1$		move.l		D2,D0
		Pop		D1-D2/A0-A2/A6
		tst.w		D0
		rts

BinToStr	Push		D0-D5/A0
		tst.l		D0
		beq.S		7$
		moveq		#4*4,D1
		moveq		#'0',D2
		moveq		#0,D4
1$		move.w		D2,D3
		move.l		9$(PC,D1.l),D5
2$		cmp.l		D5,D0
		blt.S		3$
		addq.w		#1,D3
		sub.l		D5,D0
		bra.S		2$
3$		cmp.b		D2,D3
		bne.S		4$
		tst.w		D4
		beq.S		6$
4$		moveq		#1,D4
5$		move.b		D3,(A0)+
6$		subq.w		#4,D1
		bge.S		1$
		bra.S		8$
7$		move.b		#'0',(A0)+
8$		clr.b		(A0)+
		Pop		D0-D5/A0
		rts
9$		dc.l		1,10,100,1000,10000


StrToBin	Push		D1/A0
		moveq		#0,D0
1$		move.b		(A0)+,D1
		beq.S		2$
		sub.w		#'0',D1
		mulu		#10,D0
		add.w		D1,D0
		bra.S		1$
2$		Pop		D1/A0
		rts

* Sorts HotKeys on 'Code|Qual'
SortKeys	Push		D0-D7/A0-A6
		lea		TBuf(DB),A1
		lea		PWkVersionID(PC),A0
		move.w		#pw_SIZE,D0
		Call		MemCopy
		moveq		#0,D6
		lea		TBuf+pw_KeyDefs(DB),A2
OuterLoop	moveq		#KeyFuncNumber,D5
		bra.S		ContSort
InnerLoop	moveq		#KeyFuncNumber,D0
		sub.w		D5,D0
		mulu		#HotKey_SIZE,D0
		lea		-HotKey_SIZE(A2,D0.L),A0
		lea		HotKey_SIZE(A0),A1
		move.l		HotKey_ID(A0),D0
		move.l		HotKey_ID(A1),D1
		cmp.l		D0,D1
		bge.S		ContSort
		move.l		D1,HotKey_ID(A0)
		move.l		D0,HotKey_ID(A1)
		move.l		HotKey_Mask(A0),D0
		move.l		HotKey_Mask(A1),HotKey_Mask(A0)
		move.l		D0,HotKey_Mask(A1)
ContSort	subq.w		#1,D5
		cmp.w		D5,D6
		blt.S		InnerLoop
		addq.w		#1,D6
		cmp.w		#KeyFuncNumber-1,D6
		blt.S		OuterLoop
		Pop		D0-D7/A0-A6
		rts

* Unsorts HotKeys on to 'Func'
UnsortKeys	Push		D0-D7/A0-A6
		lea		TBuf(DB),A0
		lea		PWkVersionID(PC),A1
		move.w		#pw_SIZE,D0
		Call		MemCopy
		lea		TBuf+pw_KeyDefs(DB),A2
		moveq		#KeyFuncNumber,D0
		bra.S		2$
1$		moveq		#0,D1
		move.b		HotKey_Func(A2),D1
		mulu		#HotKey_SIZE,D1
		lea		KeyDefines(PC),A1
		add.l		D1,A1
		move.l		HotKey_ID(A2),HotKey_ID(A1)
		move.l		HotKey_Mask(A2),HotKey_Mask(A1)
		addq.l		#HotKey_SIZE,A2
2$		dbf		D0,1$
		Pop		D0-D7/A0-A6
		rts

rtsValue	EQUR		D7
* Open the input device. Set up the I/O block to add or remove the
* input handler, and send the request to the input device. Finally,
* close the device
* Call:   A0 = ihs
*	  D0 = Function to perform (IND_ADDHANDLER/IND_REMHANDLER)
* Return: D0 = 0 means succes
TellInputDevice	Push		D1-D2/rtsValue/A0-A3/A6
		Prepare		Exec_Call
		moveq		#-1,rtsValue
		move.l		D0,D2
		move.l		A0,A2
		lea		IReq(DB),A0
		moveq		#IOSTD_SIZE,D0
		Call		MemClear
		lea		IPort(DB),A0
		moveq		#MP_SIZE,D0
		Call		MemClear
		move.l		A0,A3
		move.b		#NT_MSGPORT,MP+LN_TYPE(A3)	; mp_Node.ln_Type=NT_MSGPORT;
		move.b		#PA_SIGNAL,MP_FLAGS(A3)		; mp_Flags	=PA_SIGNAL;
		moveq		#-1,D0
		CallLib		AllocSignal
		move.b		D0,MP_SIGBIT(A3)		; mp_SigBit	=MPSigBit;
		bmi.S		2$
		suba.l		A1,A1
		CallLib		FindTask
		move.l		D0,MP_SIGTASK(A3)		; mp_SigTask 	=FindTask(0);
		lea		MP_MSGLIST(A3),A0
		NEWLIST		A0
		lea		IReq(DB),A1
		move.l		A3,IO+MN_REPLYPORT(A1)		; ExtReq->io_Message.mn_ReplyPort   =taskReplyPort;
		move.b		#NT_MESSAGE,IO+MN+LN_TYPE(A1)	; ExtReq->io_Message.mn_Node.ln_Type=NT_MESSAGE;
		lea		InputName(PC),A0		; input.device
		moveq		#0,D0				; unit#
		moveq		#0,D1				; flags
		CallLib		OpenDevice
		tst.w		D0				; flag: error if > 0
		bne.S		1$
		lea		IReq(DB),A1
		move.w		D2,IO_COMMAND(A1)
		lea		ihs_Interrupt(A2),A0
		move.l		A0,IO_DATA(A1)
		CallLib		DoIO
		move.l		D0,rtsValue
		lea		IReq(DB),A1
		CallLib		CloseDevice
1$		move.b		MP_SIGBIT(A3),D0
		CallLib		FreeSignal
2$		move.l		rtsValue,D0
		Pop		D1-D2/rtsValue/A0-A3/A6
		rts

* Writes the text in the function boxes
WriteTexts	Push		D0-D1
		moveq		#FUNCTEXTS+GADTEXTS,D1
		bra.S		2$
1$		move.w		D1,D0
		Call		WriteTxt
2$		dbf		D1,1$
		Pop		D0-D1
		rts

* Call: D0 = Msg-number
WriteMsg	Push		D0-D4/A0-A2/A6
		neg.w		D0
		add.w		#FUNCTEXTS+GADTEXTS,D0
		lea		TextTab(PC),A1
		move.l		A1,A2
		mulu		#TE_SIZE,D0
		add.l		D0,A2
		add.w		TE_Offset(A2),A1
		move.l		A1,A2
		move.l		DWindow(DB),A0
		Prepare		Intuition_Call
		CallLib		SetWindowTitles
		Pop		D0-D4/A0-A2/A6
		rts

* Call: D0 = Msg-number
WriteTxt	Push		D0-D1/A0-A3/A6
		Prepare		Gfx_Call
		lea		TextTab(PC),A2
		move.l		A2,A3
		mulu		#TE_SIZE,D0
		add.l		D0,A2
		move.w		TE_x(A2),D0
		move.w		TE_y(A2),D1
		movea.l		Rp(DB),A1
		CallLib		Move
		move.w		TE_Offset(A2),A0
		add.l		A3,A0
		Call		StrLen
		movea.l		Rp(DB),A1
		CallLib		Text
		Pop		D0-D1/A0-A3/A6
		rts

* Sets the drawing pen.
* Destroys D0-D1/A0-A1/A6
SetAPen0	moveq		#0,D0
		bra.S		SetPenA
SetAPen1	moveq		#1,D0
SetPenA		movea.l		Rp(DB),A1		; D0=Color
		Prepare		Gfx_Call
		CallLib		SetAPen
		rts

SetDrMd1	moveq		#1,D0
		bra.S		SetMdDr
SetDrMd2	moveq		#2,D0
SetMdDr		movea.l		Rp(DB),A1		; D0=Drawmode
		Prepare		Gfx_Call
		CallLib		SetDrMd
		rts


* Call: A0    = Memory area
*	D0:16 = Count
MemClear	Push		D0-D1/A0
		moveq		#0,D1
		bra.S		2$
1$		move.b		D1,(A0)+
2$		dbf		D0,1$
		Pop		D0-D1/A0
		rts

* Call: A0   = Source
*	A1   = Destination
*	D0:16= Count
MemCopy		Push		D0/A0-A1
		bra.S		2$
1$		move.b		(A0)+,(A1)+
2$		dbf		D0,1$
		Pop		D0/A0-A1
		rts

* Call:   A0 = String
* Return: D0 = length
StrLen		Push		A0
		moveq		#-1,D0
1$		addq.l		#1,D0
		tst.b		(A0)+
		bne.S		1$
		Pop		A0
		rts

* Return: D0 != means that we got a message
GetAMessage	Push		D0-D1/A0-A1/A6
		movea.l		Up(DB),A0
		Prepare		Exec_Call
		CallLib		GetMsg
		tst.l		D0
		beq.S		NoMessage
GotAMessage	movea.l		D0,A1
		move.l		im_Class(A1),Class(DB)
		move.w		im_Code(A1),Code(DB)
		move.w		im_Qualifier(A1),Qual(DB)
		move.l		im_IAddress(A1),IAddress(DB)
		move.w		im_MouseX(A1),MouseX(DB)
		move.w		im_MouseY(A1),MouseY(DB)
		CallLib		ReplyMsg
		moveq		#1,D0
NoMessage	Pop		D0-D1/A0-A1/A6
		rts

*====================== Data-definition start =======================
 rStart
 rWord		Quit
 rAPtr		PProcess
 rAPtr		DosBase
 rAPtr		GraphBase
 rAPtr		IntBase
 rLong		WBenchMsg
 rAPtr		FHandle
 rAPtr		DScreen
 rAPtr		DWindow
 rAPtr		ScrVp			; ViewPort
 rAPtr		Rp			; RastPort
 rAPtr		Up			; UserPort
 rLong		Class			; IDCMP->Class
 rWord		Code			; IDCMP->Code
 rWord		Qual			; IDCMP->Qualifier
 rLong		IAddress		; IDCMP->IAddress
 rWord		MouseX			; IDCMP->MouseX
 rWord		MouseY			; IDCMP->MouseY
 rAPtr		CurFunc			; Ptr to FuncBox
 rAPtr		CurCode			; Ptr to KeyBox
 rStorage	IReq,IOSTD_SIZE
 rStorage	IPort,MP_SIZE
 rStorage	TBuf,pw_SIZE
 rEnd

StrBuf		dc.b		' '
DosName		dc.b		'dos.library',0
GfxName		dc.b		'graphics.library',0
IntName		dc.b		'intuition.library',0
InputName	dc.b		'input.device',0
PWkeysPortName	PWkeys_PortName
		EVEN

ScrW		=640
ScrH		=197
NewS		dc.w		0,0,ScrW,ScrH,PLANES
		dc.b		0,1
		dc.w		V_HIRES,CUSTOMSCREEN
		dc.l		TxtAttr,0,0,0
IDCMP_Flags	=GADGETUP|MOUSEBUTTONS
Other_Flags	=NOCAREREFRESH|ACTIVATE|BORDERLESS
NewW		dc.w		0,SWDIFF,ScrW,ScrH-SWDIFF
		dc.b		0,1
		dc.l		IDCMP_Flags,Other_Flags,GadgetList,0,0,0,0
		dc.w		0,0,0,0,CUSTOMSCREEN
	IFD CUSTOMCOLORS
ColorTable	dc.w		$0AAA,$0000
	ENDC

GadgetList
Gad1		Gadget		Gad2,524,4,BWIDTH,BHEIGHT,GADGHCOMP,RELVERIFY,BOOLGADGET
		Gadget2		BBorder,0,0,0,0,DoCheck-GJ,0
Gad2		Gadget		Gad3,586,4,BWIDTH,BHEIGHT,GADGHCOMP,RELVERIFY,BOOLGADGET
		Gadget2		BBorder,0,0,0,0,DoQuit-GJ,0
Gad3		Gadget		Gad4,524,20,BWIDTH,BHEIGHT,GADGHCOMP,RELVERIFY,BOOLGADGET
		Gadget2		BBorder,0,0,0,0,DoUndo-GJ,0
Gad4		Gadget		Gad5,586,20,BWIDTH,BHEIGHT,GADGHCOMP,RELVERIFY,BOOLGADGET
		Gadget2		BBorder,0,0,0,0,DoClear-GJ,0
Gad5		Gadget		Gad6,524,36,BWIDTH,BHEIGHT,GADGHCOMP,RELVERIFY,BOOLGADGET
		Gadget2		BBorder,0,0,0,0,DoImport-GJ,0
Gad6		Gadget		Gad7,586,36,BWIDTH,BHEIGHT,GADGHCOMP,RELVERIFY,BOOLGADGET
		Gadget2		BBorder,0,0,0,0,DoExport-GJ,0
Gad7		Gadget		Gad8,524,52,BWIDTH,BHEIGHT,GADGHCOMP,RELVERIFY,BOOLGADGET
		Gadget2		BBorder,0,0,0,0,DoSave-GJ,0
Gad8		Gadget		Gad9,586,52,BWIDTH,BHEIGHT,GADGHCOMP,RELVERIFY,BOOLGADGET
		Gadget2		BBorder,0,0,0,0,DoLoad-GJ,0
Gad9		Gadget		Gad10,437,105,FWIDTH,FHEIGHT,GADGHCOMP,RELVERIFY,STRGADGET
		Gadget2		FBorder,0,0,0,FileInfo,DoGadgets-GJ,0
Gad10		Gadget		Gad11,256,89,TIMEW,TIMEH,GADGHCOMP,RELVERIFY|LONGINT,STRGADGET
		Gadget2		TBorder,0,0,0,ScreenInfo,DoGadgets-GJ,0
Gad11		Gadget		Gad12,348,89,TIMEW,TIMEH,GADGHCOMP,RELVERIFY|LONGINT,STRGADGET
		Gadget2		TBorder,0,0,0,MouseInfo,DoGadgets-GJ,0
Gad12		Gadget		Gad13,440,89,PRIW,PRIH,GADGHCOMP,RELVERIFY|LONGINT,STRGADGET
		Gadget2		PBorder,0,0,0,PriInfo,DoGadgets-GJ,0
Gad13		Gadget		Gad14,526,89,SPEEDW,SPEEDH,GADGHCOMP,RELVERIFY|LONGINT,STRGADGET
		Gadget2		SBorder,0,0,0,SpeedInfo,DoGadgets-GJ,0
Gad14		Gadget		0,597,89,SPEEDW,SPEEDH,GADGHCOMP,RELVERIFY|LONGINT,STRGADGET
		Gadget2		SBorder,0,0,0,ThresInfo,DoGadgets-GJ,0

FileBufLen	=80
FileInfo	dc.l		FBuffer,0
		dc.w		0,FileBufLen,0,0,0,0,0,0
		dc.l		0,0,0
FBuffer		dc.b		'S:PWkeys.Config'
		dcb.b		FileBufLen-14,0
		EVEN
SpeedInfo	dc.l		SBuffer,0
		dc.w		0,2,0,0,0,0,0,0
		dc.l		0,0,0
SBuffer		dcb.b		3,0
		EVEN
ThresInfo	dc.l		TBuffer,0
		dc.w		0,2,0,0,0,0,0,0
		dc.l		0,0,0
TBuffer		dcb.b		3,0
		EVEN
PriInfo		dc.l		PBuffer,0
		dc.w		0,4,0,0,0,0,0,0
		dc.l		0,0,0
PBuffer		dcb.b		5,0
		EVEN
ScreenInfo	dc.l		ScreenBuffer,0
		dc.w		0,5,0,0,0,0,0,0
		dc.l		0,0,0
ScreenBuffer	dcb.b		6,0
		EVEN
MouseInfo	dc.l		MouseBuffer,0
		dc.w		0,5,0,0,0,0,0,0
		dc.l		0,0,0
MouseBuffer	dcb.b		6,0
		EVEN

TxtAttr		dc.l		FontName
		dc.w		TOPAZ_EIGHTY
		dc.b		FS_NORMAL,FPB_ROMFONT
FontName	dc.b		'topaz.font',0
		EVEN

UArrowImage	Image		0,0*FySpace,16,8,1,UArrowData,%00000001,%00000000,DArrowImage
DArrowImage	Image		0,1*FySpace,16,8,1,DArrowData,%00000001,%00000000,LArrowImage
LArrowImage	Image		0,2*FySpace,16,7,1,LArrowData,%00000001,%00000000,RArrowImage
RArrowImage	Image		1,3*FySpace,16,7,1,RArrowData,%00000001,%00000000,LUArrowImage
LUArrowImage	Image		2,4*FySpace,16,7,1,LUArrowData,%00000001,%00000000,LDArrowImage
LDArrowImage	Image		2,5*FySpace,16,7,1,LDArrowData,%00000001,%00000000,RUArrowImage
RUArrowImage	Image		0,6*FySpace,16,7,1,RUArrowData,%00000001,%00000000,RDArrowImage
RDArrowImage	Image		0,7*FySpace,16,7,1,RDArrowData,%00000001,%00000000,0

FWIDTH		=204
FHEIGHT		=11
FBorder		Border		-6,-3,1,0,1,17,1$,0
1$		dc.w		2,0,FWIDTH+1,0,FWIDTH+3,2,FWIDTH+3,FHEIGHT-1,FWIDTH+1,FHEIGHT+1,2,FHEIGHT+1,0,FHEIGHT-1,0,2,2,0
		dc.w		1,0,-1,2,-1,FHEIGHT-1,1,FHEIGHT+1,FWIDTH+2,FHEIGHT+1,FWIDTH+4,FHEIGHT-1,FWIDTH+4,2,FWIDTH+2,0
SPEEDW		=24
SPEEDH		=11
SBorder		Border		-6,-3,1,0,1,17,1$,0
1$		dc.w		2,0,SPEEDW+1,0,SPEEDW+3,2,SPEEDW+3,SPEEDH-1,SPEEDW+1,SPEEDH+1,2,SPEEDH+1,0,SPEEDH-1,0,2,2,0
		dc.w		1,0,-1,2,-1,SPEEDH-1,1,SPEEDH+1,SPEEDW+2,SPEEDH+1,SPEEDW+4,SPEEDH-1,SPEEDW+4,2,SPEEDW+2,0
PRIW		=40
PRIH		=11
PBorder		Border		-6,-3,1,0,1,17,1$,0
1$		dc.w		2,0,PRIW+1,0,PRIW+3,2,PRIW+3,PRIH-1,PRIW+1,PRIH+1,2,PRIH+1,0,PRIH-1,0,2,2,0
		dc.w		1,0,-1,2,-1,PRIH-1,1,PRIH+1,PRIW+2,PRIH+1,PRIW+4,PRIH-1,PRIW+4,2,PRIW+2,0
TIMEW		=48
TIMEH		=11
TBorder		Border		-6,-3,1,0,1,17,1$,0
1$		dc.w		2,0,TIMEW+1,0,TIMEW+3,2,TIMEW+3,TIMEH-1,TIMEW+1,TIMEH+1,2,TIMEH+1,0,TIMEH-1,0,2,2,0
		dc.w		1,0,-1,2,-1,TIMEH-1,1,TIMEH+1,TIMEW+2,TIMEH+1,TIMEW+4,TIMEH-1,TIMEW+4,2,TIMEW+2,0
WFuncBorder	Border		1,0,1,0,1,24,1$,0
1$		dc.w		2,0,FFw1+1,0,FFw1+3,2,FFw1+3,FFh1-1,FFw1+1,FFh1+1,2,FFh1+1,0,FFh1-1,0,2,2,0
		dc.w		1,0,-1,2,-1,FFh1-1,1,FFh1+1,FFw1+2,FFh1+1,FFw1+4,FFh1-1,FFw1+4,2,FFw1+2,0
		dc.w		FFw1+4,2,FFw1+4,10,0,10,95,10,95,FFh1,94,FFh1,94,10
SFuncBorder	Border		1,0,1,0,1,20,1$,0
1$		dc.w		2,0,FFw2+1,0,FFw2+3,2,FFw2+3,FFh2-1,FFw2+1,FFh2+1,2,FFh2+1,0,FFh2-1,0,2,2,0
		dc.w		1,0,-1,2,-1,FFh2-1,1,FFh2+1,FFw2+2,FFh2+1,FFw2+4,FFh2-1,FFw2+4,2,FFw2+2,0
		dc.w		FFw2+4,2,FFw2+4,10,0,10
MFuncBorder	Border		1,0,1,0,1,20,1$,0
1$		dc.w		2,0,FFw3+1,0,FFw3+3,2,FFw3+3,FFh3-1,FFw3+1,FFh3+1,2,FFh3+1,0,FFh3-1,0,2,2,0
		dc.w		1,0,-1,2,-1,FFh3-1,1,FFh3+1,FFw3+2,FFh3+1,FFw3+4,FFh3-1,FFw3+4,2,FFw3+2,0
		dc.w		FFw3+4,2,FFw3+4,10,0,10
BWIDTH		=50
BHEIGHT		=11
BBorder		Border		-2,-1,1,0,1,17,1$,0
1$		dc.w		2,0,BWIDTH+1,0,BWIDTH+3,2,BWIDTH+3,BHEIGHT-1,BWIDTH+1,BHEIGHT+1,2,BHEIGHT+1,0,BHEIGHT-1,0,2,2,0
		dc.w		1,0,-1,2,-1,BHEIGHT-1,1,BHEIGHT+1,BWIDTH+2,BHEIGHT+1,BWIDTH+4,BHEIGHT-1,BWIDTH+4,2,BWIDTH+2,0
KEYBW		=ScrW-6
KEYBH		=83
KeybBorder	Border		1,0,1,0,1,17,1$,0
1$		dc.w		2,0,KEYBW+1,0,KEYBW+3,2,KEYBW+3,KEYBH-1,KEYBW+1,KEYBH+1,2,KEYBH+1,0,KEYBH-1,0,2,2,0
		dc.w		1,0,-1,2,-1,KEYBH-1,1,KEYBH+1,KEYBW+2,KEYBH+1,KEYBW+4,KEYBH-1,KEYBW+4,2,KEYBW+2,0

TE_x		=0
TE_y		=2
TE_Offset	=4
TE_SIZE		=6
TEntry		MACRO		'TextEntry'
		dc.w		\1,\2,\3-TextTab
		ENDM

FFx1		=0
FFy1		=13
FFw1		=208
FFh1		=94
FFx2		=224
FFy2		=13
FFw2		=116
FFh2		=49
FFx3		=356
FFy3		=13
FFw3		=146
FFh3		=40

FySpace		=9
FTx1		=FFx1+8
FTx1b		=FFx1+102
FTy1		=FFy1+19
FTx2		=FFx2+8
FTy2		=FFy2+19
FTx3		=FFx3+8
FTy3		=FFy3+19

TextTab		TEntry		FTx1,FTy1+0*FySpace,1$
		TEntry		FTx1,FTy1+1*FySpace,2$
		TEntry		FTx1,FTy1+2*FySpace,3$
		TEntry		FTx1,FTy1+3*FySpace,4$
		TEntry		FTx1,FTy1+4*FySpace,5$
		TEntry		FTx1,FTy1+5*FySpace,6$
		TEntry		FTx1,FTy1+6*FySpace,7$
		TEntry		FTx1,FTy1+7*FySpace,8$
		TEntry		FTx1,FTy1+8*FySpace,9$
		TEntry		FTx1b,FTy1+0*FySpace,10$
		TEntry		FTx1b,FTy1+1*FySpace,11$
		TEntry		FTx1b,FTy1+2*FySpace,12$
		TEntry		FTx1b,FTy1+3*FySpace,13$
		TEntry		FTx1b,FTy1+4*FySpace,14$
		TEntry		FTx1b,FTy1+5*FySpace,15$
		TEntry		FTx1b,FTy1+6*FySpace,16$
		TEntry		FTx1b,FTy1+7*FySpace,17$
		TEntry		FTx1b,FTy1+8*FySpace,18$
		TEntry		FTx2,FTy2+0*FySpace,19$
		TEntry		FTx2,FTy2+1*FySpace,20$
		TEntry		FTx2,FTy2+2*FySpace,21$
		TEntry		FTx2,FTy2+3*FySpace,22$
		TEntry		FTx3,FTy3+0*FySpace,23$
		TEntry		FTx3,FTy3+1*FySpace,24$
		TEntry		FTx3,FTy3+2*FySpace,25$
		TEntry		FFx1+(FFw1-6*8)/2,FFy1+8,26$
		TEntry		FFx2+(FFw2-6*8)/2,FFy2+8,27$
		TEntry		FFx3+(FFw3-13*8)/2,FFy3+8,28$

		TEntry		529,22,29$
		TEntry		594,22,30$
		TEntry		532,38,31$
		TEntry		592,38,32$
		TEntry		525,54,33$
		TEntry		587,54,34$
		TEntry		532,70,35$
		TEntry		594,70,36$
		TEntry		234,93,37$
		TEntry		332,93,38$
		TEntry		424,93,39$
		TEntry		512,93,40$
		TEntry		568,93,41$

		TEntry		10,8,42$
		TEntry		10,8,43$
		TEntry		10,8,44$
		TEntry		10,8,45$
		TEntry		10,8,46$
		TEntry		10,8,47$
		TEntry		10,8,48$
		TEntry		10,8,49$
		TEntry		10,8,50$
		TEntry		10,8,51$
		TEntry		10,8,52$
		TEntry		10,8,53$
		TEntry		10,8,54$
		TEntry		10,8,55$

* Function texts
1$
2$
3$
4$		dc.b		'Move',0
5$
6$
7$
8$		dc.b		'Place',0
9$		dc.b		'To center',0
10$		dc.b		'To front',0
11$		dc.b		'To back',0
12$		dc.b		'Back to front',0
13$		dc.b		'Front to back',0
14$		dc.b		'Activate prev',0
15$		dc.b		'Activate next',0
16$		dc.b		'Minimize',0
17$		dc.b		'Maximize',0
18$		dc.b		'Refresh',0
19$		dc.b		'Back to front',0
20$		dc.b		'Front to back',0
21$		dc.b		'Sub BitPlane',0
22$		dc.b		'Add BitPlane',0
23$		dc.b		'Toggle Input-Lock',0
24$		dc.b		'Toggle Fast-Mouse',0
25$		dc.b		'Toggle Sun-Mouse',0
26$		dc.b		'Window',0
27$		dc.b		'Screen',0
28$		dc.b		'Miscellaneous',0

* Gadget texts
29$		dc.b		'Check',0
30$		dc.b		'Quit',0
31$		dc.b		'Undo',0
32$		dc.b		'Clear',0
33$		dc.b		'Import',0
34$		dc.b		'Export',0
35$		dc.b		'Save',0
36$		dc.b		'Load',0
37$		dc.b		'Screen off',0
38$		dc.b		'Mouse off',0
39$		dc.b		'Priority',0
40$		dc.b		'Speed',0
41$		dc.b		'Threshold',0

* Message texts
42$		SetPWkeys_Title
43$		dc.b		"Error: Can't find file !",0
44$		dc.b		"Error: File is not a valid PWkeys-file !",0
45$		dc.b		"Error: Can't write file !",0
46$		dc.b		"Settings have now been loaded from file !",0
47$		dc.b		"Settings have now been written to file !",0
48$		dc.b		"Error: The PWkeys-handler is not installed !",0
49$		dc.b		"Error: Can't remove handler. Haven't installed settings !",0
50$		dc.b		"Error: Can't re-install handler. Handler has now been removed !!!",0
51$		dc.b		"Settings have now been imported from PWkeys !",0
52$		dc.b		"Settings have now been exported to PWkeys !",0
53$		dc.b		"Error: Duplicate hotkey definitions !!",0
54$		dc.b		"Error: Handler-priority has to be 0-127 (preferably 51-127) !!",0
55$		dc.b		"The settings are acceptable !",0
		EVEN

Box_x		=0
Box_y		=2
Box_Width	=4
Box_Height	=6
Box_Flags	=8
Box_SIZE	=9
Box		MACRO
		dc.w		\1,\2,\3,\4	; x,y,width,height
		dc.b		\5		; Flags
		ENDM

FuncBox_HotKey	=10
FuncBox_SIZE	=14
FuncBox		MACRO		'Functionbox'
		Box		\1,\2,\3,\4,\5	; Box definition
		dc.b		0		; Pad
		dc.l		\6		; Function
		ENDM

KeyBox_Char	=9
KeyBox_Code	=10
KeyBox_Qual	=12
KeyBox_SIZE	=14
FKeyBox_SIZE	=14
KeyBox		MACRO		'Keybox'
		Box		\1,\2,\3,\4,\5	; Box definition
		dc.b		\6		; Char
		dc.w		\7,\8		; Raw, Qual
		ENDM

FBx1		=FFx1+4
FBx1b		=FFx1+98
FBy1		=FFy1+11
FBx2		=FFx2+4
FBy2		=FFy2+11
FBx3		=FFx3+4
FBy3		=FFy3+11

FBw1		=88
FBw1b		=112
FBw2		=FFw2-4
FBw3		=FFw3-4
FBh		=11

Funcs		FuncBox		FBx1,FBy1+0*FySpace,FBw1,FBh,0,HK1
		FuncBox		FBx1,FBy1+1*FySpace,FBw1,FBh,0,HK2
		FuncBox		FBx1,FBy1+2*FySpace,FBw1,FBh,0,HK3
		FuncBox		FBx1,FBy1+3*FySpace,FBw1,FBh,0,HK4
		FuncBox		FBx1,FBy1+4*FySpace,FBw1,FBh,0,HK5
		FuncBox		FBx1,FBy1+5*FySpace,FBw1,FBh,0,HK6
		FuncBox		FBx1,FBy1+6*FySpace,FBw1,FBh,0,HK7
		FuncBox		FBx1,FBy1+7*FySpace,FBw1,FBh,0,HK8
		FuncBox		FBx1,FBy1+8*FySpace,FBw1,FBh,0,HK9
		FuncBox		FBx1b,FBy1+0*FySpace,FBw1b,FBh,0,HK10
		FuncBox		FBx1b,FBy1+1*FySpace,FBw1b,FBh,0,HK11
		FuncBox		FBx1b,FBy1+2*FySpace,FBw1b,FBh,0,HK12
		FuncBox		FBx1b,FBy1+3*FySpace,FBw1b,FBh,0,HK13
		FuncBox		FBx1b,FBy1+4*FySpace,FBw1b,FBh,0,HK14
		FuncBox		FBx1b,FBy1+5*FySpace,FBw1b,FBh,0,HK15
		FuncBox		FBx1b,FBy1+6*FySpace,FBw1b,FBh,0,HK16
		FuncBox		FBx1b,FBy1+7*FySpace,FBw1b,FBh,0,HK17
		FuncBox		FBx1b,FBy1+8*FySpace,FBw1b,FBh,0,HK18
		FuncBox		FBx2,FBy2+0*FySpace,FBw2,FBh,0,HK19
		FuncBox		FBx2,FBy2+1*FySpace,FBw2,FBh,0,HK20
		FuncBox		FBx2,FBy2+2*FySpace,FBw2,FBh,0,HK21
		FuncBox		FBx2,FBy2+3*FySpace,FBw2,FBh,0,HK22
		FuncBox		FBx3,FBy3+0*FySpace,FBw3,FBh,0,HK23
		FuncBox		FBx3,FBy3+1*FySpace,FBw3,FBh,0,HK24
		FuncBox		FBx3,FBy3+2*FySpace,FBw3,FBh,0,HK25
		FuncBox		-1,-1,-1,-1,0,Funcs

Absx		=20
KH		=10
FM		=8
FW		=27
FSPACE		=6
FD		=FW+FSPACE
NW		=20
NSPACE		=6
ND		=NW+NSPACE
KPx		=Absx+498
Arx		=Absx+410
KY		=ScrH-80
R1x		=Absx+40
R2x		=Absx+40
R3x		=Absx+50
R4x		=Absx+56
R5x		=Absx+70
R1y		=KY+0*(KH+3)
R2y		=KY+1*(KH+3)
R3y		=KY+2*(KH+3)
R4y		=KY+3*(KH+3)
R5y		=KY+4*(KH+3)
R6y		=KY+5*(KH+3)

Keys
ReturnKey1
 KeyBox		382,R3y,NW+16,KH*2+3,0,0,RETURN,0
ReturnKey2
 KeyBox		363,R3y+13,20,KH,0,0,RETURN,0
 KeyBox		Absx,R1y,NW,KH,0,0,ESC,0
 KeyBox		R1x+00*FD,R1y,FW,KH,0,0,F1,0
 KeyBox		R1x+01*FD,R1y,FW,KH,0,0,F2,0
 KeyBox		R1x+02*FD,R1y,FW,KH,0,0,F3,0
 KeyBox		R1x+03*FD,R1y,FW,KH,0,0,F4,0
 KeyBox		R1x+04*FD,R1y,FW,KH,0,0,F5,0
 KeyBox		R1x+FM+05*FD,R1y,FW,KH,0,0,F6,0
 KeyBox		R1x+FM+06*FD,R1y,FW,KH,0,0,F7,0
 KeyBox		R1x+FM+07*FD,R1y,FW,KH,0,0,F8,0
 KeyBox		R1x+FM+08*FD,R1y,FW,KH,0,0,F9,0
 KeyBox		R1x+FM+09*FD,R1y,FW,KH,0,0,F10,0
 KeyBox		Absx,R2y,FW+6,KH,0,'`',$00,0
 KeyBox		R2x+00*ND,R2y,NW,KH,0,'1',$01,0
 KeyBox		R2x+01*ND,R2y,NW,KH,0,'2',$02,0
 KeyBox		R2x+02*ND,R2y,NW,KH,0,'3',$03,0
 KeyBox		R2x+03*ND,R2y,NW,KH,0,'4',$04,0
 KeyBox		R2x+04*ND,R2y,NW,KH,0,'5',$05,0
 KeyBox		R2x+05*ND,R2y,NW,KH,0,'6',$06,0
 KeyBox		R2x+06*ND,R2y,NW,KH,0,'7',$07,0
 KeyBox		R2x+07*ND,R2y,NW,KH,0,'8',$08,0
 KeyBox		R2x+08*ND,R2y,NW,KH,0,'9',$09,0
 KeyBox		R2x+09*ND,R2y,NW,KH,0,'0',$0A,0
 KeyBox		R2x+10*ND,R2y,NW,KH,0,'-',$0B,0
 KeyBox		R2x+11*ND,R2y,NW,KH,0,'=',$0C,0
 KeyBox		R2x+12*ND,R2y,NW,KH,0,'\',$0D,0
 KeyBox		R2x+13*ND,R2y,NW,KH,0,0,BACKSPACE,0
 KeyBox		Arx,R2y,FW+6,KH,0,0,DEL,0
 KeyBox		Arx+8+FD,R2y,FW+6,KH,0,0,HELP,0
 KeyBox		KPx+00*ND,R2y,NW,KH,0,'[',$5A,0
 KeyBox		KPx+01*ND,R2y,NW,KH,0,']',$5B,0
 KeyBox		KPx+02*ND,R2y,NW,KH,0,'\',$5C,0
 KeyBox		KPx+03*ND,R2y,NW,KH,0,'*',$5D,0
 KeyBox		Absx,R3y,FW+16,KH,0,0,TAB,0
 KeyBox		R3x+00*ND,R3y,NW,KH,0,'q',$10,0
 KeyBox		R3x+01*ND,R3y,NW,KH,0,'w',$11,0
 KeyBox		R3x+02*ND,R3y,NW,KH,0,'e',$12,0
 KeyBox		R3x+03*ND,R3y,NW,KH,0,'r',$13,0
 KeyBox		R3x+04*ND,R3y,NW,KH,0,'t',$14,0
 KeyBox		R3x+05*ND,R3y,NW,KH,0,'y',$15,0
 KeyBox		R3x+06*ND,R3y,NW,KH,0,'u',$16,0
 KeyBox		R3x+07*ND,R3y,NW,KH,0,'i',$17,0
 KeyBox		R3x+08*ND,R3y,NW,KH,0,'o',$18,0
 KeyBox		R3x+09*ND,R3y,NW,KH,0,'p',$19,0
 KeyBox		R3x+10*ND,R3y,NW,KH,0,'[',$1A,0
 KeyBox		R3x+11*ND,R3y,NW,KH,0,']',$1B,0
 KeyBox		KPx+00*ND,R3y,NW,KH,0,'7',$3D,0
 KeyBox		KPx+01*ND,R3y,NW,KH,0,'8',$3E,0
 KeyBox		KPx+02*ND,R3y,NW,KH,0,'9',$3F,0
 KeyBox		KPx+03*ND,R3y,NW,KH,0,'-',$4A,0
 KeyBox		Absx,R4y,NW+3,KH,0,0,$63,CTRL
 KeyBox		Absx+ND+3,R4y,NW,KH,0,0,$62,CAPSLOCK
 KeyBox		R4x+00*ND,R4y,NW,KH,0,'a',$20,0
 KeyBox		R4x+01*ND,R4y,NW,KH,0,'s',$21,0
 KeyBox		R4x+02*ND,R4y,NW,KH,0,'d',$22,0
 KeyBox		R4x+03*ND,R4y,NW,KH,0,'f',$23,0
 KeyBox		R4x+04*ND,R4y,NW,KH,0,'g',$24,0
 KeyBox		R4x+05*ND,R4y,NW,KH,0,'h',$25,0
 KeyBox		R4x+06*ND,R4y,NW,KH,0,'j',$26,0
 KeyBox		R4x+07*ND,R4y,NW,KH,0,'k',$27,0
 KeyBox		R4x+08*ND,R4y,NW,KH,0,'l',$28,0
 KeyBox		R4x+09*ND,R4y,NW,KH,0,';',$29,0
 KeyBox		R4x+10*ND,R4y,NW,KH,0,"'",$2A,0
 KeyBox		Arx+1*ND,R4y,NW,KH,0,0,UPARROW,0
 KeyBox		KPx+00*ND,R4y,NW,KH,0,'4',$2D,0
 KeyBox		KPx+01*ND,R4y,NW,KH,0,'5',$2E,0
 KeyBox		KPx+02*ND,R4y,NW,KH,0,'6',$2F,0
 KeyBox		KPx+03*ND,R4y,NW,KH,0,'+',$5E,0
 KeyBox		Absx,R5y,63,KH,0,0,$60,LSHIFT
 KeyBox		R5x+00*ND,R5y,NW,KH,0,'z',$31,0
 KeyBox		R5x+01*ND,R5y,NW,KH,0,'x',$32,0
 KeyBox		R5x+02*ND,R5y,NW,KH,0,'c',$33,0
 KeyBox		R5x+03*ND,R5y,NW,KH,0,'v',$34,0
 KeyBox		R5x+04*ND,R5y,NW,KH,0,'b',$35,0
 KeyBox		R5x+05*ND,R5y,NW,KH,0,'n',$36,0
 KeyBox		R5x+06*ND,R5y,NW,KH,0,'m',$37,0
 KeyBox		R5x+07*ND,R5y,NW,KH,0,$2C,$38,0		;','
 KeyBox		R5x+08*ND,R5y,NW,KH,0,'.',$39,0
 KeyBox		R5x+09*ND,R5y,NW,KH,0,'/',$3A,0
 KeyBox		R5x+10*ND,R5y,67,KH,0,0,$61,RSHIFT
 KeyBox		Arx+00*ND,R5y,NW,KH,0,0,LEFTARROW,0
 KeyBox		Arx+01*ND,R5y,NW,KH,0,0,DOWNARROW,0
 KeyBox		Arx+02*ND,R5y,NW,KH,0,0,RIGHTARROW,0
 KeyBox		KPx+00*ND,R5y,NW,KH,0,'1',$1D,0
 KeyBox		KPx+01*ND,R5y,NW,KH,0,'2',$1E,0
 KeyBox		KPx+02*ND,R5y,NW,KH,0,'3',$1F,0
 KeyBox		KPx+03*ND,R5y,NW,KH*2+3,0,0,ENTER,0
 KeyBox		Absx+10,R6y,FW+2,KH,0,0,$64,LALT
 KeyBox		Absx+10+FD+2,R6y,FW+2,KH,0,0,$66,LAMIGA
 KeyBox		100,R6y,232,KH,0,0,SPACE,0
 KeyBox		338,R6y,FW+2,KH,0,0,$67,RAMIGA
 KeyBox		338+FD+2,R6y,FW+2,KH,0,0,$65,RALT
 KeyBox		KPx+00*ND,R6y,NW+ND,KH,0,'0',$0F,0
 KeyBox		KPx+02*ND,R6y,NW,KH,0,'.',$3C,0
 KeyBox		-1,-1,-1,-1,0,0,0,0

PWkVersionID	dc.l		'PWKF'
PWkVersionNum	dc.w		PWkeysVersion,PWkeysRevision
PWkPri		dc.b		PWkeysPri,0
PWkMouseAccel	dc.b		PWkeysMSpeed
PWkMouseThresh	dc.b		PWkeysMThresh
PWkMTimeout	dc.l		PWkeysMTimeout
PWkSTimeout	dc.l		PWkeysSTimeout
PWkMWaitTime	dc.l		0
PWkSWaitTime	dc.l		0
PWkHotKeys	dc.w		KeyFuncNumber
KeyDefines
HK1		HotKey		KP8,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_TOP
HK2		HotKey		KP2,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_BOTTOM
HK3		HotKey		KP4,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_LEFT
HK4		HotKey		KP6,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_RIGHT
HK5		HotKey		KP7,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_LEFT_TOP
HK6		HotKey		KP1,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_LEFT_BOTTOM
HK7		HotKey		KP9,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_RIGHT_TOP
HK8		HotKey		KP3,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_RIGHT_BOTTOM
HK9		HotKey		KP5,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_CENTER
HK10		HotKey		DOWNARROW,LSHIFT|LAMIGA,SHIFT|AMIGA,W_TO_FRONT
HK11		HotKey		UPARROW,LSHIFT|LAMIGA,SHIFT|AMIGA,W_TO_BACK
HK12		HotKey		DOWNARROW,LAMIGA,SHIFT|AMIGA,BACK_W_TO_FRONT
HK13		HotKey		UPARROW,LAMIGA,SHIFT|AMIGA,FRONT_W_TO_BACK
HK14		HotKey		LEFTARROW,LSHIFT|LAMIGA,LSHIFT|LAMIGA,ACTIVATE_PREV_W
HK15		HotKey		RIGHTARROW,LSHIFT|LAMIGA,LSHIFT|LAMIGA,ACTIVATE_NEXT_W
HK16		HotKey		F1,LSHIFT|LAMIGA,LSHIFT|LAMIGA,MINIMIZE_W
HK17		HotKey		F2,LSHIFT|LAMIGA,LSHIFT|LAMIGA,MAXIMIZE_W
HK18		HotKey		TAB,LSHIFT|LAMIGA,LSHIFT|LAMIGA,REFRESH_W
HK19		HotKey		DOWNARROW,RSHIFT|RAMIGA,SHIFT|AMIGA,BACK_S_TO_FRONT
HK20		HotKey		UPARROW,RSHIFT|RAMIGA,SHIFT|AMIGA,FRONT_S_TO_BACK
HK21		HotKey		F9,RSHIFT|RAMIGA,RSHIFT|RAMIGA,SUB_BITPLANE
HK22		HotKey		F10,RSHIFT|RAMIGA,RSHIFT|RAMIGA,ADD_BITPLANE
HK23		HotKey		BACKSPACE,LAMIGA|RAMIGA,LAMIGA|RAMIGA,TOGGLE_INPUTLOCK
HK24		HotKey		DEL,LAMIGA|RAMIGA,LAMIGA|RAMIGA,TOGGLE_FASTMOUSE
HK25		HotKey		HELP,LAMIGA|RAMIGA,LAMIGA|RAMIGA,TOGGLE_SUNMOUSE

* Image data in CHIP-RAM
		SECTION		IMAGEDATA,DATA_C
Mask		dc.w		%0011001100110011
		dc.w		%1100110011001100
		dc.w		%0011001100110011
		dc.w		%1100110011001100

UArrowData	dc.w		%0000000110000000
		dc.w		%0000011111100000
		dc.w		%0001111111111000
		dc.w		%0111111111111110
		dc.w		%0000011111100000
		dc.w		%0000011111100000
		dc.w		%0000011111100000
		dc.w		%0000011111100000
DArrowData	dc.w		%0000011111100000
		dc.w		%0000011111100000
		dc.w		%0000011111100000
		dc.w		%0000011111100000
		dc.w		%0111111111111110
		dc.w		%0001111111111000
		dc.w		%0000011111100000
		dc.w		%0000000110000000
LArrowData	dc.w		%0000001100000000
		dc.w		%0000111100000000
		dc.w		%0011111111111111
		dc.w		%1111111111111111
		dc.w		%0011111111111111
		dc.w		%0000111100000000
		dc.w		%0000001100000000
RArrowData	dc.w		%0000000011000000
		dc.w		%0000000011110000
		dc.w		%1111111111111100
		dc.w		%1111111111111111
		dc.w		%1111111111111100
		dc.w		%0000000011110000
		dc.w		%0000000011000000
LUArrowData	dc.w		%1111111111110000
		dc.w		%1111111111000000
		dc.w		%1111111111000000
		dc.w		%1111111111110000
		dc.w		%1111111111111100
		dc.w		%1100001111110000
		dc.w		%0000000011000000
LDArrowData	dc.w		%0000000011000000
		dc.w		%1100001111110000
		dc.w		%1111111111111100
		dc.w		%1111111111110000
		dc.w		%1111111111000000
		dc.w		%1111111111000000
		dc.w		%1111111111110000
RUArrowData	dc.w		%0000111111111111
		dc.w		%0000001111111111
		dc.w		%0000001111111111
		dc.w		%0000111111111111
		dc.w		%0011111111111111
		dc.w		%0000111111000011
		dc.w		%0000001100000000
RDArrowData	dc.w		%0000001100000000
		dc.w		%0000111111000011
		dc.w		%0011111111111111
		dc.w		%0000111111111111
		dc.w		%0000001111111111
		dc.w		%0000001111111111
		dc.w		%0000111111111111
		END

