├── README.md ├── build.bat ├── build.sh ├── clean.sh ├── inc ├── cmacros.inc └── windefs.inc ├── lib └── libw.lib ├── out ├── i33mouse.drv └── oemsetup.inf ├── src ├── INT33H.ASM ├── MAKEFILE ├── MOUSE.ASM ├── MOUSE.DEF ├── MOUSE.INC └── MOUSE.LNK └── tools ├── link.exe ├── masm.exe ├── nmake.exe └── rc.exe /README.md: -------------------------------------------------------------------------------- 1 | # win31-mouse-driver 2 | Universal (int 33h) mouse driver for Windows 3.1. 3 | Best choice for emulators like dosemu2, but can be used under real PC too. 4 | Supports 3 buttons. 5 | 6 | # This driver is deprecated! 7 | Please use this driver instead: 8 | https://depot.javispedro.com/vbox/vbados/vbados.zip 9 | -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | set PATH=..\TOOLS;%PATH% 2 | set INCLUDE=..\INC 3 | set LIB=..\LIB 4 | cd src 5 | nmake 6 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | dosemu -dumb -K ./build.bat 2 | if [ $? = 0 ]; then 3 | [ -d out ] || mkdir out 4 | cp -f src/i33mouse.drv out 5 | fi -------------------------------------------------------------------------------- /clean.sh: -------------------------------------------------------------------------------- 1 | cd src 2 | rm -f *.lst *.obj *.sym *.map *.drv 3 | -------------------------------------------------------------------------------- /inc/cmacros.inc: -------------------------------------------------------------------------------- 1 | comment $ 2 | cmacros - assembly macros for interfacing to hlls 3 | (C)Copyright Microsoft Corp. 1984-1988 4 | $ 5 | .xcref 6 | .xcref ??_out 7 | ??_out macro t 8 | ifndef ?QUIET 9 | %out t 10 | endif 11 | endm 12 | outif macro name,defval,onmsg,offmsg 13 | ifndef name 14 | ifb 15 | name=0 16 | else 17 | name=defval 18 | endif 19 | endif 20 | if name 21 | name=1 22 | ifnb 23 | ??_out 24 | endif 25 | else 26 | ifnb 27 | ??_out 28 | endif 29 | endif 30 | endm 31 | .xcref ??error 32 | ??error macro msg 33 | e r r o r ----- msg 34 | .err 35 | endm 36 | .xcref ASMpass 37 | .xcref memS,memM,memL,memC,memH,memMOD,sizec,sized 38 | if1 39 | ASMpass=1 40 | ifdef ?SMALL 41 | memS=1 42 | endif 43 | ifdef ?MEDIUM 44 | memM=1 45 | endif 46 | ifdef ?COMPACT 47 | memC=1 48 | endif 49 | ifdef ?LARGE 50 | memL=1 51 | endif 52 | ifdef ?HUGE 53 | memH=1 54 | endif 55 | ??_out 56 | outif memS,0, 57 | outif memM,0, 58 | outif memL,0, 59 | outif memC,0, 60 | outif memH,0, 61 | memMOD= memS + memM + memL + memC + memH 62 | if memMOD ne 1 63 | if memMOD eq 0 64 | memS = 1 65 | else 66 | ??error 67 | endif 68 | endif 69 | sizec= memM + memL + memH 70 | sized= memL + memC + (memH*2) 71 | outif ?DF,0, 72 | outif ?TF,0, 73 | outif ?WIN,1, 74 | ifdef PMODE 75 | ?pmd=1 76 | ??_out 77 | else 78 | ?pmd=0 79 | endif 80 | ifdef ?386regs 81 | if ?386regs 82 | ??_out 83 | endif 84 | else 85 | ?386regs=0 86 | endif 87 | if ?WIN eq 1 88 | outif ?PLM,1,<> 89 | else 90 | outif ?PLM,1, 91 | endif 92 | ifndef ?NODATA 93 | ?nodata1=0 94 | else 95 | ?nodata1=1 96 | ??_out 97 | endif 98 | ifndef ?CHKSTK 99 | ?chkstk1=0 100 | else 101 | ?chkstk1=1 102 | ifdef ?CHKSTKPROC 103 | ??_out 104 | else 105 | ??_out 106 | endif 107 | endif 108 | ifndef DOS5 109 | ?DOS5=0 110 | else 111 | ?DOS5=1 112 | ??_out 113 | endif 114 | ifdef ?PROFILE 115 | ??_out 116 | endif 117 | else 118 | ASMpass=2 119 | endif 120 | ifdef ?pmd 121 | .286p 122 | endif 123 | if ?386regs 124 | .xcref ?n,?ax,?eax,?bx,?ebx 125 | .xcref ?cx,?ecx,?dx,?edx 126 | .xcref ?si,?esi,?di,?edi,?es,?ds,?fs 127 | .xcref ?gs 128 | else 129 | .xcref ?n,?ax,?ah,?al,?bx,?bh 130 | .xcref ?bl,?cx,?ch,?cl,?dx,?dh 131 | .xcref ?dl,?si,?di,?es,?ds,?bp 132 | .xcref ?sp,?ss,?cs 133 | endif 134 | .xcref ?rsl,?cpd,?argl,?argc,?ba 135 | .xcref ?acb,???,?po 136 | .xcref ?pas,?pc 137 | .xcref uconcat,mpush,mpop 138 | .xcref ?ri,?pp,?pp1,?al1 139 | .xcref ?ad,?ap,?atal,?dd,?dd1,?dd2 140 | .xcref ?pg,?pg1,?aloc,?cs1,?cs2 141 | .xcref ?DF,?TF,?ff,?PLM,?WIN,?ia,?pu,?adj 142 | .xcref ?uf,?rp,?nx,?nd,?nodata1,?chkstk1,?DOS5,?pmd,?lds,?exp 143 | .xcref ?wfp,arg,cCall,cProc,assumes,?cs3,?cs2,?cs1 144 | .xcref defgrp,addseg,createSeg 145 | .xcref save,outif,errnz,errn$,errnz1 146 | .xcref ?PLMPrevParm,?gcc 147 | .xcref ?cCall1,?pcc 148 | ?rsl = 0 149 | ?cpd = 0 150 | ?argl = 0 151 | ?argc = 0 152 | ?ba = 0 153 | ?acb = 0 154 | ??? = 0 155 | ?po = 0 156 | ?pas = 0 157 | ?pc = 0 158 | ?ia = 0 159 | ?pu = 0 160 | ?adj = 0 161 | ?rp = 0 162 | ?uf = 0 163 | ?nd = 0 164 | ?nx = 0 165 | ?wfp = 0 166 | ?lds = 0 167 | ?exp = 0 168 | ?ff = 0 169 | ?dd2 = 0 170 | ?cCall1 = 0 171 | ?pcc = 0 172 | ?PLMPrevParm = 0 173 | .xcref ?casen 174 | if1 175 | ?casen = 0 176 | endif 177 | if ?386regs 178 | ?n = 0000000000000000b 179 | ?ax = 0000000000000001b 180 | ?eax = 0000000000000010b 181 | ?bx = 0000000000000100b 182 | ?ebx = 0000000000001000b 183 | ?cx = 0000000000010000b 184 | ?ecx = 0000000000100000b 185 | ?dx = 0000000001000000b 186 | ?edx = 0000000010000000b 187 | ?si = 0000000100000000b 188 | ?esi = 0000001000000000b 189 | ?di = 0000010000000000b 190 | ?edi = 0000100000000000b 191 | ?ds = 0001000000000000b 192 | ?es = 0010000000000000b 193 | ?fs = 0100000000000000b 194 | ?gs = 1000000000000000b 195 | else 196 | ?n = 0000000000000000b 197 | ?ax = 0000000000000011b 198 | ?ah = 0000000000000001b 199 | ?al = 0000000000000010b 200 | ?bx = 0000000000001100b 201 | ?bh = 0000000000000100b 202 | ?bl = 0000000000001000b 203 | ?cx = 0000000000110000b 204 | ?ch = 0000000000010000b 205 | ?cl = 0000000000100000b 206 | ?dx = 0000000011000000b 207 | ?dh = 0000000001000000b 208 | ?dl = 0000000010000000b 209 | ?si = 0000000100000000b 210 | ?di = 0000001000000000b 211 | ?es = 0000010000000000b 212 | ?ds = 0000100000000000b 213 | ?bp = 0001000000000000b 214 | ?sp = 0010000000000000b 215 | ?ss = 0100000000000000b 216 | ?cs = 1000000000000000b 217 | endif 218 | .cref 219 | uconcat macro a,b,c,d,e,f,g 220 | a&b c&d e&f&g 221 | endm 222 | if ?386regs 223 | mpush macro r 224 | irp x, 225 | if (r and ?&&x) 226 | push x 227 | endif 228 | endm 229 | endm 230 | else 231 | mpush macro r 232 | irp x, 233 | if (r and ?&&x) 234 | push x 235 | endif 236 | endm 237 | endm 238 | endif 239 | if ?386regs 240 | mpop macro r 241 | irp x, 242 | if (r and ?&&x) 243 | pop x 244 | endif 245 | endm 246 | endm 247 | else 248 | mpop macro r 249 | irp x, 250 | if (r and ?&&x) 251 | pop x 252 | endif 253 | endm 254 | endm 255 | endif 256 | save macro r 257 | ?rsl=0 258 | ?ri ?rsl, 259 | endm 260 | ?ri macro n,r 261 | irp x, 262 | .ERRNDEF ?&&x 263 | n=n or ?&&x 264 | endm 265 | endm 266 | .xcref 267 | .xcref parmB,parmW,parmD,parmQ,parmT,parmCP,parmDP 268 | .cref 269 | parmB macro n 270 | ?pp ,,2,1 271 | endm 272 | parmW macro n 273 | ?pp ,,2,2 274 | endm 275 | parmD macro n 276 | ife ?PLM 277 | irp x, 278 | ?pp <&&x>,,0,4 279 | ?pp ,,2,2 280 | ?pp ,,2,2 281 | endm 282 | else 283 | irp x, 284 | ?pp ,,2,2 285 | ?pp ,,2,2 286 | ?pp <&&x>,,0,4 287 | endm 288 | endif 289 | endm 290 | parmQ macro n 291 | ?pp ,,8,8 292 | endm 293 | parmT macro n 294 | ?pp ,,10,10 295 | endm 296 | if sizec 297 | parmCP macro n 298 | parmD 299 | endm 300 | else 301 | parmCP macro n 302 | parmW 303 | endm 304 | endif 305 | if sized 306 | parmDP macro n 307 | parmD 308 | endm 309 | else 310 | parmDP macro n 311 | parmW 312 | endm 313 | endif 314 | ?pp macro n,t,l,s 315 | if ?cpd 316 | .xcref 317 | irp x, 318 | .xcref ?t&&x 319 | ?t&&x=s 320 | ife ?PLM 321 | ?pp1 x,,,,%(?po+?adj) 322 | ?po=?po+l 323 | else 324 | ?PLMPrevParm=?PLMPrevParm+1 325 | ?po=?po+l 326 | ?pp1 x,,%?po,%?adj,,%?PLMPrevParm,%(?PLMPrevParm-1) 327 | endif 328 | endm 329 | .cref 330 | else 331 | ??error 332 | endif 333 | endm 334 | ?pp1 macro n,t,o,a,b,cpc,ppc 335 | ife ?PLM 336 | n equ (t ptr [bp+b]) 337 | else 338 | .xcref 339 | .xcref ?PLMParm&cpc 340 | .cref 341 | ?PLMParm&cpc ¯o po 342 | uconcat ,,,,<(t ptr [bp+>,%(a+po-o),<])> 343 | ?PLMParm&ppc po 344 | purge ?PLMParm&cpc 345 | &endm 346 | endif 347 | endm 348 | ifndef ?NOPARMR 349 | if ?pmd 350 | parmR macro n,r,r2 351 | ??error 352 | endm 353 | else 354 | .xcref 355 | .xcref ?pr,parmR 356 | .cref 357 | parmR macro n,r,r2 358 | ?pr n,r,r2,%?rp,%(?ia+2) 359 | endm 360 | ?pr macro n,r,r2,i,o 361 | .xcref 362 | ifnb 363 | parmR seg_&n,r 364 | parmR off_&n,r2 365 | n equ (dword ptr [bp-o-2]) 366 | .xcref ?t&n 367 | ?t&n=4 368 | else 369 | .xcref ?rp&i 370 | ?rp&i=0 371 | ifdef ?&r 372 | ?rp&i=?&r 373 | endif 374 | if ??? or (?cpd eq 0) or (?rp&i eq 0) 375 | ??error 376 | exitm 377 | endif 378 | n equ (word ptr [bp-o]) 379 | ?t&n=2 380 | irp x, 381 | if ?&&x eq ?&r 382 | n equ (byte ptr [bp-o]) 383 | ?t&n=1 384 | exitm 385 | endif 386 | endm 387 | ?ia=?ia+2 388 | ?rp=?rp+1 389 | endif 390 | .cref 391 | endm 392 | endif 393 | endif 394 | .xcref 395 | .xcref localB,localW,localD,localQ,localT,localCP,localDP,localV 396 | .cref 397 | localB macro n 398 | ?aloc ,,1,1,0 399 | endm 400 | localW macro n 401 | ?aloc ,,2,2,1 402 | endm 403 | localD macro n 404 | irp x, 405 | ?aloc ,,2,2,1 406 | ?aloc ,,2,2,1 407 | ?aloc <&&x>,,0,4,1 408 | endm 409 | endm 410 | localQ macro n 411 | ?aloc ,,8,8,1 412 | endm 413 | localT macro n 414 | ?aloc ,,10,10,1 415 | endm 416 | if sizec 417 | localCP macro n 418 | localD 419 | endm 420 | else 421 | localCP macro n 422 | localW 423 | endm 424 | endif 425 | if sized 426 | localDP macro n 427 | localD 428 | endm 429 | else 430 | localDP macro n 431 | localW 432 | endm 433 | endif 434 | localV macro n,a 435 | ?aloc ,,%(a),0,1 436 | endm 437 | ?aloc macro n,t,l,s,a 438 | if ?cpd 439 | .xcref 440 | irp x, 441 | ???=???+l 442 | if a 443 | ???=((??? + 1) and 0fffeh) 444 | endif 445 | ?al1 x,,%(???+?ia) 446 | .xcref ?t&&x 447 | ?t&&x=s 448 | endm 449 | .cref 450 | else 451 | ??error 452 | endif 453 | endm 454 | ?al1 macro n,t,o 455 | n equ (t [bp-o]) 456 | endm 457 | ?gcc macro s,i,cc 458 | s = i 459 | ifnb 460 | ifidn , 461 | s=0 462 | endif 463 | ifidn , 464 | s=1 465 | endif 466 | ifidn , 467 | s=1 468 | endif 469 | endif 470 | endm 471 | ifndef ?NOGLOBAL 472 | .xcref 473 | .xcref globalB,globalW,globalD,globalQ,globalT,globalCP,globalDP 474 | .cref 475 | globalB macro n,i,s,c 476 | ?ad ,1 477 | ?dd n,1,,,,, 478 | endm 479 | globalW macro n,i,s,c 480 | ?ad ,2 481 | ?dd n,1,,,,, 482 | endm 483 | globalD macro n,i,s,c 484 | ?ad ,4 485 | ?dd n,1,,
,,, 486 | off_&n equ n 487 | seg_&n equ n[2] 488 | endm 489 | globalQ macro n,i,s,c 490 | ?ad ,8 491 | ?dd n,1,,,,, 492 | endm 493 | globalT macro n,i,s,c 494 | ?ad ,10 495 | ?dd n,1,,
,,, 496 | endm 497 | if sizec 498 | globalCP macro n,i,s,c 499 | globalD n,,, 500 | endm 501 | else 502 | globalCP macro n,i,s,c 503 | globalW n,,, 504 | endm 505 | endif 506 | if sized 507 | globalDP macro n,i,s,c 508 | globalD n,,, 509 | endm 510 | else 511 | globalDP macro n,i,s,c 512 | globalW n,,, 513 | endm 514 | endif 515 | endif 516 | ifndef ?NOSTATIC 517 | .xcref 518 | .xcref staticB,staticW,staticD,staticQ,staticT,staticCP,staticDP 519 | .cref 520 | staticB macro n,i,s 521 | ?ad ,1 522 | ?dd n,0,,,,, 523 | endm 524 | staticW macro n,i,s 525 | ?ad ,2 526 | ?dd n,0,,,,, 527 | endm 528 | staticD macro n,i,s 529 | ?ad ,4 530 | ?dd n,0,,
,,, 531 | endm 532 | staticQ macro n,i,s 533 | ?ad ,8 534 | ?dd n,0,,,,, 535 | endm 536 | staticT macro n,i,s 537 | ?ad ,10 538 | ?dd n,0,,
,,, 539 | endm 540 | if sizec 541 | staticCP macro n,i,s 542 | staticD n,, 543 | endm 544 | else 545 | staticCP macro n,i,s 546 | staticW n,, 547 | endm 548 | endif 549 | if sized 550 | staticDP macro n,i,s 551 | staticD n,, 552 | endm 553 | else 554 | staticDP macro n,i,s 555 | staticW n,, 556 | endm 557 | endif 558 | endif 559 | ?dd macro n,p,t,d,i,s,c 560 | ?gcc ?dd2,%?PLM, 561 | ife ?dd2 562 | n label t 563 | ?dd1 _&n,p,,, 564 | else 565 | ?dd1 n,p,,, 566 | endif 567 | endm 568 | ?dd1 macro n,p,d,i,s 569 | if p 570 | public n 571 | endif 572 | ifb 573 | n d i 574 | else 575 | ifb 576 | n d s dup (?) 577 | else 578 | n d s dup (i) 579 | endif 580 | endif 581 | endm 582 | ifndef ?NOEXTERN 583 | .xcref 584 | .xcref ?ex1,?ex2,externB,externW,externD,externQ,externT 585 | .xcref externNP,externFP,externP,externCP,externDP,externA 586 | .cref 587 | ?ex2 = 0 588 | externA macro n,c 589 | ?ex1 ,40h,,,<> 590 | endm 591 | externB macro n,c 592 | ?ex1 ,1,,,<> 593 | endm 594 | externW macro n,c 595 | ?ex1 ,2,,,<> 596 | endm 597 | externD macro n,c 598 | ?ex1 ,4,,,<> 599 | endm 600 | externQ macro n,c 601 | ?ex1 ,8,,,<> 602 | endm 603 | externT macro n,c 604 | ?ex1 ,10,,,<> 605 | endm 606 | externNP macro n,c 607 | ?ex1 ,2,,, 608 | endm 609 | externFP macro n,c 610 | ?ex1 ,4,,, 611 | endm 612 | if sizec 613 | externP macro n,c 614 | ?ex1 ,4,,, 615 | endm 616 | else 617 | externP macro n,c 618 | ?ex1 ,2,,, 619 | endm 620 | endif 621 | if sizec 622 | externCP macro n,c 623 | ?ex1 ,4,,,<> 624 | endm 625 | else 626 | externCP macro n,c 627 | ?ex1 ,2,,,<> 628 | endm 629 | endif 630 | if sized 631 | externDP macro n,c 632 | ?ex1 ,4,,,<> 633 | endm 634 | else 635 | externDP macro n,c 636 | ?ex1 ,2,,,<> 637 | endm 638 | endif 639 | ?ex1 macro n,s,d,c,scv 640 | ?gcc ?ex2,%?PLM, 641 | irp x, 642 | .xcref 643 | .xcref ?t&&x 644 | .cref 645 | ?t&&x=s 646 | ife ?ex2 647 | extrn _&&x:&d 648 | x equ _&&x 649 | else 650 | extrn x:&d 651 | endif 652 | ifidn , 653 | .xcref 654 | .xcref ?CC&&x 655 | .cref 656 | ?CC&&x=?ex2 657 | endif 658 | endm 659 | endm 660 | endif 661 | ifndef ?NOLABEL 662 | .xcref 663 | .xcref ?lb1,?lblpu,?lb2 664 | .xcref labelB,labelW,labelD,labelQ,labelT 665 | .xcref labelNP,labelFP,labelP,labelCP,labelDP 666 | .cref 667 | ?lblpu = 0 668 | ?lb2 = 0 669 | labelB macro n,c 670 | ?lb1 ,1,, 671 | endm 672 | labelW macro n,c 673 | ?lb1 ,2,, 674 | endm 675 | labelD macro n,c 676 | ?lb1 ,4,, 677 | endm 678 | labelQ macro n,c 679 | ?lb1 ,8,, 680 | endm 681 | labelT macro n,c 682 | ?lb1 ,10,, 683 | endm 684 | labelNP macro n,c 685 | ?lb1 ,2,, 686 | endm 687 | labelFP macro n,c 688 | ?lb1 ,4,, 689 | endm 690 | if sizec 691 | labelP macro n,c 692 | ?lb1 ,4,, 693 | endm 694 | else 695 | labelP macro n,c 696 | ?lb1 ,2,, 697 | endm 698 | endif 699 | if sizec 700 | labelCP macro n,c 701 | ?lb1 ,4,, 702 | endm 703 | else 704 | labelCP macro n,c 705 | ?lb1 ,2,, 706 | endm 707 | endif 708 | if sized 709 | labelDP macro n,c 710 | ?lb1 ,4,, 711 | endm 712 | else 713 | labelDP macro n,c 714 | ?lb1 ,2,, 715 | endm 716 | endif 717 | ?lb1 macro n,s,d,c 718 | ?gcc ?lb2,%?PLM, 719 | ?lblpu=0 720 | irp x, 721 | ifidn , 722 | ?lblpu=1 723 | else 724 | .xcref 725 | .xcref ?t&&x 726 | .cref 727 | ?t&&x=s 728 | ife ?lb2 729 | if ?lblpu 730 | public _&&x 731 | endif 732 | _&&x label &d 733 | x equ _&&x 734 | else 735 | if ?lblpu 736 | public x 737 | endif 738 | x label &d 739 | endif 740 | endif 741 | endm 742 | endm 743 | endif 744 | ifndef ?NODEF 745 | .xcref 746 | .xcref defB,defW,defD,defQ,defT,defCP,defDP 747 | .cref 748 | defB macro n 749 | ?ad ,1 750 | endm 751 | defW macro n 752 | ?ad ,2 753 | endm 754 | defD macro n 755 | ?ad ,4 756 | endm 757 | defQ macro n 758 | ?ad ,8 759 | endm 760 | defT macro n 761 | ?ad ,10 762 | endm 763 | if sizec 764 | defCP macro n 765 | defD 766 | endm 767 | else 768 | defCP macro n 769 | defW 770 | endm 771 | endif 772 | if sized 773 | defDP macro n 774 | defD 775 | endm 776 | else 777 | defDP macro n 778 | defW 779 | endm 780 | endif 781 | endif 782 | ?ad macro n,s 783 | irp x, 784 | .xcref 785 | .xcref ?t&&x 786 | .cref 787 | ?t&&x=s 788 | endm 789 | endm 790 | ifndef ?NOPTR 791 | .xcref 792 | .xcref regPtr,farPtr 793 | .cref 794 | regPtr macro n,s,o 795 | farPtr n,s,o 796 | endm 797 | farPtr macro n,s,o 798 | .xcref 799 | .xcref ?t&n 800 | .cref 801 | n ¯o 802 | push s 803 | push o 804 | &endm 805 | ?t&n=80h 806 | endm 807 | endif 808 | arg macro a 809 | irp x, 810 | ?argc=?argc+1 811 | ?atal ,%?argc 812 | endm 813 | endm 814 | ?atal macro n,i 815 | .xcref 816 | .xcref ?ali&i 817 | .cref 818 | ?ali&i ¯o 819 | ?ap n 820 | &endm 821 | endm 822 | ?ap macro n 823 | ?argl=?argl+2 824 | ifdef ?t&n 825 | ife ?t&n-1 826 | push word ptr (n) 827 | exitm 828 | endif 829 | ife ?t&n-2 830 | push n 831 | exitm 832 | endif 833 | ife ?t&n-4 834 | push word ptr (n)[2] 835 | push word ptr (n) 836 | ?argl=?argl+2 837 | exitm 838 | endif 839 | ife ?t&n-8 840 | push word ptr (n)[6] 841 | push word ptr (n)[4] 842 | push word ptr (n)[2] 843 | push word ptr (n) 844 | ?argl=?argl+6 845 | exitm 846 | endif 847 | if ?t&n and 80h 848 | n 849 | ?argl=?argl+2 850 | exitm 851 | endif 852 | ife ?t&n 853 | push word ptr (n) 854 | exitm 855 | endif 856 | endif 857 | push n 858 | endm 859 | cCall macro n,a,c 860 | ifnb 861 | arg 862 | endif 863 | mpush %?rsl 864 | ifdef ?CC&n 865 | ?cCall1=?CC&n 866 | else 867 | ?cCall1=?PLM 868 | endif 869 | ifnb 870 | ?gcc ?cCall1,%?cCall1, 871 | endif 872 | ?argl=0 873 | ife ?cCall1 874 | ?acb=?argc 875 | else 876 | ?acb=1 877 | endif 878 | rept ?argc 879 | uconcat ,%?acb 880 | uconcat ,,,%?acb 881 | ife ?cCall1 882 | ?acb=?acb-1 883 | else 884 | ?acb=?acb+1 885 | endif 886 | endm 887 | call n 888 | if ((?cCall1 eq 0) and (?argl ne 0)) 889 | add sp,?argl 890 | endif 891 | mpop %?rsl 892 | ?rsl=0 893 | ?argc= 0 894 | ?argl= 0 895 | endm 896 | cProc macro n,cf,a 897 | if ?cpd 898 | ?utpe 899 | endif 900 | ?cpd=1 901 | ???=0 902 | ?argc=0 903 | ?ba=0 904 | ?po=0 905 | ?pu=0 906 | ?ia=0 907 | ?adj=4 908 | ?rp=0 909 | ?uf=0 910 | ?wfp=?WIN 911 | ?ff=0 912 | ?pas=0 913 | ?pcc=?PLM 914 | ?lds=0 915 | ?exp=0 916 | ifnb 917 | ?ri ?pas, 918 | endif 919 | ?pc=sizec 920 | ?nd=?nodata1 921 | ?nx=0 922 | irp x, 923 | ifidn , 924 | ?pc=1 925 | endif 926 | ifidn , 927 | ?pc=0 928 | endif 929 | ifidn , 930 | ?pu=1 931 | endif 932 | ifidn , 933 | ?uf=1 934 | endif 935 | ifidn , 936 | ?nd=0 937 | endif 938 | ifidn , 939 | ?nd=1 940 | endif 941 | ifidn , 942 | ?nx=1 943 | endif 944 | ifidn , 945 | ?pcc=0 946 | endif 947 | ifidn , 948 | ?pcc=1 949 | endif 950 | ifidn , 951 | ?pcc=1 952 | endif 953 | ifidn , 954 | ?wfp=1 955 | endif 956 | ifidn , 957 | ?wfp=0 958 | endif 959 | ifidn , 960 | ?lds=1 961 | endif 962 | ifidn , 963 | ?exp=1 964 | endif 965 | endm 966 | if ?pcc 967 | ?PLMPrevParm=0 968 | .xcref 969 | .xcref ?PLMParm0 970 | .cref 971 | ?PLMParm0 ¯o 972 | purge ?PLMParm0 973 | &endm 974 | endif 975 | .xcref 976 | .xcref ?CC&n 977 | .cref 978 | ?CC&n=?pcc 979 | if (?nx eq 1) and (?nd eq 0) 980 | ?nx = 0 981 | ??error 982 | endif 983 | if ?pc 984 | if ?wfp+?exp+?lds 985 | ife ?nx 986 | ife ?pmd 987 | ?ia=2 988 | endif 989 | ?pas = ?pas and (not ?ds) 990 | endif 991 | endif 992 | ?adj=?adj+2 993 | else 994 | ?wfp=0 995 | endif 996 | ife ?386regs 997 | ?pas = ?pas and (not (?sp+?cs+?ss)) 998 | endif 999 | if ?uf 1000 | if ?386regs 1001 | ?pas = ?pas and (not (?si+?di)) 1002 | else 1003 | ?pas = ?pas and (not (?bp+?si+?di)) 1004 | endif 1005 | endif 1006 | ife ?pcc 1007 | ?pg <_&n>,%?pu,%?pc,%?pas,%?wfp,,%?pcc 1008 | else 1009 | ?pg ,%?pu,%?pc,%?pas,%?wfp,,%?pcc 1010 | endif 1011 | endm 1012 | ?pg macro n,p,c,a,w,nnu,cc 1013 | .xcref 1014 | if ?uf 1015 | if ?nd 1016 | ??error 1017 | ?uf=0 1018 | endif 1019 | endif 1020 | .xcref cBegin 1021 | cBegin ¯o g 1022 | .xcref 1023 | if cc 1024 | uconcat ,%?PLMPrevParm,%?po 1025 | endif 1026 | if ?uf 1027 | if ?rp 1028 | ??error 1029 | ?uf=0 1030 | endif 1031 | endif 1032 | ?pg1 ,c,a,%?po,w,%?uf,%?nd,%?rp,cc 1033 | ?cpd=0 1034 | ?argc=0 1035 | ?ba=1 1036 | ???=(???+1) and 0fffeh 1037 | if p 1038 | public n 1039 | endif 1040 | ife c 1041 | n proc near 1042 | else 1043 | n proc far 1044 | endif 1045 | ife cc 1046 | nnu equ n 1047 | endif 1048 | ifidn , 1049 | if ???+?po+a+?rp 1050 | ??_out 1051 | endif 1052 | else 1053 | if ?uf 1054 | ?mf c,%???,%?po 1055 | mpush a 1056 | else 1057 | if w+?exp+?lds 1058 | if ?pmd 1059 | ife ?nd 1060 | if ?lds 1061 | mov ax,_DATA 1062 | else 1063 | if ?exp 1064 | mov ax,ds 1065 | nop 1066 | endif 1067 | endif 1068 | endif 1069 | ife ?nx 1070 | if ???+?po 1071 | if ?chkstk1 1072 | push bp 1073 | mov bp,sp 1074 | else 1075 | if ??? 1076 | enter ???,0 1077 | else 1078 | push bp 1079 | mov bp,sp 1080 | endif 1081 | endif 1082 | endif 1083 | push ds 1084 | if ?lds+?exp 1085 | mov ds,ax 1086 | endif 1087 | else 1088 | if ?ff+???+?po+?rp 1089 | push bp 1090 | mov bp,sp 1091 | endif 1092 | endif 1093 | else 1094 | ife ?nd 1095 | mov ax,ds 1096 | nop 1097 | endif 1098 | ife ?nx 1099 | ife ?DOS5 1100 | inc bp 1101 | endif 1102 | push bp 1103 | mov bp,sp 1104 | push ds 1105 | else 1106 | if ?ff+???+?po+?rp 1107 | push bp 1108 | mov bp,sp 1109 | endif 1110 | endif 1111 | ife ?nd 1112 | mov ds,ax 1113 | endif 1114 | endif 1115 | else 1116 | if ?pmd 1117 | if ?exp 1118 | mov ax,ds 1119 | nop 1120 | else 1121 | if ?lds 1122 | mov ax,_DATA 1123 | endif 1124 | endif 1125 | if ?ff+???+?po+?rp 1126 | if ?chkstk1 1127 | push bp 1128 | mov bp,sp 1129 | else 1130 | if ??? 1131 | enter ???,0 1132 | else 1133 | push bp 1134 | mov bp,sp 1135 | endif 1136 | endif 1137 | endif 1138 | if ?exp+?lds 1139 | push ds 1140 | mov ds,ax 1141 | endif 1142 | else 1143 | if ?ff+???+?po+?rp 1144 | push bp 1145 | mov bp,sp 1146 | endif 1147 | endif 1148 | endif 1149 | if ?rp 1150 | ?uf=0 1151 | rept ?rp 1152 | uconcat mpush,,?rp,%?uf 1153 | ?uf=?uf+1 1154 | endm 1155 | endif 1156 | if ??? 1157 | if ?chkstk1 1158 | ifdef ?CHKSTKPROC 1159 | ?CHKSTKPROC %??? 1160 | else 1161 | mov ax,??? 1162 | ife cc 1163 | call _chkstk 1164 | else 1165 | call chkstk 1166 | endif 1167 | endif 1168 | else 1169 | ife ?pmd 1170 | sub sp,??? 1171 | endif 1172 | endif 1173 | endif 1174 | mpush a 1175 | endif 1176 | ifdef ?PROFILE 1177 | if c 1178 | call StartNMeas 1179 | endif 1180 | endif 1181 | endif 1182 | .cref 1183 | purge cBegin 1184 | &endm 1185 | .xcref ?utpe 1186 | ?utpe ¯o 1187 | ??error 1188 | &endm 1189 | .cref 1190 | endm 1191 | ?pg1 macro n,c,a,o,w,f,d,r,cc 1192 | .xcref 1193 | .xcref cEnd 1194 | cEnd ¯o g 1195 | .xcref 1196 | ?ba=0 1197 | ifidn , 1198 | if o+a+r 1199 | ??_out 1200 | endif 1201 | else 1202 | ifdef ?PROFILE 1203 | if c 1204 | call StopNMeas 1205 | endif 1206 | endif 1207 | mpop a 1208 | if f 1209 | db 0c3h 1210 | else 1211 | if w+?exp+?lds 1212 | if ?pmd 1213 | ife ?nx 1214 | pop ds 1215 | endif 1216 | ife ?nx 1217 | if ?chkstk1+???+?po 1218 | leave 1219 | endif 1220 | else 1221 | if ?ff+???+?po+?rp 1222 | leave 1223 | endif 1224 | endif 1225 | else 1226 | ife ?nx 1227 | if (?TF eq 0) or (???+?rp) 1228 | lea sp,-2[bp] 1229 | endif 1230 | pop ds 1231 | pop bp 1232 | ife ?DOS5 1233 | dec bp 1234 | endif 1235 | else 1236 | if (?TF eq 0) or (???+?rp) 1237 | mov sp,bp 1238 | endif 1239 | if ???+?po+?rp 1240 | pop bp 1241 | endif 1242 | endif 1243 | endif 1244 | else 1245 | if ?pmd 1246 | if ?ff+???+?po+?rp 1247 | leave 1248 | endif 1249 | else 1250 | if ?ff+???+?po+?rp 1251 | if (?TF eq 0) or (???+?rp) 1252 | mov sp,bp 1253 | endif 1254 | pop bp 1255 | endif 1256 | endif 1257 | endif 1258 | ife cc 1259 | ret 1260 | else 1261 | ret o 1262 | endif 1263 | endif 1264 | endif 1265 | n endp 1266 | .cref 1267 | purge cEnd 1268 | &endm 1269 | .cref 1270 | endm 1271 | assumes macro s,ln 1272 | ifndef ln&_assumes 1273 | assume s:ln 1274 | else 1275 | ln&_assumes s 1276 | endif 1277 | endm 1278 | createSeg macro n,ln,a,co,cl,grp 1279 | ifnb 1280 | addseg grp,n 1281 | else 1282 | ln&OFFSET equ offset n: 1283 | ln&BASE equ n 1284 | ?cs3 , 1285 | endif 1286 | ifnb 1287 | n segment a co '&cl' 1288 | else 1289 | n segment a co 1290 | endif 1291 | n ends 1292 | ?cs1 , 1293 | endm 1294 | addseg macro grp,seg 1295 | .xcref 1296 | .xcref grp&_def 1297 | .cref 1298 | ifndef grp&_def 1299 | grp&_def=0 1300 | endif 1301 | if grp&_def ne ASMpass 1302 | .xcref 1303 | .xcref grp&_add 1304 | .cref 1305 | grp&_add ¯o s 1306 | grp&_in ,s 1307 | &endm 1308 | .xcref 1309 | .xcref grp&_in 1310 | .cref 1311 | grp&_in ¯o sl,s 1312 | ifb 1313 | grp group sl 1314 | else 1315 | grp&_add ¯o ns 1316 | grp&_in ,ns 1317 | &endm 1318 | endif 1319 | &endm 1320 | grp&_def=ASMpass 1321 | else 1322 | grp&_add seg 1323 | endif 1324 | endm 1325 | defgrp macro grp,ln 1326 | addseg grp 1327 | ifnb 1328 | irp x, 1329 | ?cs3 <&x>, 1330 | x&&OFFSET equ offset grp: 1331 | x&&BASE equ grp 1332 | endm 1333 | endif 1334 | endm 1335 | ?cs1 macro ln,n 1336 | .xcref 1337 | .xcref ln&_sbegin 1338 | .cref 1339 | ln&_sbegin ¯o 1340 | .xcref 1341 | .xcref ?mf 1342 | .cref 1343 | ?mf &¯o c,l,p 1344 | if c 1345 | extrn n&_FARFRAME:near 1346 | call n&_FARFRAME 1347 | else 1348 | extrn n&_NEARFRAME:near 1349 | call n&_NEARFRAME 1350 | endif 1351 | db l shr 1 1352 | db p shr 1 1353 | &&endm 1354 | ?cs2 , 1355 | n segment 1356 | &endm 1357 | endm 1358 | ?cs2 macro ln,n 1359 | .xcref 1360 | .xcref sEnd 1361 | .cref 1362 | sEnd ¯o 1363 | n ends 1364 | purge ?mf 1365 | purge sEnd 1366 | &endm 1367 | endm 1368 | ?cs3 macro ln,n 1369 | .xcref 1370 | .xcref ln&_assumes 1371 | .cref 1372 | ln&_assumes ¯o s 1373 | assume s:&n 1374 | &endm 1375 | endm 1376 | .xcref 1377 | .xcref sBegin 1378 | .cref 1379 | sBegin macro ln 1380 | ln&_sbegin 1381 | endm 1382 | ife ?DF 1383 | createSeg _TEXT,Code,word,public,CODE 1384 | ife ?nodata1 1385 | createSeg _DATA,Data,word,public,DATA,DGROUP 1386 | defgrp DGROUP,Data 1387 | endif 1388 | if ?chkstk1 1389 | ifndef ?CHKSTKPROC 1390 | externp 1391 | endif 1392 | endif 1393 | endif 1394 | errnz macro x 1395 | if2 1396 | if x 1397 | errnz1 ,%(x) 1398 | endif 1399 | endif 1400 | endm 1401 | errnz1 macro x1,x2 1402 | = *errnz* x1 = x2 1403 | .err 1404 | endm 1405 | errn$ macro l,x 1406 | errnz 1407 | endm 1408 | ifdef ?PROFILE 1409 | externFP 1410 | endif 1411 | -------------------------------------------------------------------------------- /inc/windefs.inc: -------------------------------------------------------------------------------- 1 | ;*************************************************************************** 2 | ; * 3 | ; Copyright (C) 1983,1984 by Microsoft Inc. * 4 | ; * 5 | ;*************************************************************************** 6 | 7 | ; Macros for disabling and restoring hardware interrupt enable flag 8 | ; 9 | ; The LeaveCrit macro has been updated for the mask problem on 10 | ; the 80286 processor. 11 | 12 | 13 | EnterCrit MACRO 14 | pushf 15 | cli 16 | ENDM 17 | 18 | LeaveCrit macro reg ;;this macro will restore the state of 19 | ifnb ;;the interrupt flag to what is was 20 | pop reg&x ;;before EnterCrit. All other flags 21 | test reg&h, 2 ;;are discarded. 22 | jz @f 23 | sti 24 | @@: 25 | else 26 | push bp 27 | mov bp, sp 28 | test byte ptr [bp+3], 2 29 | jz @f 30 | sti 31 | @@: 32 | pop bp 33 | popf 34 | endif 35 | endm 36 | 37 | 38 | if 0 39 | POPFF equ 40 | 41 | LeaveCrit MACRO 42 | POPFF 43 | ENDM 44 | endif 45 | 46 | POPFF MACRO ;;this macro will restore ALL flags, 47 | local a ;;EXCEPT the interrupt flag, to 48 | jmp $+3 ;;their previous state 49 | a label near 50 | iret 51 | push cs 52 | call a 53 | ENDM 54 | 55 | 56 | 57 | 58 | ;*************************************************************************** 59 | ; * 60 | ; Inquire data structures for Timer, Keyboard, Mouse and Cursor modules * 61 | ; * 62 | ;*************************************************************************** 63 | 64 | TIMERINFO STRUC 65 | tiResolution DD 0 ; #microseconds each timer tick 66 | TIMERINFO ENDS 67 | 68 | KBINFO STRUC 69 | kbRanges DB 4 dup (0) ; Far East ranges for KANJI 70 | kbStateSize DW 0 ; #bytes of state info maintained by TOASCII 71 | KBINFO ENDS 72 | 73 | 74 | MOUSEINFO STRUC 75 | msExists DB 0 ; true => mouse exists 76 | msRelative DB 0 ; true => relative coordinate 77 | msNumButtons DW 0 ; number of buttons on the mouse 78 | msRate DW 0 ; maximum rate of mouse input events 79 | msXThresh DW 0 ; threshold before acceleration 80 | msYThresh DW 0 ; 81 | msXRes DW 0 ; x resolution 82 | msYRes DW 0 ; y resolution 83 | MOUSEINFO ENDS 84 | 85 | 86 | CURSORINFO STRUC 87 | dpXRate DW 0 ; horizontal mickey/pixel ratio 88 | dpYRate DW 0 ; vertical mickey/pixel ratio 89 | CURSORINFO ENDS 90 | 91 | 92 | ;*************************************************************************** 93 | ; * 94 | ; Cursor data structure passed to OEM routines. Defines a graphics display* 95 | ; cursor in terms of a hotspot, an AND mask and an XOR mask. The hot * 96 | ; spot defines the pixel within the cursor that is the cursor is "pointing"* 97 | ; to. So when displaying a cursor at location X,Y the pixel that * 98 | ; is the hot spot should be painted at that X,Y coordinate. The "shape" * 99 | ; of the cursor is defined by two pixel masks. The first mask is ANDed * 100 | ; with the bits in the display bitmap and the second mask is XORed with * 101 | ; the result to determine the bits that will be placed in the display * 102 | ; bitmap. The bits for the masks are in the byte array that begins * 103 | ; at the csBits field, with the AND mask bits first, followed by the * 104 | ; XOR mask bits. The csWidthBytes field is the width of ONE mask, in * 105 | ; bytes. Currently, MS-WIN will only generate cursors whose width and * 106 | ; height are both 16. * 107 | ; * 108 | ;*************************************************************************** 109 | 110 | cursorShape STRUC 111 | csHotX DW 0 112 | csHotY DW 0 113 | csWidth DW 0 114 | csHeight DW 0 115 | csWidthBytes DW 0 116 | csColor DW 0 117 | ; Beginning of an array of bytes that contain the bits for the AND and 118 | ; XOR masks. The first csHeight * csWidthBytes bytes contain the bits 119 | ; for the AND mask and the next csHeight * csWidthBytes bytes contain 120 | ; the bits for the XOR mask. 121 | ;csBits DB 2*2*16 DUP (?) 122 | cursorShape ENDS 123 | -------------------------------------------------------------------------------- /lib/libw.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stsp/win31-mouse-driver/50aa69e2344f62e2d5980eb853b80735ea4d4da1/lib/libw.lib -------------------------------------------------------------------------------- /out/i33mouse.drv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stsp/win31-mouse-driver/50aa69e2344f62e2d5980eb853b80735ea4d4da1/out/i33mouse.drv -------------------------------------------------------------------------------- /out/oemsetup.inf: -------------------------------------------------------------------------------- 1 | [disks] 2 | ;Names of the disks Setup can prompt for 3 | ;label=., Description of disk, Volume Name 4 | ; 5 | A=. ,"dosemu2 Driver Disk", MSDOS5.0 6 | 7 | [pointing.device] 8 | ; 9 | ;profile= mouse driver, Mouse Description, VMD 10 | ; 11 | i33mouse= A:i33mouse.drv, "Universal (int33h) Mouse Driver", x:*vmd 12 | -------------------------------------------------------------------------------- /src/INT33H.ASM: -------------------------------------------------------------------------------- 1 | page ,132 2 | ;-----------------------------Module-Header-----------------------------; 3 | ; Module Name: INT33H.ASM 4 | ; 5 | ; Windows mouse driver data and initialization routines for using the 6 | ; INT 33h mouse driver for Windows 7 | ; 8 | ; Created: 21-Aug-1987 9 | ; Author: Mr. Mouse [mickeym], Walt Moore [waltm] 10 | ; 11 | ; Copyright (c) 1987 Microsoft Corporation 12 | ; 13 | ; Exported Functions: 14 | ; None 15 | ; Public Functions: 16 | ; I33_enable 17 | ; I33_disable 18 | ; I33_init 19 | ; Public Data: 20 | ; None 21 | ; General Description: 22 | ; This module contains the functions to find, enable, disable, 23 | ; and process interrupts for the INT 33h mouse handler. 24 | ;-----------------------------------------------------------------------; 25 | 26 | 27 | title Microsoft OS/2 INT 33h Dependent Code 28 | 29 | .xlist 30 | include cmacros.inc 31 | include mouse.inc 32 | .list 33 | 34 | 35 | sBegin Data 36 | 37 | externD event_proc ;Mouse event procedure when enabled 38 | externB device_int ;Start of mouse interrupt handler 39 | externB mouse_flags ;Various flags 40 | externW enable_proc ;Address of routine to enable mouse 41 | externW disable_proc ;Address of routine to disable mouse 42 | externW IntCS 43 | 44 | sEnd Data 45 | page 46 | 47 | sBegin Code 48 | assumes cs,Code 49 | 50 | ; This is the start of the data which will be copied into 51 | ; the device_int area reserved in the data segment. References 52 | ; to defined memory locations must be made relative to device_int 53 | 54 | even 55 | 56 | I33_START equ this word 57 | 58 | 59 | ;--------------------------Interrupt-Routine----------------------------; 60 | ; I33_proc - Mouse Interrupt Handler 61 | ; 62 | ; This is the handler for the interrupt generated by the INT 33h 63 | ; mouse driver. It will reside in the Data segment. 64 | ; 65 | ; Entry: 66 | ; BL = current button status 67 | ; D0 = 1 if button 1 is down 68 | ; D1 = 1 if button 2 is down 69 | ; SI = delta X 70 | ; DI = delta Y 71 | ; Returns: 72 | ; None 73 | ; Error Returns: 74 | ; None 75 | ; Registers Preserved: 76 | ; DS,BP 77 | ; Registers Destroyed: 78 | ; AX,BX,CX,DX,SI,DI,ES,FLAGS 79 | ; Calls: 80 | ; event_proc if valid mouse event 81 | ; History: 82 | ; Fri 21-Aug-1987 11:43:42 -by- Walt Moore [waltm] & Mr. Mouse 83 | ; Initial version 84 | ;-----------------------------------------------------------------------; 85 | 86 | ;------------------------------Pseudo-Code------------------------------; 87 | ; { 88 | ; } 89 | ;-----------------------------------------------------------------------; 90 | 91 | assumes cs,Code 92 | assumes ds,nothing 93 | assumes es,nothing 94 | assumes ss,nothing 95 | 96 | 97 | I33_PROC_START equ $-I33_START ;Delta to this procedure 98 | 99 | I33_proc proc far 100 | 101 | push ax 102 | mov ax,_DATA ;Need to gain access to our 103 | mov ds,ax ; data segment 104 | assumes ds,Data 105 | push dx 106 | push cx 107 | mov ax,26h 108 | int MOUSE_SYS_VEC 109 | mov di,dx 110 | mov ax,0ffffh 111 | pop bx ; X coord 112 | mul bx 113 | div cx 114 | mov si,ax 115 | mov ax,0ffffh 116 | pop bx ; Y coord 117 | mul bx 118 | div di 119 | mov cx,ax 120 | mov bx,si 121 | pop ax 122 | mov dx,NUMBER_BUTTONS 123 | or ax,SF_ABSOLUTE 124 | 125 | call event_proc 126 | 127 | I33_nothing_happened: 128 | 129 | ret 130 | 131 | I33_proc endp 132 | page 133 | 134 | ; old_int_33h areas contain the information required to 135 | ; restore the previous INT 33h event handler when we 136 | ; finally disable ourselves. 137 | 138 | OLD_INT_33H_MASK equ $-I33_START ;Delta to this byte 139 | dw 0 ;Old INT 33h procedure mask 140 | 141 | OLD_INT_33H_PROC equ $-I33_START ;Delta to this byte 142 | dd 0 ;Old INT 33h procedure address 143 | 144 | 145 | ; old_status contains the state of the mouse the last time we 146 | ; were called to process an interrupt. 147 | 148 | page 149 | 150 | I33_INT_LENGTH = $-I33_START ;Length of code to copy 151 | .errnz I33_INT_LENGTH gt MAX_INT_SIZE 152 | page 153 | 154 | ;---------------------------Public-Routine------------------------------; 155 | ; I33_enable - Enable the INT 33h mouse handler 156 | ; 157 | ; The INT 33h mouse code will be requested to call our handler for 158 | ; all mouse events. The previous event mask and event procedure will 159 | ; be saved for the restore code. 160 | ; 161 | ; Entry: 162 | ; None 163 | ; Returns: 164 | ; None 165 | ; Error Returns: 166 | ; None 167 | ; Registers Preserved: 168 | ; DS,BP 169 | ; Registers Destroyed: 170 | ; AX,BX,CX,DX,SI,DI,ES,FLAGS 171 | ; Calls: 172 | ; INT 33h 173 | ; History: 174 | ; Fri 21-Aug-1987 11:43:42 -by- Walt Moore [waltm] & Mr. Mouse 175 | ; Initial version 176 | ;-----------------------------------------------------------------------; 177 | 178 | ;------------------------------Pseudo-Code------------------------------; 179 | ; { 180 | ; } 181 | ;-----------------------------------------------------------------------; 182 | 183 | assumes cs,Code 184 | assumes ds,Data 185 | 186 | I33_enable proc near 187 | 188 | mov es,IntCS 189 | assumes es,Data 190 | 191 | lea dx,device_int[I33_PROC_START] 192 | mov cx,CALL_ON_ANY_INT ;Call us on any event 193 | if 0 194 | mov ax,SWAP_INT_PROC ;Swap interrupt routine 195 | int MOUSE_SYS_VEC 196 | 197 | mov wptr device_int[OLD_INT_33H_MASK],cx 198 | mov wptr device_int[OLD_INT_33H_PROC][0],dx 199 | mov wptr device_int[OLD_INT_33H_PROC][2],es 200 | else 201 | mov ax,BASH_INT_PROC ;Set interrupt routine 202 | int MOUSE_SYS_VEC 203 | 204 | mov wptr device_int[OLD_INT_33H_MASK],0 205 | mov wptr device_int[OLD_INT_33H_PROC][0],0 206 | mov wptr device_int[OLD_INT_33H_PROC][2],0 207 | endif 208 | ret 209 | 210 | I33_enable endp 211 | page 212 | 213 | ;---------------------------Public-Routine------------------------------; 214 | ; I33_disable - Disable the INT 33h mouse handler 215 | ; 216 | ; The INT 33h mouse handler will be disabled from calling us. The 217 | ; previous event mask and event procedure will be restored. 218 | ; 219 | ; Entry: 220 | ; None 221 | ; Returns: 222 | ; None 223 | ; Error Returns: 224 | ; None 225 | ; Registers Preserved: 226 | ; DS,BP 227 | ; Registers Destroyed: 228 | ; AX,BX,CX,DX,SI,DI,ES,FLAGS 229 | ; Calls: 230 | ; INT 33h 231 | ; History: 232 | ; Fri 21-Aug-1987 11:43:42 -by- Walt Moore [waltm] & Mr. Mouse 233 | ; Initial version 234 | ;-----------------------------------------------------------------------; 235 | 236 | ;------------------------------Pseudo-Code------------------------------; 237 | ; { 238 | ; } 239 | ;-----------------------------------------------------------------------; 240 | 241 | assumes cs,Code 242 | assumes ds,Data 243 | 244 | I33_disable proc near 245 | 246 | mov ax,BASH_INT_PROC 247 | mov cx,wptr device_int[OLD_INT_33H_MASK] 248 | les dx,dptr device_int[OLD_INT_33H_PROC] 249 | assumes es,nothing 250 | int MOUSE_SYS_VEC 251 | 252 | ret 253 | 254 | I33_disable endp 255 | 256 | 257 | 258 | ;---------------------------Public-Routine------------------------------; 259 | ; I33_init - Initialize the INT 33h mouse handler 260 | ; 261 | ; Store the enable and disable procedure addresses where the interrupt 262 | ; procedure can find them. Return the information needed for the caller 263 | ; to copy the interrupt procedure to the data segment. 264 | ; 265 | ; Entry: 266 | ; None 267 | ; Returns: 268 | ; None 269 | ; Error Returns: 270 | ; None 271 | ; Registers Preserved: 272 | ; DS,BP 273 | ; Registers Destroyed: 274 | ; AX,BX,CX,DX,SI,DI,ES,FLAGS 275 | ; Calls: 276 | ; INT 33h 277 | ; History: 278 | ; Thu 17-Sep-1987 22:19:00 -by- Bob Grudem [bobgru] 279 | ; Coded final pieces. 280 | ; Fri 21-Aug-1987 11:43:42 -by- Walt Moore [waltm] & Mr. Mouse 281 | ; Initial version 282 | ;-----------------------------------------------------------------------; 283 | 284 | ;------------------------------Pseudo-Code------------------------------; 285 | ; { 286 | ; } 287 | ;-----------------------------------------------------------------------; 288 | 289 | assumes cs,Code 290 | assumes ds,Data 291 | 292 | public I33_init 293 | I33_init proc near 294 | 295 | mov enable_proc, CodeOFFSET I33_enable 296 | mov disable_proc,CodeOFFSET I33_disable 297 | mov si,CodeOFFSET I33_START 298 | mov cx,I33_INT_LENGTH 299 | ret 300 | I33_init endp 301 | 302 | sEnd Code 303 | end 304 | -------------------------------------------------------------------------------- /src/MAKEFILE: -------------------------------------------------------------------------------- 1 | # Microsoft Mouse Driver 2 | # 3 | # Requirements: 4 | # 5 | # MASM 4.01 or greater with the environment variable INCLUDE set to 6 | # the directories containing CMACROS.INC, and WINDEFS.INC. 7 | # 8 | # MASM 4.00 or greater with the ASM inference definition changed to 9 | # include the directories containing CMACROS.INC, and WINDEFS.INC. 10 | 11 | 12 | # Options: 13 | # 14 | # The command line may define options to MASM by defining the OPT 15 | # macro. By defining the OPT parameter in the make file, any 16 | # possible interaction with an environment definition is avoided. 17 | 18 | OPT = -l #NOP the options feature 19 | 20 | 21 | # Define the default assemble command. This command could actually 22 | # be overridden from the command line, but shouldn't be. 23 | 24 | ASM = masm -v -ML $(OPT) # MASM 4.01 & > 25 | # ASM = masm -v -ML $(OPT) -I\finc # MASM 4.00 26 | 27 | 28 | # Define the default inference rules 29 | 30 | .asm.obj: 31 | $(ASM) $*,$@; 32 | 33 | mouse: i33mouse.drv 34 | 35 | mouse.obj: mouse.asm mouse.inc 36 | 37 | int33h.obj: int33h.asm mouse.inc 38 | 39 | i33mouse.drv: mouse.def mouse.obj int33h.obj 40 | link @mouse.lnk 41 | rc i33mouse.drv 42 | -------------------------------------------------------------------------------- /src/MOUSE.ASM: -------------------------------------------------------------------------------- 1 | page ,132 2 | ;-----------------------------Module-Header-----------------------------; 3 | ; Module Name: MOUSE.ASM 4 | ; 5 | ; Windows mouse driver data and initialization routines. 6 | ; 7 | ; Created: Yester-year 8 | ; Author: Walt Moore [waltm], Mr. Mouse, and a cast of tens. 9 | ; Sun 04-Dec-1988 21:31:36 -by- David N. Weise [davidw] 10 | ; Made it bi-modal. 11 | ; 03-May-1989 RAL -by- Ralph Lipe 12 | ; Calls Windows/386 VxD when mouse detected 13 | ; 14 | ; Copyright (c) 1987, 1988, 1989 Microsoft Corporation 15 | ; 16 | ; Exported Functions: 17 | ; 18 | ; Public Functions: 19 | ; 20 | ; Public Data: 21 | ; 22 | ; General Description: 23 | ; 24 | ; This segment contains all static data used by the mouse routines. The 25 | ; hardware interrupt routine is included in the static data so that it 26 | ; has addressability to the static data through the CS register. Thus 27 | ; the data segment of this module MUST be fixed in memory, while the 28 | ; code segment can be moveable and/or discardable. 29 | ; 30 | ;-----------------------------------------------------------------------; 31 | 32 | title Mouse - Main Mouse Module 33 | 34 | .xlist 35 | include cmacros.inc 36 | include windefs.inc 37 | include mouse.inc 38 | .list 39 | 40 | externFP AllocDStoCSAlias 41 | 42 | if 0 43 | externNP inport_search 44 | externNP serial_search 45 | externNP bus_search 46 | externNP ps2_search 47 | endif 48 | externNP I33_init 49 | 50 | externA __WINFLAGS 51 | 52 | ;OS2 equ 10 ;Version number for OS/2 53 | 54 | sBegin Data 55 | 56 | globalW WinFlags,__WINFLAGS ;Windows environment flags 57 | globalB vector,-1 ;Vector # of mouse interrupt 58 | globalB mask_8259,0FFh ;8259 interrupt enable mask, FF if none 59 | globalB old_8259_mask,0FFh ;Value of mouse irq bit before enable 60 | globalB mouse_flags,0 ;Various flags 61 | globalB mouse_type,0 ;Type of mouse (inport/bus/serial/etc.) 62 | 63 | even ;Want words on word boundary 64 | 65 | globalW io_base,0 ;Mouse port base address 66 | globalD event_proc,0 ;Mouse event procedure when enabled 67 | globalD bios_proc,0 ;Contents of old interrupt vector 68 | 69 | globalW enable_proc,0 ;Address of routine to enable mouse 70 | globalW disable_proc,0 ;Address of routine to disable mouse 71 | globalW interrupt_rate,30 ;Maximum interrupt rate of mouse 72 | page 73 | ;--------------------------Interrupt-Routine----------------------------; 74 | ; 75 | ; device_int - Mouse Specific Interrupt Handler 76 | ; 77 | ; The mouse specific interrupt code will follow. It will be copied 78 | ; into the reserved area as initialization time, and executed from 79 | ; here. 80 | ; 81 | ; Entry: 82 | ; DS = Data 83 | ; CS = Data 84 | ; Returns: 85 | ; AX = status 86 | ; BX = delta X 87 | ; CX = delta Y 88 | ; Error Returns: 89 | ; None 90 | ; Registers Preserved: 91 | ; None 92 | ; Registers Destroyed: 93 | ; All 94 | ; Calls: 95 | ; none 96 | ; WARNING: 97 | ; Unused memory from device_int will be freed. Therefore device 98 | ; int must be the last thing allocated in the Data segment 99 | ; History: 100 | ; Fri 21-Aug-1987 11:43:42 -by- Walt Moore [waltm] & Mr. Mouse 101 | ; Initial version 102 | ;-----------------------------------------------------------------------; 103 | 104 | ;------------------------------Pseudo-Code------------------------------; 105 | ; { 106 | ; } 107 | ;-----------------------------------------------------------------------; 108 | 109 | assumes cs,Data 110 | assumes ds,Data 111 | assumes es,nothing 112 | assumes ss,nothing 113 | 114 | even 115 | 116 | globalW IntCS,0 ; DS alias for this routine 117 | 118 | public device_int 119 | 120 | device_int proc near 121 | 122 | db MAX_INT_SIZE dup (?) ;Specific int handler goes here 123 | 124 | device_int endp 125 | 126 | sEnd Data 127 | page 128 | 129 | sBegin Code 130 | assumes cs,Code 131 | 132 | ;--------------------------Exported-Routine-----------------------------; 133 | ; int Inquire(lp_mouse_info); 134 | ; 135 | ; Information regarding the mouse is returned to the caller. 136 | ; 137 | ; Entry: 138 | ; None 139 | ; Returns: 140 | ; AX = # bytes returned in lp_mouse_info 141 | ; Error Returns: 142 | ; None 143 | ; Registers Preserved: 144 | ; SI,DI,DS,BP 145 | ; Registers Destroyed: 146 | ; AX,BX,CX,DX,ES,FLAGS 147 | ; Calls: 148 | ; None 149 | ; History: 150 | ; Fri 21-Aug-1987 11:43:42 -by- Walt Moore [waltm] & Mr. Mouse 151 | ; Initial version 152 | ;-----------------------------------------------------------------------; 153 | 154 | ;------------------------------Pseudo-Code------------------------------; 155 | ; { 156 | ; } 157 | ;-----------------------------------------------------------------------; 158 | 159 | assumes cs,Code 160 | assumes ds,Data 161 | 162 | cProc Inquire,, 163 | 164 | parmD lp_mouse_info 165 | 166 | cBegin 167 | les di,lp_mouse_info ;Get far pointer of destination area 168 | assumes es,nothing 169 | 170 | mov al,mouse_flags ;Get and save msExists, msRelative 171 | cbw 172 | xchg al,ah ;AL = 0FFh if mouse exists, 00 if not 173 | .errnz MF_MOUSE_EXISTS-80h 174 | 175 | mov ah,0FFh ;AH = 0FFh if relative coordinates 176 | stosw ; (but is currently ignored!) 177 | .errnz msExists 178 | .errnz msRelative-msExists-1 179 | 180 | mov ax,NUMBER_BUTTONS ;Return number of buttons 181 | stosw 182 | .errnz msNumButtons-msRelative-1 183 | 184 | mov ax,interrupt_rate ;Return maximum interrupt rate 185 | stosw 186 | .errnz msRate-msNumButtons-2 187 | 188 | mov ax,X_SPEED ;Return threshold before acceleration 189 | stosw 190 | .errnz msXThresh-msRate-2 191 | 192 | if Y_SPEED ne X_SPEED ;Generally they're the same 193 | mov ax,Y_SPEED ;Return threshold before acceleration 194 | endif 195 | stosw 196 | .errnz msYThresh-msXThresh-2 197 | 198 | xor ax,ax ;Return useless x,y resolution info 199 | stosw 200 | stosw 201 | .errnz msXRes-msYThresh-2 202 | .errnz msYRes-msXRes-2 203 | .errnz msYRes+2 - size MOUSEINFO 204 | 205 | mov ax,size MOUSEINFO ;Return size of info 206 | 207 | cEnd 208 | page 209 | 210 | ;--------------------------Exported-Routine-----------------------------; 211 | ; void Enable(lp_event_proc); 212 | ; 213 | ; Enable hardware mouse interrupts, with the passed procedure address 214 | ; being the target of all mouse events. 215 | ; 216 | ; This routine may be called while already enabled. In this case the 217 | ; passed event procedure should be saved, and all other initialization 218 | ; skipped. 219 | ; 220 | ; Entry: 221 | ; None 222 | ; Returns: 223 | ; None 224 | ; Error Returns: 225 | ; None 226 | ; Registers Preserved: 227 | ; SI,DI,DS,BP 228 | ; Registers Destroyed: 229 | ; AX,BX,CX,DX,ES,FLAGS 230 | ; Calls: 231 | ; Indirect through enable_proc 232 | ; History: 233 | ; Fri 21-Aug-1987 11:43:42 -by- Walt Moore [waltm] & Mr. Mouse 234 | ; Initial version 235 | ;-----------------------------------------------------------------------; 236 | 237 | ;------------------------------Pseudo-Code------------------------------; 238 | ; { 239 | ; } 240 | ;-----------------------------------------------------------------------; 241 | 242 | assumes cs,Code 243 | assumes ds,Data 244 | 245 | cProc Enable,, 246 | 247 | parmD new_event_proc 248 | 249 | cBegin 250 | 251 | ; The new event procedure is always saved regardless of the 252 | ; mouse already being enabled. This allows the event proc 253 | ; to be changed as needed. 254 | 255 | cli ;Protect against interrupt while 256 | mov ax,off_new_event_proc ; changing the vector 257 | mov wptr event_proc[0],ax 258 | mov ax,seg_new_event_proc 259 | mov wptr event_proc[2],ax 260 | sti 261 | 262 | ; If the mouse is already enabled, or it doesn't exist, then 263 | ; we're all done with the enable call. 264 | 265 | mov al,mouse_flags ;If enabled or mouse doesn't exist, 266 | xor al,MF_MOUSE_EXISTS ; then skip the enabling 267 | test al,MF_ENABLED+MF_MOUSE_EXISTS 268 | jnz enable_done 269 | call enable_proc ;Mouse specific initialization 270 | or mouse_flags,MF_ENABLED ;Show enabled now 271 | 272 | enable_done: 273 | 274 | cEnd 275 | page 276 | 277 | ;--------------------------Exported-Routine-----------------------------; 278 | ; void Disable(); 279 | ; 280 | ; Disable hardware mouse interrupts, restoring the previous mouse 281 | ; interrupt handler and 8259 interrupt enable mask. 282 | ; 283 | ; This routine may be called while already disabled. In this case the 284 | ; disabling should be ignored. 285 | ; 286 | ; Entry: 287 | ; None 288 | ; Returns: 289 | ; None 290 | ; Error Returns: 291 | ; None 292 | ; Registers Preserved: 293 | ; SI,DI,DS,BP 294 | ; Registers Destroyed: 295 | ; AX,BX,CX,DX,ES,FLAGS 296 | ; Calls: 297 | ; Indirect through disable_proc 298 | ; History: 299 | ; Fri 21-Aug-1987 11:43:42 -by- Walt Moore [waltm] & Mr. Mouse 300 | ; Initial version 301 | ;-----------------------------------------------------------------------; 302 | 303 | ;------------------------------Pseudo-Code------------------------------; 304 | ; { 305 | ; } 306 | ;-----------------------------------------------------------------------; 307 | 308 | assumes cs,Code 309 | assumes ds,Data 310 | 311 | cProc Disable,, 312 | 313 | cBegin 314 | test mouse_flags,MF_ENABLED 315 | jz disable_done ;Mouse is already disabled 316 | call disable_proc ;Disable as needed 317 | and mouse_flags,not MF_ENABLED 318 | 319 | disable_done: 320 | 321 | cEnd 322 | page 323 | 324 | ;--------------------------Exported-Routine-----------------------------; 325 | ; WORD WEP(); 326 | ; 327 | ; Generic WEP. 328 | ; 329 | ; Entry: 330 | ; None 331 | ; Returns: 332 | ; AX = 1 333 | ; Error Returns: 334 | ; None 335 | ; Registers Preserved: 336 | ; all 337 | ; Registers Destroyed: 338 | ; none 339 | ; Calls: 340 | ; nothing 341 | ; History: 342 | ; Wed 18-Oct-1989 11:44:39 -by- David N. Weise [davidw] 343 | ; Wrote it! 344 | ;-----------------------------------------------------------------------; 345 | 346 | ;------------------------------Pseudo-Code------------------------------; 347 | ; { 348 | ; } 349 | ;-----------------------------------------------------------------------; 350 | 351 | assumes cs,Code 352 | assumes ds,Data 353 | 354 | cProc WEP, 355 | ; parmW stuff 356 | cBegin nogen 357 | mov ax,1 358 | ret 2 359 | cEnd nogen 360 | page 361 | 362 | ;--------------------------Exported-Routine-----------------------------; 363 | ; int MouseGetIntVect(); 364 | ; 365 | ; The interrupt vector used by the mouse is returned to the caller. 366 | ; If no mouse is found, then -1 is returned. 367 | ; 368 | ; Entry: 369 | ; None 370 | ; Returns: 371 | ; AX = interrupt vector 372 | ; AX = -1 if no mouse was found 373 | ; Error Returns: 374 | ; None 375 | ; Registers Preserved: 376 | ; SI,DI,DS,BP 377 | ; Registers Destroyed: 378 | ; AX,BX,CX,DX,ES,FLAGS 379 | ; Calls: 380 | ; None 381 | ; History: 382 | ; Fri 21-Aug-1987 11:43:42 -by- Walt Moore [waltm] & Mr. Mouse 383 | ; Initial version 384 | ;-----------------------------------------------------------------------; 385 | 386 | ;------------------------------Pseudo-Code------------------------------; 387 | ; { 388 | ; } 389 | ;-----------------------------------------------------------------------; 390 | 391 | assumes cs,Code 392 | assumes ds,Data 393 | 394 | cProc MouseGetIntVect, 395 | 396 | cBegin 397 | 398 | ; NOTE! vector must be less than 7Fh for the sign extension to work 399 | 400 | mov al,vector ;Will be -1 if mouse wasn't found 401 | cbw ;AX = -1 if no mouse was found 402 | cEnd 403 | page 404 | 405 | ;---------------------------Public-Routine-----------------------------; 406 | ; hook_us_in 407 | ; 408 | ; This is a utility routine for the specific mouse handlers. The 409 | ; following initialization will be performed in preperation of 410 | ; hooking in the interrupt handler: 411 | ; 412 | ; save old 8259 mask 413 | ; disable our IRQ at the 8259 414 | ; save old interrupt vector contents 415 | ; set new interrupt vector 416 | ; 417 | ; Entry: 418 | ; None offset in Data segment of interrupt handler 419 | ; Returns: 420 | ; None 421 | ; Error Returns: 422 | ; None 423 | ; Registers Preserved: 424 | ; DI,SI,DS,BP 425 | ; Registers Destroyed: 426 | ; AX,BX,CX,DX,ES,FLAGS 427 | ; Calls: 428 | ; Int 21h 429 | ; History: 430 | ; Mon 24-Aug-1987 22:41:22 -by- Walt Moore [waltm] & Mr. Mouse 431 | ; Initial version 432 | ;-----------------------------------------------------------------------; 433 | 434 | ;------------------------------Pseudo-Code------------------------------; 435 | ; { 436 | ; } 437 | ;-----------------------------------------------------------------------; 438 | 439 | assumes cs,Code 440 | assumes ds,Data 441 | 442 | public hook_us_in 443 | hook_us_in proc near 444 | 445 | mov ah,mask_8259 ;Get our 8259 enable mask 446 | xor ah,0FFh ;A 1 bit for our IRQ (not AH) 447 | jz hook_us_in_no_irq ;No IRQ is involved 448 | cli 449 | in al,MASK_PORT ;Get current 8259 mask 450 | mov bl,al 451 | or al,ah 452 | and bl,ah ;Isolate old mouse IRQ bit 453 | out MASK_PORT,al ;Disable mouse int 454 | sti 455 | 456 | mov old_8259_mask,bl ;Will be 0 if previously enabled 457 | 458 | hook_us_in_no_irq: 459 | mov ah,35h ;Save old interrupt vector 460 | mov al,vector 461 | int 21h 462 | mov wptr bios_proc[0],bx 463 | mov wptr bios_proc[2],es 464 | 465 | push ds 466 | push IntCS 467 | pop ds 468 | mov ah,25h ;Set our interrupt vector 469 | mov al,vector 470 | mov dx,DataOFFSET device_int 471 | int 21h 472 | pop ds 473 | sti 474 | 475 | ret 476 | 477 | hook_us_in endp 478 | page 479 | 480 | ;---------------------------Public-Routine-----------------------------; 481 | ; enable_our_int 482 | ; 483 | ; The 8259 is enabled for our interrupt, as specified by mask_8259. 484 | ; 485 | ; This routine will only be called by those functions which actually 486 | ; require an IRQ. 487 | ; 488 | ; Entry: 489 | ; None 490 | ; Returns: 491 | ; None 492 | ; Error Returns: 493 | ; None 494 | ; Registers Preserved: 495 | ; BX,CX,DX,SI,DI,ES,DS,BP 496 | ; Registers Destroyed: 497 | ; AX,FLAGS 498 | ; Calls: 499 | ; None 500 | ; History: 501 | ; Mon 24-Aug-1987 22:41:22 -by- Walt Moore [waltm] & Mr. Mouse 502 | ; Initial version 503 | ;-----------------------------------------------------------------------; 504 | 505 | ;------------------------------Pseudo-Code------------------------------; 506 | ; { 507 | ; } 508 | ;-----------------------------------------------------------------------; 509 | 510 | assumes cs,Code 511 | assumes ds,Data 512 | 513 | public enable_our_int 514 | enable_our_int proc near 515 | 516 | mov ah,mask_8259 ;Get our enable mask 517 | cli 518 | in al,MASK_PORT ;Get current 8259 mask 519 | and al,ah ;Set our IRQ bit to 0 (enabled) 520 | out MASK_PORT,al 521 | sti 522 | ret 523 | 524 | enable_our_int endp 525 | page 526 | 527 | ;---------------------------Public-Routine-----------------------------; 528 | ; unhook_us 529 | ; 530 | ; This is a utility routine for the specific mouse handlers. The 531 | ; interrupt vector will be restored to its previous value and the 532 | ; old IRQ enable bit will be restored. 533 | ; 534 | ; Entry: 535 | ; None 536 | ; Returns: 537 | ; 'Z' set if IRQ should be left enabled at the device 538 | ; 'Z' clear if IRQ should be left disabled at the device 539 | ; Error Returns: 540 | ; None 541 | ; Registers Preserved: 542 | ; SI,DI,DS,BP 543 | ; Registers Destroyed: 544 | ; AX,BX,CX,DX,ES,FLAGS 545 | ; Calls: 546 | ; Int 21h 547 | ; History: 548 | ; Mon 24-Aug-1987 22:41:22 -by- Walt Moore [waltm] & Mr. Mouse 549 | ; Initial version 550 | ;-----------------------------------------------------------------------; 551 | 552 | ;------------------------------Pseudo-Code------------------------------; 553 | ; { 554 | ; } 555 | ;-----------------------------------------------------------------------; 556 | 557 | assumes cs,Code 558 | assumes ds,Data 559 | 560 | public unhook_us 561 | unhook_us proc near 562 | 563 | mov ah,mask_8259 ;Disable our interrupt at the 564 | xor ah,0FFh ; 8259 before changing the (not AH) 565 | jz unhook_no_irq ; vector since old versions 566 | cli ; of DOS may not cli/sti 567 | in al,MASK_PORT ; while setting int vectors 568 | or al,ah 569 | out MASK_PORT,al 570 | sti 571 | 572 | unhook_no_irq: 573 | cmp wptr bios_proc[2],0 ; PS2 mouse may have failed enable 574 | jz unhook_no_bios_proc ; so bios proc might not be set. 575 | push ds 576 | mov ah,25h ;Restore old interrupt vector 577 | mov al,vector 578 | lds dx,bios_proc 579 | assumes ds,nothing 580 | 581 | int 21h 582 | 583 | pop ds 584 | assumes ds,Data 585 | 586 | unhook_no_bios_proc: 587 | 588 | ; If IRQ mask will be set to whatever value it was when we were 589 | ; enabled. If there is no Int 33h mouse driver in the system, 590 | ; then flag the caller that interrupts should be disabled at the 591 | ; device. If there is an Int33h mouse driver and interrupts 592 | ; were disabled upon entry, also flag the caller to disable 593 | ; interrupts at the device. Only allow device interrupts to 594 | ; continue being generated if there is an Int33h mouse and 595 | ; the IRQ was previously enabled. 596 | ; 597 | ; This is in part a fix for running on IRQ2 in Compaqs and 598 | ; other machines which try to allow this. I don't recommend 599 | ; IRQ2 for ATs and compatibles, but some people try and it 600 | ; almost seems to work if mouse.com is there to handle the 601 | ; interrupt. 602 | 603 | test old_8259_mask,0FFh ;If interrupts were previous disabled 604 | jnz unhook_exit ; then leave them disabled ('Z' clear) 605 | mov ah,mask_8259 606 | cli 607 | in al,MASK_PORT 608 | and al,ah 609 | out MASK_PORT,al 610 | sti 611 | mov al,mouse_flags 612 | not al 613 | and al,MF_INT33H ;'Z' clear if to disable at the device 614 | 615 | unhook_exit: 616 | ret 617 | 618 | unhook_us endp 619 | page 620 | 621 | ;---------------------------Public-Routine-----------------------------; 622 | ; Initialize 623 | ; 624 | ; All boot time initialization will be performed. This basically 625 | ; involves searching for a mouse in the system. The ordering in 626 | ; which we will search is as follows: 627 | ; 628 | ; INT 33h installed mouse driver 629 | ; Microsoft InPort Mouse 630 | ; Microsoft Bus Mouse 631 | ; PS/2 Mouse via ROM BIOS support 632 | ; Serial Mouse 633 | ; 634 | ; After a mouse handler has been found, the Data segment will be 635 | ; resized to the minimum needed to support the mouse in use. 636 | ; 637 | ; Entry: 638 | ; CX = size of heap 639 | ; DI = module handle 640 | ; DS = automatic data segment 641 | ; ES:SI = address of command line (not used) 642 | ; Returns: 643 | ; AX <> 0 to show success 644 | ; Error Returns: 645 | ; None 646 | ; Registers Preserved: 647 | ; SI,DI,DS,BP 648 | ; Registers Destroyed: 649 | ; AX,BX,CX,DX,ES,FLAGS 650 | ; Calls: 651 | ; I33_search 652 | ; inport_search 653 | ; bus_search 654 | ; PS2_search 655 | ; serial_search 656 | ; History: 657 | ; Fri 21-Aug-1987 11:43:42 -by- Walt Moore [waltm] & Mr. Mouse 658 | ; Initial version 659 | ;-----------------------------------------------------------------------; 660 | 661 | ;------------------------------Pseudo-Code------------------------------; 662 | ; { 663 | ; } 664 | ;-----------------------------------------------------------------------; 665 | 666 | assumes cs,Code 667 | assumes ds,Data 668 | 669 | cProc Initialize,, 670 | 671 | cBegin 672 | 673 | ;-----------------------------------------------------------------------; 674 | ; Regardless of using the Int33h mouse driver, we need to 675 | ; know if it is present for disabling IRQs when the mouse 676 | ; is disabled. 677 | ;-----------------------------------------------------------------------; 678 | 679 | if 0 ;---------------------------------------------------------------- 680 | 681 | ; This code was for earlier versions of the Microsoft mouse driver which 682 | ; didn't support the GetMouseInfo call. Windows 3.0 is shipping DOS 683 | ; mouse driver 7.0x. 6.?? added the GetMouseInfo call. 684 | 685 | ; We would have liked to have done a mouse reset to see if 686 | ; the mouse was installed. However, this disables any 687 | ; user-installed call out (like menus). What we will do 688 | ; instead is the following: 689 | ; 690 | ; Swap in a bogus interrupt procedure and an event 691 | ; mask which says don't call out. If the mouse driver 692 | ; is present, then we should get back something different 693 | ; than what was passed in. If we do get back something 694 | ; different, we'll restore that data and see if what is 695 | ; returned is what was originally passed in. If so, we 696 | ; have a mouse driver, version 6.00 or greater and menus 697 | ; will still be enabled. 698 | ; 699 | ; If the above test fails, we'll do the mouse reset to 700 | ; see if the mouse is installed. This will trash menus, 701 | ; but there isn't much we can do about it. 702 | 703 | test hello,1 ;!!! just for now (WinFlags) 704 | jnz check_inport 705 | push cs ;ES:DX --> bogus_far_ret 706 | pop es 707 | mov dx,CodeOFFSET bogus_far_ret 708 | xor cx,cx ;Don't call installed int proc 709 | mov ax,SWAP_INT_PROC ;Swap interrupt routine 710 | int MOUSE_SYS_VEC 711 | cmp dx,CodeOFFSET bogus_far_ret 712 | jne swap_them_back ;Different interrupt proc address, 713 | mov ax,cs ; might be a mouse 714 | mov bx,es 715 | cmp ax,bx 716 | je try_mouse_reset ;Int proc address same, might be < 6.00 717 | 718 | ;-----------------------------------------------------------------------; 719 | ; The procedure address which was returned was different that what 720 | ; we passed in. Restore it and see if what is returned is what we 721 | ; had originally passed in. If so, this is a 6.00 or greater mouse. 722 | ;-----------------------------------------------------------------------; 723 | 724 | swap_them_back: 725 | mov ax,SWAP_INT_PROC ;Swap interrupt routine. Should get 726 | int MOUSE_SYS_VEC ; back what we set initially 727 | cmp dx,CodeOFFSET bogus_far_ret 728 | jne try_mouse_reset ;Not a 6.00+ mouse driver, go see 729 | mov ax,cs ; if it might some other version 730 | mov bx,es 731 | cmp ax,bx 732 | jne try_mouse_reset ;Not 6.00+ 733 | jcxz sys_mouse_present ;6.00 or greater 734 | 735 | ;else ;----------------------------------------------------------------- 736 | 737 | xor bx,bx ;Current DOS mouse drivers implement 738 | mov ax,INT33H_GETINFO ; a Get Mouse Info call 739 | int MOUSE_SYS_VEC 740 | cmp bh,6 ;Major version in bh, started @ 6.?? 741 | jb try_mouse_reset 742 | jmp short sys_mouse_present 743 | 744 | endif ;----------------------------------------------------------------- 745 | 746 | try_mouse_reset: 747 | xor ax,ax ;Check for DOS mouse driver 748 | .errnz INT33H_RESET 749 | int MOUSE_SYS_VEC 750 | or ax,ax ;Zero if no mouse installed 751 | jnz sys_mouse_present 752 | mov mouse_type, MT_NO_MOUSE ;Reset mouse type to none 753 | mov si,DataOFFSET device_int;Resize to this limit 754 | jmp short resize_ds 755 | 756 | sys_mouse_present: 757 | or mouse_flags,MF_INT33H ;Show mouse driver is present 758 | mov ah,30h ;Get DOS version number 759 | int 21h 760 | ; cmp al,OS2 ;OS/2? 761 | ; jb check_inport ;If not, skip int 33h search 762 | 763 | check_I33: 764 | call I33_init ;Use the installed mouse driver 765 | jmp short got_mouse ; if it exists 766 | 767 | 768 | if 0 769 | check_inport: 770 | call inport_search ;Try to find InPort mouse 771 | jnc check_bus ;InPort mouse wasn't found 772 | jcxz check_ps2 ;Was found, didn't respond 773 | mov mouse_type, MT_INPORT ;InPort mouse 774 | jmp short got_mouse ;Was found, responded 775 | 776 | check_bus: 777 | mov mouse_type, MT_BUS ;Assume bus mouse 778 | call bus_search ;Next up, the old bus mouse 779 | jc got_mouse 780 | 781 | check_ps2: 782 | mov mouse_type, MT_PS2 ;Assume PS/2 mouse 783 | call ps2_search ;PS/2 mouse port? 784 | jc got_mouse 785 | 786 | check_serial: 787 | mov mouse_type, MT_SERIAL ;Assume serial mouse 788 | call serial_search 789 | jc got_mouse 790 | mov mouse_type, MT_NO_MOUSE ;Reset mouse type to none 791 | mov si,DataOFFSET device_int;Resize to this limit 792 | jmp short resize_ds 793 | 794 | endif 795 | got_mouse: 796 | ; 797 | ; If running under Windows/386 then tell the Win386 mouse driver what 798 | ; type of mouse we found. 799 | ; 800 | push ax 801 | push bx 802 | push di 803 | push es 804 | 805 | %OUT Test flags for Win386 here! 806 | xor di, di 807 | mov es, di 808 | mov ax, 1684h ;Get device API entry point 809 | mov bx, VMD_DEVICE_ID ;for the Virtual Mouse Device 810 | int 2Fh 811 | mov ax, es 812 | or ax, di ;Q: Does VMD have API entry point? 813 | jz copy_mouse_routines ; N: Done 814 | 815 | push cs ;Return to here after call to Win386 816 | mov bx, offset vmd_call_done;virtual mouse driver 817 | push bx 818 | push es ;Call this SEG:OFF by doing a far 819 | push di ;return 820 | 821 | mov ax, 100h ;Set mouse type & int VECTOR API call 822 | mov bl, mouse_type 823 | mov bh, vector 824 | 825 | BogusFarRetProc PROC FAR 826 | ret ;"Return" to VMD's API entry point 827 | BogusFarRetProc ENDP 828 | 829 | vmd_call_done: 830 | copy_mouse_routines: 831 | pop es 832 | pop di 833 | pop bx 834 | pop ax 835 | 836 | 837 | or mouse_flags,MF_MOUSE_EXISTS 838 | mov di,DataOFFSET device_int 839 | 840 | 841 | ; The mouse routines returned the following: 842 | ; 843 | ; SI = offset within the Code segment of the handler 844 | ; CX = size of the handler 845 | ; 846 | ; After the interrupt handler has been copied into the Data 847 | ; segment, SI-1 will be used as the new size of the Data segment. 848 | 849 | push ds ;Destination is in Data 850 | pop es 851 | assumes es,Data 852 | push cs ;Source is in Code 853 | pop ds 854 | assumes cs,Code 855 | rep movsb 856 | push es 857 | pop ds 858 | assumes ds,Data 859 | 860 | push si 861 | push di 862 | push ds 863 | 864 | cCall AllocDStoCSAlias, 865 | mov IntCS,ax 866 | 867 | pop ds 868 | pop di 869 | pop si 870 | 871 | resize_ds: 872 | dec si 873 | 874 | ; !!! resize the DS here, based on SI-1 as the limit of what 875 | ; we need. If we didn't find a mouse, then resize to the start 876 | ; of device_int-1. 877 | 878 | mov ax,1 ;Successful initialization 879 | 880 | cEnd 881 | page 882 | 883 | ;-----------------------------------------------------------------------; 884 | ; bogus_far_ret is a far return instruction which can be 885 | ; passed off to the INT 33h mouse detection logic routine. 886 | ;-----------------------------------------------------------------------; 887 | 888 | bogus_far_ret proc far 889 | 890 | ret 891 | 892 | bogus_far_ret endp 893 | 894 | sEnd Code 895 | end Initialize 896 | -------------------------------------------------------------------------------- /src/MOUSE.DEF: -------------------------------------------------------------------------------- 1 | LIBRARY MOUSE 2 | 3 | DESCRIPTION 'int33 mouse driver by stsp' 4 | EXETYPE WINDOWS 5 | 6 | CODE PRELOAD DISCARDABLE 7 | DATA PRELOAD FIXED SINGLE 8 | 9 | EXPORTS 10 | Inquire @1 11 | Enable @2 12 | Disable @3 13 | MouseGetIntVect @4 14 | WEP 15 | 16 | -------------------------------------------------------------------------------- /src/MOUSE.INC: -------------------------------------------------------------------------------- 1 | ;*************************************************************************** 2 | ; * 3 | ; Copyright (C) 1983,1984 by Microsoft Inc. * 4 | ; * 5 | ;*************************************************************************** 6 | 7 | ;*************************************************************************** 8 | ; * 9 | ; Header file for Microsoft mouse device driver. Contains all machine * 10 | ; specific constant and data structure definitions. * 11 | ; * 12 | ;*************************************************************************** 13 | 14 | extrn __ROMBIOS :abs 15 | 16 | wptr equ word ptr 17 | bptr equ byte ptr 18 | dptr equ dword ptr 19 | 20 | 21 | WF_PMODE equ 01h ;Running in protect mode. 22 | 23 | 24 | MAX_INT_SIZE equ 210 ;Max. size of interrupt routine 25 | 26 | 27 | ACK_PORT equ 20h ;8259 master acknowledge port 28 | MASK_PORT equ 21h 29 | ACK_SLAVE_PORT equ 0A0h ;8259 slave acknowledge port 30 | MASK_SLAVE_PORT equ 0A1h 31 | EOI equ 20h ;8259 end of interrupt 32 | INT_REQUEST equ 0ah ;8259 interrupt request register select 33 | IN_SERVICE equ 0bh ;8259 in service register select value 34 | 35 | 36 | ; Symbolic equates for contents of the MOUSEINFO data structure 37 | 38 | NUMBER_BUTTONS equ 3 39 | X_SPEED equ 2 40 | Y_SPEED equ 2 41 | 42 | 43 | io_delay macro 44 | jmp short $+2 45 | jmp short $+2 46 | jmp short $+2 47 | endm 48 | 49 | 50 | 51 | BIOSDataSeg segment at 40h ;BIOS data areas of the IBM PC/XT/AT 52 | rs232_data dw 4 dup (?) 53 | org 6Ch 54 | bios_time db ? 55 | BIOSDataSeg ends 56 | 57 | 58 | 59 | ; Definitions of the status word passed to the event_proc 60 | ; in the AX register. The registers passed to the event_proc 61 | ; are as follows: 62 | ; 63 | ; AX = status as defined below 64 | ; BX = delta X or normalized abs 65 | ; CX = delta Y or normalized abs 66 | ; DX = number of buttons 67 | ; 68 | ; If the SF_ABSOLUTE bit is clear in the status word, then the 69 | ; BX and CX are reporting relative motion from the last reported 70 | ; position. If this bit is set, then BX and CX contain normalized 71 | ; absolute coordinates between 0 and +65535, which will be mapped 72 | ; by the event_proc onto the display surface 73 | 74 | 75 | SF_MOVEMENT equ 0001h ;Movement occured 76 | SF_B1_DOWN equ 0002h ;Button 1 (SW1) changed to down 77 | SF_B1_UP equ 0004h ;Button 1 (SW1) changed to up 78 | SF_B2_DOWN equ 0008h ;Button 2 (SW3) changed to down 79 | SF_B2_UP equ 0010h ;Button 2 (SW3) changed to up 80 | SF_ABSOLUTE equ 8000h ;BX,CX are normalized absolute coords 81 | 82 | 83 | ; Definitions of the flag byte mouse_flags 84 | 85 | MF_ENABLED equ 00000001b ;Mouse is enabled 86 | MF_INT33H equ 00000010b ;Int 33h mouse found 87 | ; equ 00000100b ; 88 | ; equ 00001000b ; 89 | ; equ 00010000b ; 90 | ; equ 00100000b ; 91 | MF_ON_SLAVEPIC equ 01000000b ;Mouse is on slave PIC 92 | MF_MOUSE_EXISTS equ 10000000b ;Mouse was found at boot time 93 | 94 | 95 | ; Definitions of mouse types for mouse_type variable 96 | 97 | MT_NO_MOUSE equ 0 ;Zero only if MF_MOUSE_EXISTS = 0 98 | MT_BUS equ 1 99 | MT_SERIAL equ 2 100 | MT_INPORT equ 3 101 | MT_PS2 equ 4 102 | MT_HP equ 5 103 | 104 | ; Windows/386 mouse VxD device ID. 105 | 106 | VMD_DEVICE_ID equ 0000Ch 107 | 108 | 109 | display_int_size macro s 110 | if2 111 | %out size of interrupt handler is s bytes 112 | endif 113 | endm 114 | 115 | 116 | ; INT 33h (Mouse) Function Numbers 117 | 118 | MOUSE_SYS_VEC equ 33h ;Software int to call MOUSE.SYS driver 119 | CALL_ON_ANY_INT equ 7Fh ; Call us on any interrupt 120 | CLEAR_COUNTERS equ 11 ; Clear dX and dY counters 121 | BASH_INT_PROC equ 12 ; Overwrite the interrupt routine 122 | SWAP_INT_PROC equ 20 ; Swap interrupt routine 123 | INT33H_RESET equ 00 ; Reset mouse 124 | INT33H_ENABLE equ 32 ; Enable mouse 125 | INT33H_GETINFO equ 24h ; Get mouse information 126 | 127 | ; type of the mouse as reported by the INT 33H driver 128 | 129 | INT33H_BUS equ 1 ; bus mouse 130 | INT33H_SERIAL equ 2 ; bus mouse 131 | INT33H_INPORT equ 3 ; bus mouse 132 | INT33H_PS_2 equ 4 ; bus mouse 133 | INT33H_HP equ 5 ; bus mouse 134 | -------------------------------------------------------------------------------- /src/MOUSE.LNK: -------------------------------------------------------------------------------- 1 | mouse + 2 | int33h 3 | i33mouse.drv 4 | mouse/map/al:16 5 | libw /NOD 6 | mouse.def 7 | -------------------------------------------------------------------------------- /tools/link.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stsp/win31-mouse-driver/50aa69e2344f62e2d5980eb853b80735ea4d4da1/tools/link.exe -------------------------------------------------------------------------------- /tools/masm.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stsp/win31-mouse-driver/50aa69e2344f62e2d5980eb853b80735ea4d4da1/tools/masm.exe -------------------------------------------------------------------------------- /tools/nmake.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stsp/win31-mouse-driver/50aa69e2344f62e2d5980eb853b80735ea4d4da1/tools/nmake.exe -------------------------------------------------------------------------------- /tools/rc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stsp/win31-mouse-driver/50aa69e2344f62e2d5980eb853b80735ea4d4da1/tools/rc.exe --------------------------------------------------------------------------------