ReactOS 0.4.15-dev-7934-g1dc8d80
mouse32.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: subsystems/mvdm/ntvdm/dos/mouse32.c
5 * PURPOSE: VDM 32-bit compatible PS/2 MOUSE.COM driver
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include "ntvdm.h"
12
13#define NDEBUG
14#include <debug.h>
15
16/* Driver Version number and Copyright */
17#include <reactos/buildno.h>
18#include <reactos/version.h>
19
20#include "emulator.h"
21
22#include "cpu/cpu.h"
23#include "int32.h"
24#include "hardware/mouse.h"
25#include "hardware/ps2.h"
26#include "hardware/pic.h"
27#include "hardware/video/svga.h"
28
29#include "../console/video.h"
30
31
32#include "mouse32.h"
33#include "bios/bios.h"
34#include "bios/bios32/bios32p.h"
35
36#include "memory.h"
37#include "io.h"
38#include "dos32krnl/memory.h"
39
40/* PRIVATE VARIABLES **********************************************************/
41
42static const CHAR MouseCopyright[] =
43 "ReactOS PS/2 16/32-bit Mouse Driver Compatible MS-MOUSE 6.26\r\n"
44 "Version "KERNEL_VERSION_STR" (Build "KERNEL_VERSION_BUILD_STR")\r\n"
45 "Copyright (C) ReactOS Team 1996-"COPYRIGHT_YEAR"\0";
46
47#pragma pack(push, 1)
48
49typedef struct _MOUSE_DRIVER
50{
57
58#pragma pack(pop)
59
60/* Global data contained in guest memory */
64
65#define MICKEYS_PER_CELL_HORIZ 8
66#define MICKEYS_PER_CELL_VERT 16
67
72
74{
75 0xE7FF, // 1110011111111111
76 0xE3FF, // 1110001111111111
77 0xE1FF, // 1110000111111111
78 0xE0FF, // 1110000011111111
79 0xE07F, // 1110000001111111
80 0xE03F, // 1110000000111111
81 0xE01F, // 1110000000011111
82 0xE00F, // 1110000000001111
83 0xE007, // 1110000000000111
84 0xE007, // 1110000000000111
85 0xE03F, // 1110000000111111
86 0xE21F, // 1110001000011111
87 0xE61F, // 1110011000011111
88 0xFF0F, // 1111111100001111
89 0xFF0F, // 1111111100001111
90 0xFF8F, // 1111111110001111
91};
92
94{
95 0x0000, // 0000000000000000
96 0x0800, // 0000100000000000
97 0x0C00, // 0000110000000000
98 0x0E00, // 0000111000000000
99 0x0F00, // 0000111100000000
100 0x0F80, // 0000111110000000
101 0x0FC0, // 0000111111000000
102 0x0FE0, // 0000111111100000
103 0x0FF0, // 0000111111110000
104 0x0F80, // 0000111110000000
105 0x0D80, // 0000110110000000
106 0x08C0, // 0000100011000000
107 0x00C0, // 0000000011000000
108 0x0060, // 0000000001100000
109 0x0060, // 0000000001100000
110 0x0000, // 0000000000000000
111};
112
113/* PRIVATE FUNCTIONS **********************************************************/
114
115/* static */
117{
118 /* Save AX and BX */
119 USHORT AX = getAX();
120 // USHORT BX = getBX();
121
122 /*
123 * Set the parameters:
124 * AL contains the character to print (already set),
125 * BL contains the character attribute,
126 * BH contains the video page to use.
127 */
128 // setBL(DOS_CHAR_ATTRIBUTE);
129 // setBH(Bda->VideoPage);
131
132 /* Call the BIOS INT 15h, AH=C2h "Pointing Device BIOS Interface (PS)" */
133 setAH(0xC2);
135
136 /* Restore AX and BX */
137 // setBX(BX);
138 setAX(AX);
139}
140
141
142
143static VOID DosMouseEnable(VOID);
145
146
148{
149 if (Bda->VideoMode <= 3)
150 {
151 WORD Character;
152 WORD CellX = DriverState.Position.X / 8;
153 WORD CellY = DriverState.Position.Y / 8;
155
157 VideoAddress
158 + (CellY * Bda->ScreenColumns + CellX) * sizeof(WORD),
159 (LPVOID)&Character,
160 sizeof(WORD));
161
162 DriverState.Character = Character;
163 Character &= DriverState.TextCursor.ScreenMask;
164 Character ^= DriverState.TextCursor.CursorMask;
165
167 VideoAddress
168 + (CellY * Bda->ScreenColumns + CellX) * sizeof(WORD),
169 (LPVOID)&Character,
170 sizeof(WORD));
171 }
172 else if (Bda->VideoMode == 0x12)
173 {
174 INT i, j;
175 BYTE OldMask;
176 BYTE OldMap;
177
178 /* Save the write mask */
180 OldMask = IOReadB(VGA_SEQ_DATA);
181
182 /* And the selected reading plane */
184 OldMap = IOReadB(VGA_GC_DATA);
185
186 for (i = 0; i < 16; i++)
187 {
188 WORD CursorLine[4];
190 + ((DriverState.Position.Y + i) * 640 + DriverState.Position.X) / 8;
191
192 for (j = 0; j < 4; j++)
193 {
194 /* Select the reading plane */
197
198 /* Read a part of the scanline */
199 EmulatorReadMemory(&EmulatorContext, VideoAddress, &CursorLine[j], sizeof(CursorLine[j]));
200 }
201
202 /* Save the data below the cursor */
203 for (j = 0; j < 16; j++)
204 {
205 DriverState.GraphicsData[i * 16 + j] = 0;
206
207 if (CursorLine[0] & (1 << j)) DriverState.GraphicsData[i * 16 + j] |= 1 << 0;
208 if (CursorLine[1] & (1 << j)) DriverState.GraphicsData[i * 16 + j] |= 1 << 1;
209 if (CursorLine[2] & (1 << j)) DriverState.GraphicsData[i * 16 + j] |= 1 << 2;
210 if (CursorLine[3] & (1 << j)) DriverState.GraphicsData[i * 16 + j] |= 1 << 3;
211 }
212
213 for (j = 0; j < 4; j++)
214 {
215 /* Apply the screen mask */
216 CursorLine[j] &= MAKEWORD(HIBYTE(DriverState.GraphicsCursor.ScreenMask[i]),
217 LOBYTE(DriverState.GraphicsCursor.ScreenMask[i]));
218
219 /* And the cursor mask */
220 CursorLine[j] ^= MAKEWORD(HIBYTE(DriverState.GraphicsCursor.CursorMask[i]),
221 LOBYTE(DriverState.GraphicsCursor.CursorMask[i]));
222
223 /* Select the writing plane */
225 IOWriteB(VGA_SEQ_DATA, 1 << j);
226
227 /* Write the cursor data for this scanline */
228 EmulatorWriteMemory(&EmulatorContext, VideoAddress, &CursorLine[j], sizeof(CursorLine[j]));
229 }
230 }
231
232 /* Restore the old mask */
234 IOWriteB(VGA_SEQ_DATA, OldMask);
235
236 /* And the old reading plane */
238 IOWriteB(VGA_GC_DATA, OldMap);
239 }
240 else if (Bda->VideoMode == 0x13)
241 {
242 INT i, j;
243
244 for (i = 0; i < 16; i++)
245 {
246 BYTE CursorLine[16];
249
250 /* Read a part of the scanline */
252 VideoAddress,
254 sizeof(CursorLine));
255
256 for (j = 0; j < 16; j++)
257 {
258 /* Apply the screen mask by leaving only the masked pixels intact */
259 CursorLine[j] = (DriverState.GraphicsCursor.ScreenMask[i] & (1 << j))
261 : 0x00;
262
263 /* Apply the cursor mask... */
264 if (DriverState.GraphicsCursor.CursorMask[i] & (1 << j))
265 {
266 /* ... by inverting the color of each masked pixel */
267 CursorLine[j] ^= 0x0F;
268 }
269 }
270
271 /* Write the cursor data for this scanline */
272 EmulatorWriteMemory(&EmulatorContext, VideoAddress, &CursorLine, sizeof(CursorLine));
273 }
274 }
275 else
276 {
277 // TODO: NOT IMPLEMENTED
279 }
280}
281
283{
284 if (Bda->VideoMode <= 3)
285 {
286 WORD CellX = DriverState.Position.X / 8;
287 WORD CellY = DriverState.Position.Y / 8;
289
291 VideoAddress
292 + (CellY * Bda->ScreenColumns + CellX) * sizeof(WORD),
294 sizeof(WORD));
295 }
296 else if (Bda->VideoMode == 0x12)
297 {
298 INT i, j;
299 BYTE OldMask;
300
301 /* Save the write mask */
303 OldMask = IOReadB(VGA_SEQ_DATA);
304
305 for (i = 0; i < 16; i++)
306 {
307 WORD CursorLine[4] = {0};
309 + ((DriverState.Position.Y + i) * 640 + DriverState.Position.X) / 8;
310
311 /* Restore the data that was below the cursor */
312 for (j = 0; j < 16; j++)
313 {
314 if (DriverState.GraphicsData[i * 16 + j] & (1 << 0)) CursorLine[0] |= 1 << j;
315 if (DriverState.GraphicsData[i * 16 + j] & (1 << 1)) CursorLine[1] |= 1 << j;
316 if (DriverState.GraphicsData[i * 16 + j] & (1 << 2)) CursorLine[2] |= 1 << j;
317 if (DriverState.GraphicsData[i * 16 + j] & (1 << 3)) CursorLine[3] |= 1 << j;
318 }
319
320 for (j = 0; j < 4; j++)
321 {
322 /* Select the writing plane */
324 IOWriteB(VGA_SEQ_DATA, 1 << j);
325
326 /* Write the original data for this scanline */
327 EmulatorWriteMemory(&EmulatorContext, VideoAddress, &CursorLine[j], sizeof(CursorLine[j]));
328 }
329 }
330
331 /* Restore the old mask */
333 IOWriteB(VGA_SEQ_DATA, OldMask);
334 }
335 else if (Bda->VideoMode == 0x13)
336 {
337 INT i;
338
339 for (i = 0; i < 16; i++)
340 {
343
344 /* Write the original data for this scanline */
346 VideoAddress,
348 16 * sizeof(BYTE));
349 }
350 }
351 else
352 {
353 // TODO: NOT IMPLEMENTED
355 }
356}
357
359{
363
365 {
366 Resolution.X *= 8;
367 Resolution.Y *= 8;
368 }
369
372}
373
375{
379
381 {
382 Resolution.X *= 8;
383 Resolution.Y *= 8;
384 }
385
388}
389
391{
392 USHORT i;
393 USHORT AX, BX, CX, DX, BP, SI, DI, DS, ES;
395
397
398 /* Call handler 0 */
399 if ((DriverState.Handler0.CallMask & CallMask) != 0 &&
401 {
402 /*
403 * Set the parameters for the callback.
404 * NOTE: In text modes, the row and column will be reported
405 * as a multiple of the cell size, typically 8x8 pixels.
406 */
407
408 AX = getAX();
409 BX = getBX();
410 CX = getCX();
411 DX = getDX();
412 BP = getBP();
413 SI = getSI();
414 DI = getDI();
415 DS = getDS();
416 ES = getES();
417
418 setAX(CallMask);
424
425 DPRINT("Calling Handler0 %04X:%04X with CallMask 0x%04X\n",
428 CallMask);
429
430 /* Call the callback */
432
433 setAX(AX);
434 setBX(BX);
435 setCX(CX);
436 setDX(DX);
437 setBP(BP);
438 setSI(SI);
439 setDI(DI);
440 setDS(DS);
441 setES(ES);
442 }
443
444 for (i = 0; i < ARRAYSIZE(DriverState.Handlers); ++i)
445 {
446 /* Call the suitable handlers */
447 if ((DriverState.Handlers[i].CallMask & CallMask) != 0 &&
449 {
450 /*
451 * Set the parameters for the callback.
452 * NOTE: In text modes, the row and column will be reported
453 * as a multiple of the cell size, typically 8x8 pixels.
454 */
455
456 AX = getAX();
457 BX = getBX();
458 CX = getCX();
459 DX = getDX();
460 BP = getBP();
461 SI = getSI();
462 DI = getDI();
463 DS = getDS();
464 ES = getES();
465
466 setAX(CallMask);
472
473 DPRINT1("Calling Handler[%d] %04X:%04X with CallMask 0x%04X\n",
474 i,
477 CallMask);
478
479 /* Call the callback */
481
482 setAX(AX);
483 setBX(BX);
484 setCX(CX);
485 setDX(DX);
486 setBP(BP);
487 setSI(SI);
488 setDI(DI);
489 setDS(DS);
490 setES(ES);
491 }
492 }
493}
494
495static inline VOID DosUpdatePosition(PCOORD NewPosition)
496{
498
499 /* Check for text mode */
501 {
502 Resolution.X *= 8;
503 Resolution.Y *= 8;
504 }
505
507 DriverState.Position = *NewPosition;
509
510 /* Call the mouse handlers */
511 CallMouseUserHandlers(0x0001); // We use MS MOUSE v1.0+ format
512}
513
514static inline VOID DosUpdateButtons(BYTE ButtonState) // WORD ButtonState
515{
516 USHORT i;
517 USHORT CallMask = 0x0000; // We use MS MOUSE v1.0+ format
518
519 for (i = 0; i < NUM_MOUSE_BUTTONS; i++)
520 {
521 BOOLEAN OldState = (DriverState.ButtonState >> i) & 1;
522 BOOLEAN NewState = (ButtonState >> i) & 1;
523
524 if (NewState > OldState)
525 {
526 /* Mouse press */
529
530 CallMask |= (1 << (2 * i + 1));
531 }
532 else if (NewState < OldState)
533 {
534 /* Mouse release */
537
538 CallMask |= (1 << (2 * i + 2));
539 }
540 }
541
543
544 /* Call the mouse handlers */
545 CallMouseUserHandlers(CallMask);
546}
547
549{
550 BYTE Flags;
551 SHORT DeltaX, DeltaY;
554
555 /* Read the whole packet at once */
557 PS2PortQueueRead(1); // NOTE: Should be a IOReadB! But see r67231
558 DeltaX = IOReadB(PS2_DATA_PORT);
559 PS2PortQueueRead(1); // NOTE: Should be a IOReadB! But see r67231
560 DeltaY = IOReadB(PS2_DATA_PORT);
561
562 /* Adjust the sign */
563 if (Flags & MOUSE_X_SIGN) DeltaX = -DeltaX;
564 if (Flags & MOUSE_Y_SIGN) DeltaY = -DeltaY;
565
566 /* Update the counters */
567 DriverState.HorizCount += DeltaX;
568 DriverState.VertCount += DeltaY;
569
570 /*
571 * Get the absolute position directly from the mouse, this is the only
572 * way to perfectly synchronize the host and guest mouse pointer.
573 */
575
576 /* Call the update subroutines */
579
580 /* Complete the IRQ */
582}
583
585{
586 switch (getAX())
587 {
588 /* Reset Driver */
589 case 0x00:
590 {
591 SHORT i;
592
595
596 /* Initialize the default clipping range */
597 DriverState.MinX = 0;
599 DriverState.MinY = 0;
601
602 /* Set the default text cursor */
603 DriverState.TextCursor.ScreenMask = 0xFFFF; /* Display everything */
604 DriverState.TextCursor.CursorMask = 0xFF00; /* ... but with inverted attributes */
605
606 /* Set the default graphics cursor */
607 DriverState.GraphicsCursor.HotSpot.X = 3;
608 DriverState.GraphicsCursor.HotSpot.Y = 1;
609
612 sizeof(DriverState.GraphicsCursor.ScreenMask));
613
616 sizeof(DriverState.GraphicsCursor.CursorMask));
617
618 /* Initialize the counters */
620
621 for (i = 0; i < NUM_MOUSE_BUTTONS; i++)
622 {
624 }
625
626 /* Return mouse information */
627 setAX(0xFFFF); // Hardware & driver installed
629
630 break;
631 }
632
633 /* Show Mouse Cursor */
634 case 0x01:
635 {
638
639 break;
640 }
641
642 /* Hide Mouse Cursor */
643 case 0x02:
644 {
647
648 break;
649 }
650
651 /* Return Position and Button Status */
652 case 0x03:
653 {
656
660 break;
661 }
662
663 /* Position Mouse Cursor */
664 case 0x04:
665 {
666 COORD Position = { getCX(), getDX() };
668
670 break;
671 }
672
673 /* Return Button Press Data */
674 case 0x05:
675 {
676 WORD Button = getBX();
677 COORD LastPress = DriverState.LastPress[Button];
678 ToMouseCoordinates(&LastPress);
679
682 setCX(LastPress.X);
683 setDX(LastPress.Y);
684
685 /* Reset the counter */
687
688 break;
689 }
690
691 /* Return Button Release Data */
692 case 0x06:
693 {
694 WORD Button = getBX();
695 COORD LastRelease = DriverState.LastRelease[Button];
696 ToMouseCoordinates(&LastRelease);
697
700 setCX(LastRelease.X);
701 setDX(LastRelease.Y);
702
703 /* Reset the counter */
705
706 break;
707
708 }
709
710 /* Define Horizontal Cursor Range */
711 case 0x07:
712 {
713 WORD Min = getCX();
714 WORD Max = getDX();
715
717 {
718 /* Text mode */
719 Min &= ~0x07;
720 Max |= 0x07;
721 }
722
723 DPRINT("Setting mouse horizontal range: %u - %u\n", Min, Max);
726 break;
727 }
728
729 /* Define Vertical Cursor Range */
730 case 0x08:
731 {
732 WORD Min = getCX();
733 WORD Max = getDX();
734
736 {
737 /* Text mode */
738 Min &= ~0x07;
739 Max |= 0x07;
740 }
741
742 DPRINT("Setting mouse vertical range: %u - %u\n", Min, Max);
745 break;
746 }
747
748 /* Define Graphics Cursor */
749 case 0x09:
750 {
751 PWORD MaskBitmap = (PWORD)SEG_OFF_TO_PTR(getES(), getDX());
752
753 DriverState.GraphicsCursor.HotSpot.X = getBX();
754 DriverState.GraphicsCursor.HotSpot.Y = getCX();
755
757 MaskBitmap,
758 sizeof(DriverState.GraphicsCursor.ScreenMask));
759
761 &MaskBitmap[16],
762 sizeof(DriverState.GraphicsCursor.CursorMask));
763
764 break;
765 }
766
767 /* Define Text Cursor */
768 case 0x0A:
769 {
770 USHORT BX = getBX();
771
772 if (BX == 0x0000)
773 {
774 /* Define software cursor */
775 DriverState.TextCursor.ScreenMask = getCX();
776 DriverState.TextCursor.CursorMask = getDX();
777 }
778 else if (BX == 0x0001)
779 {
780 /* Define hardware cursor */
781 DPRINT1("Defining hardware cursor is unimplemented\n");
783 // CX == start scan line
784 // DX == end scan line
785 }
786 else
787 {
788 DPRINT1("Invalid BX value 0x%04X\n", BX);
789 }
790
791 break;
792 }
793
794 /* Read Motion Counters */
795 case 0x0B:
796 {
799
800 /* Reset the counters */
802
803 break;
804 }
805
806 /* Define Interrupt Subroutine Parameters, compatible MS MOUSE v1.0+ */
807 case 0x0C:
808 {
810 DriverState.Handler0.Callback = MAKELONG(getDX(), getES()); // Far pointer to the callback
811 DPRINT1("Define callback 0x%04X, %04X:%04X\n",
815 break;
816 }
817
818 /* Define Mickey/Pixel Ratio */
819 case 0x0F:
820 {
821 /* This call should be completely ignored */
822 break;
823 }
824
825 /* Set Exclusion Area */
826 // http://www.ctyme.com/intr/rb-5972.htm
827 // http://www.techhelpmanual.com/849-int_33h_0010h__set_exclusion_area.html
828 //case 0x10:
829 //{
830 //}
831
832 /* Define Double-Speed Threshold */
833 case 0x13:
834 {
835 DPRINT1("INT 33h, AH=13h: Mouse double-speed threshold is UNSUPPORTED\n");
836 break;
837 }
838
839 /* Exchange Interrupt Subroutines, compatible MS MOUSE v3.0+ (see function 0x0C) */
840 case 0x14:
841 {
842 USHORT OldCallMask = DriverState.Handler0.CallMask;
843 ULONG OldCallback = DriverState.Handler0.Callback;
844
846 DriverState.Handler0.Callback = MAKELONG(getDX(), getES()); // Far pointer to the callback
847 DPRINT1("Exchange old callback 0x%04X, %04X:%04X with new callback 0x%04X, %04X:%04X\n",
848 OldCallMask,
849 HIWORD(OldCallback),
850 LOWORD(OldCallback),
854
855 /* Return old callmask in CX and callback vector in ES:DX */
856 setCX(OldCallMask);
857 setES(HIWORD(OldCallback));
858 setDX(LOWORD(OldCallback));
859 break;
860 }
861
862 /* Return Driver Storage Requirements */
863 case 0x15:
864 {
865 setBX(sizeof(MOUSE_DRIVER_STATE));
866 break;
867 }
868
869 /* Save Driver State */
870 case 0x16:
871 {
872 /* Check whether the user buffer has correct size and fail if not */
873 if (getBX() != sizeof(MOUSE_DRIVER_STATE)) break;
874
876 break;
877 }
878
879 /* Restore Driver State */
880 case 0x17:
881 {
882 /* Check whether the user buffer has correct size and fail if not */
883 if (getBX() != sizeof(MOUSE_DRIVER_STATE)) break;
884
886 break;
887 }
888
889 /* Set Alternate Mouse User Handler, compatible MS MOUSE v6.0+ */
890 case 0x18:
891 {
892 /*
893 * Up to three handlers can be defined by separate calls to this
894 * function, each with a different combination of shift states in
895 * the call mask; calling this function again with a call mask of
896 * 0000h undefines the specified handler (official documentation);
897 * specifying the same call mask and an address of 0000h:0000h
898 * undefines the handler (real life).
899 * See Ralf Brown: http://www.ctyme.com/intr/rb-5981.htm
900 * for more information.
901 */
902
903 USHORT i;
904 USHORT CallMask = getCX();
905 ULONG Callback = MAKELONG(getDX(), getES()); // Far pointer to the callback
907
908 DPRINT1("Define v6.0+ callback 0x%04X, %04X:%04X\n",
909 CallMask, HIWORD(Callback), LOWORD(Callback));
910
911 if (CallMask == 0x0000)
912 {
913 /*
914 * Find the handler entry corresponding to the given
915 * callback and undefine it.
916 */
917 for (i = 0; i < ARRAYSIZE(DriverState.Handlers); ++i)
918 {
920 {
921 /* Found it, undefine the handler */
922 DriverState.Handlers[i].CallMask = 0x0000;
924 Success = TRUE;
925 break;
926 }
927 }
928 }
929 else if (Callback == NULL32)
930 {
931 /*
932 * Find the handler entry corresponding to the given
933 * callmask and undefine it.
934 */
935 for (i = 0; i < ARRAYSIZE(DriverState.Handlers); ++i)
936 {
937 if (DriverState.Handlers[i].CallMask == CallMask)
938 {
939 /* Found it, undefine the handler */
940 DriverState.Handlers[i].CallMask = 0x0000;
942 Success = TRUE;
943 break;
944 }
945 }
946 }
947 else
948 {
949 /*
950 * Try to find a handler entry corresponding to the given
951 * callmask to redefine it, otherwise find an empty handler
952 * entry and set the new handler in there.
953 */
954
955 USHORT EmptyHandler = 0xFFFF; // Invalid handler
956
957 for (i = 0; i < ARRAYSIZE(DriverState.Handlers); ++i)
958 {
959 /* Find the first empty handler */
960 if (EmptyHandler == 0xFFFF &&
961 DriverState.Handlers[i].CallMask == 0x0000 &&
963 {
964 EmptyHandler = i;
965 }
966
967 if (DriverState.Handlers[i].CallMask == CallMask)
968 {
969 /* Found it, redefine the handler */
970 DriverState.Handlers[i].CallMask = CallMask;
972 Success = TRUE;
973 break;
974 }
975 }
976
977 /*
978 * If we haven't found anything and we found
979 * an empty handler, set it.
980 */
981 if (!Success && EmptyHandler != 0xFFFF
982 /* && EmptyHandler < ARRAYSIZE(DriverState.Handlers) */)
983 {
984 DriverState.Handlers[EmptyHandler].CallMask = CallMask;
985 DriverState.Handlers[EmptyHandler].Callback = Callback;
986 Success = TRUE;
987 }
988 }
989
990 /* If we failed, set error code */
991 if (!Success) setAX(0xFFFF);
992
993 break;
994 }
995
996 /* Return User Alternate Interrupt Vector, compatible MS MOUSE v6.0+ */
997 case 0x19:
998 {
999 USHORT i;
1000 USHORT CallMask = getCX();
1003
1004 /*
1005 * Find the handler entry corresponding to the given callmask.
1006 */
1007 for (i = 0; i < ARRAYSIZE(DriverState.Handlers); ++i)
1008 {
1009 if (DriverState.Handlers[i].CallMask == CallMask)
1010 {
1011 /* Found it */
1013 Success = TRUE;
1014 break;
1015 }
1016 }
1017
1018 if (Success)
1019 {
1020 /* Return the callback vector in BX:DX */
1023 }
1024 else
1025 {
1026 /* We failed, set error code */
1027 setCX(0x0000);
1028 }
1029
1030 break;
1031 }
1032
1033 /* Set Mouse Sensitivity */
1034 case 0x1A:
1035 {
1036 DPRINT1("INT 33h, AH=1Ah: Mouse sensitivity is UNSUPPORTED\n");
1037
1038 // FIXME: Do that at runtime!
1039
1040 // UCHAR BH = getBH();
1041 // setBH(0x00);
1042 // BiosPs2Service(0x00);
1043 // FIXME: Check for return status in AH and CF
1044 // setBH(BH);
1045
1046 break;
1047 }
1048
1049 /* Return Mouse Sensitivity */
1050 case 0x1B:
1051 {
1052 DPRINT1("INT 33h, AH=1Bh: Mouse sensitivity is UNSUPPORTED\n");
1053
1054 /* Return default values */
1055 setBX(50); // Horizontal speed
1056 setCX(50); // Vertical speed
1057 setDX(50); // Double speed threshold
1058
1059 // FIXME: Get that at runtime!
1060
1061 // UCHAR BH = getBH();
1062 // setBH(0x00);
1063 // BiosPs2Service(0x00);
1064 // FIXME: Check for return status in AH and CF
1065 // setBH(BH);
1066
1067 break;
1068 }
1069
1070 /* Disable Mouse Driver */
1071 case 0x1F:
1072 {
1073 /* INT 33h vector before the mouse driver was first installed */
1076
1078 // UCHAR BH = getBH();
1079 // setBH(0x00);
1080 // BiosPs2Service(0x00);
1081 // FIXME: Check for return status in AH and CF
1082 // setBH(BH);
1083 break;
1084 }
1085
1086 /* Enable Mouse Driver */
1087 case 0x20:
1088 {
1090 // UCHAR BH = getBH();
1091 // setBH(0x01);
1092 // BiosPs2Service(0x00);
1093 // FIXME: Check for return status in AH and CF
1094 // setBH(BH);
1095 break;
1096 }
1097
1098 /* Software Reset */
1099 case 0x21:
1100 {
1101 /*
1102 * See: http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte3sq8.htm
1103 * for detailed information and differences with respect to subfunction 0x00:
1104 * http://www.htl-steyr.ac.at/~morg/pcinfo/hardware/interrupts/inte3j74.htm
1105 */
1106
1107 SHORT i;
1108
1111
1112 /* Initialize the default clipping range */
1113 DriverState.MinX = 0;
1115 DriverState.MinY = 0;
1117
1118 /* Initialize the counters */
1120
1121 for (i = 0; i < NUM_MOUSE_BUTTONS; i++)
1122 {
1124 }
1125
1126 /* Return mouse information */
1127 setAX(0xFFFF); // Hardware & driver installed
1129
1130 break;
1131 }
1132
1133 /* Get Software Version, Mouse Type, and IRQ Number, compatible MS MOUSE v6.26+ */
1134 case 0x24:
1135 {
1136 setBX(MOUSE_VERSION); // Version Number
1137
1138 /*
1139 * See Ralf Brown: http://www.ctyme.com/intr/rb-5993.htm
1140 * for the list of possible values.
1141 */
1142 // FIXME: To be determined at runtime!
1143 setCH(0x04); // PS/2 Type
1144 setCL(0x00); // PS/2 Interrupt
1145
1146 break;
1147 }
1148
1149 // BIOS Function INT 33h, AX = 0x0025 NOT IMPLEMENTED
1150 case 0x25:
1151 {
1152 setAX(0);
1153 setBX(0);
1154 setCX(0);
1155 setDX(0);
1157 break;
1158 }
1159
1160 /* Get Maximum Virtual Coordinates */
1161 case 0x26:
1162 {
1164 // FIXME: In fact the MaxX and MaxY here are
1165 // theoretical values for the current video mode.
1166 // They therefore can be different from the current
1167 // min/max values.
1168 // See http://www.ctyme.com/intr/rb-5995.htm
1169 // for more details.
1172 break;
1173 }
1174
1175 /* Get Current Minimum/Maximum Virtual Coordinates */
1176 case 0x31:
1177 {
1182 break;
1183 }
1184
1185#if 0
1186 case 0x33:
1187 {
1188 /*
1189 * Related to http://www.ctyme.com/intr/rb-5985.htm
1190 * INT 33h, AX=001Ch "SET INTERRUPT RATE":
1191
1192 * Values for mouse interrupt rate:
1193 * BX = rate
1194 00h no interrupts allowed
1195 01h 30 per second
1196 02h 50 per second
1197 03h 100 per second
1198 04h 200 per second
1199 */
1200 }
1201#endif
1202
1203 /* Return Pointer to Copyright String */
1204 case 0x4D:
1205 {
1207 setDI(FIELD_OFFSET(MOUSE_DRIVER, Copyright));
1208 break;
1209 }
1210
1211 /* Get Version String (pointer) */
1212 case 0x6D:
1213 {
1214 /*
1215 * The format of the version "string" is:
1216 * Offset Size Description
1217 * 00h BYTE major version
1218 * 01h BYTE minor version (BCD)
1219 */
1222 break;
1223 }
1224
1225 default:
1226 {
1227 DPRINT1("BIOS Function INT 33h, AX = 0x%04X NOT IMPLEMENTED\n", getAX());
1228 }
1229 }
1230}
1231
1232/* PUBLIC FUNCTIONS ***********************************************************/
1233
1234static
1236{
1237 if (DriverEnabled) return;
1238
1240
1241 /* Get the old IRQ handler */
1243
1244 /* Set the IRQ handler */
1247}
1248
1249static
1251{
1252 if (!DriverEnabled) return;
1253
1254 /* Restore the old IRQ handler */
1256
1258}
1259
1261{
1262 /* Initialize some memory for storing our data that should be available to DOS */
1264 if (MouseDataSegment == 0) return FALSE;
1266
1267 /* Initialize the callback context */
1269
1270 /* Clear the state */
1272
1273 /* Mouse Driver Copyright */
1275
1276 /* Mouse Driver Version in BCD format, compatible MS-MOUSE */
1278
1279 /* Get the old mouse service interrupt handler */
1281
1282 /* Initialize the interrupt handler */
1285
1287 // UCHAR BH = getBH();
1288 // setBH(0x01);
1289 // BiosPs2Service(0x00);
1290 // FIXME: Check for return status in AH and CF
1291 // setBH(BH);
1292
1293 return TRUE;
1294}
1295
1297{
1300 // UCHAR BH = getBH();
1301 // setBH(0x00);
1302 // BiosPs2Service(0x00);
1303 // FIXME: Check for return status in AH and CF
1304 // setBH(BH);
1305
1306 /* Restore the old mouse service interrupt handler */
1308
1310 MouseDataSegment = 0;
1311 MouseData = 0;
1312}
1313
1314/* EOF */
unsigned char BOOLEAN
@ DS
Definition: amd64_sup.c:16
#define DPRINT1
Definition: precomp.h:8
VOID PicIRQComplete(BYTE IntNum)
Definition: bios32.c:816
#define BIOS_MISC_INTERRUPT
Definition: bios32p.h:25
#define UNIMPLEMENTED
Definition: debug.h:115
#define Max(a, b)
Definition: cdprocs.h:78
#define Min(a, b)
Definition: cdprocs.h:74
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
ButtonState
Definition: button.c:144
#define TO_LINEAR(seg, off)
Definition: emulator.h:26
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:32
#define NULL32
Definition: emulator.h:21
@ Success
Definition: eventcreate.c:712
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define DX
Definition: i386-dis.c:425
#define AX
Definition: i386-dis.c:424
ULONG RegisterInt32(IN ULONG FarPtr, IN BYTE IntNumber, IN EMULATOR_INT32_PROC IntHandler, OUT PSIZE_T CodeSize OPTIONAL)
Definition: int32.c:118
VOID Int32Call(IN PCALLBACK16 Context, IN BYTE IntNumber)
Definition: int32.c:151
#define Int16To32StubSize
Definition: int32.h:38
#define STACK_INT_NUM
Definition: int32.h:30
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
@ ES
Definition: bidi.c:78
#define MOUSE_IRQ_INT
Definition: moubios32.c:31
static VOID DosUpdatePosition(PCOORD NewPosition)
Definition: mouse32.c:495
static MOUSE_DRIVER_STATE DriverState
Definition: mouse32.c:69
static VOID DosUpdateButtons(BYTE ButtonState)
Definition: mouse32.c:514
static BOOLEAN DriverEnabled
Definition: mouse32.c:68
static VOID WINAPI DosMouseService(LPWORD Stack)
Definition: mouse32.c:584
static VOID DosMouseDisable(VOID)
Definition: mouse32.c:1250
static DWORD OldIrqHandler
Definition: mouse32.c:70
static const CHAR MouseCopyright[]
Definition: mouse32.c:42
static VOID EraseMouseCursor(VOID)
Definition: mouse32.c:282
#define MICKEYS_PER_CELL_HORIZ
Definition: mouse32.c:65
VOID BiosPs2Service(UCHAR Function)
Definition: mouse32.c:116
static DWORD OldIntHandler
Definition: mouse32.c:71
static VOID ToMouseCoordinates(PCOORD Position)
Definition: mouse32.c:358
static VOID WINAPI DosMouseIrq(LPWORD Stack)
Definition: mouse32.c:548
static PMOUSE_DRIVER MouseData
Definition: mouse32.c:62
#define MICKEYS_PER_CELL_VERT
Definition: mouse32.c:66
BOOLEAN DosMouseInitialize(VOID)
Definition: mouse32.c:1260
static WORD DefaultGfxCursorMask[16]
Definition: mouse32.c:93
static WORD MouseDataSegment
Definition: mouse32.c:61
static VOID FromMouseCoordinates(PCOORD Position)
Definition: mouse32.c:374
struct _MOUSE_DRIVER * PMOUSE_DRIVER
struct _MOUSE_DRIVER MOUSE_DRIVER
static VOID CallMouseUserHandlers(USHORT CallMask)
Definition: mouse32.c:390
VOID DosMouseCleanup(VOID)
Definition: mouse32.c:1296
static CALLBACK16 MouseContext
Definition: mouse32.c:63
static WORD DefaultGfxScreenMask[16]
Definition: mouse32.c:73
static VOID PaintMouseCursor(VOID)
Definition: mouse32.c:147
static VOID DosMouseEnable(VOID)
Definition: mouse32.c:1235
#define MOUSE_MAX_VERT
Definition: mouse32.h:22
@ NUM_MOUSE_BUTTONS
Definition: mouse32.h:29
#define MOUSE_VERSION
Definition: mouse32.h:17
#define DOS_MOUSE_INTERRUPT
Definition: mouse32.h:19
struct _MOUSE_DRIVER_STATE MOUSE_DRIVER_STATE
struct _MOUSE_DRIVER_STATE * PMOUSE_DRIVER_STATE
#define MOUSE_MAX_HORIZ
Definition: mouse32.h:21
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define LOWORD(l)
Definition: pedump.c:82
WORD * PWORD
Definition: pedump.c:67
DWORD * PDWORD
Definition: pedump.c:68
short SHORT
Definition: pedump.c:59
unsigned short USHORT
Definition: pedump.c:61
BOOLEAN PS2PortQueueRead(BYTE PS2Port)
Definition: ps2.c:415
#define PS2_DATA_PORT
Definition: ps2.h:16
#define DPRINT
Definition: sndvol32.h:71
WORD VideoPageSize
Definition: bios.h:61
BYTE VideoMode
Definition: bios.h:59
BYTE VideoPage
Definition: bios.h:66
WORD ScreenColumns
Definition: bios.h:60
Definition: window.h:573
Definition: bl.h:1338
ULONG Y
Definition: bl.h:1340
ULONG X
Definition: bl.h:1339
struct _MOUSE_DRIVER_STATE::@5061 TextCursor
MOUSE_USER_HANDLER Handlers[3]
Definition: mouse32.h:60
COORD LastRelease[NUM_MOUSE_BUTTONS]
Definition: mouse32.h:51
MOUSE_USER_HANDLER Handler0
Definition: mouse32.h:59
WORD PressCount[NUM_MOUSE_BUTTONS]
Definition: mouse32.h:48
COORD LastPress[NUM_MOUSE_BUTTONS]
Definition: mouse32.h:49
BYTE GraphicsData[256]
Definition: mouse32.h:75
struct _MOUSE_DRIVER_STATE::@5062 GraphicsCursor
WORD ReleaseCount[NUM_MOUSE_BUTTONS]
Definition: mouse32.h:50
BYTE MouseDosInt16Stub[Int16To32StubSize]
Definition: mouse32.c:54
BYTE MouseContextScratch[TRAMPOLINE_SIZE]
Definition: mouse32.c:53
BYTE MouseIrqInt16Stub[Int16To32StubSize]
Definition: mouse32.c:55
WORD Version
Definition: mouse32.c:52
CHAR Copyright[sizeof(MouseCopyright)]
Definition: mouse32.c:51
PBIOS_DATA_AREA Bda
Definition: bios.c:42
BOOLEAN VgaGetDoubleVisionState(PBOOLEAN Horizontal, PBOOLEAN Vertical)
Definition: video.c:488
VOID InitializeContext(IN PCALLBACK16 Context, IN USHORT Segment, IN USHORT Offset)
Definition: callback.c:60
VOID RunCallback16(IN PCALLBACK16 Context, IN ULONG FarPtr)
Definition: callback.c:93
#define TRAMPOLINE_SIZE
Definition: callback.h:24
FAST486_STATE EmulatorContext
Definition: cpu.c:39
WORD DosAllocateMemory(WORD Size, WORD *MaxAvailable)
Definition: memory.c:136
BOOLEAN DosFreeMemory(WORD BlockData)
Definition: memory.c:418
static BYTE Resolution
Definition: mouse.c:35
VOID MouseGetDataFast(PCOORD CurrentPosition, PBYTE CurrentButtonState)
Definition: mouse.c:419
static COORD Position
Definition: mouse.c:34
#define MOUSE_X_SIGN
Definition: mouse.h:22
#define MOUSE_Y_SIGN
Definition: mouse.h:23
VOID IOWriteB(USHORT Port, UCHAR Buffer)
Definition: io.c:111
UCHAR IOReadB(USHORT Port)
Definition: io.c:64
VOID FASTCALL EmulatorReadMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:142
VOID FASTCALL EmulatorWriteMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:186
COORD VgaGetDisplayResolution(VOID)
Definition: svga.c:1727
#define VGA_SEQ_DATA
Definition: svga.h:56
#define VGA_GC_DATA
Definition: svga.h:69
#define VGA_SEQ_INDEX
Definition: svga.h:55
@ VGA_SEQ_MASK_REG
Definition: svga.h:133
@ VGA_GC_READ_MAP_SEL_REG
Definition: svga.h:272
#define VGA_GC_INDEX
Definition: svga.h:68
#define MAKEWORD(a, b)
Definition: typedefs.h:248
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint16_t * LPWORD
Definition: typedefs.h:56
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MAKELONG(a, b)
Definition: typedefs.h:249
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
_In_ HFONT _Out_ PUINT _Out_ PUINT Width
Definition: font.h:89
_In_ HFONT _Out_ PUINT Height
Definition: font.h:88
VOID WINAPI setBX(USHORT)
Definition: registers.c:177
VOID WINAPI setCX(USHORT)
Definition: registers.c:235
VOID WINAPI setCH(UCHAR)
Definition: registers.c:249
VOID WINAPI setDX(USHORT)
Definition: registers.c:293
USHORT WINAPI getBX(VOID)
Definition: registers.c:170
VOID WINAPI setAL(UCHAR)
Definition: registers.c:149
USHORT WINAPI getDS(VOID)
Definition: registers.c:508
VOID WINAPI setAH(UCHAR)
Definition: registers.c:135
USHORT WINAPI getCX(VOID)
Definition: registers.c:228
USHORT WINAPI getSI(VOID)
Definition: registers.c:404
USHORT WINAPI getDX(VOID)
Definition: registers.c:286
VOID WINAPI setDS(USHORT)
Definition: registers.c:515
USHORT WINAPI getAX(VOID)
Definition: registers.c:114
USHORT WINAPI getES(VOID)
Definition: registers.c:522
USHORT WINAPI getBP(VOID)
Definition: registers.c:374
USHORT WINAPI getDI(VOID)
Definition: registers.c:434
VOID WINAPI setBP(USHORT)
Definition: registers.c:381
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
VOID WINAPI setES(USHORT)
Definition: registers.c:529
VOID WINAPI setCL(UCHAR)
Definition: registers.c:263
VOID WINAPI setSI(USHORT)
Definition: registers.c:411
VOID WINAPI setDI(USHORT)
Definition: registers.c:441
#define GRAPHICS_VIDEO_SEG
Definition: vidbios.h:23
#define TEXT_VIDEO_SEG
Definition: vidbios.h:24
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
#define WINAPI
Definition: msvc.h:6
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
unsigned char UCHAR
Definition: xmlstorage.h:181
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193