dos_compilers/Zortech C++ v206/SOURCE/CLIB/MSMOUSE.ASM
2024-07-02 07:30:38 -07:00

606 lines
15 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;_ msmouse.asm Tue Jul 19 1988 Modified by: Walter Bright */
; Copyright (C) 1987-1988 by Walter Bright
; All Rights Reserved
; Written by Walter Bright
; Interface to Microsoft Mouse
; The mouse coordinate system is left-handed for both text and graphics modes,
; with 0,0 being the upper left corner. Note that the display package
; uses a left-handed coordinate system, but Flash Graphics uses a
; right-handed system.
; Also note that the mouse coordinates in text mode are not in character
; coordinates!(?)
;
; To convert from fg coordinates to mouse coords:
; mouse_x = fg_x;
; mouse_y = fg_displaybox[FG_Y2] - fg_y;
; To convert from display (character) coordinates to mouse coords:
; if (40 column mode)
; mouse_x = display_x * 16;
; else
; mouse_x = display_x * 8;
; mouse_y = display_y * 8;
;
; The Microsoft mouse sometimes gets the number of screen rows wrong in text
; mode, so the recommended method of opening the mouse if the display package
; is also used is:
; disp_open(); /* initialize display */
; msm_init(); /* initialize mouse */
;
; /* Mouse driver sometimes gets the number of screen rows wrong, */
; /* so here we force it to whatever disp_open() discovered. */
; msm_setareay(0,(disp_numrows - 1) * 8);
;
; msm_showcursor(); /* turn mouse cursor on */
;
; For more information refer to the Microsoft Mouse User's Guide.
ifndef __OS2__ ;it's in MOU.C
include macros.asm
c_public msm_init,msm_term,msm_showcursor,msm_hidecursor
c_public msm_getstatus,msm_setcurpos,msm_getpress,msm_getrelease
c_public msm_setareax,msm_setareay,msm_setgraphcur,msm_settextcur
c_public msm_readcounters,msm_signal,msm_lightpenon,msm_lightpenoff
c_public msm_setratio,msm_condoff,msm_setthreshhold
mouse macro func
ifnb <func>
mov AX,func
endif
int 33h
endm
begdata
msm_inited dw 0 ;set to !=0 if there is a mouse
enddata
begcode msmouse
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; int msm_init(void);
; Initialize mouse driver:
; o Turn off all mouse interrupts
; o Turn on light pen emulation
; o If in graphics mode, set cursor to be an arrow, if in text mode,
; set cursor to be inverse video
; o Set cursor to middle of screen
; o Turn off cursor display
; o Set min/max cursor position to full screen
; o Set mickey/pixel to 1/1 in the x direction and 2/1 in the y
; Returns:
; 0 failed
; -1 success
func msm_init
L1: clr AX
mov ES,AX
;Some versions of DOS have 0 in the vector table for interrupt 33h
.if <word ptr ES:0CCh> ne AX, L3
.if <word ptr ES:0CEh> e AX, L2
L3: mouse
L2: mov msm_inited,AX
ret
c_endp msm_init
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; void msm_term(void);
; Terminate mouse driver. This should be called before the program is
; exited if the mouse was used.
func msm_term
jmp L1 ;the init routine will fix things up
c_endp msm_term
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; void msm_showcursor(void);
; Show cursor. That is, increment the cursor flag. If the cursor flag is
; 0, then the cursor is displayed. Since msm_init() sets the value of
; the cursor flag to -1, msm_showcursor() must be called after msm_init()
; in order for the cursor to appear.
; Note that showcursor and hidecursor can be nested. That is, if n
; hidecursors were done, then n showcursors must be done in order to
; show the cursor.
; Generally, the point is to remove the cursor before any screen I/O
; is done, and then restore the cursor.
func msm_showcursor
.if msm_inited e 0, S1
mouse 1
S1: ret
c_endp msm_showcursor
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; void msm_hidecursor(void);
; Hide cursor. Decrement the cursor flag. Complement to msm_showcursor().
func msm_hidecursor
.if msm_inited e 0, H1
mouse 2
H1: ret
c_endp msm_hidecursor
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; int msm_getstatus(unsigned *curposx,unsigned *curposy);
; Get status.
; Output:
; *curposx,*curposy = mouse position
; Returns:
; Bit 0: left button (1 == down, 0 == up)
; Bit 1: right button
; Bit 2: middle button (for some mice)
; Ignore other bits.
func msm_getstatus
push BP
mov BP,SP
.if msm_inited e 0, G1
mouse 3
mov AX,BX ;button status
jmps msm1
G1: clr AX
cwd
mov CX,AX
msm1:
if SPTR
mov BX,P[BP]
mov [BX],CX ;M3
mov BX,P+SIZEPTR[BP]
mov [BX],DX ;M4
else
les BX,P[BP]
mov ES:[BX],CX ;M3
les BX,P+SIZEPTR[BP]
mov ES:[BX],DX ;M4
endif
pop BP
ret
c_endp msm_getstatus
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; void msm_setcurpos(unsigned curposx,unsigned curposy);
; Set cursor position.
; The upper left corner of the screen is 0,0. The values for curposx
; and curposy must be within the screen.
func msm_setcurpos
mov AX,4 ;mouse function
msm3: .if msm_inited e 0, S4
push BP
mov BP,SP
mov CX,P[BP]
mov DX,P+2[BP]
mouse
pop BP
S4: ret
c_endp msm_setcurpos
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; int msm_getpress(unsigned *count, unsigned *curposx,unsigned *curposy);
; Get button press information.
; Input:
; *count = which button are we refering to
; (0 = left button, 1 = right button, 2 = middle)
; Output:
; *count = count of button presses since last call
; to msm_getpress. Values can be 0..32767.
; *curposx,*curposy = mouse position at last press
; Returns:
; Bit 0: left button (1 == down, 0 == up)
; Bit 1: right button
; Bit 2: middle button
; Ignore other bits
func msm_getpress
mov AX,5 ;mouse function
msm2: push BP
mov BP,SP
.save SI
if SPTR
mov BX,P[BP]
mov BX,[BX]
else
les BX,P[BP]
mov BX,ES:[BX]
endif
shr BX,1
.if msm_inited e 0, G2
mouse
jmps G3
G2: clr AX
cwd
mov BX,AX
mov CX,AX
G3:
if SPTR
mov SI,P[BP]
mov [SI],BX ;*count
mov SI,P+SIZEPTR[BP]
mov [SI],CX ;*curposx
mov SI,P+SIZEPTR+SIZEPTR[BP]
mov [SI],DX ;*curposy
else
les SI,P[BP]
mov ES:[SI],BX ;*count
les SI,P+SIZEPTR[BP]
mov ES:[SI],CX ;*curposx
les SI,P+SIZEPTR+SIZEPTR[BP]
mov ES:[SI],DX ;*curposy
endif
.restore SI
pop BP
ret
c_endp msm_getpress
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; int msm_getrelease(unsigned *count,
; unsigned *curposx,unsigned *curposy);
; Get button release information.
; Input:
; *count = which button are we refering to
; (0 = left button, 1 = right button, 2 = middle)
; Output:
; *count = count of button releases since last call
; to msm_getpress. Values can be 0..32767.
; *curposx,*curposy = mouse position at last release
; Returns:
; Bit 0: left button (1 == down, 0 == up)
; Bit 1: right button
; Bit 2: middle button
; Ignore other bits
func msm_getrelease
mov AX,6 ;mouse function
jmp msm2
c_endp msm_getrelease
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; void msm_setareax(unsigned minx,unsigned maxx);
; Set minimum and maximum horizontal position. If maxx < minx, the values
; are exchanged. The mouse horizontal motion will be restricted to be within
; these values.
func msm_setareax
mov AX,7
jmp msm3
c_endp msm_setareax
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; void msm_setareay(unsigned miny,unsigned maxy);
; Set minimum and maximum vertical position. If maxy < miny, the values
; are exchanged. The mouse vertical motion will be restricted to be within
; these values.
func msm_setareay
mov AX,8
jmp msm3
c_endp msm_setareay
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; void msm_setgraphcur(int hotx,int hoty,int *pmasks);
; Set graphics cursor block.
; Input:
; hotx,hoty Location of 'hot spot' of cursor. Values
; must be -16..16. Location 0,0 is the upper
; left corner of the cursor, positive values
; extend right and down.
; pmasks Points to 32 words which contain bit masks
; defining the cursor.
; The first 16 words define the mask, that is,
; which bits of the background 'shine' through
; the cursor. A 1 means shine through, a 0 means not.
; The second 16 words define the bitmap of the cursor,
; 1 being on and 0 being off.
; The cursor is 16*16, the first word forms
; the top row, bit 15 forms the leftmost column.
func msm_setgraphcur
.if msm_inited e 0, S2
push BP
mov BP,SP
mov BX,P[BP]
mov CX,P+2[BP]
if SPTR
push DS
pop ES
mov DX,P+4[BP] ;put pointer in ES:DX
else
les DX,P+4[BP]
endif
mouse 9
pop BP
S2: ret
c_endp msm_setgraphcur
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; void msm_settextcur(int select,int scanstart,int scanstop);
; Set text cursor.
; Input:
; select If 1, then hardware text cursor. If 0, then
; attribute cursor.
; scanstart,
; scanstop If select is 1, then these values form the
; starting and ending scan lines of the hardware
; text cursor.
; If select is 0, then these values form the
; screen mask and cursor mask, respectively, for
; the attribute cursor.
func msm_settextcur
.if msm_inited e 0, S3
push BP
mov BP,SP
mov BX,P[BP]
mov CX,P+2[BP]
mov DX,P+4[BP]
mouse 10
pop BP
S3: ret
c_endp msm_settextcur
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; void msm_readcounters(int *countx,int *county);
; Read mouse motion counters in mickeys. A mickey is 1/200 of an inch.
; Output:
; *countx,*county = mickey count since last call, values
; range from -32768 to 32767.
func msm_readcounters
push BP
mov BP,SP
.if msm_inited e 0, R1
mouse 11
jmp msm1
R1: jmp G1
c_endp msm_readcounters
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; void msm_signal(unsigned mask,
; void (*func)(unsigned mask,unsigned state,
; unsigned curposx,unsigned curposy),
; void *stack);
; Set user-defined subroutine input mask. Used to set a function
; to be called at interrupt level whenever there is input available
; from the mouse. All the caveats apply to the interrupt service routine.
; Using this function is not for the faint-hearted.
; Input:
; mask Mask defining when to call func (1 means yes):
; Bit 0: mouse moved
; Bit 1: left button is pressed
; Bit 2: left button is released
; Bit 3: right button is pressed
; Bit 4: right button is released
; Bit 5: middle button is pressed
; Bit 6: middle button is released
; Other bits are not used.
; func Pointer to application-defined interrupt service routine
; to call whenever a mouse button is
; pressed or released, or the mouse moves, according to the
; bits in mask.
; stack Value to set stack pointer to when func is called. Should
; point just past end of area that is at least 256 bytes
; long.
; When func is called, it is passed the following:
; mask Event that occured is indicated with the bit set as defined
; above.
; state If button event, this is the button number of the button that
; changed (0 = left, 1 = right, 2 = middle).
; curposx,curposy Current mouse position.
begdata
if LCODE
ptrtoisr dw ? ;pointer to C interrupt service routine
dw ?
else
ptrtoisr dw ? ;pointer to C interrupt service routine
endif
stack dw ? ;value of SP
if LPTR
dw ? ;value of SS
endif
stacksave dw ?,? ;save stack of msm_isr
enddata
func msm_signal
.if msm_inited e 0, S5
push BP
mov BP,SP
mov CS:dssave,DS ;save our data segment register
mov CX,P[BP] ;load call mask
if SPTR
push ES
endif
ifdef I8086S
mov AX,P+2[BP]
mov ptrtoisr,AX
mov AX,P+2+SIZEPTR[BP]
mov stack,AX
endif
ifdef I8086M
mov AX,P+2[BP]
mov ptrtoisr,AX
mov AX,P+2+2[BP]
mov ptrtoisr[2],AX
mov AX,P+2+2+2[BP]
mov stack,AX
endif
ifdef I8086P ;funny Lattice C P model
mov BX,P+2[BP]
mov AX,[BX]
mov ptrtoisr,AX
mov AX,2[BX]
mov ptrtoisr[2],AX
mov AX,P+2+SIZEPTR[BP]
mov stack,AX
endif
ifdef I8086C
mov AX,P+2[BP]
mov ptrtoisr,AX
les AX,P+2+SIZEPTR[BP]
mov stack,AX
mov stack+2,ES
endif
ifdef I8086L
mov AX,P+2[BP]
mov ptrtoisr,AX
mov AX,P+2+2[BP]
mov ptrtoisr+2,AX
les AX,P+2+SIZEPTR[BP]
mov stack,AX
mov stack+2,ES
endif
mov DX,offset msm_isr
push CS
pop ES ;ES:DX = pointer to msm_isr
mouse 12
if SPTR
pop ES
endif
pop BP
S5: ret
dssave dw ? ;place to save DS
c_endp msm_signal
msm_isr proc far
mov DS,CS:dssave ;reload data segment
mov stacksave,SP
mov stacksave+2,SS
if SPTR
cli ;for bug in old 8088's
mov SS,CS:dssave
mov SP,stack
sti ;for bug in old 8088's
push DS
pop ES
else ;LPTR
cli ;for bug in old 8088's
mov SS,stack+2
mov SP,stack
sti ;for bug in old 8088's
endif
cld ;no direction flag bugs
push DX ;vertical cursor coordinate
push CX ;horizontal cursor coordinate
push BX ;button state
push AX ;condition mask
if LCODE
call dword ptr ptrtoisr
else
call word ptr ptrtoisr
endif
cli ;for bug in old 8088's
mov SS,stacksave+2
mov SP,stacksave
sti ;for bug in old 8088's
ret
msm_isr endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; void msm_lightpenon(void);
; Light pen emulation mode on. The mouse emulates a light pen, that is,
; the 'pen' is off the screen when both buttons are up, and the 'pen' is
; down when both buttons are down.
func msm_lightpenon
.if msm_inited e 0, P1
mouse 13
P1: ret
c_endp msm_lightpenon
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; void msm_lightpenoff(void);
; Light pen emulation mode off.
func msm_lightpenoff
.if msm_inited e 0, P1
mouse 14
ret
c_endp msm_lightpenoff
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; void msm_setratio(unsigned ratiox,unsigned ratioy);
; Set mickey/pixel ratio (the sensitivity of the mouse). Higher values
; mean less cursor movement for corresponding mouse movement.
; The default values are 8,16. The values for
; ratiox and ratioy must be 1..32767.
func msm_setratio
mov AX,15
jmp msm3
c_endp msm_setratio
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; void msm_condoff(unsigned upperx, unsigned uppery,
; unsigned lowerx, unsigned lowery);
; Conditional off.
; The parameters define a rectangular region on the screen. When the
; mouse is in that region, the mouse cursor is hidden. This is useful
; if a portion of the screen is to be updated. A call to msm_showcursor()
; will undo this and turn the mouse cursor back on.
func msm_condoff
.if msm_inited e 0, P1
push BP
mov BP,SP
.save <SI,DI>
mov CX,P[BP]
mov DX,P+2[BP]
mov SI,P+4[BP]
mov DI,P+6[BP]
mouse 16
.restore <DI,SI>
pop BP
ret
c_endp msm_condoff
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntax:
; void msm_setthreshhold(unsigned speed);
; Set double speed threshhold, i.e. the speed at which the mickey/pixel
; ratio is temporarilly halved so the mouse apparently moves faster.
; Speed is in mickeys/second. The default is 64.
func msm_setthreshhold
.if msm_inited e 0, P1
push BP
mov BP,SP
mov DX,P[BP]
mouse 19
pop BP
ret
c_endp msm_setthreshhold
endcode msmouse
endif ;__OS2__
end