home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 325.lha / keys / k.asm < prev    next >
Assembly Source File  |  1989-12-26  |  26KB  |  1,252 lines

  1. *------------------------------------------------------------------------------
  2. *
  3. *  k.asm - a key macro utility.
  4. *  
  5. *------------------------------------------------------------------------------
  6.  
  7.     Section    KeyCode,code
  8.  
  9. ******* Included Files *************************************************
  10.  
  11.     INCLUDE "keys.i"
  12.  
  13.  
  14. ******* Imported *******************************************************
  15.  
  16.     xref    _SysBase
  17.     xref    _DOSBase
  18.     xref    _IntuitionBase    
  19.     xref    _exit
  20.  
  21.     xref    NWPointer        ; pointer to NewWindow structure.
  22.     xref    FreePort
  23.  
  24.     xref    _bopen
  25.     xref    _bclose
  26.     xref    _bread
  27.     xref    _bwrite
  28.  
  29. ******* Exported *******************************************************
  30.  
  31.     xdef    IHandler    
  32.     xdef    IntRec
  33.     xdef    ConIOBlock
  34.     xdef    InpIOBlock
  35.     xdef    TheTitle
  36.     xdef    DefinedKeys
  37.     xdef    StringBuf
  38.     xdef    AddKey
  39.     xdef    FileReadChar
  40.     xdef    _main
  41.  
  42.  
  43.  
  44. *------------------------------------------------------------------------------
  45. _main
  46.     ;------ Get ready to process input
  47.     bsr    SetupStuff
  48.  
  49. 0$    move.l    OurSigMask(pc),d0
  50.     ExecF    Wait
  51.  
  52.     ;------ We got a signal - Do what we came here for...
  53.     ;------ If Event is null, wait some more. If it is DOCMD, open
  54.     ;------ the command window. Any other value is considered to be
  55.     ;------ a process macro command.
  56.     tst.b    Event
  57.     beq.s    0$
  58.  
  59.     cmp.b    #DOCMD,Event
  60.     beq.s    2$
  61.  
  62. 1$    ;------ At this point, we have a macro to process. Check the Q
  63.     ;------ for the next one.
  64.     bsr    DeQ
  65.     beq.s    0$
  66.     
  67.     lea    kr_MacStr(a2),a2
  68.     bsr    InsertString
  69.     bra.s    1$            ; Check for another macro.
  70.  
  71. 2$    ;------ Set the current directory to the Initial CLI's.
  72.     ;------ This has been taken out because this prog crashes
  73.     ;------ violently if the Initial CLI no longer exists...
  74.     ;    bsr    SetDirectory
  75.  
  76.     ;------ Get the ptr to the current (frontmost) screen
  77.     ;------ courtesy of intuitionbase.
  78.     move.l    _IntuitionBase(pc),a0
  79.     move.l    ib_FirstScreen(a0),a1
  80.  
  81.     ;------ We now have a pointer to the screen structure in a1.
  82.     ;------ Open a window onto this screen.    
  83.     bsr    OpenTheWindow
  84.  
  85.     ;------ Open the console device on this window:
  86.     bsr    OpenCon
  87.  
  88.     ;------ Read Choice and process it
  89.     bsr    ProcessChoice
  90.  
  91.     ;------ All done - close the console device and window.
  92.     bsr    CloseAll
  93.     tst.b    KillFlag
  94.     beq.s    0$
  95.     rts
  96.  
  97.  
  98. *------------------------------------------------------------------------------
  99. SetDirectory
  100.     ;------ Set our directory to the Initial CLI's, so we can find 
  101.     ;------ stuff.
  102.  
  103.     lea    CLIName(pc),a1
  104.     ExecF    FindTask
  105.  
  106.     move.l    d0,a0
  107.     move.l    pr_CurrentDir(a0),d1
  108.     DosF    CurrentDir
  109.     rts
  110.  
  111. *------------------------------------------------------------------------------
  112. ProcessChoice
  113.     move.l    sp,ErrorSp
  114.  
  115. 0$    ;------ Prompt for a menu choice and then execute it.
  116.     lea    ChoicePrompt(pc),a0
  117.     bsr    PutPrompt
  118.  
  119.     bsr    ConReadChar        ; get key...
  120.     move.b    CharBuf,d7
  121.  
  122.     ;------ Escape will terminate the window.
  123.     cmp.b    #27,d7
  124.     bne.s    1$
  125.     rts
  126.  
  127. 1$    bsr    ConWriteChar        ; ...echo character
  128.     bsr    ConReadChar        ; ...get another
  129.  
  130.     ;------ Do something with the entered choice.
  131.     Ucase    d7
  132.     
  133.     cmp.b    #'K',d7
  134.     seq    KillFlag
  135.     bne.s    2$
  136.     rts
  137.  
  138. 2$    cmp.b    #'R',d7
  139.     bne.s    4$
  140.     bsr    RemoveKey
  141.     bra.s    0$
  142.  
  143. 4$    cmp.b    #'D',d7
  144.     bne.s    6$
  145.     bsr    DefineKey
  146.     bra.s    0$
  147.  
  148. 6$    cmp.b    #'S',d7
  149.     bne.s    8$
  150.     bsr    SaveKeys
  151.     bra.s    0$
  152.     
  153. 8$    cmp.b    #'L',d7
  154.     bne.s    10$
  155.     bsr    LoadKeys
  156.     bra.s    0$
  157.     
  158. 10$    cmp.b    #'V',d7
  159.     bne.s    12$
  160.     bsr    ViewKeys
  161.  
  162. 12$    bra.s    0$        ; Bad choice, get another one.
  163.  
  164.  
  165. *------------------------------------------------------------------------------
  166. DefineKey
  167.     ;------ Prompt for the key to define, and then define it!
  168.     lea    DefinePrompt(pc),a0
  169.     bsr    PutPrompt
  170.     
  171.     lea    StringBuf(pc),a2
  172.     bsr    ConReadLine
  173.     
  174.     bsr    AddKey
  175.     move.l    a0,d7            ; Any mem free?
  176.     bne.s    0$            ; Nope, don't do nothin
  177.  
  178.     UhOh    ErNoMem            ; Print no mem msg.
  179.  
  180. 0$    lea    MacPrompt(pc),a0
  181.     bsr    PutPrompt
  182.  
  183.     ;------ Get the key's definition
  184.     move.l    d7,a0
  185.     lea    kr_MacStr(a0),a2
  186.     bsr    ConReadLine
  187.     rts
  188.     
  189.  
  190. *------------------------------------------------------------------------------
  191. RemoveKey
  192.     ;------ Prompt for the key to remove.
  193.     lea    RemovePrompt(pc),a0
  194.     bsr    PutPrompt
  195.     
  196.     ;------ Get key description.
  197.     lea    StringBuf(pc),a2
  198.     bsr    ConReadLine
  199.     
  200.     ;------ Convert description to Qualifier/Code form.
  201.     lea    StringBuf(pc),a2
  202.     bsr    ConvertCharacter
  203.  
  204.     swap    d0
  205.     move.w    d1,d0
  206.     swap    d0
  207.     bsr    LookForKey
  208.     bne.s    2$
  209.  
  210.     UhOh    ErNoKey
  211.  
  212. 2$    ;------ Remove the key from the list.
  213.     bsr    DelKey
  214.     rts
  215.     
  216.  
  217. *------------------------------------------------------------------------------
  218. LoadKeys
  219.     lea    LoadPrompt(pc),a0
  220.     bsr    PutPrompt
  221.     lea    StringBuf(pc),a2
  222.     bsr    ConReadLine
  223.  
  224.     ;------ Attempt to open the file
  225.     move.l    #StringBuf,d1
  226.     move.l    #MODE_OLDFILE,d2
  227.     move.l    #2048,d3
  228.     jsr    _bopen
  229.     move.l    d0,d4
  230.     bne.s    0$
  231.  
  232.     UhOh    ErNoFile
  233.     
  234. 0$    lea    LoadingMsg(pc),a0
  235.     bsr    PutWindowMsg
  236.  
  237. 2$    move.b    #' ',d5
  238.     lea    StringBuf(pc),a2
  239.     bsr    FileReadItem
  240.     beq.s    4$
  241.  
  242.     bsr    AddKey
  243.     cmpa.l    #0,a0
  244.     bne.s    3$
  245.  
  246.     move.l    d4,d1
  247.     jsr    _bclose
  248.     UhOh    ErNoMem
  249.     
  250. 3$    move.b    #10,d5
  251.     lea    kr_MacStr(a0),a2
  252.     bsr    FileReadItem
  253.     bra.s    2$
  254.  
  255. 4$    move.l    d4,d1
  256.     jsr    _bclose
  257.     rts
  258.  
  259.  
  260.  
  261. *------------------------------------------------------------------------------
  262. SaveKeys    
  263.     lea    SavePrompt(pc),a0
  264.     bsr    PutPrompt
  265.     lea    StringBuf(pc),a2
  266.     bsr    ConReadLine
  267.     
  268.     ;------ Attempt to open the file
  269.     move.l    #StringBuf,d1
  270.     move.l    #MODE_NEWFILE,d2
  271.     move.l    #2048,d3
  272.     jsr    _bopen
  273.     move.l    d0,d4
  274.     bne.s    0$
  275.  
  276.     UhOh    ErNoFile
  277.     
  278. 0$    lea    SavingMsg(pc),a0
  279.     bsr    PutWindowMsg
  280.  
  281.     lea    DefinedKeys(pc),a2
  282.  
  283. 2$    move.l    kr_Next(a2),a2
  284.     cmp.l    #0,a2
  285.     beq.s    4$
  286.     
  287.     ;------ Write the key description.
  288.     lea    kr_KeyStr(a2),a3
  289.     move.b    #' ',CharBuf
  290.     bsr    FileWriteItem
  291.     
  292.     ;------ Write the key macro string.
  293.     lea    kr_MacStr(a2),a3
  294.     move.b    #10,CharBuf
  295.     bsr    FileWriteItem
  296.     bra.s    2$
  297.  
  298. 4$    move.l    d4,d1
  299.     jsr    _bclose
  300.     rts
  301.  
  302.  
  303.  
  304. *------------------------------------------------------------------------------
  305. ViewKeys    
  306.     ClearWindow
  307.     lea    ViewPrompt(pc),a0
  308.     bsr    PutWindowMsg
  309.  
  310.     ;------ Resize the window
  311.     move.l    TheWindow(pc),a0
  312.     clr.l    d0
  313.     move.l    #178,d1
  314.     IntF    SizeWindow
  315.  
  316.     ;------ Create an input event so intuition will resize the window
  317.     move.w    #128,d0
  318.     clr.w    d1
  319.     bsr    InsertEvent
  320.  
  321.     ;------ Print the macros
  322.     lea    DefinedKeys(pc),a2
  323.  
  324. 2$    move.l    kr_Next(a2),a2
  325.     cmp.l    #0,a2
  326.     beq.s    4$
  327.     
  328.     ;------ Write the key description.
  329.     lea    kr_KeyStr(a2),a0
  330.     bsr    ConWriteLine
  331.     move.b    #' ',CharBuf
  332.     bsr    ConWriteChar
  333.     
  334.     ;------ Write the key macro string.
  335.     lea    kr_MacStr(a2),a0
  336.     bsr    ConWriteLine
  337.     lea    CrLf(pc),a0
  338.     bsr    ConWriteLine
  339.     bra.s    2$
  340.  
  341. 4$    bsr    ConReadChar
  342.  
  343.     ;------ Resize the window again
  344.     move.l    TheWindow(pc),a0
  345.     clr.l    d0
  346.     move.l    #-178,d1
  347.     IntF    SizeWindow
  348.     rts
  349.  
  350.  
  351. *------------------------------------------------------------------------------
  352. AddKey
  353.     ;------ Allocate a structure for a key macro, and link it to the
  354.     ;------ list. Return its address in a0.
  355.     
  356.     move.l    #kr_SIZEOF,d0
  357.     move.l    #(MEMF_PUBLIC!MEMF_CLEAR!MEMF_CHIP),d1
  358.     ExecF    AllocMem
  359.     tst.l    d0
  360.     bne.s    0$
  361.     
  362.     suba.l    a0,a0
  363.     rts
  364.  
  365. 0$    ;------ Add the record to the front of the list
  366.     lea    DefinedKeys(pc),a0
  367.     move.l    d0,a1
  368.     
  369.     move.l    kr_Next(a0),kr_Next(a1)
  370.     move.l    a1,kr_Next(a0)
  371.     move.l    a0,kr_Prev(a1)
  372.     
  373.     tst.l    kr_Next(a1)
  374.     beq.s    2$
  375.     
  376.     move.l    kr_Next(a1),a0
  377.     move.l    a1,kr_Prev(a0)
  378.  
  379. 2$    ;------ Place the defined key in the record
  380.     lea    StringBuf(pc),a2
  381.     bsr    ConvertCharacter
  382.     
  383.     move.w    d1,kr_Qual(a1)
  384.     move.w    d0,kr_Key(a1)
  385.     
  386.     lea    StringBuf(pc),a2
  387.     lea    kr_KeyStr(a1),a0
  388.     
  389. 4$    move.b    (a2)+,(a0)+
  390.     bne.s    4$
  391.  
  392.     move.l    a1,a0
  393.     rts
  394.  
  395.  
  396. *------------------------------------------------------------------------------
  397. DelKey
  398.     ;------ Remove the key rec specified by a0 from the key list.
  399.     move.l    kr_Prev(a0),a1
  400.     move.l    kr_Next(a0),a2
  401.  
  402.     move.l    kr_Next(a0),kr_Next(a1)
  403.     cmp.l    #0,a2
  404.     beq.s    2$
  405.  
  406.     move.l    a1,kr_Prev(a2)
  407.  
  408. 2$    move.l    a0,a1
  409.     move.l    #kr_SIZEOF,d0    
  410.     ExecF    FreeMem
  411.     rts
  412.     
  413.  
  414. *------------------------------------------------------------------------------
  415. LookForKey
  416.     ;------ Search for the key specified by d0 in the DefinedKey list.
  417.     ;------ If the key was found, its address will be in a0.
  418.     lea    DefinedKeys,a0
  419.  
  420. 0$    move.l    kr_Next(a0),a0
  421.  
  422.     cmpa.l    #0,a0
  423.     beq.s    2$
  424.  
  425.     cmp.l    kr_Qual(a0),d0
  426.     bne.s    0$
  427.     
  428.     moveq    #1,d0
  429. 2$    rts
  430.  
  431.  
  432. *------------------------------------------------------------------------------
  433. FileReadItem
  434.     ;------ This routine will read either the key def or the macro
  435.     ;------ def from the file depending on the delimiter.
  436.  
  437.     clr.l    d6        ; Keep a character count.
  438.  
  439. 0$    bsr    FileReadChar
  440.     tst.l    d0
  441.     beq.s    4$
  442.  
  443.     cmp.b    #76,d6
  444.     blt.s    1$
  445.  
  446.     move.l    d4,d1
  447.     jsr    _bclose
  448.     UhOh    ErDefTooLong
  449.  
  450. 1$    cmp.b    (a2),d5
  451.     beq.s    2$
  452.  
  453.     addq.l    #1,a2
  454.     addq.l    #1,d6
  455.     bra.s    0$
  456.     
  457. 2$    clr.b    (a2)
  458.     moveq    #1,d0
  459. 4$    rts
  460.  
  461.  
  462. *------------------------------------------------------------------------------
  463. FileReadChar
  464.     move.l    d4,d1
  465.     move.l    a2,d2
  466.     moveq.l    #1,d3
  467.     jsr    _bread
  468.     rts
  469.  
  470.  
  471. *------------------------------------------------------------------------------
  472. FileWriteItem
  473.     ;------ Write the item to the file, and the terminator in CharBuf.
  474.     ;------ a3 points to the item to write.
  475.     
  476. 0$    bsr    FileWriteChar
  477.     
  478.     addq.l    #1,a3
  479.     tst.b    (a3)
  480.     bne.s    0$
  481.     
  482.     ;------ Write the terminator to the file.
  483.     lea    CharBuf(pc),a3
  484.     bsr    FileWriteChar
  485.     rts
  486.  
  487.  
  488. *------------------------------------------------------------------------------
  489. FileWriteChar
  490.     ;------ Write the character pointed to by a3 to the file (d4).
  491.     move.l    d4,d1
  492.     move.l    a3,d2
  493.     moveq.l    #1,d3
  494.     jsr    _bwrite
  495.     rts
  496.  
  497. *------------------------------------------------------------------------------
  498. PutPrompt
  499.     ;------ Put a prompt in the title line, clear the window and 
  500.     ;------ place a prompt character in it. The desired prompt
  501.     ;------ is in (a0).
  502.  
  503.     bsr    PutWindowMsg
  504.  
  505.     ClearWindow
  506.  
  507.     lea    PromptStr(pc),a0
  508.     bsr    ConWriteLine
  509.     rts
  510.  
  511.     
  512. *------------------------------------------------------------------------------
  513. PutWindowMsg
  514.     ;------ Put a message in the window's title line. The message consists
  515.     ;------ of two parts: The window's title, and the specified message.
  516.     lea    StringBuf(pc),a2
  517.     lea    TheTitle(pc),a1
  518.     
  519. 0$    move.b    (a1)+,(a2)+
  520.     bne.s    0$
  521.  
  522.     lea    -1(a2),a2
  523. 2$    move.b    (a0)+,(a2)+
  524.     bne.s    2$
  525.  
  526.     ;------ Now print the prompt.
  527.     lea    StringBuf(pc),a1
  528.     move.l    #-1,a2
  529.     move.l    TheWindow(pc),a0
  530.     IntF    SetWindowTitles
  531.     rts    
  532.  
  533. *------------------------------------------------------------------------------
  534. ProcessError
  535.     bsr    PutWindowMsg
  536.     bsr    ConReadChar
  537.     move.l    ErrorSp(pc),sp
  538.     bra    ProcessChoice    
  539.     rts
  540.  
  541.  
  542.  
  543. *------------------------------------------------------------------------------
  544. EnQ
  545.     ExecF    Forbid
  546.  
  547.     cmp.w    #64,QC            ; Full yet?
  548.     beq.s    0$
  549.  
  550.     lea    CmdQ(pc),a1
  551.  
  552.     addq.b    #4,QB+1
  553.     move.w    QB(pc),d0
  554.     move.l    a3,0(a1,d0.w)
  555.     addq.w    #1,QC
  556.  
  557. 0$    ExecF    Permit
  558.     rts
  559.  
  560. *------------------------------------------------------------------------------
  561. DeQ
  562.     ExecF    Forbid
  563.  
  564.     tst.w    QC
  565.     sne.b    d2
  566.     beq.s    0$
  567.  
  568.     lea    CmdQ(pc),a1
  569.  
  570.     addq.b    #4,QF+1
  571.     move.w    QF,d0
  572.  
  573.     move.l    0(a1,d0.w),a2
  574.     subq.w    #1,QC
  575.  
  576. 0$    ExecF    Permit
  577.     tst.b    d2
  578.     rts
  579.  
  580.  
  581. *------------------------------------------------------------------------------
  582. *
  583. *  This section contains initialization and termination routines.
  584. *  
  585. *------------------------------------------------------------------------------
  586.  
  587.  
  588. *------------------------------------------------------------------------------
  589. SetupStuff
  590.     ;------ Perform the required initialization for console and 
  591.     ;------ input device I/O.
  592.  
  593.     ;------ Initialize the queue.
  594.     move.w    #252,QF
  595.     move.w    #252,QB
  596.     clr.w    QC
  597.  
  598.     ;------ Fetch our task pointer
  599.     move.l    _SysBase(pc),a0
  600.     move.l    ThisTask(a0),OurTask
  601.     
  602.     ;------ Allocate a StdIORequest block for console I/O.
  603.     bsr    AllocIOBlock
  604.     move.l    d0,ConIOBlock
  605.  
  606.     ;------ Allocate a StdIORequest block for input.device I/O.
  607.     bsr    AllocIOBlock
  608.     move.l    d0,InpIOBlock
  609.  
  610.     ;------ Get a signal for us to use...
  611.     bsr    AllocSignal
  612.  
  613.     ;------ Open the input.device
  614.     bsr    OpenInputDevice
  615.  
  616.     ;------ Set up the interrupt handler node, and tell the input.dev
  617.     ;------ about it.
  618.     bsr    SetInputInterrupt
  619.     rts
  620.  
  621.  
  622. *------------------------------------------------------------------------------
  623. AllocIOBlock
  624.     ;------ Allocate a STDIO block.
  625.  
  626.     ;------ First, create the message port
  627.     moveq    #-1,d0
  628.     ExecF    AllocSignal
  629.  
  630.     move.l    d0,d2            ; Save this for the moment...
  631.     cmp.l    #-1,d0            ; Did we get it?
  632.     beq.s    0$
  633.  
  634.     ;------ Allocate memory for the port:
  635.     move.l    #(MEMF_PUBLIC!MEMF_CLEAR),d1
  636.     move.l    #MP_SIZE,d0
  637.     LibF    AllocMem
  638.  
  639.     tst.l    d0                ; Any memory free?
  640.     beq.s    2$                ; Nope, exit w/error.
  641.  
  642.     move.l    d0,a2                ; Make me a pointer to this...
  643.     
  644.     ;------ Set up the port values
  645.     move.b    #NT_MSGPORT,LN_TYPE(a2)        ; type = message port
  646.     move.b    #PA_SIGNAL,MP_FLAGS(a2)        ; signal me...
  647.     move.b    d2,MP_SIGBIT(a2)        ; ...with this signal
  648.     move.l    OurTask(pc),MP_SIGTASK(a2)    ; signal our task
  649.  
  650.     ;------ Add the port to the list
  651.     lea    MP_MSGLIST(a2),a0
  652.     NEWLIST    a0
  653.  
  654.     ;------ Now create the request block
  655.     move.l    #IOSTD_SIZE,d0
  656.     move.l    #(MEMF_CLEAR!MEMF_PUBLIC),d1
  657.     ExecF    AllocMem
  658.     
  659.     tst.l    d0                ; Any mem?
  660.     beq.s    0$                ; Nope, free the port & exit.
  661.     
  662.     move.l    d0,a0
  663.     move.b    #NT_MESSAGE,LN_TYPE(a0)
  664.     move.w    #IOSTD_SIZE,MN_LENGTH(a0)
  665.     move.l    a2,MN_REPLYPORT(a0)
  666.     rts
  667.  
  668. 0$    ;------ Free the port
  669.     jsr    FreePort
  670.     bra.s    4$
  671.  
  672. 2$    ;------ Free the signal
  673.     move.l    d2,d0    
  674.     LibF    FreeSignal
  675. 4$    clr.l    d0
  676.     rts
  677.  
  678.  
  679. *------------------------------------------------------------------------------
  680. AllocSignal
  681.     ;------ Get a signal for us to use, and make it into a signal mask
  682.     ;------ for the Exec Wait() function.
  683.  
  684.     moveq    #-1,d0
  685.     ExecF    AllocSignal
  686.     tst.l    d0
  687.     beq.s    0$
  688.  
  689.     moveq    #1,d1
  690.     lsl.l    d1,d0
  691.     move.l    d0,OurSigMask
  692. 0$    rts
  693.  
  694.     
  695. *------------------------------------------------------------------------------
  696. OpenInputDevice
  697.     ;------ Umm... open the input.device
  698.     
  699.     clr.l    d1            ; Flags
  700.     clr.l    d0            ; Unit number
  701.     lea    IDName(pc),a0        ; Input device name
  702.     move.l    InpIOBlock,a1        ; The IORequest block
  703.     ExecF    OpenDevice
  704.     rts
  705.  
  706.  
  707. *------------------------------------------------------------------------------
  708. SetInputInterrupt
  709.     ;------ Set up the interrupt handler node, and tell the input.dev
  710.     ;------ to install it.
  711.     
  712.     ;------ Note that we set the priority to 51. This magic number 
  713.     ;------ assures us that we will get the event before intuition
  714.     ;------ because intuition only has a priority of 50.
  715.  
  716.     lea    IntRec,a0
  717.     
  718.     clr.l    IS_DATA(a0)            ; No data...
  719.     move.l    #IHandler,IS_CODE(a0)        ; Point to our handler
  720.     move.b    #51,LN_PRI(a0)            ; Set the priority
  721.  
  722.     ;------ Set up the IO request block
  723.     move.l    InpIOBlock,a1
  724.  
  725.     move.w    #IND_ADDHANDLER,IO_COMMAND(a1)
  726.     move.l    a0,IO_DATA(a1)
  727.  
  728.     ;------ Send the bitch!
  729.     ExecF    DoIO
  730.     rts
  731.  
  732.  
  733. *------------------------------------------------------------------------------
  734. OpenCon    
  735.     ;------ Open the console device for our window...
  736.     move.l    ConIOBlock,a1
  737.     move.l    TheWindow,IO_DATA(a1)
  738.     move.l    #wd_Size,IO_LENGTH(a1)
  739.     lea    ConName(pc),a0
  740.     clr.l    d0
  741.     clr.l    d1
  742.     ExecF    OpenDevice
  743.     rts
  744.  
  745.  
  746. *------------------------------------------------------------------------------
  747. OpenTheWindow
  748.  
  749.     ;------ Open the window on the screen pointed to by a1.
  750.  
  751.     move.l    NWPointer,a0        ; Snag ptr to NewWindow struct
  752.     move.w    sc_Flags(a1),d0
  753.     and.w    #CUSTOMSCREEN,d0
  754.     
  755.     move.l    a1,nw_Screen(a0)
  756.     move.w    d0,nw_Type(a0)
  757.  
  758.     IntF    OpenWindow
  759.     move.l    d0,TheWindow
  760.     rts
  761.  
  762.  
  763. *------------------------------------------------------------------------------
  764. CloseAll
  765.  
  766.     ;------ Close the console device
  767.     move.l    ConIOBlock,a1
  768.     ExecF    CloseDevice
  769.  
  770.     ;------ Close the window
  771.     move.l    TheWindow,a0
  772.     IntF    CloseWindow
  773.     rts
  774.  
  775.  
  776. *------------------------------------------------------------------------------
  777. *
  778. *  This section contains all of the console I/O routines.
  779. *  
  780. *------------------------------------------------------------------------------
  781.  
  782. *------------------------------------------------------------------------------
  783. ConReadChar
  784.     ;------ Read one character from the console.
  785.     move.l    ConIOBlock(pc),a1
  786.     move.w    #CMD_READ,IO_COMMAND(a1)
  787.     move.l    #1,IO_LENGTH(a1)
  788.  
  789.     move.l    #CharBuf,IO_DATA(a1)
  790.     ExecF    DoIO
  791.     rts
  792.  
  793. *------------------------------------------------------------------------------
  794. ConReadLine
  795.     ;------ Read a line from the screen and stick it in (a2)
  796.     ;------ and null-terminate it in the process.
  797.  
  798.     move.l    a2,d2                ; Save this address...
  799.     moveq.l    #1,d3                ; Save character count
  800.     
  801. 0$    ;------ Get a character
  802.     bsr    ConReadChar
  803.  
  804.     ;------ Check for a BACKSPACE character.
  805.     cmp.b    #BACKSPACE,CharBuf
  806.     bne.s    2$
  807.  
  808.     bsr    EditBACKSPACE
  809.     bra.s    0$
  810.  
  811. 2$    ;------ If we have a CR char, print a newline and return.
  812.     cmp.b    #RETURN,CharBuf
  813.     bne.s    4$
  814.  
  815.     lea    CrLf(pc),a0
  816.     bsr    ConWriteLine
  817.     clr.b    (a2)
  818.     rts
  819.  
  820. 4$    ;------ Increment the buffer pointer and fetch another character.
  821.     cmp.w    #77,d3
  822.     bcc.s    0$
  823.  
  824.     ;------ Echo the character. 
  825.     bsr    ConWriteChar
  826.  
  827.     move.b    CharBuf,(a2)+
  828.     addq.l    #1,d3
  829.     bra.s    0$
  830.  
  831.  
  832. *------------------------------------------------------------------------------
  833. EditBACKSPACE
  834.     ;------ Edit the BACKSPACE character.
  835.  
  836.     ;------ If it is the first character on the line, do nothing.
  837.     cmp.l    a2,d2
  838.     beq.s    0$
  839.  
  840.     ;------ Print the backspace, and back up 1 space. 
  841.     lea    BackSpaceStr(pc),a0
  842.     bsr    ConWriteLine
  843.     subq.l    #1,a2
  844.     subq.l    #1,d3
  845. 0$    rts    
  846.  
  847.  
  848. *------------------------------------------------------------------------------
  849. ConWriteChar
  850.     ;------ Write the character in CharBuf on the screen.
  851.     lea    CharBuf(pc),a0
  852.     moveq.l    #1,d0
  853.     bra.s    ConWrite
  854.  
  855. *------------------------------------------------------------------------------
  856. ConWriteLine
  857.     ;------ Put the null terminated string (pointed to by a0) on the
  858.     ;------ screen.
  859.     moveq.l    #-1,d0            ; Fall thru to ConWrite...
  860.  
  861. *------------------------------------------------------------------------------
  862. ConWrite
  863.     ;------ Print d0 chars of string a0. If d0 is -1, we expect a0 to be
  864.     ;------ a null-terminated string.
  865.     move.l    ConIOBlock,a1
  866.     
  867.     move.l    a0,IO_DATA(a1)
  868.     move.l    d0,IO_LENGTH(a1)
  869.     move.w    #CMD_WRITE,IO_COMMAND(a1)
  870.     ExecF    DoIO
  871.     rts
  872.  
  873.  
  874. *------------------------------------------------------------------------------
  875. *
  876. *  This section handles the insertion of input events into the event stream.
  877. *  
  878. *------------------------------------------------------------------------------
  879.  
  880. *------------------------------------------------------------------------------
  881. ConvertCharacter
  882.     ;------ Convert the character pointed to by a2 to an Amiga-useable
  883.     ;------ qualifier/code pair.
  884.     clr.w    d0
  885.     clr.w    d1
  886.     lea    KeyTable(pc),a0
  887.  
  888. 0$    move.b    (a2)+,d0
  889.     beq    99$
  890.  
  891.     ;------ Test for an escape character.
  892.     cmp.b    #'\',d0
  893.     bne    50$
  894.  
  895.     ;------ Process escape character.
  896.     move.b    (a2)+,d0
  897.  
  898.     ;------ Test for left shift
  899.     cmp.b    #'s',d0
  900.     bne.s    2$
  901.  
  902.     bset    #L_SHIFT,d1
  903.     bra.s    0$
  904.  
  905. 2$    ;------ Test for right shift
  906.     cmp.b    #'S',d0
  907.     bne.s    4$
  908.  
  909.     bset    #R_SHIFT,d1
  910.     bra    0$
  911.  
  912. 4$    ;------ Test for left alt
  913.     cmp.b    #'a',d0
  914.     bne.s    6$
  915.  
  916.     bset    #L_ALT,d1
  917.     bra    0$
  918.  
  919. 6$    ;------ Test for right alt
  920.     cmp.b    #'A',d0
  921.     bne.s    8$
  922.  
  923.     bset    #R_ALT,d1
  924.     bra    0$
  925.  
  926. 8$    ;------ Not a case-sensitive key at this point, make it upper
  927.     ;------ case...
  928.     Ucase    d0
  929.  
  930.     ;------ Add Control qualifier.
  931.     cmp.b    #'C',d0
  932.     bne.s    10$
  933.  
  934.     bset    #CONTROL,d1
  935.     bra    0$            
  936.  
  937. 10$    ;------ Process Left-Amiga qualifier.
  938.     cmp.b    #'L',d0
  939.     bne.s    16$
  940.  
  941.     bset    #L_AMIGA,d1
  942.     bra    0$            
  943.     
  944.     ;------ Process Right-Amiga qualifier.
  945. 16$    cmp.b    #'R',d0
  946.     bne.s    18$
  947.  
  948.     bset    #R_AMIGA,d1
  949.     bra    0$            
  950.     
  951. 18$    ;------ Process Keypad qualifier.
  952.     cmp.b    #'K',d0
  953.     bne.s    24$
  954.  
  955.     ;------ The keypad keys present a special case: If the key is between
  956.     ;------ 0 and 9, set the keypad bit, else don't.
  957.     move.b    (a2)+,d0
  958.     cmp.b    #'0',d0
  959.     blt.s    20$
  960.  
  961.     bset    #KPAD,d1
  962.  
  963. 20$    lea    KeypadTable(pc),a0
  964.     sub.b    #'(',d0
  965.     lsl.b    #1,d0
  966.     move.b    1(a0,d0.w),d0        ; Fetch character code.
  967.     rts        
  968.  
  969.  
  970. 24$    ;------ Process Function keys.
  971.     cmp.b    #'F',d0
  972.     bne.s    28$
  973.  
  974.     move.b    (a2)+,d0
  975.     cmp.b    #'1',d0
  976.     bne.s    26$
  977.  
  978.     cmp.b     #'0',(a2)
  979.     bne.s    26$
  980.     
  981.     ;------ Process f10
  982.     addq.l    #1,a2
  983.     move.b    #('9'+1),d0
  984.     
  985. 26$    add.b    #31,d0
  986.     rts
  987.  
  988. 28$    ;------ Process Help key
  989.     cmp.b    #'H',d0
  990.     bne.s    30$
  991.  
  992.     move.b    #$5f,d0
  993.     rts
  994.  
  995. 30$    ;------ Process Cursor keys.
  996.     cmp.b    #'^',d0
  997.     bne.s    50$
  998.  
  999.     move.b    (a2)+,d0
  1000.     Ucase    d0
  1001.  
  1002.     cmp.b    #'U',d0
  1003.     bne.s    32$
  1004.  
  1005.     move.b    #$4c,d0
  1006.     rts
  1007.  
  1008. 32$    cmp.b    #'D',d0
  1009.     bne.s    34$
  1010.  
  1011.     move.b    #$4d,d0
  1012.     rts
  1013.  
  1014. 34$    cmp.b    #'L',d0
  1015.     bne.s    36$
  1016.  
  1017.     move.b    #$4f,d0
  1018.     rts
  1019.  
  1020. 36$    cmp.b    #'R',d0
  1021.     bne.s    38$
  1022.  
  1023.     move.b    #$4e,d0
  1024.     rts
  1025.  
  1026. 38$    bra    0$
  1027.  
  1028.     
  1029. 50$    ;------ Not an escape code, just print the character.
  1030.     sub.w    #27,d0            ; Subtract table base.
  1031.     lsl.b    #1,d0            ; Calc table offset.    
  1032.  
  1033.     move.b    0(a0,d0.w),d2
  1034.     or.b    d2,d1            ; Form character qualifer.
  1035.  
  1036.     move.b    1(a0,d0.w),d0        ; Fetch character code.
  1037. 99$    rts
  1038.  
  1039.  
  1040.     
  1041. *------------------------------------------------------------------------------
  1042. InsertString
  1043.     ;------ Insert the string into the input event stream
  1044.     bsr    ConvertCharacter
  1045.     beq.s    0$
  1046.  
  1047.     bsr    InsertEvent
  1048.     bra.s    InsertString
  1049. 0$    rts
  1050.     
  1051.  
  1052. *------------------------------------------------------------------------------
  1053. InsertEvent
  1054.     ;------ Insert the event into the input stream. The event will be
  1055.     ;------ coded as: code=d0, qualifier=d1
  1056.     lea    MyEventDn(pc),a0
  1057.     lea    MyEventUp(pc),a1
  1058.  
  1059.     ;------ Set up the input event.
  1060.     move.l    a1,ie_NextEvent(a0)
  1061.     move.b    #IECLASS_RAWKEY,ie_Class(a0)
  1062.     move.w    d0,ie_Code(a0)
  1063.     move.w    d1,ie_Qualifier(a0)
  1064.     clr.w    ie_X(a0)
  1065.     clr.w    ie_Y(a0)
  1066.     clr.l    ie_TimeStamp(a0)
  1067.     clr.l    (ie_TimeStamp+4)(a0)
  1068.  
  1069.     ;------ Set up the input event.
  1070.     clr.l    ie_NextEvent(a1)
  1071.     move.b    #IECLASS_RAWKEY,ie_Class(a1)
  1072.     add.w    #128,d0
  1073.     move.w    d0,ie_Code(a1)
  1074.     move.w    d1,ie_Qualifier(a1)
  1075.     clr.w    ie_X(a1)
  1076.     clr.w    ie_Y(a1)
  1077.     clr.l    ie_TimeStamp(a1)
  1078.     clr.l    (ie_TimeStamp+4)(a1)
  1079.  
  1080.     ;------ Set up the IORequest block
  1081.     move.l    InpIOBlock(pc),a1
  1082.     move.w    #IND_WRITEEVENT,IO_COMMAND(a1)
  1083.     clr.b    IO_FLAGS(a1)
  1084.     move.l    #ie_SIZEOF,IO_LENGTH(a1)
  1085.     move.l    a0,IO_DATA(a1)
  1086.  
  1087.     ;------ Send the event
  1088.     ExecF    DoIO
  1089.     rts
  1090.  
  1091. *------------------------------------------------------------------------------
  1092. *
  1093. *  These two routines are input handler related
  1094. *  
  1095. *------------------------------------------------------------------------------
  1096.  
  1097. *------------------------------------------------------------------------------
  1098. LookupKey
  1099.     ;------ See if input event matches a defined key. a2 points to 
  1100.     ;------ input event struct.
  1101.  
  1102.     ;------ First, form search key.
  1103.     move.w    ie_Qualifier(a2),d0
  1104.     and.w    #%111111111,d0        ; don't care about upper bits
  1105.     
  1106.     ;------ Add the keycode to the qualifier, and look it up.
  1107.     swap    d0
  1108.     move.w    ie_Code(a2),d0
  1109.     bsr    LookForKey
  1110.     beq.s    4$    
  1111.  
  1112.     ;------ If we get here, we found the key. EnQ the event, set 
  1113.     ;------ Event to DOMAC, and leave.
  1114.     move.l    a0,a3            ; Get macro rec address for queueing
  1115.     bsr    EnQ
  1116.     move.b    #DOMAC,Event
  1117. 4$    rts
  1118.  
  1119.     
  1120.     
  1121. *------------------------------------------------------------------------------
  1122. IHandler
  1123.     ;------ When called, we get a pointer to the input-event chain
  1124.     ;------ in a0, and a pointer to our data in a1. We don't need
  1125.     ;------ a1 tho. 
  1126.  
  1127.     movem.l    a2/a3/a6,-(sp)        ; Save these
  1128.     move.l    a0,a2
  1129.  
  1130.     clr.b    Event                
  1131.     
  1132. 0$    cmp.b    #IECLASS_RAWKEY,ie_Class(a2)
  1133.     bne.s    4$
  1134.  
  1135.     bsr    LookupKey
  1136.     bne.s    2$
  1137.  
  1138.     cmp.w    #HELPKEY,ie_Code(a2)
  1139.     bne.s    4$
  1140.     btst.b    #IEQUALIFIERB_LCOMMAND,(ie_Qualifier+1)(a2)
  1141.     beq.s    4$
  1142.  
  1143.     move.b    #DOCMD,Event        ; Indicate: open command window
  1144.  
  1145. 2$    ;------ This is our event, remove it from the list and signal
  1146.     ;------ our task.
  1147.     move.l    ie_NextEvent(a2),a2
  1148.  
  1149.     ;------ Signal the waiting task.
  1150.     move.l    OurSigMask(pc),d0
  1151.     move.l    OurTask(pc),a1
  1152.     ExecF    Signal
  1153.  
  1154. 4$    move.l    a2,d0            ; Pass return value in d0
  1155.     movem.l    (sp)+,a2/a3/a6
  1156.     rts
  1157.     
  1158.  
  1159.  
  1160. *------------------------------------------------------------------------------
  1161. *
  1162. *  This is the Data section!
  1163. *  
  1164. *------------------------------------------------------------------------------
  1165. ConIOBlock    ds.l    1        ; Pointer to console.dev IOblock.
  1166. InpIOBlock    ds.l    1        ; Pointer to input.dev IOblock.
  1167. IntRec        ds.b    IS_SIZE        ; The interrupt handler node
  1168. MyEventDn    ds.b    ie_SIZEOF    ; My input event structure (key down).
  1169. MyEventUp    ds.b    ie_SIZEOF    ; My input event structure (key up).
  1170. ErrorSp        ds.l    1        ; Stack ptr used for error recovery.
  1171. CmdQ        ds.w    128        ; Queue for macros.
  1172. QF        ds.w    1        ; Front of Q pointer.
  1173. QB        ds.w    1        ; Back of Q pointer.
  1174. QC        ds.w    1        ; Elements in Q.
  1175.  
  1176. DefinedKeys    ;------ The first record in the chain
  1177.         dc.l    0    ; next
  1178.         dc.l    0    ; prev
  1179.         dc.w    0    ; key
  1180.         dc.b    0    ; definition
  1181.         ds.b    79
  1182.  
  1183. OurTask        ds.l    1        ; Pointer to our TCB.
  1184. OurSigMask    ds.l    1        ; Signal mask for our port.
  1185. TheWindow    ds.l    1        ; Pointer to our window structure.
  1186. StringBuf    ds.b    160        ; Buffer for reading strings
  1187.  
  1188. ;------ The following table is used to convert ascii characters to their 
  1189. ;------ keyboard equivalents. We put the qualifier in the first byte, and 
  1190. ;------ the key-code in the second. The table starts with an <escape> character.
  1191. KeyTable    
  1192.         ;------ Punctuation and digits (<esc> to '@')
  1193.         dc.w    $0045,$0000,$0000,$0000,$0000,$0040,$0101,$012a,$0103
  1194.         dc.w    $0104,$0105,$0107,$002a,$0109,$010a,$0108,$010c,$0038
  1195.         dc.w    $000b,$0039,$003a,$000a,$0001,$0002,$0003,$0004,$0005
  1196.         dc.w    $0006,$0007,$0008,$0009,$0129,$0029,$0138,$000c,$0139
  1197.         dc.w    $013a,$0102
  1198.         
  1199.         ;------ Upper case letters
  1200.         dc.w    $0120,$0135,$0133,$0122,$0112,$0123,$0124,$0125,$0117
  1201.         dc.w    $0126,$0127,$0128,$0137,$0136,$0118,$0119,$0110,$0113
  1202.         dc.w    $0121,$0114,$0116,$0134,$0111,$0132,$0115,$0131
  1203.         
  1204.         ;------ Punctuation
  1205.         dc.w    $001a,$000d,$001b,$0106,$010b,$0000
  1206.  
  1207.         ;------ Lower case letters
  1208.         dc.w    $0020,$0035,$0033,$0022,$0012,$0023,$0024,$0025,$0017
  1209.         dc.w    $0026,$0027,$0028,$0037,$0036,$0018,$0019,$0010,$0013
  1210.         dc.w    $0021,$0014,$0016,$0034,$0011,$0032,$0015,$0031
  1211.  
  1212.         ;------ Punctuation
  1213.         dc.w    $011a,$010d,$011b,$0100,$0046
  1214.  
  1215. KeypadTable
  1216.         ;------ Keypad keys starting with '('
  1217.         dc.w    $005a,$005b,$005d,$005e,$0000,$004a,$003c,$005c
  1218.         dc.w    $000f,$001d,$001e,$001f,$002d,$002e,$002f,$003d,$003e
  1219.         dc.w    $003f
  1220.  
  1221.  
  1222. CharBuf        ds.b    1            ; Buffer for reading characters.
  1223. KillFlag    ds.b    1            ; 'kill program' flag.
  1224. Event        ds.b    1            ; 'Type of input event' flag.
  1225.         cnop    0,2
  1226.  
  1227. CrLf        dc.b    13,10,0
  1228. BackSpaceStr    dc.b    $9b,$44,$9b,$50,0    ; Back up and delete char.
  1229. ClrWindowStr    dc.b    12,0
  1230. PromptStr    dc.b    '>',0
  1231.  
  1232. TheTitle    dc.b    'Keys V1.0  --  ',0
  1233. ChoicePrompt    dc.b    'Enter: (K)ill, (D)efine, (R)emove, (L)oad, (S)ave, (V)iew',0
  1234. DefinePrompt    dc.b    'Describe key to Define:',0
  1235. RemovePrompt    dc.b    'Describe key to Remove:',0
  1236. MacPrompt    dc.b    'Enter key definition:',0
  1237. LoadPrompt    dc.b    'Enter file name to Load:',0
  1238. SavePrompt    dc.b    'Enter file name to Save:',0
  1239. ViewPrompt    dc.b    'Key listing. Press any key to exit...',0
  1240.  
  1241. LoadingMsg    dc.b    'Loading...',0
  1242. SavingMsg    dc.b    'Saving...',0
  1243.  
  1244. ErNoMem        dc.b    'Error: No memory available',0
  1245. ErNoFile    dc.b    'Error: File not found',0
  1246. ErNoKey        dc.b    'Error: Key not defined',0
  1247. ErDefTooLong    dc.b    'Error: Macro definition exceeds 76 characters',0
  1248. ConName        dc.b    'console.device',0
  1249. IDName        dc.b    'input.device',0
  1250. CLIName        dc.b    'Initial CLI',0
  1251.         end    
  1252.