home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / new / amigalibdisks / d983 / capslockext / capslockextender.s < prev    next >
Text File  |  1994-04-04  |  10KB  |  429 lines

  1. ***************************************************
  2. * CapsLockExtender                                *
  3. *    by Douglas Nelson                            *
  4. *                                                 *
  5. * Assemble with Macro68                           *
  6. *                                                 *
  7. * To make the executable small, this uses (x,A4)  *
  8. * addressing and byte branches where possible.    *
  9. * Executable size is 1265 bytes.                  *
  10. ***************************************************
  11.  
  12.  
  13.     strict
  14.     exeobj
  15.     errfile    ram:assem.output
  16.     objfile    ram:CLE
  17.     listfile    ram:listfile
  18.     incpath    mac:includes
  19.     incpath    ram:includes
  20.     macfile    alllibraryoffsets.i
  21.     macfile    exec/alerts.i
  22.     macfile    workbench/workbench.i
  23.     macfile    workbench/startup.i
  24.     macfile    devices/inputevent.i
  25.     macfile    libraries/commodities.i
  26.     macfile    dos/dosextens.i
  27.  
  28. libcall    macro
  29.     jsr    (_LVO\1,a6)
  30.     endm
  31.  
  32. * 2.0 startups are so easy, what with ReadArgs and all
  33.     lea    (dt,pc),a4
  34.     move.l    sp,(stackptr-dt,a4)
  35.     move.l    d0,d7    ;store dosCmdLen
  36.     movea.l    (4).w,a6
  37.     move.l    a6,(execbase-dt,a4)
  38.  
  39. * open dos
  40.     lea    (dosname-dt,a4),a1
  41.     move.l    #37,d0
  42.     libcall    OpenLibrary
  43.     move.l    d0,(dosbase-dt,a4)
  44.     bne.b    gotdos
  45.     move.l    #AG_OpenLib!AO_DOSLib,d7
  46.     libcall    Alert
  47. failexit    tst.l    d7
  48.     bne.b    fail2
  49.     bsr.b    getWbMsg
  50.     bsr.b    replyWbMsg
  51. fail2    moveq    #20,d0    ;FAIL
  52.     rts
  53.  
  54. exit    movea.l    (execbase-dt,a4),a6
  55.     movea.l    (dosbase-dt,a4),a1
  56.     libcall    CloseLibrary
  57.     tst.l    (WBenchMsg-dt,a4)
  58.     beq.b    exit2
  59.     bsr.b    replyWbMsg
  60. exit2    move.l    (rc-dt,a4),d0
  61.  
  62.     movea.l    (stackptr-dt,a4),sp
  63.     rts
  64.  
  65. * the next two subroutines here appear to allow byte branches
  66.  
  67. replyWbMsg    movea.l    (execbase-dt,a4),a6
  68.     libcall    Forbid
  69.     movea.l    (WBenchMsg-dt,a4),a1
  70.     libcall    ReplyMsg
  71.     rts
  72.  
  73. getWbMsg    suba.l    a1,a1
  74.     libcall    FindTask
  75.     movea.l    d0,a5
  76.     lea    (pr_MsgPort,a5),a0
  77.     libcall    WaitPort
  78.     lea    (pr_MsgPort,a5),a0
  79.     libcall    GetMsg
  80.     move.l    d0,(WBenchMsg-dt,a4)
  81.     rts
  82.  
  83. gotdos    move.l    #10,(rc-dt,a4)    ;ERROR for early exit
  84.     tst.l    d7    ;dosCmdLen
  85.     beq.b    WBstart
  86.  
  87. * read command line
  88.     lea    (template-dt,a4),a0
  89.     move.l    a0,d1
  90.     lea    (priority-dt,a4),a0
  91.     move.l    a0,d2
  92.     moveq    #0,d3    ;no optional RdArgs
  93.     movea.l    (dosbase-dt,a4),a6
  94.     libcall    ReadArgs
  95.     move.l    d0,d1
  96.     libcall    FreeArgs
  97.     tst.l    (priority-dt,a4)
  98.     beq    main
  99.     movea.l    (priority-dt,a4),a0    ;priority is ptr to value
  100.     move.l    (a0),(priority-dt,a4)    ;put value in priority
  101.  
  102.     bra    main
  103.  
  104. WBstart
  105.     bsr.b    getWbMsg
  106. * read WBArgs
  107.     movea.l    d0,a2
  108.     movea.l    (sm_ArgList,a2),a2
  109.     move.l    (wa_Lock,a2),d1
  110.     movea.l    (dosbase),a6
  111.     libcall    CurrentDir
  112.     move.l    d0,d7    ;store old dir
  113.  
  114. * open icon.library
  115.     lea    (iconname-dt,a4),a1
  116.     move.l    #37,d0
  117.     movea.l    (execbase-dt,a4),a6
  118.     libcall    OpenLibrary
  119.     move.l    d0,(iconbase-dt,a4)
  120.     beq.b    endicon
  121.  
  122. *read ToolTypes
  123.     movea.l    d0,a6
  124.     movea.l    (wa_Name,a2),a0
  125.     libcall    GetDiskObject
  126.     tst.l    d0
  127.     beq.b    closeicon
  128.     movea.l    d0,a2
  129.     movea.l    (do_ToolTypes,a2),a0
  130.     lea    (priorityname-dt,a4),a1
  131.     libcall    FindToolType    ;returns ptr to digits
  132.     move.l    d0,d1
  133.     beq.b    checkNKP        ;no CX_PRIORITY
  134.     lea    (priority-dt,a4),a0
  135.     move.l    a0,d2
  136.     movea.l    (dosbase-dt,a4),a6
  137.     libcall    StrToLong    ;sets priority
  138.  
  139. checkNKP    movea.l    (do_ToolTypes,a2),a0
  140.     lea    (nokeypadname-dt,a4),a1
  141.     movea.l    (iconbase-dt,a4),a6
  142.     libcall    FindToolType
  143.     tst.l    d0
  144.     beq.b    checkhot        ;no NOKEYPAD
  145.     move.l    #1,(nokeypad-dt,a4)
  146.  
  147. checkhot    movea.l    (do_ToolTypes,a2),a0
  148.     lea    (hotname-dt,a4),a1
  149.     movea.l    (iconbase-dt,a4),a6
  150.     libcall    FindToolType
  151.     tst.l    d0
  152.     beq.b    freediskobj        ;no HOT
  153.     move.l    #1,(hot-dt,a4)
  154.  
  155. freediskobj
  156.     movea.l    (iconbase-dt,a4),a6
  157.     movea.l    a2,a0
  158.     libcall    FreeDiskObject
  159.  
  160. closeicon    movea.l    (iconbase-dt,a4),a1
  161.     movea.l    (execbase-dt,a4),a6
  162.     libcall    CloseLibrary
  163.  
  164. * restore old dir
  165. endicon    move.l    d7,d1
  166.     movea.l    (dosbase),a6
  167.     libcall    CurrentDir
  168.  
  169.  
  170. main
  171. * open commodities.library
  172.     lea    (cxname-dt,a4),a1
  173.     move.l    #37,d0
  174.     movea.l    (execbase-dt,a4),a6
  175.     libcall    OpenLibrary
  176.     move.l    d0,(cxbase-dt,a4)
  177.     beq    exit
  178.  
  179. * create MsgPort for broker
  180. gotcx    libcall    CreateMsgPort
  181.     move.l    d0,(brokerport-dt,a4)
  182.     beq    cleanup
  183.  
  184. * put priority in NewBroker
  185. * priority must be longword for ReadArgs, but nb_Priority is a byte
  186.     move.b    (priority+3-dt,a4),(nbpriority-dt,a4)
  187.  
  188. * create broker
  189.     lea    (brokererror-dt,a4),a0
  190.     move.l    a0,d0
  191.     lea    (newbroker-dt,a4),a0
  192.     movea.l    (cxbase-dt,a4),a6
  193.     libcall    CxBroker
  194.     move.l    d0,(broker-dt,a4)
  195.     beq    cleanup
  196.  
  197. * create null FILTER CxObj
  198.     moveq    #CX_FILTER,d0
  199.     suba.l    a0,a0
  200.     suba.l    a1,a1
  201.     libcall    CreateCxObj
  202.     move.l    d0,(filterobj-dt,a4)
  203.     beq    cleanup
  204.  
  205. * set FILTER to our InputXpression
  206.     movea.l    d0,a0
  207.     tst.l    (nokeypad-dt,a4)
  208.     bne.b    setNKPix
  209.     lea    (ix-dt,a4),a1
  210.     bra.b    setfilter
  211. setNKPix    lea    (NKPix-dt,a4),a1
  212. setfilter    libcall    SetFilterIX
  213.     tst.l    d0
  214.     beq    cleanup
  215.  
  216. * create CUSTOM CxObj
  217.     moveq    #CX_CUSTOM,d0
  218.     tst.l    (hot-dt,a4)
  219.     bne.b    setHOTfunc
  220.     lea    (defaultfunc-dt,a4),a0
  221.     bra.b    makecustom
  222. setHOTfunc    lea    (hotfunc-dt,a4),a0
  223. makecustom    movea.l    #1,a1        ;id
  224.     libcall    CreateCxObj
  225.     move.l    d0,(customobj-dt,a4)
  226.     beq    cleanup
  227.  
  228. * link CxObjs to broker
  229.     movea.l    (broker-dt,a4),a0
  230.     movea.l    (filterobj-dt,a4),a1
  231.     libcall    AttachCxObj
  232.     movea.l    (filterobj-dt,a4),a0
  233.     movea.l    (customobj-dt,a4),a1
  234.     libcall    AttachCxObj
  235.  
  236. * activate broker
  237.     movea.l    (broker-dt,a4),a0
  238.     moveq    #1,d0
  239.     libcall    ActivateCxObj
  240.  
  241. * cleared all obstacles, so set rc to SUCCESS
  242.     move.l    #0,(rc-dt,a4)
  243.  
  244. * make waitmask
  245.     movea.l    (brokerport-dt,a4),a0
  246.     moveq    #0,d0
  247.     move.b    (MP_SIGBIT,a0),d0
  248.     moveq    #1,d7
  249.     lsl.l    d0,d7    ;port signal
  250.     ori.w    #(1<<$E)!(1<<$C),d7    ;CTRL-E or CTRL-C
  251.  
  252. * wait for signal
  253. waitloop    move.l    d7,d0
  254.     movea.l    (execbase-dt,a4),a6
  255.     libcall    Wait
  256.     andi.l    #(1<<$C)!(1<<$E),d0
  257.     bne    cleanup
  258.  
  259. * not CTRL-C or CTRL-E so must be portsignal
  260. getmsgloop    movea.l    (execbase-dt,a4),a6
  261.     movea.l    (brokerport-dt,a4),a0
  262.     libcall    GetMsg
  263.     tst.l    d0    ;another Message?
  264.     beq.b    waitloop
  265.     movea.l    d0,a5    ;store Message ptr
  266.  
  267. * check Message type
  268.     movea.l    d0,a0
  269.     movea.l    (cxbase-dt,a4),a6
  270.     libcall    CxMsgType
  271.     cmpi.l    #CXM_COMMAND,d0
  272.     bne.b    replymsg    ;unknown msg
  273.  
  274. * respond to command
  275.     movea.l    a5,a0
  276.     libcall    CxMsgID
  277. disable    cmpi.l    #CXCMD_DISABLE,d0
  278.     bne.b    enable
  279.     movea.l    (broker-dt,a4),a0
  280.     moveq    #0,d0    ;disable code
  281.     libcall    ActivateCxObj
  282.     bra.b    replymsg
  283.  
  284. enable    cmpi.l    #CXCMD_ENABLE,d0
  285.     bne.b    kill
  286.     movea.l    (broker-dt,a4),a0
  287.     moveq    #1,d0    ;enable code
  288.     libcall    ActivateCxObj
  289.     bra.b    replymsg
  290.  
  291. kill    cmpi.l    #CXCMD_KILL,d0
  292.     bne.b    unique
  293. gotkill    movea.l    a5,a1
  294.     movea.l    (execbase-dt,a4),a6
  295.     libcall    ReplyMsg
  296.     bra     cleanup
  297.  
  298. unique    cmpi.l    #CXCMD_UNIQUE,d0
  299.     bne.b    replymsg
  300.     bra.b    gotkill
  301.  
  302. replymsg    movea.l    a5,a1
  303.     movea.l    (execbase-dt,a4),a6
  304.     libcall    ReplyMsg
  305.     bra    getmsgloop
  306.  
  307. cleanup    move.l    (broker-dt,a4),d0
  308.     beq.b    deleteport
  309.     movea.l    d0,a0
  310.     movea.l    (cxbase-dt,a4),a6
  311.     libcall    DeleteCxObjAll    ;delete CxObjs
  312.  
  313. deleteport    tst.l    (brokerport-dt,a4)
  314.     beq.b    closecx
  315. clearmsg    movea.l    (execbase-dt,a4),a6
  316.     movea.l    (brokerport-dt,a4),a0
  317.     libcall    GetMsg
  318.     tst.l    d0    ;another Message?
  319.     beq.b    nomsgs
  320.     movea.l    d0,a1
  321.     libcall    ReplyMsg
  322.     bra.b    clearmsg
  323.  
  324. nomsgs    movea.l    (brokerport-dt,a4),a0
  325.     libcall    DeleteMsgPort
  326.  
  327. closecx    movea.l    (execbase-dt,a4),a6
  328.     movea.l    (cxbase-dt,a4),a1
  329.     libcall    CloseLibrary
  330.     bra    exit
  331.  
  332. * Here are the two CUSTOM CxObj functions.  Since they are called from
  333. * commodities.library, they cannot use (x,A4) addressing.
  334.  
  335. * An oddity: Under 2.04 the function need not save a6 if all input comes
  336. * from the keyboard.  However, if another program is simulating keypresses
  337. * by writing to input.device, then the system will crash if a6 is not saved.
  338.  
  339. defaultfunc    pushm    d0/a0/a6
  340.     movea.l    (16,sp),a0        ;CxMsg ptr is on stack
  341.     movea.l    (cxbase,pc),a6
  342.     libcall    CxMsgData    ;get input event
  343.     movea.l    d0,a0
  344.     move.w    (ie_Qualifier,a0),d0
  345.     andi.w    #IEQUALIFIER_LSHIFT!IEQUALIFIER_RSHIFT,d0
  346.     bne.b    cancel1
  347.     ori.w    #IEQUALIFIER_LSHIFT,(ie_Qualifier,a0) ;add SHIFT
  348.     bra.b    enddefaultfunc
  349.  
  350. cancel1    andi.w    #~(IEQUALIFIER_LSHIFT!IEQUALIFIER_RSHIFT!IEQUALIFIER_CAPSLOCK),(ie_Qualifier,a0)
  351. * this clears the Shift and CapsLock bits
  352.  
  353. enddefaultfunc
  354.     popm    d0/a0/a6
  355.     rts
  356.  
  357. hotfunc    pushm    d0/a0/a6
  358.     movea.l    (16,sp),a0        ;CxMsg ptr is on stack
  359.     movea.l    (cxbase,pc),a6
  360.     libcall    CxMsgData    ;get input event
  361.     movea.l    d0,a0
  362.     move.w    (ie_Qualifier,a0),d0
  363.     andi.w    #IEQUALIFIER_LSHIFT!IEQUALIFIER_RSHIFT,d0
  364.     bne.b    cancel2
  365.     ori.w    #IEQUALIFIER_LSHIFT,(ie_Qualifier,a0) ;add SHIFT
  366.     andi.w    #~IEQUALIFIER_CAPSLOCK,(ie_Qualifier,a0) ;delete CAPSLOCK
  367.     bra.b    endhotfunc
  368.  
  369. cancel2    andi.w    #~(IEQUALIFIER_LSHIFT!IEQUALIFIER_RSHIFT