home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_progs / prog-asm / assemtls.lzh / ASSEMTOOLS / ASOURCE / FKEY.ASM < prev    next >
Encoding:
Assembly Source File  |  1991-08-16  |  12.2 KB  |  503 lines

  1. ;
  2. ; ### Function key handler by JM v 1.06 ###
  3. ;
  4. ; - Created 890125 by JM -
  5. ;
  6. ;
  7. ; This program links an input handler into the Input.device and converts
  8. ; the function key codes into ASCII strings.
  9. ;
  10. ;
  11. ;
  12. ;
  13. ; Bugs: yet unknown
  14. ;
  15. ;
  16. ; Edited:
  17. ;
  18. ; - 890125 by JM -> v0.01    - uh-huh
  19. ; - 890126 by JM -> v0.02    - first test
  20. ; - 890126 by JM -> v0.03    - replyport and sigbit really needed for
  21. ;                  DoIO().
  22. ; - 890126 by JM -> v0.04    - now allocates space for handler routine and
  23. ;                  key strings and creates a public message
  24. ;                  port.
  25. ; - 890126 by JM -> v0.05    - now allocates buffer for the generated
  26. ;                  input events.
  27. ; - 890126 by JM -> v0.06    - now generates the input events correctly.
  28. ; - 890126 by JM -> v0.07    - some minor changes.
  29. ; - 890126 by JM -> v0.08    - default fkey values added.
  30. ; - 890126 by JM -> v0.10    - comments improved.
  31. ; - 890127 by JM -> v0.11    - more keys defined.
  32. ; - 890127 by JM -> v1.0    - MESSAGE added.
  33. ; - 890311 by JM -> v1.01    - two branches converted to .s.
  34. ; - 890508 by JM -> v1.05    - cmd line parameters I (install) and R
  35. ;                  (remove) now processed.
  36. ; - 890513 by JM -> v1.06    - If key not defined, handler returns the
  37. ;                  original rawkey event.
  38. ;
  39. ;
  40.  
  41.  
  42.  
  43.         include    "exec.xref"
  44.         include    "dos.xref"
  45.         include    "JMPLibs.i"
  46.         include    "relative.i"
  47.         include    "com.i"
  48.         include    "string.i"
  49.         include    "exec/types.i"
  50.         include    "exec/nodes.i"
  51.         include    "exec/lists.i"
  52.         include    "exec/ports.i"
  53.         include    "exec/memory.i"
  54.         include    "exec/devices.i"
  55.         include    "exec/io.i"
  56.         include    "exec/tasks.i"
  57.         include    "devices/input.i"
  58.         include    "devices/inputevent.i"
  59.  
  60.  
  61. strcpy        macro    * a0,a1
  62. strcpy\@    move.b    (\1)+,(\2)+
  63.         bne.s    strcpy\@
  64.         endm
  65.  
  66.  
  67. RELATIVE    equ    1
  68.  
  69.         .var            allocates variables from stack
  70.         dl    _DosBase     using LINK a4,#-size
  71.         dl    iderror
  72.         dl    SignalB
  73.         dl    ioreq
  74.         dl    msgport
  75.         dl    globport
  76.         dl    cmd
  77.  
  78.  
  79. start        .begin                this turns to LINK a4,#-NN
  80.         bsr    ck_cmd
  81.         move.l    d0,cmd(a4)
  82.         moveq.l    #-1,d0
  83.         move.l    d0,iderror(a4)
  84.         move.l    d0,SignalB(a4)
  85.         clr.l    _DosBase(a4)
  86.         clr.l    globport(a4)
  87.         lea    IORequest,a0
  88.         move.l    a0,ioreq(a4)
  89.         lea    MsgPort,a0
  90.         move.l    a0,msgport(a4)
  91.  
  92.         openlib    Dos,cleanup        open dos.library
  93.  
  94.         lea    indevname(pc),a0    input.device
  95.         moveq.l    #0,d0            unit#
  96.         move.l    ioreq(a4),a1        IoReq
  97.         moveq.l    #0,d1            flags
  98.         lib    Exec,OpenDevice
  99.         move.l    d0,iderror(a4)        flag: error if > 0
  100.         bne    cleanup            if error
  101.  
  102.         move.l    msgport(a4),a2
  103.         move.b    #NT_MSGPORT,LN_TYPE(a2)    msgport.mp_Node.ln_Type = 4
  104.         clr.b    MP_FLAGS(a2)        msgport.mp_Flags = 0
  105.         clr.l    LN_NAME(a2)        no name
  106.  
  107.         moveq.l    #-1,d0
  108.         lib    Exec,AllocSignal    get a signal bit
  109.         move.l    d0,SignalB(a4)
  110.         bmi    cleanup
  111.         move.b    d0,MP_SIGBIT(a2)    msgport.mp_SigBit = d0
  112.  
  113.         sub.l    a1,a1
  114.         flib    Exec,FindTask        find this task
  115.         move.l    d0,MP_SIGTASK(a2)    set msgport.mp_SigTask
  116.  
  117.         lea    MP_MSGLIST(a2),a0
  118.         NEWLIST    a0
  119.         move.l    ioreq(a4),a1
  120.         move.l    a2,MN_REPLYPORT(a1)    ioreq.io_Message.mn_ReplyPort
  121.  
  122.         lea    MESSAGE(pc),a0
  123.         printa    a0
  124.  
  125.         lea    portname(pc),a1        test if port already exists
  126.         lib    Exec,FindPort
  127.         move.l    d0,globport(a4)
  128.  
  129.         move.l    cmd(a4),d0
  130.         beq.s    NoCommand
  131.         subq.l    #1,d0
  132.         bne.s    Command_1
  133.  
  134.         lea    USAGE(pc),a0
  135.         printa    a0
  136.         bra.s    clean1
  137.  
  138. Command_1    subq.l    #1,d0
  139.         bne.s    Command_2
  140.  
  141.         move.l    globport(a4),d0        install command
  142.         bne.s    clean1            -> already installed
  143.         bra.s    InstallKeys
  144.  
  145. Command_2    subq.l    #1,d0
  146.         bne.s    clean1
  147.  
  148.         move.l    globport(a4),d0        remove command
  149.         bne    RemoveKeys
  150. clean1        bra    cleanup
  151.  
  152. NoCommand    move.l    globport(a4),d0
  153.         bne.s    RemoveKeys        port exists -> remove everything
  154.  
  155. InstallKeys    bsr    CreatePort        create messageport
  156.         bcs.s    clean1            -> can't CreatePort()
  157.  
  158.         bsr    AllocBuffer        allocate memory
  159.         beq.s    clean1
  160.  
  161.         lea    MP_HANDLER(a2),a1    space for handler routine
  162.         lea    HANDBEG(pc),a0        source for copy
  163.         move.w    #HNDSIZ-1,d0        bytes to copy
  164. 1$        move.b    (a0)+,(a1)+
  165.         dbf    d0,1$
  166.  
  167.         lea    MP_FKEYS(a2),a0
  168.         move.l    a0,MP_DATA(a2)        set string buffer ptr
  169.  
  170.         lea    MP_HANDLER(a2),a0    a0 points to copy of hstuff
  171.         lea    HS_HANDLER(a0),a1
  172.         move.l    a1,HS_SERVER(a0)    set handler address
  173.         move.l    globport(a4),HS_PORT(a0) set port address
  174.  
  175.         move.l    ioreq(a4),a1
  176.         move.w    #IND_ADDHANDLER,IO_COMMAND(a1)
  177.         move.l    a0,IO_DATA(a1)
  178.         flib    Exec,DoIO        add handler
  179.         tst.l    d0
  180.         bne.s    cleanup
  181.  
  182.         bsr    defdef            set default fkey values
  183.  
  184.         lea    INSTALLED(pc),a0
  185.         printa    a0
  186.  
  187.         bra.s    cleanup
  188.  
  189.  
  190. RemoveKeys    move.l    ioreq(a4),a1
  191.         move.w    #IND_REMHANDLER,IO_COMMAND(a1)
  192.         move.l    d0,a0
  193.         lea    MP_HANDLER(a0),a0    addr of hstuff
  194.         move.l    a0,IO_DATA(a1)
  195.         lib    Exec,DoIO        remove handler
  196.         tst.l    d0
  197.         bne.s    cleanup
  198.  
  199.         lea    REMOVED(pc),a0        inform the user
  200.         printa    a0
  201.  
  202.         bsr    FreeBuffer        free allocated memory
  203.  
  204.         bsr    DeletePort        delete messageport
  205.  
  206. cleanup        move.l    iderror(a4),d0        test if input.device open
  207.         bne.s    cleanup10
  208.         move.l    ioreq(a4),a1
  209.         lib    Exec,CloseDevice    close input.device
  210.  
  211. cleanup10    move.l    SignalB(a4),d0        test if a signal allocated
  212.         bmi.s    cleanup11
  213.         lib    Exec,FreeSignal        if so, free it
  214.  
  215. cleanup11    closlib    Dos            close dos.library
  216.         moveq.l    #0,d0
  217.         .end                UNLK and RTS
  218.  
  219.  
  220.  
  221. *************************************************************************
  222. *                                    *
  223. * Create messageport so that the key strings etc. can be found by    *
  224. * other tasks like KEY.  Also needed to find the input handler and    *
  225. * to remove it from system when desired.                *
  226. *                                    *
  227. * This messageport stays in memory as long as the function keys are    *
  228. * active although the actual fkey program exits.  The buffers and    *
  229. * other variables immediately follow the standard MsgPort structure.    *
  230. *                                    *
  231. *************************************************************************
  232.  
  233. CreatePort    move.l    #MYPORT,d0
  234.         move.l    #MEMF_PUBLIC!MEMF_CLEAR,d1
  235.         lib    Exec,AllocMem
  236.         move.l    d0,globport(a4)
  237.         beq.s    CreatePort_e
  238.         move.l    d0,a2
  239.         move.b    #0,LN_PRI(a2)
  240.         move.b    #NT_MSGPORT,LN_TYPE(a2)
  241.  
  242.         lea    MP_MYNAME(a2),a1    pos of name within myport
  243.         move.l    a1,LN_NAME(a2)
  244.         lea    portname(pc),a0
  245.         strcpy    a0,a1            copy name into myport
  246.  
  247.         move.l    a2,a1
  248.         flib    Exec,AddPort        AddPort!  - Crash!? - No.
  249.         clrc
  250.         rts
  251.  
  252. CreatePort_e    setc
  253.         rts
  254.  
  255.  
  256. DeletePort    lea    portname(pc),a1
  257.         lib    Exec,FindPort
  258.         move.l    d0,a1
  259.         move.l    d0,d2
  260.         beq.s    DeletePort_ok
  261.         flib    Exec,RemPort
  262.         move.l    #MYPORT,d0
  263.         move.l    d2,a1
  264.         flib    Exec,FreeMem
  265. DeletePort_ok    rts
  266.  
  267.  
  268.  
  269. *************************************************************************
  270. *                                    *
  271. * Allocate buffer for extra InputEvent structures created when the user    *
  272. * presses a function key.                        *
  273. * We don't use dynamic allocation to save some time in the input    *
  274. * handler routine.                            *
  275. *                                    *
  276. *************************************************************************
  277.  
  278. AllocBuffer    move.l    globport(a4),a2
  279.         move.l    #(64*ie_SIZEOF),d0
  280.         move.l    d0,MP_BUFSIZ(a2)
  281.         move.l    #MEMF_PUBLIC!MEMF_CLEAR,d1
  282.         lib    Exec,AllocMem
  283.         move.l    d0,MP_BUFPTR(a2)
  284.         rts
  285.  
  286. FreeBuffer    move.l    globport(a4),a2
  287.         move.l    MP_BUFPTR(a2),d0
  288.         beq.s    FreeBuf_ok
  289.         move.l    d0,a1
  290.         move.l    MP_BUFSIZ(a2),d0
  291.         lib    Exec,FreeMem
  292.         clr.l    MP_BUFPTR(a2)
  293. FreeBuf_ok    rts
  294.  
  295.  
  296.  
  297. *************************************************************************
  298. *                                    *
  299. * Set default function key definitions:                    *
  300. *                                    *
  301. *************************************************************************
  302.  
  303. defdef        lea    deftable(pc),a0
  304.         move.l    globport(a4),a1
  305.         lea    MP_FKEYS(a1),a1
  306.         moveq.l    #19,d0            counter
  307. defloop1    lea.l    64(a1),a2        addr of next string
  308. defloop2    move.b    (a0)+,(a1)+
  309.         bpl.s    defloop2
  310.         move.l    a2,a1            next
  311.         dbf    d0,defloop1
  312.         rts
  313.  
  314.  
  315.  
  316. *************************************************************************
  317. *                                    *
  318. * Check for a command:                            *
  319. *                                    *
  320. *************************************************************************
  321.  
  322. ck_cmd        clr.b    -1(a0,d0)        NULL terminate cmd line
  323.         moveq.l    #0,d1            default: no command
  324.         move.b    (a0)+,d0        get first char
  325.         beq.s    ck_cmd_x        if NULL, exit
  326.         moveq.l    #1,d1            set flag: command exists
  327.         strlib    ucase
  328.         cmp.b    #'I',d0
  329.         bne.s    ck_cmd_1
  330.         moveq.l    #2,d1            'install' command
  331. ck_cmd_1    cmp.b    #'R',d0
  332.         bne.s    ck_cmd_x
  333.         moveq.l    #3,d1            'remove' command
  334. ck_cmd_x    move.l    d1,d0
  335.         rts
  336.  
  337.  
  338.         strlib
  339.         
  340. *************************************************************************
  341. *                                    *
  342. * My input handler routine.  It doesn't handle a linked list of input    *
  343. * events correctly because it only checks the first event of the list.    *
  344. * If the first one is a fkey the rest of the events in the queue are    *
  345. * discarded.  If the first event is not a fkey the list is passed    *
  346. * untouched to the next handler (ie. no later events are checked for    *
  347. * fkey codes).                                *
  348. *                                    *
  349. *************************************************************************
  350.  
  351. HANDBEG
  352.  
  353. hstuff        dc.l    0            ln_Succ
  354.         dc.l    0            ln_Pred
  355.         dc.b    2            ln_Type = NT_INTERRUPT
  356.         dc.b    60            ln_Pri
  357.         dc.l    0            ln_Name
  358. glport        dc.l    0            data
  359. hserver        dc.l    0            server
  360.  
  361. handler        push    d1-d7/a1-a6
  362.         move.l    a0,a5
  363.         cmpi.b    #IECLASS_RAWKEY,ie_Class(a0)
  364.         bne.s    handex
  365.         move.w    ie_Code(a0),d0
  366.         sub.w    #$50,d0
  367.         blo.s    handex
  368.         cmp.w    #$9,d0
  369.         bhi.s    handex
  370.         moveq.l    #IEQUALIFIER_LSHIFT!IEQUALIFIER_RSHIFT,d1 mask
  371.         and.w    ie_Qualifier(a0),d1    shift status
  372.         bsr.s    handlefkeys
  373.  
  374. handex        pull    d1-d7/a1-a6
  375.         move.l    a0,d0
  376.         rts
  377.  
  378. handlefkeys    tst.w    d1
  379.         beq.s    1$
  380.         add.w    #10,d0            -> shifted keys 10...19
  381. 1$        asl.w    #6,d0            calculate index into table
  382.         move.l    glport(pc),a0
  383.         move.l    MP_BUFPTR(a0),a1    buffer for input events
  384.         move.l    a1,a4            save it
  385.         lea    MP_FKEYS(a0),a0
  386.         add.w    d0,a0            pointer to fkey buffer
  387.         tst.b    (a0)
  388.         bmi.s    hndlfkeys_NULL        -> empty string
  389.  
  390.         moveq.l    #31,d2            char counter
  391.  
  392. hndl_next    clr.l    ie_NextEvent(a1)    initialize IEvent structure
  393.         move.b    #IECLASS_RAWKEY,ie_Class(a1)
  394.         clr.b    ie_SubClass(a1)
  395.         moveq.l    #0,d0
  396.         move.b    (a0)+,d0
  397.         move.w    d0,ie_Code(a1)
  398.         move.b    31(a0),d0
  399.         move.w    d0,ie_Qualifier(a1)
  400.         clr.l    ie_EventAddress(a1)
  401.         move.l    ie_TimeStamp(a5),ie_TimeStamp(a1)
  402.         move.l    ie_TimeStamp+4(a5),ie_TimeStamp+4(a1)
  403.         tst.b    (a0)
  404.         bmi.s    hndl_no_more        -> no more chars
  405.         subq.w    #1,d2
  406.         bmi.s    hndl_no_more
  407.         lea    ie_SIZEOF(a1),a2
  408.         move.l    a2,(a1)            set ptr to next ie
  409.         move.l    a2,a1
  410.         bra.s    hndl_next
  411.  
  412. hndl_no_more    move.l    a4,a0            -> return addr of new stream
  413.         rts
  414. hndlfkeys_NULL    move.l    a5,a0            -> original event
  415.         rts
  416.  
  417. HANDEND
  418. HS_SERVER    equ    hserver-hstuff        define offsets
  419. HS_HANDLER    equ    handler-hstuff
  420. HS_PORT        equ    glport-hstuff
  421. HNDSIZ        equ    HANDEND-HANDBEG
  422.  
  423.  
  424.  
  425. *************************************************************************
  426. *                                    *
  427. * Allocate space within messageport for port name, function key strings *
  428. * and the handler routine.                        *
  429. *                                    *
  430. *************************************************************************
  431.  
  432. MP_DATA        equ    MP_SIZE            pointer to string buffer
  433. MP_HANDLER    equ    MP_DATA+4        space for handler routine
  434. MP_BUFPTR    equ    MP_HANDLER+HNDSIZ    input event buffer pointer
  435. MP_BUFSIZ    equ    MP_BUFPTR+4        input event buffer size
  436. MP_MYNAME    equ    MP_BUFSIZ+4        pointer to buffer
  437. MP_FKEYS    equ    MP_MYNAME+16        buffer for key strings
  438. MYPORT        equ    MP_FKEYS+1340        size of my msgport
  439.  
  440.  
  441.  
  442.  
  443. indevname    dc.b    'input.device',0
  444. portname    dc.b    'FKeyPort',0
  445. INSTALLED    dc.b    'FKeys installed',10,0
  446. REMOVED        dc.b    'FKeys removed',10,0
  447. MESSAGE        dc.b    'FKEY 1.06 by Supervisor Software 1989',10,0
  448. USAGE        dc.b    'Usage: FKEY [I|R] where I=install; R=remove',10,0
  449.  
  450. *************************************************************************
  451. *                                    *
  452. * Default function key definitions in raw key codes.            *
  453. * No qualifiers can be set here.                    *
  454. *                                    *
  455. *************************************************************************
  456.  
  457. deftable    dc.b    $36,$12,$11,$33,$28,$17,$44,-1       newcli<cr>
  458.         dc.b    $12,$36,$22,$33,$28,$17,$44,-1       endcli<cr>
  459.         dc.b    $22,$17,$13,$44,-1           dir<cr>
  460.         dc.b    $28,$17,$21,$14,$44,-1           list<cr>
  461.         dc.b    $33,$22,$40,-1               cd<spc>
  462.         dc.b    $13,$16,$36,$40,-1           run<spc>
  463.         dc.b    $12,$32,$12,$33,$16,$14,$12,$40,-1 execute<spc>
  464.         dc.b    $17,$36,$23,$18,$44,-1           info<cr>
  465.         dc.b    $20,$34,$20,$17,$28,$44,-1       avail<cr>
  466.         dc.b    $35,$13,$12,$20,$27,$40,-1       break<spc>
  467.         dc.b    -1            11
  468.         dc.b    -1            12
  469.         dc.b    -1            13
  470.         dc.b    -1            14
  471.         dc.b    -1            15
  472.         dc.b    -1            16
  473.         dc.b    -1            17
  474.         dc.b    -1            18
  475.         dc.b    -1            19
  476.         dc.b    -1            20
  477.  
  478.  
  479.  
  480. *************************************************************************
  481. *                                    *
  482. * This macro produces only the dos.library name in this program.    *
  483. *                                    *
  484. *************************************************************************
  485.  
  486.         libnames
  487.  
  488.  
  489.  
  490. *************************************************************************
  491. *                                    *
  492. * Structures defined in a bss chunk to make the program file smaller.    *
  493. *                                    *
  494. *************************************************************************
  495.  
  496.         section    struct,bss
  497.  
  498. IORequest    ds.b    IO_SIZE            struct IOStdReq
  499. MsgPort        ds.b    MP_SIZE            struct MsgPort
  500.  
  501.         end
  502.  
  503.