home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CASM.ARJ / MSMOUSE.ASM < prev    next >
Assembly Source File  |  1988-07-27  |  15KB  |  604 lines

  1. ;_ msmouse.asm   Tue Jul 19 1988   Modified by: Walter Bright */
  2. ; Copyright (C) 1987-1988 by Northwest Software
  3. ; All Rights Reserved
  4. ; Written by Walter Bright
  5. ; Interface to Microsoft Mouse
  6.  
  7. ; The mouse coordinate system is left-handed for both text and graphics modes,
  8. ; with 0,0 being the upper left corner. Note that the display package
  9. ; uses a left-handed coordinate system, but Flash Graphics uses a
  10. ; right-handed system.
  11. ; Also note that the mouse coordinates in text mode are not in character
  12. ; coordinates!(?)
  13. ;
  14. ; To convert from fg coordinates to mouse coords:
  15. ;    mouse_x = fg_x;
  16. ;    mouse_y = fg_displaybox[FG_Y2] - fg_y;
  17. ; To convert from display (character) coordinates to mouse coords:
  18. ;    if (40 column mode)
  19. ;        mouse_x = display_x * 16;
  20. ;    else
  21. ;        mouse_x = display_x * 8;
  22. ;    mouse_y = display_y * 8;
  23. ;
  24. ; The Microsoft mouse sometimes gets the number of screen rows wrong in text
  25. ; mode, so the recommended method of opening the mouse if the display package
  26. ; is also used is:
  27. ;    disp_open();            /* initialize display        */
  28. ;    msm_init();            /* initialize mouse        */
  29. ;
  30. ;    /* Mouse driver sometimes gets the number of screen rows wrong,    */
  31. ;    /* so here we force it to whatever disp_open() discovered.    */
  32. ;    msm_setareay(0,(disp_numrows - 1) * 8);
  33. ;
  34. ;    msm_showcursor();        /* turn mouse cursor on        */
  35. ;
  36. ; For more information refer to the Microsoft Mouse User's Guide.
  37.  
  38. include    macros.asm
  39.  
  40.     c_public msm_init,msm_term,msm_showcursor,msm_hidecursor
  41.     c_public msm_getstatus,msm_setcurpos,msm_getpress,msm_getrelease
  42.     c_public msm_setareax,msm_setareay,msm_setgraphcur,msm_settextcur
  43.     c_public msm_readcounters,msm_signal,msm_lightpenon,msm_lightpenoff
  44.     c_public msm_setratio,msm_condoff,msm_setthreshhold
  45.  
  46.  
  47. mouse    macro    func
  48.     ifnb    <func>
  49.      mov    AX,func
  50.     endif
  51.     int    33h
  52.     endm
  53.  
  54.     begdata
  55.  
  56. msm_inited    dw    0    ;set to !=0 if there is a mouse
  57.  
  58.     enddata
  59.  
  60.     begcode    msmouse
  61.  
  62. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  63. ; Syntax:
  64. ;    int msm_init(void);
  65. ; Initialize mouse driver:
  66. ;    o Turn off all mouse interrupts
  67. ;    o Turn on light pen emulation
  68. ;    o If in graphics mode, set cursor to be an arrow, if in text mode,
  69. ;      set cursor to be inverse video
  70. ;    o Set cursor to middle of screen
  71. ;    o Turn off cursor display
  72. ;    o Set min/max cursor position to full screen
  73. ;    o Set mickey/pixel to 1/1 in the x direction and 2/1 in the y
  74. ; Returns:
  75. ;    0    failed
  76. ;    -1    success
  77.  
  78. func    msm_init
  79. L1:    clr    AX
  80.     pushES
  81.     mov    ES,AX
  82.     ;Some versions of DOS have 0 in the vector table for interrupt 33h
  83.     .if    <word ptr ES:0CCh> ne AX, L3
  84.     .if    <word ptr ES:0CEh> e AX, L2
  85. L3:    mouse
  86. L2:    mov    msm_inited,AX
  87.     popES
  88.     ret
  89. c_endp    msm_init
  90.  
  91. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  92. ; Syntax:
  93. ;    void msm_term(void);
  94. ; Terminate mouse driver. This should be called before the program is
  95. ; exited if the mouse was used.
  96.  
  97. func    msm_term
  98.     jmp    L1        ;the init routine will fix things up
  99. c_endp    msm_term
  100.  
  101. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  102. ; Syntax:
  103. ;    void msm_showcursor(void);
  104. ; Show cursor. That is, increment the cursor flag. If the cursor flag is
  105. ; 0, then the cursor is displayed. Since msm_init() sets the value of
  106. ; the cursor flag to -1, msm_showcursor() must be called after msm_init()
  107. ; in order for the cursor to appear.
  108. ; Note that showcursor and hidecursor can be nested. That is, if n
  109. ; hidecursors were done, then n showcursors must be done in order to
  110. ; show the cursor.
  111. ; Generally, the point is to remove the cursor before any screen I/O
  112. ; is done, and then restore the cursor.
  113.  
  114. func    msm_showcursor
  115.     .if    msm_inited e 0, S1
  116.     mouse    1
  117. S1:    ret
  118. c_endp    msm_showcursor
  119.  
  120. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  121. ; Syntax:
  122. ;    void msm_hidecursor(void);
  123. ; Hide cursor. Decrement the cursor flag. Complement to msm_showcursor().
  124.  
  125. func    msm_hidecursor
  126.     .if    msm_inited e 0, H1
  127.     mouse    2
  128. H1:    ret
  129. c_endp    msm_hidecursor
  130.  
  131. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  132. ; Syntax:
  133. ;    int msm_getstatus(unsigned *curposx,unsigned *curposy);
  134. ; Get status.
  135. ; Output:
  136. ;    *curposx,*curposy =    mouse position
  137. ; Returns:
  138. ;    Bit 0:    left button (1 == down, 0 == up)
  139. ;    Bit 1:    right button
  140. ;    Bit 2:    middle button (for some mice)
  141. ;    Ignore other bits.
  142.  
  143. func    msm_getstatus
  144.     push    BP
  145.     mov    BP,SP
  146.     .if    msm_inited e 0, G1
  147.     mouse    3
  148.     mov    AX,BX        ;button status
  149.     jmps    msm1
  150.  
  151. G1:    clr    AX
  152.     cwd
  153.     mov    CX,AX
  154. msm1:
  155.     if SPTR
  156.     mov    BX,P[BP]
  157.     mov    [BX],CX        ;M3
  158.     mov    BX,P+SIZEPTR[BP]
  159.     mov    [BX],DX        ;M4
  160.     else
  161.     les    BX,P[BP]
  162.     mov    ES:[BX],CX    ;M3
  163.     les    BX,P+SIZEPTR[BP]
  164.     mov    ES:[BX],DX    ;M4
  165.     endif
  166.     pop    BP
  167.     ret
  168. c_endp    msm_getstatus
  169.  
  170. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  171. ; Syntax:
  172. ;    void msm_setcurpos(unsigned curposx,unsigned curposy);
  173. ; Set cursor position.
  174. ; The upper left corner of the screen is 0,0. The values for curposx
  175. ; and curposy must be within the screen.
  176.  
  177. func    msm_setcurpos
  178.     mov    AX,4        ;mouse function
  179. msm3:    .if    msm_inited e 0, S4
  180.     push    BP
  181.     mov    BP,SP
  182.     mov    CX,P[BP]
  183.     mov    DX,P+2[BP]
  184.     mouse
  185.     pop    BP
  186. S4:    ret
  187. c_endp    msm_setcurpos
  188.  
  189. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  190. ; Syntax:
  191. ;    int msm_getpress(unsigned *count, unsigned *curposx,unsigned *curposy);
  192. ; Get button press information.
  193. ; Input:
  194. ;    *count =        which button are we refering to
  195. ;                (0 = left button, 1 = right button, 2 = middle)
  196. ; Output:
  197. ;    *count =        count of button presses since last call
  198. ;                to msm_getpress. Values can be 0..32767.
  199. ;    *curposx,*curposy =    mouse position at last press
  200. ; Returns:
  201. ;    Bit 0:    left button (1 == down, 0 == up)
  202. ;    Bit 1:    right button
  203. ;    Bit 2:    middle button
  204. ;    Ignore other bits
  205.  
  206. func    msm_getpress
  207.     mov    AX,5        ;mouse function
  208. msm2:    push    BP
  209.     mov    BP,SP
  210.     .save    SI
  211.     if SPTR
  212.     mov    BX,P[BP]
  213.     mov    BX,[BX]
  214.     else
  215.     les    BX,P[BP]
  216.     mov    BX,ES:[BX]
  217.     endif
  218.     shr    BX,1
  219.     .if    msm_inited e 0, G2
  220.     mouse
  221.     jmps    G3
  222.  
  223. G2:    clr    AX
  224.     cwd
  225.     mov    BX,AX
  226.     mov    CX,AX
  227. G3:
  228.     if SPTR
  229.     mov    SI,P[BP]
  230.     mov    [SI],BX        ;*count
  231.     mov    SI,P+SIZEPTR[BP]
  232.     mov    [SI],CX        ;*curposx
  233.     mov    SI,P+SIZEPTR+SIZEPTR[BP]
  234.     mov    [SI],DX        ;*curposy
  235.     else
  236.     les    SI,P[BP]
  237.     mov    ES:[SI],BX        ;*count
  238.     les    SI,P+SIZEPTR[BP]
  239.     mov    ES:[SI],CX        ;*curposx
  240.     les    SI,P+SIZEPTR+SIZEPTR[BP]
  241.     mov    ES:[SI],DX        ;*curposy
  242.     endif
  243.     .restore SI
  244.     pop    BP
  245.     ret
  246. c_endp    msm_getpress
  247.  
  248. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  249. ; Syntax:
  250. ;    int msm_getrelease(unsigned *count,
  251. ;        unsigned *curposx,unsigned *curposy);
  252. ; Get button release information.
  253. ; Input:
  254. ;    *count =        which button are we refering to
  255. ;                (0 = left button, 1 = right button, 2 = middle)
  256. ; Output:
  257. ;    *count =        count of button releases since last call
  258. ;                to msm_getpress. Values can be 0..32767.
  259. ;    *curposx,*curposy =    mouse position at last release
  260. ; Returns:
  261. ;    Bit 0:    left button (1 == down, 0 == up)
  262. ;    Bit 1:    right button
  263. ;    Bit 2:    middle button
  264. ;    Ignore other bits
  265.  
  266. func    msm_getrelease
  267.     mov    AX,6        ;mouse function
  268.     jmp    msm2
  269. c_endp    msm_getrelease
  270.  
  271. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  272. ; Syntax:
  273. ;    void msm_setareax(unsigned minx,unsigned maxx);
  274. ; Set minimum and maximum horizontal position. If maxx < minx, the values
  275. ; are exchanged. The mouse horizontal motion will be restricted to be within
  276. ; these values.
  277.  
  278. func    msm_setareax
  279.     mov    AX,7
  280.     jmp    msm3
  281. c_endp    msm_setareax
  282.  
  283. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  284. ; Syntax:
  285. ;    void msm_setareay(unsigned miny,unsigned maxy);
  286. ; Set minimum and maximum vertical position. If maxy < miny, the values
  287. ; are exchanged. The mouse vertical motion will be restricted to be within
  288. ; these values.
  289.  
  290. func    msm_setareay
  291.     mov    AX,8
  292.     jmp    msm3
  293. c_endp    msm_setareay
  294.  
  295. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  296. ; Syntax:
  297. ;    void msm_setgraphcur(int hotx,int hoty,int *pmasks);
  298. ; Set graphics cursor block.
  299. ; Input:
  300. ;    hotx,hoty    Location of 'hot spot' of cursor. Values
  301. ;            must be -16..16. Location 0,0 is the upper
  302. ;            left corner of the cursor, positive values
  303. ;            extend right and down.
  304. ;    pmasks        Points to 32 words which contain bit masks
  305. ;            defining the cursor.
  306. ;            The first 16 words define the mask, that is,
  307. ;            which bits of the background 'shine' through
  308. ;            the cursor. A 1 means shine through, a 0 means not.
  309. ;            The second 16 words define the bitmap of the cursor,
  310. ;            1 being on and 0 being off.
  311. ;            The cursor is 16*16, the first word forms
  312. ;            the top row, bit 15 forms the leftmost column.
  313.  
  314. func    msm_setgraphcur
  315.     .if    msm_inited e 0, S2
  316.     push    BP
  317.     mov    BP,SP
  318.     mov    BX,P[BP]
  319.     mov    CX,P+2[BP]
  320.     if SPTR
  321.     push    DS
  322.     pop    ES
  323.     mov    DX,P+4[BP]    ;put pointer in ES:DX
  324.     else
  325.     les    DX,P+4[BP]
  326.     endif
  327.     mouse    9
  328.     pop    BP
  329. S2:    ret
  330. c_endp    msm_setgraphcur
  331.  
  332. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  333. ; Syntax:
  334. ;    void msm_settextcur(int select,int scanstart,int scanstop);
  335. ; Set text cursor.
  336. ; Input:
  337. ;    select        If 1, then hardware text cursor. If 0, then
  338. ;            attribute cursor.
  339. ;    scanstart,
  340. ;    scanstop    If select is 1, then these values form the
  341. ;            starting and ending scan lines of the hardware
  342. ;            text cursor.
  343. ;            If select is 0, then these values form the
  344. ;            screen mask and cursor mask, respectively, for
  345. ;            the attribute cursor.
  346.  
  347. func    msm_settextcur
  348.     .if    msm_inited e 0, S3
  349.     push    BP
  350.     mov    BP,SP
  351.     mov    BX,P[BP]
  352.     mov    CX,P+2[BP]
  353.     mov    DX,P+4[BP]
  354.     mouse    10
  355.     pop    BP
  356. S3:    ret
  357. c_endp    msm_settextcur
  358.  
  359. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  360. ; Syntax:
  361. ;    void msm_readcounters(int *countx,int *county);
  362. ; Read mouse motion counters in mickeys. A mickey is 1/200 of an inch.
  363. ; Output:
  364. ;    *countx,*county =    mickey count since last call, values
  365. ;                range from -32768 to 32767.
  366.  
  367. func    msm_readcounters
  368.     push    BP
  369.     mov    BP,SP
  370.     .if    msm_inited e 0, R1
  371.     mouse    11
  372.     jmp    msm1
  373.  
  374. R1:    jmp    G1
  375. c_endp    msm_readcounters
  376.  
  377. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  378. ; Syntax:
  379. ;    void msm_signal(unsigned mask,
  380. ;        void (*func)(unsigned mask,unsigned state,
  381. ;            unsigned curposx,unsigned curposy),
  382. ;        void *stack);
  383. ; Set user-defined subroutine input mask. Used to set a function
  384. ; to be called at interrupt level whenever there is input available
  385. ; from the mouse. All the caveats apply to the interrupt service routine.
  386. ; Using this function is not for the faint-hearted.
  387. ; Input:
  388. ;    mask    Mask defining when to call func (1 means yes):
  389. ;        Bit 0:    mouse moved
  390. ;        Bit 1:    left button is pressed
  391. ;        Bit 2:    left button is released
  392. ;        Bit 3:    right button is pressed
  393. ;        Bit 4:    right button is released
  394. ;        Bit 5:    middle button is pressed
  395. ;        Bit 6:    middle button is released
  396. ;        Other bits are not used.
  397. ;    func    Pointer to application-defined interrupt service routine
  398. ;        to call whenever a mouse button is
  399. ;        pressed or released, or the mouse moves, according to the
  400. ;        bits in mask.
  401. ;    stack    Value to set stack pointer to when func is called. Should
  402. ;        point just past end of area that is at least 256 bytes
  403. ;        long.
  404. ; When func is called, it is passed the following:
  405. ;    mask    Event that occured is indicated with the bit set as defined
  406. ;        above.
  407. ;    state    If button event, this is the button number of the button that
  408. ;        changed (0 = left, 1 = right, 2 = middle).
  409. ;    curposx,curposy    Current mouse position.
  410.  
  411.     begdata
  412.     if LCODE
  413. ptrtoisr    dw    ?    ;pointer to C interrupt service routine
  414.         dw    ?
  415.     else
  416. ptrtoisr    dw    ?    ;pointer to C interrupt service routine
  417.     endif
  418. stack        dw    ?    ;value of SP
  419.     if LPTR
  420.         dw    ?    ;value of SS
  421.     endif
  422. stacksave    dw    ?,?    ;save stack of msm_isr
  423.     enddata
  424.  
  425. func    msm_signal
  426.     .if    msm_inited e 0, S5
  427.     push    BP
  428.     mov    BP,SP
  429.     mov    CS:dssave,DS    ;save our data segment register
  430.     mov    CX,P[BP]    ;load call mask
  431.     if SPTR
  432.     push    ES
  433.     endif
  434.     ifdef I8086S
  435.     mov    AX,P+2[BP]
  436.     mov    ptrtoisr,AX
  437.     mov    AX,P+2+SIZEPTR[BP]
  438.     mov    stack,AX
  439.     endif
  440.     ifdef I8086M
  441.     mov    AX,P+2[BP]
  442.     mov    ptrtoisr,AX
  443.     mov    AX,P+2+2[BP]
  444.     mov    ptrtoisr[2],AX
  445.     mov    AX,P+2+2+2[BP]
  446.     mov    stack,AX
  447.     endif
  448.     ifdef I8086P        ;funny Lattice C P model
  449.     mov    BX,P+2[BP]
  450.     mov    AX,[BX]
  451.     mov    ptrtoisr,AX
  452.     mov    AX,2[BX]
  453.     mov    ptrtoisr[2],AX
  454.     mov    AX,P+2+SIZEPTR[BP]
  455.     mov    stack,AX
  456.     endif
  457.     ifdef I8086C
  458.     mov    AX,P+2[BP]
  459.     mov    ptrtoisr,AX
  460.     les    AX,P+2+SIZEPTR[BP]
  461.     mov    stack,AX
  462.     mov    stack+2,ES
  463.     endif
  464.     ifdef I8086L
  465.     mov    AX,P+2[BP]
  466.     mov    ptrtoisr,AX
  467.     mov    AX,P+2+2[BP]
  468.     mov    ptrtoisr+2,AX
  469.     les    AX,P+2+SIZEPTR[BP]
  470.     mov    stack,AX
  471.     mov    stack+2,ES
  472.     endif
  473.     mov    DX,offset msm_isr
  474.     push    CS
  475.     pop    ES        ;ES:DX = pointer to msm_isr
  476.     mouse    12
  477.     if SPTR
  478.     pop    ES
  479.     endif
  480.     pop    BP
  481. S5:    ret
  482.  
  483. dssave    dw    ?        ;place to save DS
  484. c_endp    msm_signal
  485.  
  486. msm_isr    proc    far
  487.     mov    DS,CS:dssave    ;reload data segment
  488.     mov    stacksave,SP
  489.     mov    stacksave+2,SS
  490.     if SPTR
  491.     cli                ;for bug in old 8088's
  492.     mov    SS,CS:dssave
  493.     mov    SP,stack
  494.     sti                ;for bug in old 8088's
  495.     push    DS
  496.     pop    ES
  497.     else ;LPTR
  498.     cli                ;for bug in old 8088's
  499.     mov    SS,stack+2
  500.     mov    SP,stack
  501.     sti                ;for bug in old 8088's
  502.     endif
  503.     cld            ;no direction flag bugs
  504.     push    DX        ;vertical cursor coordinate
  505.     push    CX        ;horizontal cursor coordinate
  506.     push    BX        ;button state
  507.     push    AX        ;condition mask
  508.     if LCODE
  509.     call    dword ptr ptrtoisr
  510.     else
  511.     call    word ptr ptrtoisr
  512.     endif
  513.     cli                ;for bug in old 8088's
  514.     mov    SS,stacksave+2
  515.     mov    SP,stacksave
  516.     sti                ;for bug in old 8088's
  517.     ret
  518. msm_isr    endp
  519.  
  520. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  521. ; Syntax:
  522. ;    void msm_lightpenon(void);
  523. ; Light pen emulation mode on. The mouse emulates a light pen, that is,
  524. ; the 'pen' is off the screen when both buttons are up, and the 'pen' is
  525. ; down when both buttons are down.
  526.  
  527. func    msm_lightpenon
  528.     .if    msm_inited e 0, P1
  529.     mouse    13
  530. P1:    ret
  531. c_endp    msm_lightpenon
  532.  
  533. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  534. ; Syntax:
  535. ;    void msm_lightpenoff(void);
  536. ; Light pen emulation mode off.
  537.  
  538. func    msm_lightpenoff
  539.     .if    msm_inited e 0, P1
  540.     mouse    14
  541.     ret
  542. c_endp    msm_lightpenoff
  543.  
  544. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  545. ; Syntax:
  546. ;    void msm_setratio(unsigned ratiox,unsigned ratioy);
  547. ; Set mickey/pixel ratio (the sensitivity of the mouse). Higher values
  548. ; mean less cursor movement for corresponding mouse movement.
  549. ; The default values are 8,16. The values for
  550. ; ratiox and ratioy must be 1..32767.
  551.  
  552. func    msm_setratio
  553.     mov    AX,15
  554.     jmp    msm3
  555. c_endp    msm_setratio
  556.  
  557. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  558. ; Syntax:
  559. ;    void msm_condoff(unsigned upperx, unsigned uppery,
  560. ;             unsigned lowerx, unsigned lowery);
  561. ; Conditional off.
  562. ; The parameters define a rectangular region on the screen. When the
  563. ; mouse is in that region, the mouse cursor is hidden. This is useful
  564. ; if a portion of the screen is to be updated. A call to msm_showcursor()
  565. ; will undo this and turn the mouse cursor back on.
  566.  
  567. func    msm_condoff
  568.     .if    msm_inited e 0, P1
  569.     push    BP
  570.     mov    BP,SP
  571.     .save    <SI,DI>
  572.     mov    CX,P[BP]
  573.     mov    DX,P+2[BP]
  574.     mov    SI,P+4[BP]
  575.     mov    DI,P+6[BP]
  576.     mouse    16
  577.     .restore <DI,SI>
  578.     pop    BP
  579.     ret
  580. c_endp    msm_condoff
  581.  
  582. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  583. ; Syntax:
  584. ;    void msm_setthreshhold(unsigned speed);
  585. ; Set double speed threshhold, i.e. the speed at which the mickey/pixel
  586. ; ratio is temporarilly halved so the mouse apparently moves faster.
  587. ; Speed is in mickeys/second. The default is 64.
  588.  
  589. func    msm_setthreshhold
  590.     .if    msm_inited e 0, P1
  591.     push    BP
  592.     mov    BP,SP
  593.     mov    DX,P[BP]
  594.     mouse    19
  595.     pop    BP
  596.     ret
  597. c_endp    msm_setthreshhold
  598.  
  599.     endcode    msmouse
  600.  
  601.     end
  602.  
  603.  
  604.