ReactOS  0.4.13-dev-651-g5dbc677
moubios32.c File Reference
#include "ntvdm.h"
#include <debug.h>
#include "emulator.h"
#include "cpu/cpu.h"
#include "moubios32.h"
#include "bios32p.h"
#include "io.h"
#include "hardware/mouse.h"
#include "hardware/ps2.h"
Include dependency graph for moubios32.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MOUSE_IRQ_INT   0x74
 

Functions

static VOID DisableMouseInt (VOID)
 
static VOID EnableMouseInt (VOID)
 
static VOID SendMouseCommand (UCHAR Command)
 
static UCHAR ReadMouseData (VOID)
 
static VOID BiosMouseEnable (VOID)
 
static VOID BiosMouseDisable (VOID)
 
static VOID WINAPI BiosMouseIrq (LPWORD Stack)
 
VOID BiosMousePs2Interface (LPWORD Stack)
 
VOID MouseBios32Post (VOID)
 
BOOLEAN MouseBiosInitialize (VOID)
 
VOID MouseBios32Cleanup (VOID)
 

Variables

static BOOLEAN MouseEnabled = FALSE
 
static DWORD OldIrqHandler
 
static ULONG DeviceHandler = 0
 

Macro Definition Documentation

◆ MOUSE_IRQ_INT

#define MOUSE_IRQ_INT   0x74

Definition at line 31 of file moubios32.c.

◆ NDEBUG

#define NDEBUG

Definition at line 16 of file moubios32.c.

Function Documentation

◆ BiosMouseDisable()

static VOID BiosMouseDisable ( VOID  )
static

Definition at line 115 of file moubios32.c.

116 {
117  if (!MouseEnabled) return;
118 
119  /* Restore the old IRQ handler */
120  // ((PDWORD)BaseAddress)[MOUSE_IRQ_INT] = OldIrqHandler;
121 
123 }
static BOOLEAN MouseEnabled
Definition: moubios32.c:33

Referenced by BiosMousePs2Interface().

◆ BiosMouseEnable()

static VOID BiosMouseEnable ( VOID  )
static

Definition at line 100 of file moubios32.c.

101 {
102  if (MouseEnabled) return;
103 
104  MouseEnabled = TRUE;
105 
106  /* Get the old IRQ handler */
108 
109  /* Set the IRQ handler */
110  //RegisterInt32(MAKELONG(FIELD_OFFSET(MOUSE_DRIVER, MouseIrqInt16Stub), MouseDataSegment),
111  // MOUSE_IRQ_INT, DosMouseIrq, NULL);
112 }
#define TRUE
Definition: types.h:120
#define MOUSE_IRQ_INT
Definition: moubios32.c:31
static BOOLEAN MouseEnabled
Definition: moubios32.c:33
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
DWORD * PDWORD
Definition: pedump.c:68
static DWORD OldIrqHandler
Definition: moubios32.c:34

Referenced by BiosMousePs2Interface().

◆ BiosMouseIrq()

static VOID WINAPI BiosMouseIrq ( LPWORD  Stack)
static

Definition at line 127 of file moubios32.c.

128 {
129  DPRINT1("PS/2 Mouse IRQ! DeviceHandler = 0x%04X:0x%04X\n",
131 
132  if (DeviceHandler != 0)
133  {
134  /*
135  * Prepare the stack for the mouse device handler:
136  * push Status, X and Y data, and a zero word.
137  */
138  setSP(getSP() - sizeof(WORD));
139  *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = 0; // Status
140  setSP(getSP() - sizeof(WORD));
141  *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = 0; // X data (high byte = 0)
142  setSP(getSP() - sizeof(WORD));
143  *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = 0; // Y data (high byte = 0)
144  setSP(getSP() - sizeof(WORD));
145  *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = 0; // Zero
146 
147  /* Call the device handler */
149 
150  /* Pop the stack */
151  setSP(getSP() + 4*sizeof(WORD));
152  }
153 
155 }
#define STACK_INT_NUM
Definition: int32.h:30
#define LOBYTE(W)
Definition: jmemdos.c:487
USHORT WINAPI getSS(VOID)
Definition: registers.c:494
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
VOID WINAPI setSP(USHORT)
Definition: registers.c:351
VOID PicIRQComplete(BYTE IntNum)
Definition: bios32.c:812
CALLBACK16 BiosContext
Definition: bios32.c:45
unsigned short WORD
Definition: ntddk_ex.h:93
uint16_t * LPWORD
Definition: typedefs.h:54
#define DPRINT1
Definition: precomp.h:8
VOID RunCallback16(IN PCALLBACK16 Context, IN ULONG FarPtr)
Definition: callback.c:93
static ULONG DeviceHandler
Definition: moubios32.c:44
#define HIWORD(l)
Definition: typedefs.h:246
USHORT WINAPI getSP(VOID)
Definition: registers.c:344
#define LOWORD(l)
Definition: pedump.c:82

Referenced by MouseBios32Post().

◆ BiosMousePs2Interface()

VOID BiosMousePs2Interface ( LPWORD  Stack)

Definition at line 157 of file moubios32.c.

158 {
159  /* Disable mouse interrupt and events */
160  DisableMouseInt();
161 
162  switch (getAL())
163  {
164  /* Enable / Disable */
165  case 0x00:
166  {
167  UCHAR State = getBH();
168 
169  if (State > 2)
170  {
171  /* Invalid function */
172  setAH(0x01);
173  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
174  break;
175  }
176 
177  if (State == 0x00)
178  {
180 
181  /* Disable packet reporting */
182  SendMouseCommand(0xF5);
183  }
184  else // if (State == 0x01)
185  {
186  /* Check for the presence of the device handler */
187  if (DeviceHandler == 0)
188  {
189  /* No device handler installed */
190  setAH(0x05);
191  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
192  break;
193  }
194 
195  BiosMouseEnable();
196 
197  /* Enable packet reporting */
198  SendMouseCommand(0xF4);
199  }
200 
201  if (ReadMouseData() != MOUSE_ACK)
202  {
203  /* Failure */
204  setAH(0x03);
205  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
206  break;
207  }
208 
209  /* Success */
210  setAH(0x00);
211  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
212  break;
213  }
214 
215  /* Initialize */
216  case 0x05:
217  {
218  // Fall through
219  }
220 
221  /* Reset */
222  case 0x01:
223  {
224  UCHAR Answer;
225 
226  SendMouseCommand(0xFF);
227  Answer = ReadMouseData();
228  /* A "Resend" signal (0xFE) is sent if no mouse is attached */
229  if (Answer == 0xFE)
230  {
231  /* Resend */
232  setAH(0x04);
233  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
234  break;
235  }
236  else if (Answer != MOUSE_ACK)
237  {
238  /* Failure */
239  setAH(0x03);
240  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
241  break;
242  }
243 
244  setBL(ReadMouseData()); // Should be MOUSE_BAT_SUCCESS
245  setBH(ReadMouseData()); // Mouse ID
246 
247  /* Success */
248  setAH(0x00);
249  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
250  break;
251  }
252 
253  /* Set Sampling Rate */
254  case 0x02:
255  {
256  UCHAR SampleRate = 0;
257 
258  switch (getBH())
259  {
260  case 0x00: SampleRate = 10; break; // 10 reports/sec
261  case 0x01: SampleRate = 20; break; // 20 " "
262  case 0x02: SampleRate = 40; break; // 40 " "
263  case 0x03: SampleRate = 60; break; // 60 " "
264  case 0x04: SampleRate = 80; break; // 80 " "
265  case 0x05: SampleRate = 100; break; // 100 " "
266  case 0x06: SampleRate = 200; break; // 200 " "
267  default: SampleRate = 0;
268  }
269 
270  if (SampleRate == 0)
271  {
272  /* Invalid input */
273  setAH(0x02);
274  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
275  break;
276  }
277 
278  SendMouseCommand(0xF3);
279  if (ReadMouseData() != MOUSE_ACK)
280  {
281  /* Failure */
282  setAH(0x03);
283  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
284  break;
285  }
286 
287  SendMouseCommand(SampleRate);
288  if (ReadMouseData() != MOUSE_ACK)
289  {
290  /* Failure */
291  setAH(0x03);
292  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
293  break;
294  }
295 
296  /* Success */
297  setAH(0x00);
298  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
299  break;
300  }
301 
302  /* Set Resolution */
303  case 0x03:
304  {
305  UCHAR Resolution = getBH();
306 
307  /*
308  * 0: 25 dpi, 1 count per millimeter
309  * 1: 50 dpi, 2 counts per millimeter
310  * 2: 100 dpi, 4 counts per millimeter
311  * 3: 200 dpi, 8 counts per millimeter
312  */
313  if (Resolution > 3)
314  {
315  /* Invalid input */
316  setAH(0x02);
317  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
318  break;
319  }
320 
321  SendMouseCommand(0xE8);
322  if (ReadMouseData() != MOUSE_ACK)
323  {
324  /* Failure */
325  setAH(0x03);
326  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
327  break;
328  }
329 
331  if (ReadMouseData() != MOUSE_ACK)
332  {
333  /* Failure */
334  setAH(0x03);
335  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
336  break;
337  }
338 
339  /* Success */
340  setAH(0x00);
341  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
342  break;
343  }
344 
345  /* Get Type */
346  case 0x04:
347  {
348  SendMouseCommand(0xF2);
349  if (ReadMouseData() != MOUSE_ACK)
350  {
351  /* Failure */
352  setAH(0x03);
353  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
354  break;
355  }
356 
357  setBH(ReadMouseData());
358 
359  /* Success */
360  setAH(0x00);
361  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
362  break;
363  }
364 
365  /* Extended Commands (Return Status and Set Scaling Factor) */
366  case 0x06:
367  {
368  UCHAR Command = getBH();
369 
370  switch (Command)
371  {
372  /* Return Status */
373  case 0x00:
374  {
375  SendMouseCommand(0xE9);
376  if (ReadMouseData() != MOUSE_ACK)
377  {
378  /* Failure */
379  setAH(0x03);
380  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
381  break;
382  }
383 
384  setBL(ReadMouseData()); // Status
385  setCL(ReadMouseData()); // Resolution
386  setDL(ReadMouseData()); // Sample rate
387 
388  /* Success */
389  setAH(0x00);
390  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
391  break;
392  }
393 
394  /* Set Scaling Factor to 1:1 */
395  case 0x01:
396  /* Set Scaling Factor to 2:1 */
397  case 0x02:
398  {
399  SendMouseCommand(Command == 0x01 ? 0xE6 : 0xE7);
400  if (ReadMouseData() != MOUSE_ACK)
401  {
402  /* Failure */
403  setAH(0x03);
404  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
405  break;
406  }
407 
408  /* Success */
409  setAH(0x00);
410  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
411  break;
412  }
413 
414  default:
415  {
416  /* Invalid function */
417  setAH(0x01);
418  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
419  break;
420  }
421  }
422 
423  break;
424  }
425 
426  /* Set Device Handler Address */
427  case 0x07:
428  {
429  /* ES:BX == 0000h:0000h removes the device handler */
431 
432  /* Success */
433  setAH(0x00);
434  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
435  break;
436  }
437 
438  /* Write to Pointer Port */
439  case 0x08:
440  {
442  if (ReadMouseData() != MOUSE_ACK)
443  {
444  /* Failure */
445  setAH(0x03);
446  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
447  break;
448  }
449 
450  /* Success */
451  setAH(0x00);
452  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
453  break;
454  }
455 
456  /* Read from Pointer Port */
457  case 0x09:
458  {
459  setBL(ReadMouseData());
460  setCL(ReadMouseData());
461  setDL(ReadMouseData());
462 
463  /* Success */
464  setAH(0x00);
465  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
466  break;
467  }
468 
469  default:
470  {
471  DPRINT1("INT 15h, AH = C2h, AL = %02Xh NOT IMPLEMENTED\n",
472  getAL());
473 
474  /* Unknown function */
475  setAH(0x01);
476  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
477  }
478  }
479 
480  /* Reenable mouse interrupt and events */
481  EnableMouseInt();
482 }
static UCHAR ReadMouseData(VOID)
Definition: moubios32.c:92
USHORT WINAPI getBX(VOID)
Definition: registers.c:170
VOID WINAPI setBL(UCHAR)
Definition: registers.c:205
VOID WINAPI setAH(UCHAR)
Definition: registers.c:135
static VOID BiosMouseDisable(VOID)
Definition: moubios32.c:115
UCHAR WINAPI getAL(VOID)
Definition: registers.c:142
Definition: shell.h:41
static VOID SendMouseCommand(UCHAR Command)
Definition: moubios32.c:81
static VOID BiosMouseEnable(VOID)
Definition: moubios32.c:100
#define EMULATOR_FLAG_CF
Definition: cpu.h:19
#define MAKELONG(a, b)
Definition: typedefs.h:248
#define STACK_FLAGS
Definition: int32.h:35
USHORT WINAPI getES(VOID)
Definition: registers.c:522
static VOID EnableMouseInt(VOID)
Definition: moubios32.c:64
UCHAR WINAPI getBH(VOID)
Definition: registers.c:184
unsigned char UCHAR
Definition: xmlstorage.h:181
#define MOUSE_ACK
Definition: i8042prt.h:285
VOID WINAPI setBH(UCHAR)
Definition: registers.c:191
UCHAR WINAPI getBL(VOID)
Definition: registers.c:198
VOID WINAPI setDL(UCHAR)
Definition: registers.c:321
#define DPRINT1
Definition: precomp.h:8
static ULONG DeviceHandler
Definition: moubios32.c:44
static BYTE Resolution
Definition: mouse.c:35
static VOID DisableMouseInt(VOID)
Definition: moubios32.c:48
VOID WINAPI setCL(UCHAR)
Definition: registers.c:263

◆ DisableMouseInt()

static VOID DisableMouseInt ( VOID  )
static

Definition at line 48 of file moubios32.c.

49 {
51 
52  /* Clear the mouse queue */
53  while (PS2PortQueueRead(1)) ; // NOTE: Should be a IOReadB! But see r67231
54 
55  /* Disable mouse interrupt and events */
58  ControllerConfig &= ~0x02; // Turn off IRQ12
59  ControllerConfig |= 0x20; // Disable mouse clock line
62 }
#define PS2_DATA_PORT
Definition: ps2.h:16
#define ControllerConfig
Definition: ps2.c:55
UCHAR IOReadB(USHORT Port)
Definition: io.c:64
VOID IOWriteB(USHORT Port, UCHAR Buffer)
Definition: io.c:111
BOOLEAN PS2PortQueueRead(BYTE PS2Port)
Definition: ps2.c:415
#define PS2_CONTROL_PORT
Definition: ps2.h:17
unsigned char BYTE
Definition: mem.h:68

Referenced by BiosMousePs2Interface().

◆ EnableMouseInt()

static VOID EnableMouseInt ( VOID  )
static

Definition at line 64 of file moubios32.c.

65 {
67 
68  /* Clear the mouse queue */
69  while (PS2PortQueueRead(1)) ; // NOTE: Should be a IOReadB! But see r67231
70 
71  /* Enable mouse interrupt and events */
74  ControllerConfig |= 0x02; // Turn on IRQ12
75  ControllerConfig &= ~0x20; // Enable mouse clock line
78 }
#define PS2_DATA_PORT
Definition: ps2.h:16
#define ControllerConfig
Definition: ps2.c:55
UCHAR IOReadB(USHORT Port)
Definition: io.c:64
VOID IOWriteB(USHORT Port, UCHAR Buffer)
Definition: io.c:111
BOOLEAN PS2PortQueueRead(BYTE PS2Port)
Definition: ps2.c:415
#define PS2_CONTROL_PORT
Definition: ps2.h:17
unsigned char BYTE
Definition: mem.h:68

Referenced by BiosMousePs2Interface(), and MouseBios32Post().

◆ MouseBios32Cleanup()

VOID MouseBios32Cleanup ( VOID  )

Definition at line 538 of file moubios32.c.

539 {
540 }

Referenced by Bios32Cleanup().

◆ MouseBios32Post()

VOID MouseBios32Post ( VOID  )

Definition at line 486 of file moubios32.c.

487 {
488  UCHAR Answer;
489 
490  /* Initialize PS/2 mouse port */
491  // Enable the port
492  IOWriteB(PS2_CONTROL_PORT, 0xA8);
493 
494  /* Detect mouse presence by attempting a reset */
495  SendMouseCommand(0xFF);
496  Answer = ReadMouseData();
497  /* A "Resend" signal (0xFE) is sent if no mouse is attached */
498  if (Answer == 0xFE)
499  {
500  DPRINT1("No mouse present!\n");
501  }
502  else if (Answer != MOUSE_ACK)
503  {
504  DPRINT1("Mouse reset failure!\n");
505  }
506  else
507  {
508  /* Mouse present, try to completely enable it */
509 
510  // FIXME: The following is temporary until
511  // this is moved into the mouse driver!!
512 
513  /* Enable packet reporting */
514  SendMouseCommand(0xF4);
515  if (ReadMouseData() != MOUSE_ACK)
516  {
517  DPRINT1("Failed to enable mouse!\n");
518  }
519  else
520  {
521  /* Enable mouse interrupt and events */
522  EnableMouseInt();
523  }
524  }
525 
526  /* No mouse driver available so far */
527  RegisterBiosInt32(0x33, NULL);
528 
529  /* Set up the HW vector interrupts */
531 }
static UCHAR ReadMouseData(VOID)
Definition: moubios32.c:92
static VOID SendMouseCommand(UCHAR Command)
Definition: moubios32.c:81
#define RegisterBiosInt32(IntNumber, IntHandler)
Definition: bios32p.h:34
static VOID WINAPI BiosMouseIrq(LPWORD Stack)
Definition: moubios32.c:127
smooth NULL
Definition: ftsmooth.c:416
VOID IOWriteB(USHORT Port, UCHAR Buffer)
Definition: io.c:111
VOID EnableHwIRQ(UCHAR hwirq, EMULATOR_INT32_PROC func)
Definition: bios32.c:798
static VOID EnableMouseInt(VOID)
Definition: moubios32.c:64
unsigned char UCHAR
Definition: xmlstorage.h:181
#define PS2_CONTROL_PORT
Definition: ps2.h:17
#define MOUSE_ACK
Definition: i8042prt.h:285
#define DPRINT1
Definition: precomp.h:8

Referenced by Bios32Post().

◆ MouseBiosInitialize()

BOOLEAN MouseBiosInitialize ( VOID  )

Definition at line 533 of file moubios32.c.

534 {
535  return TRUE;
536 }
#define TRUE
Definition: types.h:120

Referenced by Bios32Initialize().

◆ ReadMouseData()

static UCHAR ReadMouseData ( VOID  )
inlinestatic

Definition at line 92 of file moubios32.c.

93 {
94  PS2PortQueueRead(1); // NOTE: Should be a IOReadB! But see r67231
95  return IOReadB(PS2_DATA_PORT);
96 }
#define PS2_DATA_PORT
Definition: ps2.h:16
UCHAR IOReadB(USHORT Port)
Definition: io.c:64
BOOLEAN PS2PortQueueRead(BYTE PS2Port)
Definition: ps2.c:415

Referenced by BiosMousePs2Interface(), and MouseBios32Post().

◆ SendMouseCommand()

static VOID SendMouseCommand ( UCHAR  Command)
inlinestatic

Definition at line 81 of file moubios32.c.

82 {
83  /* Clear the mouse queue */
84  while (PS2PortQueueRead(1)) ; // NOTE: Should be a IOReadB! But see r67231
85 
86  /* Send the command */
89 }
#define PS2_DATA_PORT
Definition: ps2.h:16
Definition: shell.h:41
VOID IOWriteB(USHORT Port, UCHAR Buffer)
Definition: io.c:111
BOOLEAN PS2PortQueueRead(BYTE PS2Port)
Definition: ps2.c:415
#define PS2_CONTROL_PORT
Definition: ps2.h:17

Referenced by BiosMousePs2Interface(), and MouseBios32Post().

Variable Documentation

◆ DeviceHandler

ULONG DeviceHandler = 0
static

Definition at line 44 of file moubios32.c.

Referenced by BiosMouseIrq(), and BiosMousePs2Interface().

◆ MouseEnabled

BOOLEAN MouseEnabled = FALSE
static

Definition at line 33 of file moubios32.c.

Referenced by BiosMouseDisable(), and BiosMouseEnable().

◆ OldIrqHandler

DWORD OldIrqHandler
static

Definition at line 34 of file moubios32.c.

Referenced by BiosMouseEnable().