home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 2: PC / frozenfish_august_1995.bin / bbs / d07xx / d0789.lha / QMouse / qmouse.s < prev    next >
Text File  |  1992-12-24  |  29KB  |  1,493 lines

  1. ;QMouse.s
  2. ;Written by Dan Babcock
  3.  
  4. ;This source was assembled with Macro68 release 3.
  5.  
  6.     exeobj
  7.     objfile    'c:QMouse'
  8.     MC68000
  9.     multipass
  10.  
  11.     IFND    SYS
  12. SYS    macro
  13.     jsr    _LVO\1(a6)
  14.     endm
  15.     ENDC
  16.  
  17.     IFND    _custom
  18. _custom    equ    $dff000
  19.     ENDC
  20.  
  21.     IFND    _LVOSystemTagList
  22. _LVOSystemTagList    equ    -$25E
  23.     ENDC
  24.  
  25. SCREENLISTSIZE    equ    32    ;maximum number of screens to keep track of
  26. POINTERLISTSIZE    equ    32
  27. HANDLERPRI    equ    60    ;priority of input.device handler
  28. MaxCopperSize    equ    500
  29.  
  30. SysBackground    equ    $e    ;offset into gb_copinit copper list
  31. WindowStart    equ    $0    ;offset into LOF copper list
  32. DefColor    equ    $fff    ;white
  33. WaitLine    equ    $16
  34.  
  35.     move.l    4,a6
  36.     cmp.w    #37,LIB_VERSION(a6)
  37.     bhs    GoodVersion
  38.  
  39. ;Print an error message - the user doesn't have 2.0
  40.     lea    DosName(pc),a1
  41.     SYS    OldOpenLibrary
  42.     tst.l    d0
  43.     beq    ErrEnd
  44.     move.l    d0,a6
  45.     SYS    Output
  46.     move.l    d0,d1
  47.     moveq    #EndSorry-Sorry,d3
  48.     lea    Sorry(pc),a0
  49.     move.l    a0,d2
  50.     SYS    Write
  51.     move.l    a6,a1
  52.     move.l    4,a6
  53.     SYS    CloseLibrary
  54. ErrEnd:    moveq    #RETURN_FAIL,d0
  55.     rts
  56.  
  57.     dc.b    '$VER: QMouse 2.21 (6.12.92)',$a,0
  58. Sorry:    dc.b    'Sorry, this program requires Kickstart 2.0!',$a,0
  59. EndSorry:    even
  60.  
  61. GoodVersion:
  62.  
  63. ;Allocate global data structure
  64.     move.l    #Data_Sizeof,d0
  65.     move.l    #MEMF_CLEAR,d1
  66.     SYS    AllocMem
  67.     tst.l    d0
  68.     beq    ErrEnd
  69.     move.l    d0,a5
  70.     lea    GlobalPtr(pc),a0
  71.     move.l    a5,(a0)
  72.  
  73. ;Allocate chip RAM data.
  74.     move.l    #CData_Sizeof,d0
  75.     move.l    #MEMF_CLEAR+MEMF_CHIP,d1
  76.     SYS    AllocMem
  77.     move.l    d0,ChipData(a5)
  78.     beq    CleanUp
  79.  
  80. ;Initialize static data
  81.     move.b    #HANDLERPRI,InputInterrupt+LN_PRI(a5)
  82.     move.l    a5,InputInterrupt+IS_DATA(a5)
  83.     moveq    #1,d0
  84.     move.l    d0,ClickCount(a5)    ;***BUG: WAS A1 (trashing memory)
  85.                 ;THANKS to Chris Schneider for finding
  86.                 ;it!!!!!!!!!!!!!!!!
  87.  
  88. ;Open libraries
  89.     lea    LibTable(pc),a2
  90.     move.l    a2,a3
  91.     moveq    #NumLibs-1,d2
  92. .OLibLoop:
  93.     move.w    (a2)+,a1
  94.     add.l    a3,a1
  95.     SYS    OldOpenLibrary
  96.     move.w    (a2)+,a0
  97.     add.l    a5,a0
  98.     move.l    d0,(a0)
  99.     beq    CleanUp
  100.     dbra    d2,.OLibLoop
  101.  
  102. ;Parse command line
  103.     lea    Template(pc),a0
  104.     move.l    a0,d1
  105.     lea    Options(a5),a0
  106.     move.l    a0,d2
  107.     moveq    #0,d3    ;no custom rdarg structure
  108.     move.l    DosBase(a5),a6
  109.     SYS    ReadArgs
  110.     move.l    d0,ArgPtr(a5)
  111.     beq    CleanUp
  112.     move.l    4,a6
  113.  
  114. ;Process QUIT option, if selected.
  115.     tst.l    QuitOption(a5)
  116.     beq    .SkipQuit
  117.     lea    ProcName(pc),a1
  118.     SYS    FindTask
  119.     tst.l    d0
  120.     beq    CleanUp
  121.     move.l    d0,a1
  122.     move.l    TC_Userdata(a1),a0
  123.     move.l    QuitSig(a0),d0
  124.     SYS    Signal    ;tell task to quit
  125.     bsr    CleanUp
  126.     bra    .Exit
  127. .SkipQuit:
  128.  
  129. ;If already installed, kill the existing process.
  130.     lea    ProcName(pc),a1
  131.     SYS    FindTask
  132.     tst.l    d0
  133.     beq    .NotInstalled
  134.     move.l    d0,a1
  135.     move.l    TC_Userdata(a1),a0
  136.     move.l    QuitSig(a0),d0
  137.     SYS    Signal    ;tell task to quit
  138.  
  139.     moveq    #26,d2
  140. .Kill:    subq.l    #1,d2
  141.     beq    .Exit
  142.     move.l    DosBase(a5),a6
  143.     moveq    #2,d1
  144.     SYS    Delay
  145.     lea    ProcName(pc),a1
  146.     move.l    4,a6
  147.     SYS    FindTask
  148.     tst.l    d0
  149.     bne    .Kill
  150. .NotInstalled:
  151.  
  152. ;Get stack for command.
  153.     move.l    DosBase(a5),a6
  154.     SYS    Cli
  155.     move.l    d0,a0
  156.     move.l    cli_DefaultStack(a0),d0
  157.     lsl.l    #2,d0
  158.     lea    CmdStackSize(pc),a0
  159.     move.l    d0,(a0)
  160.     move.l    4,a6
  161.  
  162. ;Copy resident part of code into allocated memory
  163.     lea    StartAllocCode(pc),a0    ;source
  164.     lea    ResidentCode(a5),a1    ;destination
  165.     move.l    #ResidentCodeSize,d0    ;size
  166.     SYS    CopyMem
  167.     SYS    CacheClearU    ;for 020/030/040
  168.  
  169. ;Start a process
  170.     move.l    DosBase(a5),a6
  171.     lea    ResidentCode(a5),a0
  172.     lea    EntryPoint(pc),a1
  173.     move.l    a0,(a1)
  174.     lea    ProcName-StartAllocCode+ResidentCode(a5),a0
  175.     lea    ProcNamePtr(pc),a1
  176.     move.l    a0,(a1)
  177.     lea    NewProcTags(pc),a0
  178.     move.l    a0,d1
  179.     SYS    CreateNewProc
  180.  
  181. ;Exit back to CLI
  182. .Exit:    moveq    #0,d0
  183.     rts
  184.  
  185. ***************************************************************************
  186. * The following code is copied into allocated memory.                     *
  187. ***************************************************************************
  188.  
  189. StartAllocCode:
  190.     move.l    4,a6
  191.     move.l    GlobalPtr(pc),a5
  192.     lea    IntRoutine(pc),a0
  193.     move.l    a0,InputInterrupt+IS_CODE(a5)
  194.  
  195. ;Perform relocations.
  196.     lea    PatchAlert(pc),a1
  197.     movem.l    8(a1),d0-d2
  198.     add.l    a1,d0
  199.     add.l    a1,d1
  200.     add.l    a1,d2
  201.     movem.l    d0-d2,8(a1)
  202.  
  203. ;Initialize damping constant.
  204.     move.l    AccelOption(a5),d0
  205.     beq    .NoDamp
  206.     move.l    d0,a0
  207.     move.l    (a0),d0
  208.     subq.l    #1,d0
  209.     move.l    ThreshOption(a5),d1
  210.     beq    .DefThresh
  211.     move.l    d1,a0
  212.     move.l    (a0),d1
  213. .DefThresh:
  214.     addq.l    #1,d1
  215.     mulu.w    d0,d1
  216.     move.w    d1,DampingConstant(a5)
  217. .NoDamp:
  218.  
  219. ;Allocate signals
  220.     moveq    #NumSigs-1,d2
  221.     lea    Sigs(a5),a2
  222. .SigLoop:    moveq    #-1,d0
  223.     SYS    AllocSignal
  224.     tst.l    d0
  225.     bmi    CleanUp
  226.     moveq    #0,d1
  227.     bset    d0,d1
  228.     move.l    d1,(a2)+
  229.     dbra    d2,.SigLoop
  230.  
  231. ;Initialize semaphore(s)
  232.     lea    MySemaphore(a5),a0
  233.     SYS    InitSemaphore
  234.  
  235.     move.l    ThisTask(a6),a0
  236.     move.l    a0,Task(a5)
  237.     move.l    a5,TC_Userdata(a0)
  238.  
  239. ;Install no-flicker option if selected.
  240.     tst.l    FlickerOption(a5)
  241.     beq    .NoFlicker
  242.     move.l    GraphBase(a5),a0
  243.     move.l    gb_copinit(a0),a0
  244.     move.l    a0,OriginalCopInit(a5)
  245.     move.l    ChipData(a5),a1
  246.     lea    Copper(a1),a1
  247.     move.l    a1,a2
  248.     move.w    #MaxCopperSize/4-1,d0
  249. .CLoop:    move.l    (a0)+,d1
  250.     cmp.l    #$008A0000,d1
  251.     beq    .CopEnd
  252.     move.l    d1,(a1)+
  253.     dbra    d0,.CLoop
  254.     clr.l    FlickerOption(a5)
  255.     bra    .NoFlicker
  256. .CopEnd:    move.l    #$01800000,(a1)+
  257.     move.l    a1,WaitLineAddress(a5)
  258.     move.l    #$1607FFFE,(a1)+
  259.     move.w    #$0180,(a1)+
  260.     move.l    #$008A0000,2(a1)
  261.     move.l    a1,RealBackground(a5)
  262.     move.l    a2,cop1lc+_custom
  263.     move.l    GraphBase(a5),a0
  264.     move.l    a2,gb_copinit(a0)
  265.     cmp.w    #color,SysBackground-2(a2)
  266.     bne    .DefColor
  267.     move.w    SysBackground(a2),(a1)
  268.     bra    .NoFlicker
  269. .DefColor:
  270.     move.w    #DefColor,(a1)
  271. .NoFlicker:
  272.  
  273. ;Patch MANY system routines.
  274.     lea    PatchTable(pc),a2
  275.     move.l    a2,a3
  276. .Patch:    move.w    (a2)+,d0    ;get base
  277.     beq    .EndPatch
  278.     move.l    (a5,d0.w),a1    ;library base to patch
  279.     move.w    (a2)+,d0    ;get offset to new routine
  280.     lea    (a3,d0.w),a0
  281.     move.l    a0,d0    ;new routine address
  282.     move.w    (a2)+,a0    ;_LVO offset
  283.     SYS    SetFunction
  284.     move.w    (a2)+,d1
  285.     move.l    d0,(a5,d1.w)
  286.     bra    .Patch
  287. .EndPatch:
  288.  
  289. ;Create an IORequest structure
  290.     SYS    CreateMsgPort
  291.     move.l    d0,InputMsgPort(a5)
  292.     beq    CleanUp
  293.     move.l    d0,a0
  294.     moveq    #IOSTD_SIZE,d0
  295.     SYS    CreateIORequest
  296.     move.l    d0,InputIORequest(a5)
  297.     beq    CleanUp
  298.  
  299. ;Perform NoClick, if desired.
  300.     move.l    NoClickOption(a5),d2
  301.     beq    .Click
  302.     move.l    d2,a0
  303.     move.l    (a0),d2
  304. .Click:    moveq    #0,d3
  305.     moveq    #3,d4
  306. .ClickLoop:
  307.     lea    TrackName(pc),a0    ;device name
  308.     move.l    d3,d0    ;unit number
  309.     move.l    InputIORequest(a5),a1    ;IO request
  310.     moveq    #0,d1    ;flags
  311.     SYS    OpenDevice
  312.     tst.l    d0
  313.     bne    .ECLoop
  314.     move.l    InputIORequest(a5),a1    ;IO request
  315.     move.l    IO_UNIT(a1),a0
  316.     btst    d3,d2
  317.     beq    .SkipNoClick
  318.     bchg    #TDPB_NOCLICK,TDU_PUBFLAGS(a0)
  319. .SkipNoClick:
  320.     tst.l    VerifyOption(a5)
  321.     beq    .SkipVerify
  322.     bchg    #1,TDU_PUBFLAGS(a0)
  323. .SkipVerify:
  324.     SYS    CloseDevice
  325. .ECLoop:    addq.l    #1,d3
  326.     dbra    d4,.ClickLoop
  327.  
  328. ;Handle 'STAR' option.
  329.     tst.l    StarOption(a5)
  330.     beq    .NoStar
  331.     move.l    DosBase(a5),a0
  332.     move.l    dl_Root(a0),a0
  333.     bchg    #0,rn_Flags(a0)
  334. .NoStar:
  335.  
  336. ;Open the input.device
  337.     lea    InputName(pc),a0    ;device name
  338.     moveq    #0,d0    ;unit number
  339.     move.l    InputIORequest(a5),a1    ;IO request
  340.     moveq    #0,d1    ;flags
  341.     SYS    OpenDevice
  342.     tst.l    d0
  343.     bne    CleanUp
  344.  
  345. ;Install input handler
  346.     move.l    InputIORequest(a5),a1
  347.     move.w    #IND_ADDHANDLER,IO_COMMAND(a1)
  348.     lea    InputInterrupt(a5),a0
  349.     move.l    a0,IO_DATA(a1)
  350.     SYS    DoIO
  351.     tst.l    d0
  352.     bne    CleanUp
  353.     st    HandlerInstalled(a5)
  354.  
  355. ;Wait for signal(s)
  356. Wait:
  357.     lea    Sigs(a5),a0
  358.     move.l    (a0)+,d0
  359.     moveq    #NumSigs-2,d1
  360. ..    add.l    (a0)+,d0
  361.     dbra    d1,..
  362.     move.l    4,a6
  363.     SYS    Wait
  364.     move.l    d0,d1
  365.     and.l    QuitSig(a5),d1
  366.     bne    SafeCleanUp
  367.     move.l    IntBase(a5),a6
  368.     move.l    d0,d1
  369.     and.l    CLISig(a5),d1
  370.     bne    .Execute
  371.     move.l    d0,d1
  372.     and.l    WBenchToFrontSig(a5),d1
  373.     bne    .WBenchToFront
  374.  
  375. ;Perform ScreenToBack
  376.     move.l    ScreenPtr(a5),d0
  377.     beq    Wait
  378.     clr.l    ScreenPtr(a5)
  379.     move.l    d0,a0
  380.     SYS    ScreenToBack
  381.     bra    Wait
  382. .WBenchToFront:
  383.     SYS    WBenchToFront
  384.     bra    Wait
  385. .Execute:
  386. ;Execute the desired command
  387.     SYS    WBenchToFront
  388.     move.l    DosBase(a5),a6
  389.  
  390.     move.l    CmdOption(a5),d1
  391.     beq    Wait
  392.     lea    .Tags(pc),a0
  393.     move.l    a0,d2    ;tags
  394.     SYS    SystemTagList
  395.     bra    Wait
  396. .Tags:    dc.l    SYS_UserShell,0
  397.     dc.l    NP_StackSize
  398. CmdStackSize:
  399.     dc.l    0
  400.     dc.l    0    ;end of tag list
  401.  
  402. SafeCleanUp:
  403. ;Make sure the SetFunction'ed vectors are still intact.
  404.     lea    PatchTable(pc),a0
  405.     move.l    a0,a2
  406. .Safe:    move.w    (a0)+,d0
  407.     beq    CleanUp
  408.     move.l    (a5,d0.w),a1    ;library base
  409.     move.w    (a0)+,d0
  410.     lea    (a2,d0.w),a3    ;address of new routine
  411.     move.w    (a0)+,d0
  412.     addq.l    #2,a0
  413.     cmp.l    2(a1,d0.w),a3
  414.     beq    .Safe
  415.  
  416. ;A routine has been patched by another program. Alert the user.
  417.  
  418.     move.l    IntBase(a5),a6
  419.     sub.l    a0,a0
  420.     lea    PatchAlert(pc),a1
  421.     sub.l    a2,a2
  422.     SYS    EasyRequestArgs
  423.     bra    Wait
  424. PatchAlert:
  425.     dc.l    es_SIZEOF
  426.     dc.l    0
  427.     dc.l    .TitleText-PatchAlert
  428.     dc.l    .AlertText-PatchAlert
  429.     dc.l    .OkayText-PatchAlert
  430. .TitleText:
  431.     dc.b    'QMouse message',0
  432. .AlertText:
  433.     dc.b    'Can''t quit or modify parameters. Another program '
  434.     dc.b    $a,'has patched the same OS routines!',0
  435. .OkayText:
  436.     dc.b    'OK',0
  437.     even
  438.  
  439. CleanUp:
  440.  
  441. ;Enter with global ptr in A5
  442.  
  443.     move.l    4,a6
  444.  
  445. ;Remove input handler, if installed.
  446.     tst.b    HandlerInstalled(a5)
  447.     beq    .SkipHand
  448.     move.l    InputIORequest(a5),a1
  449.     move.w    #IND_REMHANDLER,IO_COMMAND(a1)
  450.     lea    InputInterrupt(a5),a0
  451.     move.l    a0,IO_DATA(a1)
  452.     SYS    DoIO
  453. .SkipHand:
  454.  
  455.     tst.l    OldCloseScreen(a5)
  456.     beq    .SkipRestore
  457.  
  458.     bsr    RestoreMouse
  459.     bsr    RestoreScreen
  460.  
  461. ;Restore original vectors.
  462.  
  463.     lea    PatchTable(pc),a2
  464. .RestoreVecs:
  465.     move.w    (a2),d0
  466.     beq    .SkipRestore
  467.     addq.l    #4,a2    ;skip new routine info
  468.     move.l    (a5,d0.w),a1    ;get library base
  469.     move.w    (a2)+,a0    ;get _LVO
  470.     move.w    (a2)+,d0
  471.     move.l    (a5,d0.w),d0    ;old routine
  472.     SYS    SetFunction
  473.     bra    .RestoreVecs
  474. .SkipRestore:
  475.  
  476. ;Delay for 1/10 second to ensure that no-one is using the patch code.
  477.     move.l    DosBase(a5),d0
  478.     beq    .SkipFreeArg
  479.     move.l    d0,a6
  480.     moveq    #5,d1
  481.     SYS    Delay
  482.  
  483. ;Free argument structure
  484.     move.l    ArgPtr(a5),d1
  485.     beq    .SkipFreeArg
  486.     SYS    FreeArgs
  487. .SkipFreeArg:
  488.  
  489.     move.l    4,a6
  490.  
  491. ;Free signals
  492.     lea    Sigs(a5),a2
  493.     moveq    #NumSigs-1,d2
  494. .SigLoop:    move.l    (a2)+,d1
  495.     beq    .NextSig
  496.     moveq    #-1,d0
  497. .BitLoop:    addq.l    #1,d0
  498.     btst    d0,d1
  499.     beq    .BitLoop
  500.     SYS    FreeSignal
  501. .NextSig:    dbra    d2,.SigLoop
  502.  
  503. ;Remove flicker option, if selected.
  504.     tst.l    FlickerOption(a5)
  505.     beq    .SkipFlicker
  506.     move.l    OriginalCopInit(a5),a0
  507.     move.l    GraphBase(a5),a2
  508.     move.l    gb_copinit(a2),a1
  509. .CLoop:    move.l    (a1)+,(a0)+
  510.     cmp.l    #$008A0000,(a0)
  511.     bne    .CLoop
  512.     move.l    OriginalCopInit(a5),gb_copinit(a2)
  513.     move.l    OriginalCopInit(a5),cop1lc+_custom
  514. .SkipFlicker:
  515.  
  516. ;Close libraries
  517.     lea    LibTable+2(pc),a2
  518.     moveq    #NumLibs-1,d2
  519. .CLibLoop:
  520.     move.w    (a2),a0
  521.     add.l    a5,a0
  522.     tst.l    (a0)
  523.     beq    .SkipClose
  524.     move.l    (a0),a1
  525.     SYS    CloseLibrary
  526. .SkipClose:
  527.     addq.l    #4,a2
  528.     dbra    d2,.CLibLoop
  529.  
  530. ;Close input.device
  531.     move.l    InputIORequest(a5),d0
  532.     beq    .SkipCloseDev
  533.     move.l    d0,a1
  534.     tst.b    IO_ERROR(a1)    ;was there an error?
  535.     bne    .SkipCloseDev    ;yes, don't close
  536.     SYS    CloseDevice
  537. .SkipCloseDev:
  538.  
  539. ;Delete IORequest structure
  540.     move.l    InputIORequest(a5),a0
  541.     SYS    DeleteIORequest
  542.     move.l    InputMsgPort(a5),a0
  543.     SYS    DeleteMsgPort
  544.  
  545. ;Free chip data.
  546.     move.l    ChipData(a5),d0
  547.     beq    .SkipChipData
  548.     move.l    d0,a1
  549.     move.l    #CData_Sizeof,d0
  550.     SYS    FreeMem
  551. .SkipChipData:
  552.  
  553. ;Deallocate global structure. Note that this code is (sometimes) executed
  554. ;within the memory that we are freeing, so we are careful to terminate with
  555. ;a JMP.
  556.     move.l    a5,a1
  557.     move.l    #Data_Sizeof,d0
  558.     jmp    _LVOFreeMem(a6)
  559.  
  560. ;Semaphore routines
  561.  
  562. GetSemaphore:
  563.     movem.l    a0/a6,-(sp)
  564.     move.l    GlobalPtr(pc),a0
  565.     lea    MySemaphore(a0),a0
  566.     move.l    4,a6
  567.     SYS    ObtainSemaphore
  568.     movem.l    (sp)+,a0/a6
  569.     rts
  570. FreeSemaphore:
  571.     movem.l    a0/a6,-(sp)
  572.     move.l    GlobalPtr(pc),a0
  573.     lea    MySemaphore(a0),a0
  574.     move.l    4,a6
  575.     SYS    ReleaseSemaphore
  576.     movem.l    (sp)+,a0/a6
  577.     rts
  578.  
  579. LibTable:    dc.w    DosName-LibTable
  580.     dc.w    DosBase
  581.     dc.w    IntName-LibTable
  582.     dc.w    IntBase
  583.     dc.w    LayersName-LibTable
  584.     dc.w    LayersBase
  585.     dc.w    GraphName-LibTable
  586.     dc.w    GraphBase
  587. EndLibTable:
  588.  
  589. NumLibs    equ    (EndLibTable-LibTable)/4
  590.  
  591. ;****************** SetFunction'ed routines ***************
  592.  
  593. patch    macro
  594.     dc.w    \1
  595.     dc.w    New\2-PatchTable
  596.     dc.w    _LVO\2
  597.     dc.w    Old\2
  598.     endm
  599.  
  600. PatchTable:
  601.     patch    IntBase,CloseScreen
  602.     patch    IntBase,CloseWindow
  603.     patch    IntBase,OpenScreen
  604.     patch    IntBase,ScreenToFront
  605.     patch    IntBase,ScreenToBack
  606.     patch    IntBase,OpenScreenTagList
  607.     patch    IntBase,WBenchToFront
  608.     patch    IntBase,WBenchToBack
  609.     patch    IntBase,SetPointer
  610.     patch    IntBase,ClearPointer
  611.     patch    IntBase,DisplayBeep
  612.     patch    GraphBase,LoadView
  613.     dc.w    0
  614.  
  615. NewDisplayBeep:
  616.     move.l    GlobalPtr(pc),a1
  617.     tst.l    BeepOption(a1)
  618.     bne    .SkipBeep
  619.     move.l    OldDisplayBeep(a1),-(sp)
  620. .SkipBeep:
  621.     rts
  622.  
  623. NewSetPointer:
  624.     bsr    GetSemaphore
  625.     movem.l    d4-d5/a2-a3/a5,-(sp)
  626.     move.l    GlobalPtr(pc),a5
  627.     lea    PointerList(a5),a2
  628.  
  629. ;Find if window is already in table and find empty spot.
  630.     moveq    #POINTERLISTSIZE-1,d4
  631.     sub.l    a3,a3
  632. .WinSearch:
  633.     move.l    pt_Window(a2),d5
  634.     bne    .SkipSave
  635.     move.l    a2,a3
  636. .SkipSave:
  637.     cmp.l    d5,a0
  638.     beq    .Found
  639.     lea    pt_Sizeof(a2),a2
  640.     dbra    d4,.WinSearch
  641.     move.l    a3,a2
  642.     move.l    a2,d4
  643.     beq    .End    ;no room in table, so forget it
  644. .Found:    movem.l    d0-d3/a0-a1,(a2)
  645. .End:    cmp.l    MBlankWindow(a5),a0
  646.     beq    .End1
  647. .SkipMBlank:
  648.     movem.l    (sp)+,d4-d5/a2-a3/a5
  649.     subq.l    #8,sp
  650.     move.l    a0,(sp)
  651.     move.l    GlobalPtr(pc),a0
  652.     move.l    OldSetPointer(a0),4(sp)
  653.     move.l    (sp)+,a0
  654.     bra    FreeSemaphore
  655. .End1:    movem.l    (sp)+,d4-d5/a2-a3/a5
  656.     bra    FreeSemaphore
  657.  
  658. NewClearPointer:
  659.     bsr    GetSemaphore
  660.     move.l    GlobalPtr(pc),a1
  661.     lea    PointerList(a1),a1
  662.     moveq    #POINTERLISTSIZE-1,d0
  663. .ClearLoop:
  664.     cmp.l    pt_Window(a1),a0
  665.     beq    .Found
  666.     lea    pt_Sizeof(a1),a1
  667.     dbra    d0,.ClearLoop
  668.     bra    .End
  669. .Found:    clr.l    pt_Window(a1)
  670. .End:    move.l    GlobalPtr(pc),a1
  671.     cmp.l    MBlankWindow(a1),a0
  672.     beq    .End1
  673. .SkipMBlank:
  674.     move.l    OldClearPointer(a1),-(sp)
  675. .End1:    bra    FreeSemaphore
  676.  
  677. NewLoadView:
  678.     pea    .NewLoad(pc)
  679.     move.l    GlobalPtr(pc),a0
  680.     move.l    OldLoadView(a0),-(sp)
  681.     rts
  682. .NewLoad:
  683.     move.l    GlobalPtr(pc),a0
  684.     tst.l    FlickerOption(a0)
  685.     beq    .End
  686.     move.l    RealBackground(a0),a1
  687.     move.l    GraphBase(a0),a0
  688.     move.l    gb_copinit(a0),a0
  689.     move.w    SysBackground(a0),(a1)
  690. .End:    rts
  691.  
  692. NewCloseScreen:
  693.     bsr    GetSemaphore
  694.     move.l    GlobalPtr(pc),a1
  695.     lea    ScreenList(a1),a1
  696.     moveq    #SCREENLISTSIZE-1,d0
  697. .Loop:    cmp.l    (a1),a0
  698.     beq    .Match
  699.     addq.l    #8,a1
  700.     dbra    d0,.Loop
  701. .End:    move.l    GlobalPtr(pc),a1
  702.     pea    RestoreWindow(pc)
  703.     move.l    OldCloseScreen(a1),-(sp)
  704.     bra    FreeSemaphore
  705. .Match:    clr.l    (a1)
  706.     bra    .End
  707.  
  708. NewCloseWindow:
  709.     bsr    GetSemaphore
  710.     push    a0
  711.     SYS    ClearPointer
  712.     pop    a0
  713.     move.l    GlobalPtr(pc),a1
  714.     cmp.l    MBlankWindow(a1),a0
  715.     bne    .SkipClear
  716.     clr.l    MBlankWindow(a1)
  717. .SkipClear:
  718.     lea    ScreenList+4(a1),a1
  719.     moveq    #SCREENLISTSIZE-1,d0
  720. .Loop:    cmp.l    (a1),a0
  721.     beq    .Match
  722.     addq.l    #8,a1
  723.     dbra    d0,.Loop
  724. .End:    move.l    GlobalPtr(pc),a1
  725.     move.l    OldCloseWindow(a1),-(sp)
  726.     bra    FreeSemaphore
  727. .Match:    clr.l    -4(a1)
  728.     bra    .End
  729.  
  730. MyRemember:
  731.     bsr    GetSemaphore
  732.     bsr    RememberWindow
  733.     move.l    a0,-(sp)
  734.     move.l    GlobalPtr(pc),a0
  735.     move.l    (a0,d0.w),d0
  736.     move.l    (sp)+,a0
  737.     move.l    d0,-(sp)
  738.     bra    FreeSemaphore
  739.  
  740. NewOpenScreen:
  741.     move.w    #OldOpenScreen,d0
  742.     bra    MyRemember
  743. NewOpenScreenTagList:
  744.     move.w    #OldOpenScreenTagList,d0
  745.     bra    MyRemember
  746. NewWBenchToFront:
  747.     move.w    #OldWBenchToFront,d0
  748.     bsr    MyRemember
  749.     bra    RestoreWindow
  750. NewWBenchToBack:
  751.     move.w    #OldWBenchToBack,d0
  752.     bsr    MyRemember
  753.     bra    RestoreWindow
  754. NewScreenToFront:
  755.     move.w    #OldScreenToFront,d0
  756.     bsr    MyRemember
  757.     bra    RestoreWindow
  758. NewScreenToBack:
  759.     move.w    #OldScreenToBack,d0
  760.     bsr    MyRemember
  761.     bra    RestoreWindow
  762.  
  763. ;****************** End of SetFunction'ed routines ***************
  764.  
  765. RememberWindow:
  766.  
  767. ;This routine remembers the currently activated window on the current
  768. ;screen.
  769.  
  770.     movem.l    d0-d1/a0-a2/a4-a6,-(sp)
  771.     move.l    GlobalPtr(pc),a5
  772.     move.l    IntBase(a5),a4
  773.     move.l    4,a6
  774.     SYS    Forbid
  775.     move.l    ib_ActiveScreen(a4),a0
  776.     move.l    ib_ActiveWindow(a4),a2
  777.     SYS    Permit
  778.  
  779. ;Sanity checks
  780.     move.l    a0,d0
  781.     beq    .End
  782.     move.l    a2,d0
  783.     beq    .End
  784.  
  785.     lea    ScreenList(a5),a1
  786.     moveq    #SCREENLISTSIZE-1,d0
  787. .ScLoop:    cmp.l    (a1),a0
  788.     beq    .Match
  789.     addq.l    #8,a1
  790.     dbra    d0,.ScLoop
  791.  
  792. ;Screen not found. Add to screen list.
  793.     lea    ScreenList(a5),a1
  794.     moveq    #SCREENLISTSIZE-1,d0
  795. .AddLoop:    tst.l    (a1)
  796.     beq    .Match
  797.     addq.l    #8,a1
  798.     dbra    d0,.AddLoop
  799.     bra    .End    ;table is full
  800. .Match:
  801.     move.l    a0,(a1)+    ;screen
  802.     move.l    a2,(a1)    ;currently activated window
  803. .End:    movem.l    (sp)+,d0-d1/a0-a2/a4-a6
  804.     rts
  805.  
  806. RestoreWindow:
  807.  
  808. ;This routine restores (re-activates) the previously activated window for
  809. ;this screen.
  810.  
  811.     bsr    GetSemaphore
  812.     movem.l    d0-d1/a0-a1/a6,-(sp)
  813.     move.l    GlobalPtr(pc),a0
  814.     lea    ScreenList(a0),a1
  815.     move.l    IntBase(a0),a6
  816.     move.l    ib_FirstScreen(a6),a0
  817.     move.l    a0,d0
  818.     beq    .End    ;sanity check
  819.     moveq    #SCREENLISTSIZE-1,d0
  820. .Loop:    cmp.l    (a1),a0
  821.     beq    .Match
  822.     addq.l    #8,a1
  823.     dbra    d0,.Loop
  824.     move.l    sc_FirstWindow(a0),a0    ;default window
  825.     move.l    a0,d0
  826.     beq    .End    ;sanity check
  827.     bra    .SkipMatch
  828. .Match:
  829.     move.l    4(a1),a0
  830. .SkipMatch:
  831.     SYS    ActivateWindow
  832. .End:    movem.l    (sp)+,d0-d1/a0-a1/a6
  833.     bra    FreeSemaphore
  834.  
  835. ;***************************************************************************
  836. ;Start of input handler code
  837. ;***************************************************************************
  838.  
  839. ;Get window associated with current mouse position.
  840. ;Returns Window in D0 and screen in D1.
  841.  
  842. GetWindow:
  843.     movem.l    d2-d4/a0-a1/a4-a6,-(sp)
  844.     move.l    GlobalPtr(pc),a5
  845.     move.l    LayersBase(a5),a6
  846.     move.l    IntBase(a5),a4
  847.     move.l    ib_FirstScreen(a4),d4
  848. .ScLoop:    tst.l    d4
  849.     beq    .ErrEnd
  850.     move.l    d4,a0
  851.     move.l    sc_NextScreen(a0),d4
  852.     move.w    ib_MouseX(a4),d0
  853.     move.w    ib_MouseY(a4),d1
  854.     move.w    sc_ViewPort+vp_Modes(a0),d2
  855.     move.w    d2,d3
  856.     and.w    #V_LACE,d2    ;interlace?
  857.     bne    .Lace    ;yes
  858.     lsr.w    #1,d1
  859. .Lace:    and.w    #V_HIRES,d3    ;hires?
  860.     bne    .Hires    ;yes
  861.     lsr.w    #1,d0
  862. .Hires:    sub.w    sc_ViewPort+vp_DxOffset(a0),d0
  863.     bmi    .ScLoop
  864.     sub.w    sc_ViewPort+vp_DyOffset(a0),d1
  865.     bmi    .ScLoop
  866.     push    a0
  867.     lea    sc_LayerInfo(a0),a0
  868.     SYS    WhichLayer
  869.     pop    d1
  870.     tst.l    d0
  871.     beq    .End
  872.     move.l    d0,a0
  873.     move.l    lr_Window(a0),d0
  874. .End:    movem.l    (sp)+,d2-d4/a0-a1/a4-a6
  875.     rts
  876. .ErrEnd:    moveq    #0,d0
  877.     moveq    #0,d1
  878.     bra    .End
  879.  
  880. DoWindowToFront:
  881.  
  882. ;Perform a WindowToFront on the window in D0.
  883. ;Enter with global ptr in A1.
  884.  
  885.     tst.l    d0
  886.     beq    .End1
  887.     movem.l    d0-d1/a0-a1/a6,-(sp)
  888.     move.l    IntBase(a1),a6
  889.     move.l    d0,a0
  890.     move.l    wd_WLayer(a0),a1
  891.     move.l    a1,d0
  892.     beq    .End
  893.     move.l    lr_ClipRect(a1),a1
  894.     move.l    a1,d0
  895.     beq    .End
  896.     tst.l    (a1)
  897.     beq    .End
  898.     move.l    wd_Flags(a0),d0
  899.     and.l    #WFLG_BACKDROP,d0
  900.     bne    .End
  901.     SYS    WindowToFront
  902. .End:    movem.l    (sp)+,d0-d1/a0-a1/a6
  903. .End1:    rts
  904.  
  905. BlankMouse:
  906.     movem.l    d0-d3/a0-a1/a5-a6,-(sp)
  907.     move.l    GlobalPtr(pc),a5
  908.     move.l    IntBase(a5),a6
  909.     move.l    ib_ActiveWindow(a6),d0
  910.     beq    .End
  911.     cmp.l    MBlankWindow(a5),d0
  912.     beq    .End
  913.     move.l    d0,MBlankWindow(a5)
  914.     move.l    d0,a0
  915.     move.l    ChipData(a5),a1
  916. ;    lea    ZeroMouse(a1),a1    ;not needed
  917.     moveq    #1,d0    ;height
  918.     moveq    #16,d1    ;width
  919.     moveq    #0,d2    ;xoffset
  920.     moveq    #0,d3    ;yoffset
  921.     pea    .End(pc)
  922.     move.l    OldSetPointer(a5),-(sp)
  923.     rts
  924. .End:    movem.l    (sp)+,d0-d3/a0-a1/a5-a6
  925.     rts
  926.  
  927. RestoreMouse:
  928.     movem.l    d0-d1/a0-a2/a5-a6,-(sp)
  929.     move.l    GlobalPtr(pc),a5
  930.     move.l    IntBase(a5),a6
  931.     move.l    MBlankWindow(a5),d0
  932.     beq    .End
  933.  
  934. ;Look for window in pointer table. If present, do a SetPointer to restore
  935. ;the custom pointer. Otherwise call ClearPointer.
  936.  
  937.     move.l    d0,a0
  938.     clr.l    MBlankWindow(a5)
  939.     lea    PointerList(a5),a1
  940.     moveq    #POINTERLISTSIZE-1,d0
  941. .WinLoop:    cmp.l    pt_Window(a1),a0
  942.     beq    .Found
  943.     lea    pt_Sizeof(a1),a1
  944.     dbra    d0,.WinLoop
  945.     pea    .End(pc)
  946.     move.l    OldClearPointer(a5),-(sp)
  947.     rts
  948. .End:    movem.l    (sp)+,d0-d1/a0-a2/a5-a6
  949.     rts
  950. .Found:    move.l    a1,a2
  951.     movem.l    (a2),d0-d3/a0-a1
  952.     pea    .End(pc)
  953.     move.l    OldSetPointer(a5),-(sp)
  954.     rts
  955.  
  956. RestoreScreen:
  957.     push    a5
  958.     move.l    GlobalPtr(pc),a5
  959.     bclr    #STB_SBlanked,Status(a5)
  960.     beq    .End
  961.     move.w    #DMAF_SETCLR+DMAF_COPPER+DMAF_RASTER,dmacon+_custom
  962. .End:    pop    a5
  963.     rts
  964.  
  965. SigTask:
  966. ;Enter with GlobalPtr in A1 and signal in D0.
  967.     movem.l    d0-d1/a0-a1/a6,-(sp)
  968.     move.l    Task(a1),a1
  969.     move.l    4,a6
  970.     SYS    Signal
  971.     movem.l    (sp)+,d0-d1/a0-a1/a6
  972.     rts
  973.  
  974. ;**************************** Input handler *********************************
  975.  
  976. IntRoutine:
  977.     movem.l    a2/a6,-(sp)
  978.     move.l    IntBase(a1),a6
  979.     bsr    GetSemaphore
  980.     move.l    a0,-(sp)
  981.  
  982. ;Handle NoFlicker option
  983.     tst.l    FlickerOption(a1)
  984.     beq    .SkipFlick
  985.     move.l    GraphBase(a1),a0
  986.     move.l    gb_LOFlist(a0),a2
  987.     move.l    WaitLineAddress(a1),a0
  988.     cmp.b    #WaitLine-1,WindowStart(a2)
  989.     blo    .DisableNF
  990.     move.b    #WaitLine,(a0)
  991.     bra    .SkipDisableNF
  992. .DisableNF:
  993.     clr.b    (a0)
  994. .SkipDisableNF:
  995.     move.l    GraphBase(a1),a0
  996.     move.l    gb_copinit(a0),a0
  997.     cmp.w    #color,SysBackground-2(a0)
  998.     bne    .DefColor
  999.     move.w    SysBackground(a0),d0
  1000.     move.l    RealBackground(a1),a0
  1001.     move.w    d0,(a0)
  1002.     bra    .SkipColor
  1003. .DefColor:
  1004.     move.l    RealBackground(a1),a0
  1005.     move.w    #DefColor,(a0)
  1006. .SkipColor:
  1007.     move.l    (sp),a0
  1008. .SkipFlick:
  1009.  
  1010. ;Perform SunMouse
  1011.     tst.l    SunMouseOption(a1)
  1012.     beq    .SkipSunMouse1
  1013.     cmp.b    #IECLASS_RAWMOUSE,ie_Class(a0)
  1014.     beq    .SkipSunMouse1
  1015.     bclr    #STB_SunMouse,Status(a1)
  1016.     beq    .SkipSunMouse1
  1017.     bsr    GetWindow
  1018.     movem.l    a0-a1,-(sp)
  1019.     move.l    d0,a0
  1020.     cmp.l    ib_ActiveWindow(a6),a0
  1021.     beq    .EndSun
  1022.     SYS    ActivateWindow
  1023. .EndSun:    movem.l    (sp)+,a0-a1
  1024. .SkipSunMouse1:
  1025.  
  1026.     move.l    MBlankWindow(a1),d0
  1027.     beq    .Loop
  1028.     cmp.l    ib_ActiveWindow(a6),d0
  1029.     beq    .EndMBW
  1030.     bsr    RestoreMouse
  1031.     bsr    BlankMouse
  1032. .EndMBW:
  1033.  
  1034. .Loop:    cmp.b    #IECLASS_TIMER,ie_Class(a0)
  1035.     beq    .NotKey
  1036.  
  1037. ;Reset screen blank
  1038.     tst.l    SBlankOption(a1)
  1039.     beq    .SkipSRestore
  1040.     move.l    ie_TimeStamp(a0),ScreenTime(a1)
  1041.     bsr    RestoreScreen
  1042. .SkipSRestore:
  1043.  
  1044.     cmp.b    #IECLASS_RAWKEY,ie_Class(a0)
  1045.     bne    .NotKey
  1046.     tst.b    ie_Code+1(a0)
  1047.     bmi    .Next    ;ignore up key codes
  1048.  
  1049. ;Do Northgate keyboard mapping.
  1050.     tst.l    NorthGateOption(a1)
  1051.     beq    .SkipNorthgate
  1052.     lea    NorthgateTable(pc),a2
  1053.     move.w    ie_Code(a0),d0
  1054.     bclr    #7,d0
  1055. .NorthgateLoop:
  1056.     move.b    (a2),d1
  1057.     beq    .EndNorthgate
  1058.     addq.l    #3,a2
  1059.     cmp.b    d0,d1
  1060.     bne    .NorthgateLoop
  1061.     and.w    #$80,ie_Code(a0)
  1062.     move.b    -2(a2),d0
  1063.     or.b    d0,ie_Code+1(a0)
  1064.     move.b    -1(a2),d0
  1065.     bmi    .EndNorthgate
  1066.     bset    d0,ie_Qualifier+1(a0)
  1067. .EndNorthgate:
  1068. .SkipNorthgate:
  1069.  
  1070.     btst    #IEQUALIFIERB_LCOMMAND,ie_Qualifier+1(a0)
  1071.     bne    .DoLAmiga
  1072.  
  1073. ;Blank mouse pointer
  1074.     tst.l    MBlankOption(a1)
  1075.     beq    .NoMBlank
  1076.     bsr    BlankMouse
  1077. .NoMBlank:
  1078.     bra    .Next
  1079.  
  1080. .DoLAmiga:
  1081.     cmp.w    #$37,ie_Code(a0)    ;'m'?
  1082.     bne    .NotM
  1083.  
  1084. ;We found an Amiga-M. Defuse and perform action.
  1085.     clr.b    ie_Class(a0)
  1086.     move.l    ib_FirstScreen(a6),a0
  1087.     move.l    a0,d0
  1088.     beq    .EndM    ;sanity check
  1089.     move.l    a0,ScreenPtr(a1)
  1090.     move.l    ScreenToBackSig(a1),d0
  1091.     bsr    SigTask
  1092. .EndM:    bra    .End
  1093. .NotM:
  1094.     cmp.w    #$36,ie_Code(a0)    ;'n'?
  1095.     bne    .NotN
  1096.  
  1097. ;We found an Amiga-N. Defuse and perform action.
  1098.     clr.b    ie_Class(a0)
  1099.     move.l    WBenchToFrontSig(a1),d0
  1100.     bsr    SigTask
  1101.     bra    .End
  1102. .NotN:
  1103.     tst.l    CmdOption(a1)
  1104.     beq    .Next
  1105.     cmp.w    #$45,ie_Code(a0)    ;ESC?
  1106.     bne    .Next
  1107.     clr.b    ie_Class(a0)
  1108.     move.l    CLISig(a1),d0
  1109.     bsr    SigTask
  1110.     bra    .End
  1111.  
  1112. .NotKey:
  1113.     move.w    ib_MouseX(a6),d0
  1114.     move.w    ib_MouseY(a6),d1
  1115.     cmp.b    #IECLASS_RAWMOUSE,ie_Class(a0)
  1116.     beq    .DoMouse
  1117.     cmp.w    CurrentX(a1),d0
  1118.     bne    .DoMouse
  1119.     cmp.w    CurrentY(a1),d1
  1120.     beq    .Next
  1121.  
  1122. .DoMouse:
  1123.     move.w    d0,CurrentX(a1)
  1124.     move.w    d1,CurrentY(a1)
  1125.     tst.l    MBlankOption(a1)
  1126.     beq    .NoRestore
  1127.     move.l    ie_TimeStamp(a0),MouseTime(a1)
  1128.     bsr    RestoreMouse
  1129. .NoRestore:
  1130.  
  1131. ;Perform SunMouse
  1132.     tst.l    SunMouseOption(a1)
  1133.     beq    .SkipSunMouse
  1134.     move.w    ie_Qualifier(a0),d0
  1135.     and.w    #IEQUALIFIER_LEFTBUTTON+IEQUALIFIER_RBUTTON+IEQUALIFIER_MIDBUTTON,d0
  1136.     bne    .SkipSunMouse
  1137.     cmp.w    #IECODE_LBUTTON+IECODE_UP_PREFIX,ie_Code(a0)
  1138.     beq    .SkipSunMouse
  1139.     bset    #STB_SunMouse,Status(a1)
  1140. .SkipSunMouse:
  1141.  
  1142. ;Perform click-to-back.
  1143.     tst.l    CTBOption(a1)
  1144.     beq    .NoCTB
  1145.     cmp.w    #IECODE_RBUTTON,ie_Code(a0)
  1146.     bne    .NoCTB
  1147.     move.w    ie_Qualifier(a0),d0
  1148.     btst    #IEQUALIFIERB_LEFTBUTTON,d0
  1149.     beq    .NoCTB
  1150.  
  1151.     movem.l    d2/a0-a1,-(sp)
  1152.     bsr    GetWindow
  1153.     tst.l    d0
  1154.     beq    .FlipScreen
  1155.     move.l    d0,a1
  1156.     move.l    wd_Flags(a1),d2
  1157.     and.l    #WFLG_BACKDROP,d2
  1158.     bne    .FlipScreen
  1159.  
  1160. ;Is this the only window on this screen, except for backdrop windows?
  1161.     move.l    wd_WScreen(a1),a1
  1162.     move.l    sc_FirstWindow(a1),a1
  1163. .BackLoop:
  1164.     cmp.l    a1,d0
  1165.     beq    .EBackLoop
  1166.     move.l    wd_Flags(a1),d2
  1167.     and.l    #WFLG_BACKDROP,d2
  1168.     beq    .FlipWindow
  1169. .EBackLoop:
  1170.     move.l    (a1),a1
  1171.     move.l    a1,d2
  1172.     bne    .BackLoop
  1173. .FlipScreen:
  1174.     tst.l    d1
  1175.     beq    .ECTB
  1176.     move.l    GlobalPtr(pc),a1
  1177.     move.l    d1,ScreenPtr(a1)
  1178.     move.l    ScreenToBackSig(a1),d0
  1179.     bsr    SigTask
  1180.     bra    .ECTB
  1181. .FlipWindow:
  1182.     move.l    d0,a0
  1183.     SYS    WindowToBack
  1184.  
  1185. .ECTB:    movem.l    (sp)+,d2/a0-a1
  1186.     clr.b    ie_Class(a0)
  1187.     bra    .Next
  1188. .NoCTB:
  1189.  
  1190. ;Perform click-to-front.
  1191.     tst.l    CTFOption(a1)
  1192.     beq    .NoCTF
  1193.     cmp.w    #IECODE_LBUTTON,ie_Code(a0)
  1194.     bne    .NoCTF
  1195.     bsr    GetWindow
  1196.     tst.l    d0
  1197.     beq    .NoCTF
  1198.     move.l    CTFOption(a1),a2
  1199.     move.l    (a2),d1
  1200.     cmp.l    #1,d1
  1201.     bhi    .MoreThanOne
  1202.     bsr    DoWindowToFront
  1203.     bra    .NoCTF
  1204. .MoreThanOne:
  1205.     cmp.l    ClickWindow(a1),d0
  1206.     beq    .SameWindow
  1207.     move.l    d0,ClickWindow(a1)
  1208.     moveq    #1,d0
  1209.     move.l    d0,ClickCount(a1)
  1210. .Time:    move.l    ie_TimeStamp+TV_SECS(a0),ClickTime+TV_SECS(a1)
  1211.     move.l    ie_TimeStamp+TV_MICRO(a0),ClickTime+TV_MICRO(a1)
  1212.     bra    .NoCTF
  1213. .SameWindow:
  1214.  
  1215. ;Check to see whether MaxClickDelay has been exceeded. If not, increment
  1216. ;ClickCount and compare with (CTFOption). If equal, do a WindowToFront.
  1217. ;Window under pointer in D0.
  1218.  
  1219.     push    d0
  1220.     movem.l    d2-d3/a0-a1,-(sp)
  1221.     move.l    ClickTime+TV_SECS(a1),d0
  1222.     move.l    ClickTime+TV_MICRO(a1),d1
  1223.     move.l    ie_TimeStamp+TV_SECS(a0),d2
  1224.     move.l    ie_TimeStamp+TV_MICRO(a0),d3
  1225.     SYS    DoubleClick
  1226.     movem.l    (sp)+,d2-d3/a0-a1
  1227.     tst.l    d0
  1228.     beq    .TimeExceeded
  1229.     addq.l    #1,ClickCount(a1)
  1230.     push    a0
  1231.     move.l    CTFOption(a1),a0
  1232.     move.l    (a0),d0
  1233.     pop    a0
  1234.     cmp.l    ClickCount(a1),d0
  1235.     bhi    .NeedMoreClicks
  1236.     clr.l    ClickCount(a1)
  1237.     pop    d0
  1238.     bsr    DoWindowToFront
  1239.     bra    .NoCTF
  1240. .TimeExceeded:
  1241.     moveq    #1,d0
  1242.     move.l    d0,ClickCount(a1)
  1243. .NeedMoreClicks:
  1244.     pop    d0
  1245.     bra    .Time
  1246. .NoCTF:
  1247.  
  1248. ;Perform acceleration.
  1249.     tst.l    AccelOption(a1)
  1250.     beq    .Next
  1251.  
  1252.     moveq    #0,d0
  1253.     tst.l    ThreshOption(a1)
  1254.     beq    .T1
  1255.     move.l    ThreshOption(a1),a2
  1256.     move.l    (a2),d0
  1257. .T1:    move.w    ie_X(a0),d1
  1258.     bpl    .PosX
  1259.     neg.w    d1
  1260. .PosX:    cmp.w    d0,d1
  1261.     bls    .SkipX    ;below threshold
  1262.     move.l    AccelOption(a1),a2
  1263.     move.l    (a2),d1
  1264.     muls.w    ie_X(a0),d1
  1265.     bpl    .SubDampX
  1266.     add.w    DampingConstant(a1),d1
  1267.     bra    .DampX
  1268. .SubDampX:
  1269.     sub.w    DampingConstant(a1),d1
  1270. .DampX:    move.w    d1,ie_X(a0)
  1271. .SkipX:    move.w    ie_Y(a0),d1
  1272.     bpl    .PosY
  1273.     neg.w    d1
  1274. .PosY:    cmp.w    d0,d1
  1275.     bls    .EndAccel
  1276.     move.l    AccelOption(a1),a2
  1277.     move.l    (a2),d1
  1278.     muls.w    ie_Y(a0),d1
  1279.     bpl    .SubDampY
  1280.     add.w    DampingConstant(a1),d1
  1281.     bra    .DampY
  1282. .SubDampY:
  1283.     sub.w    DampingConstant(a1),d1
  1284.  
  1285. .DampY:    move.w    d1,ie_Y(a0)
  1286. .EndAccel:
  1287.  
  1288. .Next:    move.l    a0,d1
  1289.     move.l    (a0),d0
  1290.     move.l    d0,a0
  1291.     bne    .Loop
  1292.  
  1293. ;Check for time-outs (mouse and screen blanking)
  1294.     move.l    d1,a0
  1295.     tst.l    MBlankOption(a1)
  1296.     beq    .NoMTime
  1297.     move.l    MBlankOption(a1),a0
  1298.     move.l    (a0),d0    ;get value in seconds
  1299.     move.l    d1,a0
  1300.     move.l    ie_TimeStamp(a0),d1
  1301.     tst.l    MouseTime(a1)
  1302.     beq    .InitMBlank
  1303.     sub.l    MouseTime(a1),d1
  1304.     cmp.l    d0,d1    ;TimePassed ? UserSetting
  1305.     blo    .NoMTime
  1306.     bsr    BlankMouse
  1307. .NoMTime:
  1308.     tst.l    SBlankOption(a1)
  1309.     beq    .End
  1310.     btst    #STB_SBlanked,Status(a1)
  1311.     bne    .End
  1312.     push    a0
  1313.     move.l    SBlankOption(a1),a0
  1314.     move.l    (a0),d0    ;get value in seconds
  1315.     pop    a0
  1316.     move.l    ie_TimeStamp(a0),d1
  1317.     tst.l    ScreenTime(a1)
  1318.     beq    .InitSBlank
  1319.     sub.l    ScreenTime(a1),d1
  1320.     cmp.l    d0,d1    ;TimePassed ? UserSetting
  1321.     blo    .End
  1322.     move.w    #DMAF_COPPER+DMAF_RASTER,dmacon+_custom
  1323.     clr.w    color+_custom
  1324.     bset    #STB_SBlanked,Status(a1)
  1325.  
  1326. .End:    move.l    (sp)+,d0
  1327.     bsr    FreeSemaphore
  1328.     movem.l    (sp)+,a2/a6
  1329.     rts
  1330. .InitMBlank:
  1331.     move.l    ie_TimeStamp(a0),MouseTime(a1)
  1332.     bra    .NoMTime
  1333. .InitSBlank:
  1334.     move.l    ie_TimeStamp(a0),ScreenTime(a1)
  1335.     bra    .End
  1336.  
  1337. GlobalPtr:
  1338.     dc.l    0
  1339.  
  1340. NorthgateTable:
  1341. ;Assign PageUp/PageDown/Home/End to shift-cursor sequences
  1342.     dc.b    $6b,$4f,IEQUALIFIERB_LSHIFT
  1343.     dc.b    $6c,$4e,IEQUALIFIERB_LSHIFT
  1344.     dc.b    $6d,$4c,IEQUALIFIERB_LSHIFT
  1345.     dc.b    $6e,$4d,IEQUALIFIERB_LSHIFT
  1346.  
  1347. ;Change a couple keypad key assignments to be more Amiga-like.
  1348.     dc.b    $5c,$5b,0    ;'/' key -> ')' key
  1349.     dc.b    $5d,$5c,0    ;'*' key -> '/' key
  1350.     dc.b    $4a,$5d,0    ;'-' key -> '*' key
  1351.     dc.b    0
  1352.  
  1353. ProcName:    dc.b    'QMouse process',0
  1354. InputName:
  1355.     dc.b    'input.device',0
  1356. TrackName:
  1357.     dc.b    'trackdisk.device',0
  1358.     even
  1359.  
  1360. EndAllocCode:    ;end of code copied into allocated memory
  1361. ;***********************************************************************
  1362.  
  1363. NewProcTags:
  1364.     dc.l    NP_Entry
  1365. EntryPoint:
  1366.     dc.l    0
  1367.     dc.l    NP_Name
  1368. ProcNamePtr:
  1369.     dc.l    0
  1370.     dc.l    NP_Cli,-1
  1371.     dc.l    0    ;end of tags
  1372.  
  1373. Template:    dc.b    'M=MBLANK/K/N,'
  1374.     dc.b    'S=SBLANK/K/N,'
  1375.     dc.b    'N=NOFLICKER/S,'
  1376.     dc.b    'CMD/K,'
  1377.     dc.b    'A=ACCELERATION/K/N,'
  1378.     dc.b    'T=THRESHOLD/K/N,'
  1379.     dc.b    'CTB=CLICKTOBACK/S,'
  1380.     dc.b    'CTF=CLICKTOFRONT/K/N,'
  1381.     dc.b    'SUNMOUSE/S,'
  1382.     dc.b    'NORTHGATE/S,'
  1383.     dc.b    'NOBEEP/S,'
  1384.     dc.b    'NOCLICK/K/N,'
  1385.     dc.b    'VERIFY/S,'
  1386.     dc.b    'STAR/S,'
  1387.     dc.b    'QUIT/S',0
  1388.  
  1389. IntName:    dc.b    'intuition.library',0
  1390. GraphName:
  1391.     dc.b    'graphics.library',0
  1392. DosName:    dc.b    'dos.library',0
  1393. LayersName:
  1394.     dc.b    'layers.library',0
  1395.  
  1396. ;The ordering here is special: data registers first, then address
  1397. ;registers, so that MOVEM may be used to save/restore the data.
  1398.  
  1399.     STRUCTURE    pt,0
  1400.     LONG    pt_Height
  1401.     LONG    pt_Width
  1402.     LONG    pt_XOffset
  1403.     LONG    pt_YOffset
  1404.     LONG    pt_Window
  1405.     LONG    pt_Pointer
  1406.     LABEL    pt_Sizeof
  1407.  
  1408. ResidentCodeSize    equ    EndAllocCode-StartAllocCode
  1409.  
  1410.     STRUCTURE    Data,0
  1411.     WORD    Nothing    ;to make zero special
  1412.     LONG    Task
  1413.     LONG    InputMsgPort
  1414.     LONG    InputIORequest
  1415.     STRUCT    InputInterrupt,IS_SIZE
  1416.     LONG    IntBase
  1417.     LONG    GraphBase
  1418.     LONG    LayersBase
  1419.     STRUCT    ScreenList,SCREENLISTSIZE*8
  1420.     STRUCT    PointerList,POINTERLISTSIZE*pt_Sizeof
  1421.     LONG    OldCloseScreen
  1422.     LONG    OldCloseWindow
  1423.     LONG    OldScreenToFront
  1424.     LONG    OldScreenToBack
  1425.     LONG    OldOpenScreen
  1426.     LONG    OldOpenScreenTagList
  1427.     LONG    OldWBenchToFront
  1428.     LONG    OldWBenchToBack
  1429.     LONG    OldLoadView
  1430.     LONG    OldSetPointer
  1431.     LONG    OldClearPointer
  1432.     LONG    OldDisplayBeep
  1433.     LONG    DosBase
  1434.     LONG    ArgPtr
  1435.     STRUCT    ResidentCode,ResidentCodeSize
  1436.     LONG    MouseTime    ;timeout for mouse blanking
  1437.     LONG    ScreenTime    ;for screen blanking
  1438.     LONG    MBlankWindow
  1439.     WORD    DampingConstant
  1440.     STRUCT    MySemaphore,SS_SIZE
  1441.     LONG    ClickWindow
  1442.     STRUCT    ClickTime,TV_SIZE
  1443.     LONG    ClickCount
  1444.     LONG    Path
  1445.     LONG    ChipData
  1446.     LONG    RealBackground
  1447.     LONG    OriginalCopInit
  1448.     LONG    ScreenPtr
  1449.     WORD    CurrentX
  1450.     WORD    CurrentY
  1451.     LONG    WaitLineAddress
  1452.  
  1453.     LABEL    Sigs
  1454.     LONG    CLISig
  1455.     LONG    QuitSig
  1456.     LONG    ScreenToBackSig
  1457.     LONG    WBenchToFrontSig
  1458.     LABEL    EndSigs
  1459.  
  1460.     LABEL    Options
  1461.     LONG    MBlankOption
  1462.     LONG    SBlankOption
  1463.     LONG    FlickerOption
  1464.     LONG    CmdOption
  1465.     LONG    AccelOption
  1466.     LONG    ThreshOption
  1467.     LONG    CTBOption
  1468.     LONG    CTFOption
  1469.     LONG    SunMouseOption
  1470.     LONG    NorthGateOption
  1471.     LONG    BeepOption
  1472.     LONG    NoClickOption
  1473.     LONG    VerifyOption
  1474.     LONG    StarOption
  1475.     LONG    QuitOption
  1476.  
  1477.     BYTE    HandlerInstalled
  1478.     BYTE    Status    ;various status bits (defined below)
  1479.     LABEL    Data_Sizeof
  1480.  
  1481. ;Bit definitions for Status
  1482.     BITDEF    ST,SBlanked,0
  1483.     BITDEF    ST,SunMouse,1
  1484.  
  1485. NumSigs    equ    (EndSigs-Sigs)/4
  1486.  
  1487.     STRUCTURE    CData,0
  1488.     STRUCT    ZeroMouse,12
  1489.     STRUCT    Copper,MaxCopperSize+4*4
  1490.     LABEL    CData_Sizeof
  1491.  
  1492.     end
  1493.