home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 4
/
FreshFish_May-June1994.bin
/
new
/
amigalibdisks
/
d983
/
capslockext
/
capslockextender.s
< prev
next >
Wrap
Text File
|
1994-04-04
|
10KB
|
429 lines
***************************************************
* CapsLockExtender *
* by Douglas Nelson *
* *
* Assemble with Macro68 *
* *
* To make the executable small, this uses (x,A4) *
* addressing and byte branches where possible. *
* Executable size is 1265 bytes. *
***************************************************
strict
exeobj
errfile ram:assem.output
objfile ram:CLE
listfile ram:listfile
incpath mac:includes
incpath ram:includes
macfile alllibraryoffsets.i
macfile exec/alerts.i
macfile workbench/workbench.i
macfile workbench/startup.i
macfile devices/inputevent.i
macfile libraries/commodities.i
macfile dos/dosextens.i
libcall macro
jsr (_LVO\1,a6)
endm
* 2.0 startups are so easy, what with ReadArgs and all
lea (dt,pc),a4
move.l sp,(stackptr-dt,a4)
move.l d0,d7 ;store dosCmdLen
movea.l (4).w,a6
move.l a6,(execbase-dt,a4)
* open dos
lea (dosname-dt,a4),a1
move.l #37,d0
libcall OpenLibrary
move.l d0,(dosbase-dt,a4)
bne.b gotdos
move.l #AG_OpenLib!AO_DOSLib,d7
libcall Alert
failexit tst.l d7
bne.b fail2
bsr.b getWbMsg
bsr.b replyWbMsg
fail2 moveq #20,d0 ;FAIL
rts
exit movea.l (execbase-dt,a4),a6
movea.l (dosbase-dt,a4),a1
libcall CloseLibrary
tst.l (WBenchMsg-dt,a4)
beq.b exit2
bsr.b replyWbMsg
exit2 move.l (rc-dt,a4),d0
movea.l (stackptr-dt,a4),sp
rts
* the next two subroutines here appear to allow byte branches
replyWbMsg movea.l (execbase-dt,a4),a6
libcall Forbid
movea.l (WBenchMsg-dt,a4),a1
libcall ReplyMsg
rts
getWbMsg suba.l a1,a1
libcall FindTask
movea.l d0,a5
lea (pr_MsgPort,a5),a0
libcall WaitPort
lea (pr_MsgPort,a5),a0
libcall GetMsg
move.l d0,(WBenchMsg-dt,a4)
rts
gotdos move.l #10,(rc-dt,a4) ;ERROR for early exit
tst.l d7 ;dosCmdLen
beq.b WBstart
* read command line
lea (template-dt,a4),a0
move.l a0,d1
lea (priority-dt,a4),a0
move.l a0,d2
moveq #0,d3 ;no optional RdArgs
movea.l (dosbase-dt,a4),a6
libcall ReadArgs
move.l d0,d1
libcall FreeArgs
tst.l (priority-dt,a4)
beq main
movea.l (priority-dt,a4),a0 ;priority is ptr to value
move.l (a0),(priority-dt,a4) ;put value in priority
bra main
WBstart
bsr.b getWbMsg
* read WBArgs
movea.l d0,a2
movea.l (sm_ArgList,a2),a2
move.l (wa_Lock,a2),d1
movea.l (dosbase),a6
libcall CurrentDir
move.l d0,d7 ;store old dir
* open icon.library
lea (iconname-dt,a4),a1
move.l #37,d0
movea.l (execbase-dt,a4),a6
libcall OpenLibrary
move.l d0,(iconbase-dt,a4)
beq.b endicon
*read ToolTypes
movea.l d0,a6
movea.l (wa_Name,a2),a0
libcall GetDiskObject
tst.l d0
beq.b closeicon
movea.l d0,a2
movea.l (do_ToolTypes,a2),a0
lea (priorityname-dt,a4),a1
libcall FindToolType ;returns ptr to digits
move.l d0,d1
beq.b checkNKP ;no CX_PRIORITY
lea (priority-dt,a4),a0
move.l a0,d2
movea.l (dosbase-dt,a4),a6
libcall StrToLong ;sets priority
checkNKP movea.l (do_ToolTypes,a2),a0
lea (nokeypadname-dt,a4),a1
movea.l (iconbase-dt,a4),a6
libcall FindToolType
tst.l d0
beq.b checkhot ;no NOKEYPAD
move.l #1,(nokeypad-dt,a4)
checkhot movea.l (do_ToolTypes,a2),a0
lea (hotname-dt,a4),a1
movea.l (iconbase-dt,a4),a6
libcall FindToolType
tst.l d0
beq.b freediskobj ;no HOT
move.l #1,(hot-dt,a4)
freediskobj
movea.l (iconbase-dt,a4),a6
movea.l a2,a0
libcall FreeDiskObject
closeicon movea.l (iconbase-dt,a4),a1
movea.l (execbase-dt,a4),a6
libcall CloseLibrary
* restore old dir
endicon move.l d7,d1
movea.l (dosbase),a6
libcall CurrentDir
main
* open commodities.library
lea (cxname-dt,a4),a1
move.l #37,d0
movea.l (execbase-dt,a4),a6
libcall OpenLibrary
move.l d0,(cxbase-dt,a4)
beq exit
* create MsgPort for broker
gotcx libcall CreateMsgPort
move.l d0,(brokerport-dt,a4)
beq cleanup
* put priority in NewBroker
* priority must be longword for ReadArgs, but nb_Priority is a byte
move.b (priority+3-dt,a4),(nbpriority-dt,a4)
* create broker
lea (brokererror-dt,a4),a0
move.l a0,d0
lea (newbroker-dt,a4),a0
movea.l (cxbase-dt,a4),a6
libcall CxBroker
move.l d0,(broker-dt,a4)
beq cleanup
* create null FILTER CxObj
moveq #CX_FILTER,d0
suba.l a0,a0
suba.l a1,a1
libcall CreateCxObj
move.l d0,(filterobj-dt,a4)
beq cleanup
* set FILTER to our InputXpression
movea.l d0,a0
tst.l (nokeypad-dt,a4)
bne.b setNKPix
lea (ix-dt,a4),a1
bra.b setfilter
setNKPix lea (NKPix-dt,a4),a1
setfilter libcall SetFilterIX
tst.l d0
beq cleanup
* create CUSTOM CxObj
moveq #CX_CUSTOM,d0
tst.l (hot-dt,a4)
bne.b setHOTfunc
lea (defaultfunc-dt,a4),a0
bra.b makecustom
setHOTfunc lea (hotfunc-dt,a4),a0
makecustom movea.l #1,a1 ;id
libcall CreateCxObj
move.l d0,(customobj-dt,a4)
beq cleanup
* link CxObjs to broker
movea.l (broker-dt,a4),a0
movea.l (filterobj-dt,a4),a1
libcall AttachCxObj
movea.l (filterobj-dt,a4),a0
movea.l (customobj-dt,a4),a1
libcall AttachCxObj
* activate broker
movea.l (broker-dt,a4),a0
moveq #1,d0
libcall ActivateCxObj
* cleared all obstacles, so set rc to SUCCESS
move.l #0,(rc-dt,a4)
* make waitmask
movea.l (brokerport-dt,a4),a0
moveq #0,d0
move.b (MP_SIGBIT,a0),d0
moveq #1,d7
lsl.l d0,d7 ;port signal
ori.w #(1<<$E)!(1<<$C),d7 ;CTRL-E or CTRL-C
* wait for signal
waitloop move.l d7,d0
movea.l (execbase-dt,a4),a6
libcall Wait
andi.l #(1<<$C)!(1<<$E),d0
bne cleanup
* not CTRL-C or CTRL-E so must be portsignal
getmsgloop movea.l (execbase-dt,a4),a6
movea.l (brokerport-dt,a4),a0
libcall GetMsg
tst.l d0 ;another Message?
beq.b waitloop
movea.l d0,a5 ;store Message ptr
* check Message type
movea.l d0,a0
movea.l (cxbase-dt,a4),a6
libcall CxMsgType
cmpi.l #CXM_COMMAND,d0
bne.b replymsg ;unknown msg
* respond to command
movea.l a5,a0
libcall CxMsgID
disable cmpi.l #CXCMD_DISABLE,d0
bne.b enable
movea.l (broker-dt,a4),a0
moveq #0,d0 ;disable code
libcall ActivateCxObj
bra.b replymsg
enable cmpi.l #CXCMD_ENABLE,d0
bne.b kill
movea.l (broker-dt,a4),a0
moveq #1,d0 ;enable code
libcall ActivateCxObj
bra.b replymsg
kill cmpi.l #CXCMD_KILL,d0
bne.b unique
gotkill movea.l a5,a1
movea.l (execbase-dt,a4),a6
libcall ReplyMsg
bra cleanup
unique cmpi.l #CXCMD_UNIQUE,d0
bne.b replymsg
bra.b gotkill
replymsg movea.l a5,a1
movea.l (execbase-dt,a4),a6
libcall ReplyMsg
bra getmsgloop
cleanup move.l (broker-dt,a4),d0
beq.b deleteport
movea.l d0,a0
movea.l (cxbase-dt,a4),a6
libcall DeleteCxObjAll ;delete CxObjs
deleteport tst.l (brokerport-dt,a4)
beq.b closecx
clearmsg movea.l (execbase-dt,a4),a6
movea.l (brokerport-dt,a4),a0
libcall GetMsg
tst.l d0 ;another Message?
beq.b nomsgs
movea.l d0,a1
libcall ReplyMsg
bra.b clearmsg
nomsgs movea.l (brokerport-dt,a4),a0
libcall DeleteMsgPort
closecx movea.l (execbase-dt,a4),a6
movea.l (cxbase-dt,a4),a1
libcall CloseLibrary
bra exit
* Here are the two CUSTOM CxObj functions. Since they are called from
* commodities.library, they cannot use (x,A4) addressing.
* An oddity: Under 2.04 the function need not save a6 if all input comes
* from the keyboard. However, if another program is simulating keypresses
* by writing to input.device, then the system will crash if a6 is not saved.
defaultfunc pushm d0/a0/a6
movea.l (16,sp),a0 ;CxMsg ptr is on stack
movea.l (cxbase,pc),a6
libcall CxMsgData ;get input event
movea.l d0,a0
move.w (ie_Qualifier,a0),d0
andi.w #IEQUALIFIER_LSHIFT!IEQUALIFIER_RSHIFT,d0
bne.b cancel1
ori.w #IEQUALIFIER_LSHIFT,(ie_Qualifier,a0) ;add SHIFT
bra.b enddefaultfunc
cancel1 andi.w #~(IEQUALIFIER_LSHIFT!IEQUALIFIER_RSHIFT!IEQUALIFIER_CAPSLOCK),(ie_Qualifier,a0)
* this clears the Shift and CapsLock bits
enddefaultfunc
popm d0/a0/a6
rts
hotfunc pushm d0/a0/a6
movea.l (16,sp),a0 ;CxMsg ptr is on stack
movea.l (cxbase,pc),a6
libcall CxMsgData ;get input event
movea.l d0,a0
move.w (ie_Qualifier,a0),d0
andi.w #IEQUALIFIER_LSHIFT!IEQUALIFIER_RSHIFT,d0
bne.b cancel2
ori.w #IEQUALIFIER_LSHIFT,(ie_Qualifier,a0) ;add SHIFT
andi.w #~IEQUALIFIER_CAPSLOCK,(ie_Qualifier,a0) ;delete CAPSLOCK
bra.b endhotfunc
cancel2 andi.w #~(IEQUALIFIER_LSHIFT!IEQUALIFIER_RSHIFT