home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / virus / df350a.zip / DFM.ASM < prev    next >
Assembly Source File  |  1989-10-12  |  28KB  |  661 lines

  1. ;DFMOUSE version 1.00
  2. ;Quick and dirty fixes by Gordon Haff - 10/89
  3. ;                         3205 Windsor Ridge Dr., Westboro MA 01581
  4. ; This file and DFMOUSE.COM is NOT an integral part of Directory Freedom.
  5. ; While this file and program are released into the public domain,
  6. ; Directory Freedom, DFCONFIG, and their associated documentation are
  7. ; SHAREWARE.
  8. ;
  9. ; See the Directory Freedom documentation for information on the use of
  10. ; this program in conjunction with DF.  Unless you are interested in some
  11. ; of the technical nitty-gritty, you need not concern yourself with the
  12. ; balance of this file.
  13. ;--------------------------------------------------------------------------
  14. ; This program has (for the time being) been modified in a "quick and
  15. ; dirty" manner to provide functionality with Directory Freedom (DF).
  16. ; As written, MOUSER has some problems -- not only with DF, but with other
  17. ; programs I have tested.  This problem results in the mouse buttons
  18. ; being non-functional.  The problem appears to be that DF and other assembly
  19. ; language programs often use int 16h to scan for keys.  Then the keyboard
  20. ; scan code returned in ah is used for key processing, rather than the
  21. ; Ascii value returned in al.  There may be more to it than this, but
  22. ; this explanation seems to be the obvious one.
  23. ;
  24. ; So, I've done the following to this program.  I may try to do a proper
  25. ; fixup at a later date if someone else doesn't beat me to it.
  26. ;    Hard set left button to <space>
  27. ;    Hard set right button to <CR>
  28. ;    Disabled both button option (there wasn't anything especially wrong
  29. ;        with this option, but in practice it just didn't produce the
  30. ;         desired results for me
  31. ;    Adjusted menus, help screens to reflect changes
  32. ; Since this program is still basically the same as MOUSER, I am
  33. ; distributing this file in accordance with the original author's wishes
  34.  
  35. ;MOUSER.007 - MOUSE cursoR for the Microsoft Mouse & Compatibles - 09/87
  36. ; --------------------------------------------------------------------------
  37. ; (c) OZZARD of WIS / Paul Noeldner, 510 S. Dickinson, Madison, WI 53703
  38. ;                This Software is In the Public Domaine
  39. ; OZZARD of WIS assumes no liability for any loss or damage from use of this
  40. ; program.  Use of the program constitutes agreement to this disclaimer.
  41. ; When copied or distributed, it must include this ASM code documentation.
  42. ; --------------------------------------------------------------------------
  43. ;                       PURPOSE
  44. ; MOUSER is dedicated to all cats (cursor arrow tappers) out there who are
  45. ; interested in seeing how nice a mouse can work in everyday PC programs.
  46. ; The feel of high-powered point-and-click mouse software, can be quickly
  47. ; realized in any scrolling-menu program by using MOUSER and a mouse -
  48. ; without high-falutin graphics or window software, or gobs of TSR memory.
  49. ; --------------------------------------------------------------------------
  50. ;            ENVIRONMENT
  51. ; The MicroSoft(Tm) MOUSE.COM or MOUSE.SYS mouse driver, or a compatible
  52. ; using the same driver protocol, must be implemented to run MOUSER.
  53. ; MOUSER then works with ANY PROGRAM that accepts cursor up/down/left/right.
  54. ; The mouse buttons can be used for COMMON KEYS like return and escape -
  55. ; both mouse speed, and buttons, can be set via parms to suit your needs.
  56. ; --------------------------------------------------------------------------
  57. ;            USE
  58. ; The MOUSER defaults - average cursor speed, and RETURN/ESCAPE/BREAK buttons,
  59. ; work well in many applications.  Individuals may wish to adjust the
  60. ; speed and the button functions for particular applications, to make mouse
  61. ; use satisfying and productive (rather than tedius or target practice).
  62. ; The cursor speed and buttons can be customized by you to complement
  63. ; your applications.  You run MOUSER with control parameters from the DOS
  64. ; prompt or in any application .bat procedure file.
  65. ; --------------------------------------------------------------------------
  66. ;            PARMS
  67. ; MOUSER Hn Vn Lnn Rnn Bnn?
  68. ;    ? - help - which also appears if parms are not understood
  69. ;    Hn, Vn  n=1 to 9 - sets Horizontal or Vertical cursor speed
  70. ;    Lx, Rx, Bx - x=character or 2-digit ASCII value - sets Left,
  71. ;                    Right, or Both (pressed together) button key values
  72. ;                 Digit values above 31 are treated as 'extended' keys.
  73. ;    These parms are all optional, in any order, with any delimiters.
  74. ; --------------------------------------------------------------------------
  75. ;            SAMPLES
  76. ;  MOUSER ?         - shows full help, sample button ASCII values.
  77. ;  MOUSER        - sets default medium cursor, RETURN, ESCAPE buttons
  78. ;  MOUSER H1 V1 L27 R13 B/ - slow cursor, left ESCAPE, right RETURN, both /
  79. ;    This might be appropriate for a scrolling-bar menu program.
  80. ;    This example shows how to reverse the return/escape buttons,
  81. ;       if you happen to prefer them in that order.  Both buttons would
  82. ;       input a slash, which may be useful for spreadsheet commands.
  83. ;  MOUSER V9 L73 R81 B27 - fast vertical, left PGUP, right PGDN, both ESC
  84. ;    This would be useful in a text file browse, and to
  85. ;       quickly position the cursor and mark blocks in an editor.
  86. ;   The button keys work in any program that accepts the specified keys.
  87. ;   The MOUSER ? help display shows several more common key values.
  88. ;   See your DOS or BASIC manual for a complete list of the ASCII values
  89. ;   of keys below 32 (space), such as 13-RETURN, and the 'extended' keys
  90. ;   such as 81-PGUP.  Any values over 32 are considered 'extended' keys.
  91. ;   If a character is specified instead of a 2-digit value, it is used.
  92. ;   MOUSER +         - the + parm is the currently implemented means to
  93. ;                reactivate MOUSER if it becomes deactivated.
  94. ;                         Once you use +, it must be used subsequently.
  95. ;                         Hopefully, the next version will not need this.
  96. ; --------------------------------------------------------------------------
  97. ; The regular cursor keys continue to work as usual.  Programs that have
  98. ; their own mouse driver support, work independently of MOUSER.
  99. ; MOUSER does not prevent or preclude any normal use of the keyboard.
  100. ; --------------------------------------------------------------------------
  101. ; Some programs appear to disable MOUSER; you may want to put MOUSER
  102. ; in the application .bat startup file, after the application program,
  103. ; to turn the mouse back on after running the application.  Programs
  104. ; that have custom mouse drivers are commonly guilty of this crime.
  105. ; In that case, use the + parameter to ask that a fresh copy be loaded.
  106. ; Once the + parameter is used, it must subsequently be used each time.
  107. ; --------------------------------------------------------------------------
  108. ;            MORE ABOUT TSR AND RELOADING
  109. ; Normally one copy of MOUSER loads memory resident; after that, the parms
  110. ; are updated whenever the program is run.  The program takes about 600 bytes
  111. ; of memory - much less than 'custom' mouse menus.  By not reloading
  112. ; each time it is run, it saves that much more memory for you.
  113. ; If the mouse driver has been disengaged by any program, it is reengaged
  114. ; by using the + parameter, which loads a fresh copy of MOUSER.  A future
  115. ; version of this program should get around that requirement, but my
  116. ; knowledge of assembler is pretty weak and I cannot seem to reengage by
  117. ; pointing at the current resident version.  Give it a hack - give me a call!
  118. ; See the code related to tsrsav and address 126h - that was my attempt.
  119. ; --------------------------------------------------------------------------
  120. ;            ACKNOWLEDGMENT
  121. ; The program code was modeled after MOUSEKEY by Jeff Prosise / Ziff Davis.
  122. ; --------------------------------------------------------------------------
  123. ;            CHANGES FROM MOUSEKEY
  124. ; While MOUSER can be used in place of MOUSEKEY, the defaults are different.
  125. ; Enhancements have been made to improve user control over parameters.
  126. ; The program normally loads just one TSR copy even if run more than once.
  127. ; --------------------------------------------------------------------------
  128. ;            SPECIFIC IMPROVEMENTS
  129. ; (1) Added control over sensitivity of horizontal motion.
  130. ; (2) Prioritized vertical above horizontal movement (otherwise the mouse
  131. ;     tends to jump left and right while positioning vertically).
  132. ; (3) Set defaults to suit menu scrolling - slower cursor speed, and
  133. ;     mouse buttons set to RETURN, ESCAPE (instead of MOUSEKEY PGUP, PGDN).
  134. ; (4) Allow optional parms for speed 1-9 and custom mouse button values
  135. ;     specified as actual characters or 2-digit ASCII codes.
  136. ;     Example:  MOUSER H5 V5 L13 R27 B03 (example indicates the defaults).
  137. ;     All parms are optional in any order.  Any delimiters are ignored.
  138. ;     Any unrecognized 'junk' on the command line displays help and a message.
  139. ; (5) Added processing for 'both buttons' pressed, giving a third key value
  140. ;     in addition to left and right button values.  Default is 03, CTRL-C.
  141. ; (5) Added help - enter MOUSER ? for help display.
  142. ; (6) Posts current TSR version if already loaded, by finding itself in
  143. ;     memory.  This is especially important since the intent is to run
  144. ;     MOUSER whenever it is desirable to set parms to suit particular programs.
  145. ;     It may be run as part of .BAT files for specific applications.
  146. ;     Currently, if driver is 'disengaged', must reload using + parm.
  147. ; --------------------------------------------------------------------------
  148. ;            PROGRAM STRUCTURE
  149. ; The following program structure is based on Jeff Prosise's MOUSEKEY.
  150. ; It includes a TSR segment and an initialization segment that now sets the
  151. ; parameters and terminates after pointing the PLP to the end of the TSR part.
  152. ; If already loaded, parms are posted to the current address of the program.
  153. ; --------------------------------------------------------------------------
  154. bios_data     segment at 40h
  155.               org 1Ah
  156. buffer_head   dw ?                          ;pointer to keyboard buffer head
  157. buffer_tail   dw ?                          ;pointer to keyboard buffer tail
  158.               org 80h
  159. buffer_start  dw ?                          ;starting keyboard buffer address
  160. buffer_end    dw ?                          ;ending keyboard buffer address
  161. bios_data     ends
  162. ;
  163. code          segment para public 'code'
  164.               assume cs:code
  165.               org 100h
  166. begin:        jmp init                    ;goto initialization code
  167. ; --------------------------------------------------------------------------
  168. ;This part was enhanced in MOUSER to include hdelay and lkey/rkey/bkey values,
  169. ;and to support location and posting of current TSR version of program.
  170. ; --------------------------------------------------------------------------
  171. resfinder    db 'MOUSER CODE'    ;This is used to find and change parms
  172.                     ;if MOUSER program is already resident.
  173.                     ;Address of above literal is mcb+113h.
  174.                     ;If this db block is changed, also
  175.                     ;change the initialize mcb: and post:
  176.                     ;code that finds and changes the parms.
  177.                     ;The following parms are at mcb+11Eh.
  178. vdelay        db 2            ;vertical delay (set by Vn speed parm)
  179. hdelay        db 5            ;horizontal delay (set by Hn parm)
  180. lkey        dw  0020h        ;keycode for left button (set by Lnn)
  181. rkey        dw 01C0Dh        ;keycode for right button (set by Rnn)
  182. bkey        dw  5100h        ;keycode for both buttons (set by Bnn)
  183. tsrsav        dw 0000h        ;address of 'mouse' segment below
  184. ;
  185. vcount        db 1            ;vertical mouse mickey counter
  186. hcount        db 1            ;horizontal mouse mickey counter
  187. vflag        dw ?            ;vertical count sign flag
  188. hflag        dw ?            ;horizontal count sign flag
  189. keycode        db 4Dh,4Bh,50h,48h    ;keycodes for up/dn/lf/rt cursor keys
  190. ;------------------------------------------------------------------------------
  191. ;This subroutine is handed control by the mouse driver when the mouse is
  192. ;moved or a button is pressed.
  193. ;------------------------------------------------------------------------------
  194. mouse         proc far
  195. ;
  196. ;Determine which event occurred and branch accordingly.
  197. ;
  198.               test ax,2                     ;was the left button pressed?
  199.               jnz lbut                      ;yes, then branch
  200.               test ax,8                     ;was the right button pressed?
  201.               jnz rbut                      ;yes, then branch
  202. ; --------------------------------------------------------------------------
  203. ;Move the cursor in the direction indicated by the most recent mouse move.
  204. ;This was modified from MOUSEKEY to prioritize vertical over horizontal,
  205. ;and to test a horizontal delay factor.
  206. ; --------------------------------------------------------------------------
  207. mouse0:       mov ax,11                     ;function 11
  208.               int 51                        ;read mouse motion counters
  209.               mov hflag,0                   ;initialize sign flags
  210.               mov vflag,2
  211.               xor al,al                     ;zero AL for extended keycode
  212.               cmp dx,0                      ;vertical count positive?
  213.               jge mouse1                    ;yes, then branch
  214.               inc vflag                     ;record negative condition
  215.               neg dx                        ;convert negative to positive
  216. mouse1:       cmp cx,0                      ;horizontal count positive?
  217.               jge mouse2                    ;yes, then branch
  218.               inc hflag                     ;record negative condition
  219.               neg cx                        ;convert negative to positive
  220. mouse2:       mov bx,vflag                  ;assume motion was vertical
  221.               cmp dx,cx                     ;was the assumption correct?
  222.               jae mouse4                    ;yes, then branch
  223.               mov bx,hflag                  ;no, then correct it
  224.               dec hcount                    ;decrement horizontal count
  225.               jz  mouse3                    ;continue if count is zero
  226.               ret                           ;exit if it's not
  227. ; --------------------------------------------------------------------------
  228. ;The hdelay/vdelay values allow control over horizontal sensitivity.
  229. ;These are input as Hn Vn parms as speed 1-slow to 9-fast, and converted
  230. ;for decrementing to delay 9-slow to 1-fast.  The delay simply ignores
  231. ;the indicated number of mickeys (mouse increments) before responding.
  232. ;They correspond roughly to screen pixels; e.g. speed 1 moves 1 pixel where
  233. ;speed 9 moves 9 pixels in a similar physical mouse movement (about 1/32").
  234. ; --------------------------------------------------------------------------
  235. mouse3:       mov ah,hdelay
  236.           mov hcount,ah                 ;reset horizontal delay
  237.               jmp setkey                    ;
  238. mouse4:       dec vcount                    ;decrement vertical delay
  239.               jz  mouse5                    ;continue if count is zero
  240.               ret                           ;exit if it's not
  241. mouse5:       mov ah,vdelay
  242.           mov vcount,ah                 ;reset vertical delay
  243. setkey:       mov ah,keycode[bx]            ;get keycode from table
  244.               jmp insert                    ;insert it into keyboard buffer
  245. ;
  246. ;The left button was pressed.  Load AX with the keycode.
  247. ;
  248. lbut: ;     test ax,8
  249.      ;     jnz bbut                ;both buttons?
  250.           mov ax,lkey                   ;load left button keycode
  251.               jmp insert        ;insert into the keyboard buffer
  252. ;
  253. ;The right button was pressed.  Load AX with the keycode.
  254. ;
  255. rbut:         mov ax,rkey                   ;load keycode
  256.           jmp insert        ;insert into keyboard buffer
  257. ;
  258. ;Both buttons were pressed.  Load AX with the keycode.
  259. ;
  260. bbut:          mov ax,bkey        ;load both button keycode
  261. ;
  262. ;Insert the keycode in AX into the keyboard buffer.
  263. ;
  264. insert:       mov bx,bios_data              ;point DS to BIOS data area
  265.               mov ds,bx
  266.               assume ds:bios_data
  267.               cli                           ;disable interrupts
  268.               mov bx,buffer_tail            ;get buffer tail address
  269.               mov dx,bx                     ;transfer it to DX
  270.               add dx,2                      ;calculate next buffer position
  271.               cmp dx,buffer_end             ;did we overshoot the end?
  272.               jne insert1                   ;no, then continue
  273.               mov dx,buffer_start           ;yes, then wrap around
  274. insert1:      cmp dx,buffer_head            ;is the buffer full?
  275.               je insert2                    ;yes, then end now
  276.               mov [bx],ax                   ;insert the keycode
  277.               mov bx,dx                     ;advance the tail
  278.               mov buffer_tail,bx            ;record its new position
  279. insert2:      sti                           ;enable interrupts
  280.               assume ds:nothing
  281.               ret                           ;exit user-defined subroutine
  282. mouse         endp
  283. ;
  284. ;------------------------------------------------------------------------------
  285. ;INIT routine points the mouse driver to the user-defined subroutine,
  286. ;then leaves it resident in memory.
  287. ;------------------------------------------------------------------------------
  288. init        proc near
  289.                 jmp setup
  290. ;
  291. logo        db 201,205,205,181
  292. db'     DFM / 10/89 / Gordon Haff / Public Domain / ?-HELP      '
  293. db 198,205,205,187,13,10,'$'
  294. ;
  295. helpmsg        db 186
  296. db ' modified from MOUSER by Paul Noeldner, Madison, WI 608-255-5577   '
  297. db 186,13,10,186
  298. db '   ',15,' For users of Directory Freedom to simulate:                   '
  299. db 186,13,10,186
  300. db '                - Up/Down cursor keys (move the mouse)             '
  301. db 186,13,10,186
  302. db '                - <Space Bar> (press the left mouse button)        '
  303. db 186,13,10,186
  304. db '                - <CR> (press the right mouse button)              '
  305. db 186,13,10,186
  306. db ' DFM V8 H5   Example showing default parameters.                   '
  307. db 186,13,10,186
  308. db '    Hn, Vn      Horizontal ,Vertical speed 1-9: 5 = medium.        '
  309. db 186,13,10,186
  310. db '    +           Loads new copy of DFM (use only if disengaged).    '
  311. db 186,13,10,186
  312. db '    All parms are optional, in any order, with any delimiters.     '
  313. db 186,13,10,200
  314. db 67 dup ('═')
  315. db 188,13,10,'$'
  316. ;
  317. errmsg      db 7,200
  318. db 8 dup ('═')
  319. db 16,' DRIVER MISSING: Install MOUSE.SYS or MOUSE.COM ',17
  320. db 9 dup ('═')
  321. db 188,7,13,10,'$'
  322. ;
  323. junkmsg      db 7,200
  324. db 7 dup ('═')
  325. db 16,' UKNOWN INPUT PARAMETER - CHECK THIS HELP DISPLAY ',17
  326. db 8 dup ('═')
  327. db 188,7,'$'
  328. ;
  329. loadmsg        db 200
  330. db 18 dup ('═')
  331. db 16,' OK - Mouse Cursor Installed ',17
  332. db 18 dup ('═')
  333. db 188,13,10,'$'
  334. ;
  335. postmsg        db 200
  336. db 16 dup ('═')
  337. db 16,' OK - Mouse Cursor Parms Adjusted ',17
  338. db 15 dup ('═')
  339. db 188,13,10,'$'
  340. ;
  341. endparm     dw 81h        ;end of parm input
  342. mcbptr        dw 0000h    ;pointer to memory control blocks
  343. found           db 'N'        ;is MOUSER already loaded TSR in memory
  344. newcopy        db 'N'        ;indicates if + (update) parm entered
  345. lit        db ?        ;literal parm input character
  346. dig        db 'N'        ;found a digit?
  347. ;
  348. ;Logo display
  349. ;
  350. setup:    lea dx,logo              ;show logo
  351.     mov ah,9
  352.     int 21h
  353.     call parms        ;process input parms
  354.     call mcbwalk        ;check if MOUSER is already resident
  355. endit:    jmp allthru        ;exit program
  356. ;
  357. init    endp
  358. ;
  359. ;-----------------------------------------------------------------------------
  360. ;Process the command line parms (if any)
  361. ;
  362. parms    proc near
  363.     mov bx,0        ;point at input parm length in Pgm Seg Prefix
  364.     mov si,80h
  365.     mov ah,0
  366.         mov al,byte ptr[si]     ;now we have the length
  367.     add ax,80h        ;compute end of parm
  368.         mov endparm,ax          ;remember it
  369.     inc si            ;skip initial space in input parm
  370. ;
  371. parmloop:
  372.     mov bx,0
  373.     inc si            ;get input from command parm
  374.     cmp si,endparm             ;see if at end of parm
  375.         jle parse        ;if not, process it
  376.     ret            ;if so, done with setup work
  377. ;
  378. parse:    mov al,byte ptr[si]    ;get next character
  379.         cmp al,' '        ;skip blanks
  380.     je  parmloop
  381.     cmp al,'/'        ;skip slashes
  382.     je  parmloop
  383.     cmp al,','        ;skip commas
  384.     je  parmloop
  385.     cmp al,'+'        ;load new copy?
  386.     jne help
  387.     mov newcopy,'Y'
  388.     jmp parmloop
  389. help:    cmp al,'?'        ;show help?
  390.     jne case
  391.     lea dx,helpmsg        ;help display
  392.     mov ah,9
  393.     int 21h
  394.     int 20h
  395. ;
  396. case:     cmp al,91        ;upper case?
  397.     jl  upper
  398.           sub al,32        ;convert lower to upper case
  399. ;
  400. upper:    call parmcheck        ;see if H, V, L, R
  401.     jmp parmloop        ;continue parsing thru parm
  402. ;
  403. parms    endp
  404. ;
  405. ;-----------------------------------------------------------------------------
  406. ;Check for Horizontal and Vertical Speed, Left/Right/Both button control values
  407. ;
  408. parmcheck proc near
  409.     cmp al,'H'        ;is it horizontal speed parm
  410.     jne parmv               ;if not, check vertical speed
  411.     call digedit        ;check it out, value returned in al
  412.         cmp dig,'Y'        ;is it a digit?
  413.         jne junk        ;if not, return message
  414.     not al            ;invert 10-speed to get delay
  415.       mov hdelay,al           ;store horizontal delay value
  416.     ret            ;back to parsing parms
  417. ;
  418. parmv:    cmp al,'V'        ;is it vertical speed parm?
  419.     jne parml               ;if not, check left button
  420.     call digedit        ;check it out, value returned in al
  421.     cmp dig,'Y'        ;is it a digit?
  422.     jne junk        ;if not, return message
  423.     not al            ;invert 10-speed to get delay
  424.     mov vdelay,al           ;store vertical delay value
  425.     ret
  426. ;
  427. parml:    cmp al,'L'        ;is it left button parm?
  428.     jmp parmr               ;if not, check right button  [DISABLED]
  429.         call dighex        ;get digits into hex
  430.     mov lkey,ax        ;set left button key code
  431.     ret
  432. ;
  433. parmr:    cmp al,'R'        ;is it right button parm?
  434.     jmp parmb        ;if not,check both buttons            [DISABLED]
  435.     call dighex        ;get digits into hex
  436.     mov rkey,ax        ;set right button key code
  437.     ret
  438. ;
  439. parmb:    cmp al,'B'        ;is it both buttons parm?
  440.     jmp junk        ;send message if unknown parm         [DISABLED]
  441.     call dighex        ;get digits into hex
  442.     mov bkey,ax        ;set both buttons key code
  443.     ret
  444. ;
  445. ;Junk parm error message
  446. ;
  447. junk:    lea dx,helpmsg        ;help, plus error message for invalid parms
  448.     mov ah,9
  449.     int 21h
  450.     lea dx,junkmsg
  451.     mov ah,9
  452.     int 21h
  453.     int 20h            ;and program ends
  454. ;
  455. parmcheck endp
  456. ;
  457. ;-----------------------------------------------------------------------------
  458. ;Digits to hex routine
  459. ;
  460. dighex    proc near
  461.     call digedit        ;get next digit
  462.         cmp dig,'Y'        ;is it a digit?
  463.     je  digcon         ;if so, continue
  464.     ret            ;otherwise got literal, return it
  465. digcon:    cbw            ;byte in al goes to word in ax
  466.     xchg ax,bx        ;trade digit and number
  467.     mov cx,10d
  468.     mul cx            ;number in ax times 10
  469.     xchg ax,bx        ;trade number and digit
  470.     add bx,ax        ;add digit to number
  471.     call digedit        ;get next digit
  472.     cmp dig,'Y'        ;is it a digit?
  473.     jne junk        ;return message if not
  474.     cbw            ;byte in al goes to word in ax
  475.     xchg ax,bx        ;trade digit and number
  476.     mov cx,10d
  477.     mul cx            ;number in ax times 10
  478.     xchg ax,bx        ;trade number and digit
  479.     add bx,ax        ;add digit to number
  480.         mov ax,bx
  481.         cmp al,20h        ;is number > 20?
  482.     jl setok        ;no, set as is
  483.     mov ah,al        ;yes, make it high byte
  484.     mov al,0        ;null low byte
  485. setok:    ret            ;all thru, got 2 digits into binary form
  486. ;
  487. dighex endp
  488. ;
  489. ;-----------------------------------------------------------------------------
  490. ;Get value of ASCII digit or literal, return in ah
  491. ;
  492. digedit    proc near
  493.     mov dig,'N'        ;may not have a digit here
  494.     inc si
  495.     mov al,byte ptr[si]    ;get next byte
  496.         mov lit,al        ;save literal value
  497.     sub al,30h        ;drop ascii code to convert digit to value
  498.     jl  liter        ;if not digit, use literal
  499.     cmp al,9d        ;
  500.     jg  liter        ;if not digit, use literal
  501.      sub al,11d
  502.     mov dig,'Y'        ;yes, got a digit
  503.     ret
  504. liter:    or ax,ax        ;get ax to null
  505.     mov al,lit        ;plug in literal character
  506.     ret            ;back to parm scan
  507. ;
  508. digedit endp
  509. ;
  510. ;-----------------------------------------------------------------------------
  511. ;See if MOUSER is already resident by walking memory control blocks.
  512. ;
  513. ;Each MCB is marked with M in first byte, last block has Z in first byte.
  514. ;The length of each MCB is in byte 3.  Adding len + 1 locates the next MCB.
  515. ;If MOUSER is already resident, parms are updated in that copy of the program.
  516. ;
  517. mcbwalk proc near
  518.     push bp            ;remember right where we were (we hope)
  519.     push ax                 ;the stack was getting messed in this code
  520.     push bx
  521.     push cx
  522.     push dx
  523.     push ds
  524.     push es
  525.     mov ah,52h        ;DOS fn to get first memory control block
  526.     int 21h
  527.     mov ax,es:[bx-2]    ;stash starting mcb address in variable
  528.     mov mcbptr,ax
  529. ;
  530. search: mov es,mcbptr        ;get first byte at current mcb address
  531.     mov dl,byte ptr es:[0]
  532.         cmp dl,'M'        ;an M means TSR, but not last one loaded
  533.         je  gotmcb
  534.     pop es
  535.     pop ds
  536.     pop dx
  537.     pop cx
  538.     pop bx
  539.     pop ax
  540.     pop bp            ;back to current memory values and pointers
  541.         ret            ;Done with TSR chain
  542. ;
  543. gotmcb: cmp found,'Y'        ;see if already found
  544.     je  nextmcb        ;skip to end of chain if already found
  545.     mov dl,byte ptr es:[113h] ;if not found yet, look for 'MOUSER CODE'
  546.     cmp dl,'M'          ;literal starting in byte 4
  547.     jne nextmcb
  548.     mov dl,byte ptr es:[114h]
  549.     cmp dl,'O'
  550.     jne nextmcb
  551.     mov dl,byte ptr es:[115h]
  552.     cmp dl,'U'
  553.     jne nextmcb
  554.     mov dl,byte ptr es:[116h]
  555.     cmp dl,'S'
  556.     jne nextmcb
  557.     mov dl,byte ptr es:[117h]
  558.     cmp dl,'E'
  559.     jne nextmcb
  560.     mov dl,byte ptr es:[118h]
  561.     cmp dl,'R'
  562.     jne nextmcb
  563.     mov dl,byte ptr es:[11Ah]
  564.     cmp dl,'C'
  565.     jne nextmcb
  566.     mov dl,byte ptr es:[11Bh]
  567.     cmp dl,'O'
  568.     jne nextmcb
  569.     mov dl,byte ptr es:[11Ch]
  570.     cmp dl,'D'
  571.     jne nextmcb
  572.     mov dl,byte ptr es:[11Dh]
  573.     cmp dl,'E'
  574.     jne nextmcb
  575.     call post        ;post parms to existing MOUSER TSR copy
  576.     jmp nextmcb
  577. ;
  578. nextmcb: mov ax,mcbptr        ;on to the next mcb
  579.     mov es,ax
  580.     add ax,word ptr es:3    ;length of block is in byte 3
  581.         inc ax            ;add length plus 1 for next mcbptr
  582.     mov mcbptr,ax
  583.         jmp search
  584. ;
  585. mcbwalk endp
  586. ;
  587. ;-----------------------------------------------------------------------------
  588. ;Post parms to data locations in current resident version of MOUSER
  589. ;
  590. post    proc near
  591.     mov found,'Y'        ;indicate TSR now found
  592.     mov al,vdelay        ;and post V, H, L, R and B parms to memory
  593.      mov byte ptr es:[11Eh],al
  594.     mov al,hdelay
  595.     mov byte ptr es:[11Fh],al
  596.     mov ax,lkey
  597.     mov word ptr es:[120h],ax
  598.     mov ax,rkey
  599.     mov word ptr es:[122h],ax
  600.     mov ax,bkey
  601.     mov word ptr es:[124h],ax
  602. ;
  603. ;The following code should re-activate the mouse driver addressability
  604. ;to the currently loaded tsr mouse routine we just found.
  605. ;It is commented out because the code as written here leaves the mouse
  606. ;driver pointing into never-never land somewhere.  Please help me Peter Pan!
  607. ;
  608. ;    mov ax,12                     ;function 12, set ms driver active
  609. ;    mov cx,11                     ;subroutine call mask
  610. ;    mov dx,word ptr es:[126h]     ;offset of tsrsav pointer to mouse seg
  611. ;    int 51                        ;pass information to mouse driver
  612.      ret
  613. ;
  614. post    endp
  615. ;
  616. ;-----------------------------------------------------------------------------
  617. ;If MOUSER already TSR, end normally, else end TSR
  618. ;
  619. allthru proc
  620.     cmp found,'Y'
  621.     jne tsr
  622.     cmp newcopy,'Y'
  623.     je  tsr
  624.      mov ah,9        ;send post message
  625.     lea dx,postmsg
  626.     int 21h
  627.     int 20h            ;normal exit to DOS
  628. ;
  629. tsr:    call msmouse        ;make sure mouse driver is resident
  630.     mov ah,9        ;send load message
  631.     lea dx,loadmsg
  632.     int 21h
  633.     mov ax,12        ;function 12, set ms driver active
  634.     mov cx,11        ;subroutine call mask (bits 1011)
  635.                 ;call if mouse moved, or button tapped
  636.     mov dx,offset mouse    ;point ES:DX to the TSR subroutine
  637.     mov tsrsav,dx        ;and save this address for later use
  638.     int 51            ;pass address to mouse driver
  639.     lea dx,init        ;point DX to end of resident code
  640.     int 27h            ;terminate-but-stay-resident
  641. ;
  642. allthru endp
  643. ;
  644. ;-----------------------------------------------------------------------------
  645. ;Make sure the ms mouse hardware and software are in place.
  646. ;
  647. msmouse proc near
  648.     mov ax,0                      ;function 0
  649.     int 51                        ;get installation flag
  650.     or ax,ax                      ;is AX zero?
  651.     jne msok                      ;proceed with loading
  652.     mov ah,9                      ;print error message and abort
  653.     lea dx,errmsg
  654.     int 21h
  655.     int 20h
  656. ;
  657. msok:    ret            ;continue loading
  658. ;
  659. msmouse endp
  660. code    ends
  661.         end begin