Category : Dbase (Clipper, FoxBase, etc) Languages Source Code
Archive   : CL_MOUSE.ZIP
Filename : BMOUSE.ASM
;* Filename..............:BMOUSE.asm
;*------------------------------------------
;* PART I - Adapted from.: PC Magazine, Vol.6 No.13; July 21,1987
;* Article: MOUSE SOFTWARE by Jeff Prosise
;* Modified by...........: Bao Hoang
;* Date..................: August 1987
;*
;* Syntax.......: memvar = M_SET_ON()
;* : memvar = M_SET_OFF()
;*
;* Return values: M_SET_ON() - .T. if everything is O.K. and .F.
;* if something is wrong (i.e.,
;* mouse driver not installed)
;* M_SET_OFF() - always returns .T. and return
;* value can pretty much be ignored
;*
;* CSR_ON() - .T. if everything is O.K. and .F.
;* if it was not able to install the
;* routine (i.e., mouse driver not
;* installed)
;*
;* CSR_OFF() - always returns a .T.
;*
;*******************************************
;*** declare callable routines as PUBLIC
;
public M_SET_ON
public M_SET_OFF
public CSR_ON
public CSR_OFF
public LD_SCR
;*** declare Clipper's procedures for returning variables as FAR
;
extrn __RETL:far ; returns logical type
extrn __PARNI:far
;*** define keys to insert based on mouse conditions.
;
LB equ 1C0Dh ; set LEFT button to RETURN key
CB equ 3B00h ; set CENTER button to F1 key
RB equ 011Bh ; set RIGHT button to ESC key
;*** Define keyboard buffer area.
;
BIOS_DATA segment at 40h
org 1ah
BUFFER_HEAD dw ? ;pointer to the keybord
;buffer head
BUFFER_TAIL dw ? ;pointer to the keyboard
;buffer tail
org 80h
BUFFER_START dw ? ;starting keyboard buffer address
BUFFER_END dw ? ;ending keyboard buffer address
BIOS_DATA ends
;
;
;
CODE segment 'CODE' ; declare code segment of class CODE
assume cs:CODE,ds:BIOS_DATA
VCOUNT db 10 ; vertical delay counter
HCOUNT db 10 ; horizontal delay counter
HFLAG dw ? ; horizontal count sign flag
VFLAG dw ? ; vertical count sign flag
KEYCODE db 4Dh,4Bh,50h,48h ;keycodes for cursor keys
EIGHTY db 80 ; to allow multiply by 80
SV_AX dw ? ; temporary storage of AX register
SV_DX dw ? ; temporary storage of DX register
SCR_MAP db 2000 dup (0) ;screen map 80x25
SCR_OFF dw 0 ; screen offset
P_LEN dw 0 ; prompt length
FILL_CHAR db 0 ; character to fill are with
;=========================================
;= PART I:
;=
;= MOUSE, M_SET_ON(), M_SET_OFF()
;=
;= Used for the "keyboard emulation" mouse. These are the mouse
;= routines used to make the highlighting bar (w/ @...prompt/menu
;= to) move when you move the mouse.
;=========================================
;
MOUSE proc far
;
; determine which event occured, and branch accordingly
;
test ax,2 ; left button pressed?
jnz LEFT ; if yes, then go insert 'LB' into buffer
test ax,8 ; right button pressed?
jnz RIGHT ; if yes, then go insert 'RB' into buffer
test ax,32 ; center button pressed? (PC MOUSE)
jnz CENTER ; if yes, then go insert 'CB' into buffer
MOUSE0:
mov ax,11 ; use mouse driver's function 11
int 51 ; read mouse motion counters
mov HFLAG,0 ; initialize sign flags
mov VFLAG,2 ;
xor al,al ; zero AL for extended keycode
cmp cx,0 ; horizontal count positive?
jge MOUSE1 ; yes, then branch
inc HFLAG ; record negative condition
neg cx ; convert negative to positive
MOUSE1:
cmp dx,0 ; vertical count positive
jge MOUSE2 ; yes, then branch
inc VFLAG ; record negative condition
neg dx ; convert negative to positive
MOUSE2:
mov bx,HFLAG ; assume motion was horizontal
cmp cx,dx ; was assumption correct?
jae HORIZ ; yes, then branch
mov bx,VFLAG ; no, then correct it
dec VCOUNT ; decrement vertical delay count
jz MOUSE3 ; continue if count is zero
jmp GET_OUT
HORIZ:
dec HCOUNT
jz MOUSE3
GET_OUT:
ret
MOUSE3:
mov HCOUNT,10
mov VCOUNT,10 ; reset delay counter
mov ah,KEYCODE[bx] ; get keycode from table
call INSERT ; insert it into keyboard buffer
jmp RETURN
LEFT:
mov ax,LB ; load pre-defined 'LB' keycode
; into buffer
call INSERT ; insert it into buffer
jmp RETURN
RIGHT:
mov ax,RB ; load pre-defined 'RB' keycode
; into buffer
call INSERT ; insert it into buffer
jmp RETURN
CENTER:
mov ax,CB ; load pre-defined 'CB' keycode
; into buffer
call INSERT ; insert it into buffer
RETURN:
ret
MOUSE endp
;
;
;
;****************************************
;** M_SET_ON() : routine to set up a function to be called upon
;** mouse activity, using the mouse driver's
;** function 12.
;****************************************
M_SET_ON proc far
push bp ; save everything as documented in
mov bp,sp ; Aut '86 Nantucket News or you
push ds ; will blow up!
push es ;
mov ax,0 ; use function 0 of driver to see
int 33h ; if mouse and driver are installed
or ax,ax ; is there a mouse?
jne OK ; yes, continue
mov bx,0 ; return to Clipper a .F. to tell
push bx ; it that M_SET_ON() failed to set
call __retl ; up the routine (extended interface)
jmp DONE ; go back to Clipper
OK:
mov ax,15 ; use function 15 of mouse driver to
mov cx,400 ; set the mouses sensitivity
mov dx,800 ;
int 33h ;
mov ax,seg MOUSE ; tell function 12 where to find the
mov es,ax ; the mouse routine
mov dx,offset MOUSE ;
mov ax,12 ; use function 12
mov cx,0000000000101011b ; set up the mask for buttons
; and cursor
int 33h ; set it up!
mov bx,1 ; return a .T. to Clipper to tell it
push bx ; that the installation was successful
call __retl ; (using Clipper's extended interface)
DONE:
pop bx ; restore the stack or DIE!!!!
pop es ;
pop ds ;
pop bp ;
ret ; exit and pray!!
M_SET_ON endp
;
;
;
;***********************************************
;** M_SET_OFF() : routine to disable the mouse routine so that
;** accidentally hitting the mouse won't cause the
;** cursor keys to be inserted into the keyboard
;** buffer
;***********************************************
M_SET_OFF proc far
push bp ; save these registers as usual
mov bp,sp ;
push ds ; or DIE!!!!!
push es ;
mov ax,0 ; use function 0 of the mouse driver
int 33h ; to reset the mouse settings which
mov bx,1 ; effectively turns off the mouse routine
push bx ; return a .T. which really has no
call __retl ; meaning but needs to be done to allow
pop bx ; the routine to be used as a UDF without
pop es ; hanging. Restore the stack or hang
pop ds ; like a
pop bp ; bleep, bleep !!!!
ret ;
M_SET_OFF endp
;=====================================================
;= PART II:
;=
;= CSR_ON(),CSR_OFF(),MOUSER
;=
;= Routines used to simulate a "free floating" mouse cursor
;= (Mac-like).
;=====================================================
;
;
;*****************************************************
;* CSR_ON() - Sets the mouse cursor on.
;*****************************************************
CSR_ON proc far
push bp ; save everything as documented in
mov bp,sp ; Aut '86 Nantucket News or you
push ds ; will blow up!
push es ;
mov ax,0 ; use function 0 of driver to see
int 33h ; if mouse and driver are installed
or ax,ax ; is there a mouse?
jne OK2 ; yes, continue
mov bx,0 ; return to Clipper a .F. to tell
push bx ; it that CSR_ON() failed to turn
call __retl ; on the mouse cursor
jmp DONE2 ; go back to Clipper
OK2: mov ax,1 ; use function 1 of mouse driver
int 33h ; to turn cursor on
mov ax,seg MOUSER ; tell function 12 where to
mov es,ax ; find the mouse routine
mov dx,offset MOUSER ;
mov ax,12 ; use function 12
mov cx,0000000000101010b; set up the mask for buttons
; and cursor
int 33h ; set it up!
mov bx,1 ; return a .T. to Clipper to tell it
push bx ; that the installation was successful
call __retl ; (using Clipper's extended interface)
DONE2:
pop bx ; restore the stack or DIE!!!!
pop es ;
pop ds ;
pop bp ;
ret ; exit and pray!!
CSR_ON endp
;
;
;*****************************************************
;* CSR_OFF() - Sets the mouse cursor off.
;*****************************************************
CSR_OFF proc far
push bp ; save everything as documented in
mov bp,sp ; Aut '86 Nantucket News or you
push ds ; will blow up!
push es ;
OK3: mov ax,2 ; use function 2 of mouse driver
int 33h ; to turn cursor off
mov ax,0 ; use function 0 to
int 33h ; reset mouse...
mov bx,1 ; return a .T. to Clipper to tell it
push bx ; that the un-installation was successful
call __retl ; (using Clipper's extended interface)
DONE3:
pop bx ; restore the stack or DIE!!!!
pop es ;
pop ds ;
pop bp ;
ret ; exit and pray!!
CSR_OFF endp
;
;
;*********************************************************
;* MOUSER - Resident mouse routine for "free form mouse"
;*********************************************************
MOUSER proc far
mov ax,3 ; use function 3 of
int 33h ; mouse interrupt to determine
mov ax,cx ; store horiz. position in ax
xor ch,ch ;
mov cl,3 ;
sar ax,cl ; divide horiz. pos. by 8
sar dx,cl ; divide vert. pos by 8
mov SV_AX,ax ; save ax
mov SV_DX,dx ; save dx
mov ax,dx ;
call MULT10 ; multiply vert. count by 80
mov cl,3 ;
shl ax,cl ;
add ax,SV_AX ; then add horiz. pos.
mov bx,ax ;
int 3h
cmp SCR_MAP[bx],0 ; check to see if we are supposed to
; hit return
je DO_NADA ; don't do nothin' if it's 0
mov al,SCR_MAP[bx] ;
xor ah,ah
call INSERT
DO_NADA:
ret
MOUSER endp
;
;
;
;*****************************************************************
;* LD_SCR() - load the SCR_MAP with the appropriate values (called
;* from Clipper)
;*****************************************************************
LD_SCR proc far
push bp ; save stack or DIE !!
mov bp,sp
push ds
push es
mov ax,1 ; get first parameter (SCR_OFF)
push ax ;
call __parni ;
mov SCR_OFF,ax ;
pop ax
mov ax,2 ; get second parameter (P_LEN)
push ax ;
call __parni ;
mov P_LEN,ax ;
pop ax
mov ax,3 ; get third parameter (ASC(
push ax ;
call __parni ;
mov SV_AX,ax ;
pop ax
mov ax,SV_AX
xor ah,ah
mov cx,P_LEN ; fill SCR_MAP with appropriate
mov bx,SCR_OFF ; characters
NEXT:mov SCR_MAP[bx],al ;
inc bx ;
loop next ;
pop es ; restore stack or DIE !!
pop ds ;
pop bp ;
ret
LD_SCR endp
;
;
;=========================================================
;= Utility routines....... =
;=========================================================
;
;*********************************************************
;* INSERT - procedure to insert keys into keyboard buffer
;*********************************************************
INSERT proc near
mov bx,BIOS_DATA ; point DS to the BIOS data area
mov ds,bx ;
assume ds:BIOS_DATA ;
cli ; disable interrupts
mov bx,BUFFER_TAIL ; get buffer tail address
mov dx,bx ; transfer it to DX
add dx,2 ; calculate next buffer position
cmp dx,BUFFER_END ; did we overshoot the end?
jne INSERT1 ; no, then continue
mov dx,BUFFER_START ; yes, then wrap to start
; of buffer
INSERT1:
cmp cx,BUFFER_HEAD ; is the buffer full?
je INSERT2 ; yes, then end now
mov [bx],ax ; insert the keycode
mov bx,dx ; advance the tail
mov BUFFER_TAIL,bx ; record its new position
INSERT2:
sti ; enable interrupts
assume ds:nothing ;
ret ; exit user sub-routine
INSERT endp
;
;
;
;****************************************************************
;* MULT10 - multiply by ten
;****************************************************************
MULT10 proc near
shl ax,1
mov cx,ax
shl ax,1
shl ax,1
add ax,cx
ret
MULT10 endp
CODE ends
end
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/