ReactOS  0.4.13-dev-66-gc714b7f
ps2.c File Reference
#include "ntvdm.h"
#include <debug.h>
#include "emulator.h"
#include "ps2.h"
#include "memory.h"
#include "io.h"
#include "pic.h"
#include "clock.h"
Include dependency graph for ps2.c:

Go to the source code of this file.

Classes

struct  _PS2_PORT
 

Macros

#define NDEBUG
 
#define BUFFER_SIZE   32
 
#define PS2_PORTS   2
 
#define ControllerConfig   Memory[0]
 

Typedefs

typedef struct _PS2_PORT PS2_PORT
 
typedef struct _PS2_PORTPPS2_PORT
 

Functions

static VOID PS2SendCommand (BYTE PS2Port, BYTE Command)
 
static BYTE WINAPI PS2ReadControl (USHORT Port)
 
static BYTE WINAPI PS2ReadData (USHORT Port)
 
static VOID WINAPI PS2WriteControl (USHORT Port, BYTE Data)
 
static VOID WINAPI PS2WriteData (USHORT Port, BYTE Data)
 
static VOID FASTCALL GeneratePS2Irq (ULONGLONG ElapsedTime)
 
BOOLEAN PS2PortQueueRead (BYTE PS2Port)
 
VOID PS2SetDeviceCmdProc (BYTE PS2Port, LPVOID Param, PS2_DEVICE_CMDPROC DeviceCommand)
 
BOOLEAN PS2QueuePush (BYTE PS2Port, BYTE Data)
 
BOOLEAN PS2Initialize (VOID)
 
VOID PS2Cleanup (VOID)
 

Variables

static PS2_PORT Ports [PS2_PORTS]
 
static BYTE Memory [0x20]
 
static BYTE StatusRegister = 0x00
 
static BYTE OutputBuffer = 0x00
 
static BYTE ControllerCommand = 0x00
 
static PHARDWARE_TIMER IrqTimer = NULL
 

Macro Definition Documentation

◆ BUFFER_SIZE

#define BUFFER_SIZE   32

Definition at line 31 of file ps2.c.

◆ ControllerConfig

#define ControllerConfig   Memory[0]

Definition at line 55 of file ps2.c.

◆ NDEBUG

#define NDEBUG

Definition at line 18 of file ps2.c.

◆ PS2_PORTS

#define PS2_PORTS   2

Definition at line 51 of file ps2.c.

Typedef Documentation

◆ PPS2_PORT

◆ PS2_PORT

Function Documentation

◆ GeneratePS2Irq()

static VOID FASTCALL GeneratePS2Irq ( ULONGLONG  ElapsedTime)
static

Definition at line 392 of file ps2.c.

393 {
394  UNREFERENCED_PARAMETER(ElapsedTime);
395 
396  /*
397  * Pop out fresh new data from the PS/2 port output queues, and only
398  * in case there is data ready, generate an IRQ1 or IRQ12 depending
399  * on whether interrupts are enabled for the given port.
400  *
401  * NOTE: The first PS/2 port (keyboard) has priority over the second one (mouse).
402  */
403  if (PS2PortQueueRead(0))
404  {
406  }
407  else if (PS2PortQueueRead(1))
408  {
410  }
411 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define ControllerConfig
Definition: ps2.c:55
BOOLEAN PS2PortQueueRead(BYTE PS2Port)
Definition: ps2.c:415
#define PS2_CONFIG_AUX_INT
Definition: ps2.h:31
#define PS2_CONFIG_KBD_INT
Definition: ps2.h:30
VOID PicInterruptRequest(BYTE Number)
Definition: pic.c:192

Referenced by PS2Initialize().

◆ PS2Cleanup()

VOID PS2Cleanup ( VOID  )

Definition at line 546 of file ps2.c.

547 {
549 
550  CloseHandle(Ports[1].QueueMutex);
551  CloseHandle(Ports[0].QueueMutex);
552 }
#define CloseHandle
Definition: compat.h:398
static PS2_PORT Ports[PS2_PORTS]
Definition: ps2.c:52
VOID DestroyHardwareTimer(PHARDWARE_TIMER Timer)
Definition: clock.c:210
static PHARDWARE_TIMER IrqTimer
Definition: ps2.c:63

Referenced by EmulatorCleanup().

◆ PS2Initialize()

BOOLEAN PS2Initialize ( VOID  )

Definition at line 520 of file ps2.c.

521 {
522  /* Initialize the PS/2 ports */
523  Ports[0].IsEnabled = FALSE;
524  Ports[0].QueueEmpty = TRUE;
525  Ports[0].QueueStart = 0;
526  Ports[0].QueueEnd = 0;
528 
529  Ports[1].IsEnabled = FALSE;
530  Ports[1].QueueEmpty = TRUE;
531  Ports[1].QueueStart = 0;
532  Ports[1].QueueEnd = 0;
534 
535  /* Register the I/O Ports */
538 
540  HZ_TO_NS(100),
542 
543  return TRUE;
544 }
#define PS2_DATA_PORT
Definition: ps2.h:16
#define TRUE
Definition: types.h:120
UINT QueueStart
Definition: ps2.c:39
static BYTE WINAPI PS2ReadData(USHORT Port)
Definition: ps2.c:109
BOOLEAN QueueEmpty
Definition: ps2.c:37
VOID RegisterIoPort(USHORT Port, EMULATOR_INB_PROC InHandler, EMULATOR_OUTB_PROC OutHandler)
Definition: io.c:320
static VOID FASTCALL GeneratePS2Irq(ULONGLONG ElapsedTime)
Definition: ps2.c:392
static VOID WINAPI PS2WriteControl(USHORT Port, BYTE Data)
Definition: ps2.c:130
BOOLEAN IsEnabled
Definition: ps2.c:35
PHARDWARE_TIMER CreateHardwareTimer(ULONG Flags, ULONGLONG Delay, PHARDWARE_TIMER_PROC Callback)
Definition: clock.c:144
smooth NULL
Definition: ftsmooth.c:416
#define CreateMutex
Definition: winbase.h:3570
static PS2_PORT Ports[PS2_PORTS]
Definition: ps2.c:52
#define HARDWARE_TIMER_ONESHOT
Definition: clock.h:16
#define PS2_CONTROL_PORT
Definition: ps2.h:17
static VOID WINAPI PS2WriteData(USHORT Port, BYTE Data)
Definition: ps2.c:278
#define HZ_TO_NS(Freq)
Definition: clock.h:20
static BYTE WINAPI PS2ReadControl(USHORT Port)
Definition: ps2.c:90
HANDLE QueueMutex
Definition: ps2.c:41
UINT QueueEnd
Definition: ps2.c:40
static PHARDWARE_TIMER IrqTimer
Definition: ps2.c:63

Referenced by EmulatorInitialize().

◆ PS2PortQueueRead()

BOOLEAN PS2PortQueueRead ( BYTE  PS2Port)

Definition at line 415 of file ps2.c.

416 {
417  BOOLEAN Result = FALSE;
418  PPS2_PORT Port;
419 
420  // NOTE: The first PS/2 port (keyboard) has priority over the second one (mouse).
421 
422  Port = &Ports[PS2Port];
423 
424  if (!Port->IsEnabled) return FALSE;
425 
426  /* Make sure the queue is not empty (fast check) */
427  if (Port->QueueEmpty)
428  {
429  /* Only the keyboard should have its last data latched */
430  // FIXME: Alternatively this can be done in PS2ReadData when
431  // we read PS2_DATA_PORT. What is the best solution??
432  if (PS2Port == 0)
433  {
434  OutputBuffer = Port->Queue[(Port->QueueStart - 1) % BUFFER_SIZE];
435  StatusRegister &= ~PS2_STAT_AUX_OUT_BUF_FULL; // Clear flag: keyboard data
436  }
437 
438  return FALSE;
439  }
440 
441  WaitForSingleObject(Port->QueueMutex, INFINITE);
442 
443  /*
444  * Recheck whether the queue is not empty (it may
445  * have changed after having grabbed the mutex).
446  */
447  if (Port->QueueEmpty) goto Done;
448 
449  /* Get the data */
450  OutputBuffer = Port->Queue[Port->QueueStart];
451 
452  // StatusRegister &= ~(PS2_STAT_AUX_OUT_BUF_FULL | PS2_STAT_OUT_BUF_FULL);
453 
454  /* Always set the "Output buffer full" flag */
456 
457  /* Set the "Auxiliary output buffer full" flag according to where the data came from */
458  if (PS2Port == 0)
459  StatusRegister &= ~PS2_STAT_AUX_OUT_BUF_FULL; // Clear flag: keyboard data
460  else // if (PS2Port == 1)
461  StatusRegister |= PS2_STAT_AUX_OUT_BUF_FULL; // Set flag: mouse data
462 
463  /* Remove the value from the queue */
464  Port->QueueStart++;
465  Port->QueueStart %= BUFFER_SIZE;
466 
467  /* Check if the queue is now empty */
468  if (Port->QueueStart == Port->QueueEnd)
469  Port->QueueEmpty = TRUE;
470 
471  Result = TRUE;
472 
473 Done:
474  ReleaseMutex(Port->QueueMutex);
475  return Result;
476 }
static BYTE StatusRegister
Definition: ps2.c:57
CPPORT Port[4]
Definition: headless.c:34
#define TRUE
Definition: types.h:120
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define BUFFER_SIZE
Definition: ps2.c:31
unsigned char BOOLEAN
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
Definition: ps2.c:33
static PS2_PORT Ports[PS2_PORTS]
Definition: ps2.c:52
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:564
static BYTE OutputBuffer
Definition: ps2.c:59
#define PS2_STAT_OUT_BUF_FULL
Definition: ps2.h:20
#define INFINITE
Definition: serial.h:102
#define PS2_STAT_AUX_OUT_BUF_FULL
Definition: ps2.h:25

Referenced by DisableMouseInt(), DosMouseIrq(), EnableMouseInt(), GeneratePS2Irq(), ReadMouseData(), and SendMouseCommand().

◆ PS2QueuePush()

BOOLEAN PS2QueuePush ( BYTE  PS2Port,
BYTE  Data 
)

Definition at line 486 of file ps2.c.

487 {
488  BOOLEAN Result = FALSE;
489  PPS2_PORT Port;
490 
491  ASSERT(PS2Port < PS2_PORTS);
492  Port = &Ports[PS2Port];
493 
494  if (!Port->IsEnabled) return FALSE;
495 
496  WaitForSingleObject(Port->QueueMutex, INFINITE);
497 
498  /* Check if the queue is full */
499  if (!Port->QueueEmpty && (Port->QueueStart == Port->QueueEnd))
500  goto Done;
501 
502  /* Insert the value in the queue */
503  Port->Queue[Port->QueueEnd] = Data;
504  Port->QueueEnd++;
505  Port->QueueEnd %= BUFFER_SIZE;
506 
507  /* The queue is not empty anymore */
508  Port->QueueEmpty = FALSE;
509 
510  /* Schedule the IRQ */
512 
513  Result = TRUE;
514 
515 Done:
516  ReleaseMutex(Port->QueueMutex);
517  return Result;
518 }
CPPORT Port[4]
Definition: headless.c:34
#define TRUE
Definition: types.h:120
#define PS2_PORTS
Definition: ps2.c:51
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define BUFFER_SIZE
Definition: ps2.c:31
unsigned char BOOLEAN
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
Definition: ps2.c:33
static PS2_PORT Ports[PS2_PORTS]
Definition: ps2.c:52
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:564
VOID EnableHardwareTimer(PHARDWARE_TIMER Timer)
Definition: clock.c:161
#define INFINITE
Definition: serial.h:102
static PHARDWARE_TIMER IrqTimer
Definition: ps2.c:63

Referenced by KeyboardCommand(), KeyboardEventHandler(), MouseCommand(), MouseDispatchPacket(), and PS2WriteData().

◆ PS2ReadControl()

static BYTE WINAPI PS2ReadControl ( USHORT  Port)
static

Definition at line 90 of file ps2.c.

91 {
93 
94  /*
95  * Be sure the "Keyboard enable" flag is always set.
96  * On IBM PC-ATs this is the state of the hardware keyboard
97  * lock mechanism. It is not widely used, but some programs
98  * still use it, see for example:
99  * http://www.os2museum.com/wp/the-dos-4-0-shell-mouse-mystery/
100  */
102 
103  /* We do not have any timeouts nor parity errors */
105 
106  return StatusRegister;
107 }
static BYTE StatusRegister
Definition: ps2.c:57
CPPORT Port[4]
Definition: headless.c:34
#define PS2_STAT_KBD_ENABLE
Definition: ps2.h:24
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define PS2_STAT_PARITY_ERROR
Definition: ps2.h:27
#define PS2_STAT_GEN_TIMEOUT
Definition: ps2.h:26

Referenced by PS2Initialize().

◆ PS2ReadData()

static BYTE WINAPI PS2ReadData ( USHORT  Port)
static

Definition at line 109 of file ps2.c.

110 {
112 
113  /*
114  * If there is something to read (response byte from the
115  * controller or data from a PS/2 device), read it.
116  */
118 
119  // Keep the state of the "Auxiliary output buffer full" flag
120  // in order to remember from where the data came from.
121  // StatusRegister &= ~PS2_STAT_AUX_OUT_BUF_FULL;
122 
123  // FIXME: We may check there whether there is data latched in
124  // PS2 ports 1 or 2 (keyboard or mouse) and retrieve it there...
125 
126  /* Always return the available byte stored in the output buffer */
127  return OutputBuffer;
128 }
static BYTE StatusRegister
Definition: ps2.c:57
CPPORT Port[4]
Definition: headless.c:34
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
static BYTE OutputBuffer
Definition: ps2.c:59
#define PS2_STAT_OUT_BUF_FULL
Definition: ps2.h:20

Referenced by PS2Initialize().

◆ PS2SendCommand()

static VOID PS2SendCommand ( BYTE  PS2Port,
BYTE  Command 
)
static

Definition at line 67 of file ps2.c.

68 {
70 
71  ASSERT(PS2Port < PS2_PORTS);
72  Port = &Ports[PS2Port];
73 
74  /*
75  * According to http://www.win.tue.nl/~aeb/linux/kbd/scancodes-11.html#kccad
76  * any PS/2 command sent reenables the corresponding port.
77  */
78  if (PS2Port == 0)
80  else // if (PS2Port == 1)
82 
83  Port->IsEnabled = TRUE;
84 
85  /* Call the device command */
86  if (Port->DeviceCommand) Port->DeviceCommand(Port->Param, Command);
87 }
CPPORT Port[4]
Definition: headless.c:34
#define TRUE
Definition: types.h:120
#define PS2_PORTS
Definition: ps2.c:51
#define PS2_CONFIG_KBD_DISABLE
Definition: ps2.h:34
Definition: shell.h:41
#define ControllerConfig
Definition: ps2.c:55
Definition: ps2.c:33
#define PS2_CONFIG_AUX_DISABLE
Definition: ps2.h:35
static PS2_PORT Ports[PS2_PORTS]
Definition: ps2.c:52
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)

Referenced by PS2WriteData().

◆ PS2SetDeviceCmdProc()

VOID PS2SetDeviceCmdProc ( BYTE  PS2Port,
LPVOID  Param,
PS2_DEVICE_CMDPROC  DeviceCommand 
)

Definition at line 478 of file ps2.c.

479 {
480  ASSERT(PS2Port < PS2_PORTS);
481  Ports[PS2Port].Param = Param;
482  Ports[PS2Port].DeviceCommand = DeviceCommand;
483 }
#define PS2_PORTS
Definition: ps2.c:51
PS2_DEVICE_CMDPROC DeviceCommand
Definition: ps2.c:44
static PS2_PORT Ports[PS2_PORTS]
Definition: ps2.c:52
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
LPVOID Param
Definition: ps2.c:43

Referenced by KeyboardInit(), and MouseInit().

◆ PS2WriteControl()

static VOID WINAPI PS2WriteControl ( USHORT  Port,
BYTE  Data 
)
static

Definition at line 130 of file ps2.c.

131 {
133 
134  switch (Data)
135  {
136  /* Read configuration byte (byte 0 from internal memory) */
137  case 0x20:
138  /* Read byte N from internal memory */
139  case 0x21: case 0x22: case 0x23:
140  case 0x24: case 0x25: case 0x26: case 0x27:
141  case 0x28: case 0x29: case 0x2A: case 0x2B:
142  case 0x2C: case 0x2D: case 0x2E: case 0x2F:
143  case 0x30: case 0x31: case 0x32: case 0x33:
144  case 0x34: case 0x35: case 0x36: case 0x37:
145  case 0x38: case 0x39: case 0x3A: case 0x3B:
146  case 0x3C: case 0x3D: case 0x3E: case 0x3F:
147  {
148  OutputBuffer = Memory[Data & 0x1F];
150  break;
151  }
152 
153  /* Write configuration byte (byte 0 from internal memory) */
154  case 0x60:
155  /* Write to byte N of internal memory */
156  case 0x61: case 0x62: case 0x63:
157  case 0x64: case 0x65: case 0x66: case 0x67:
158  case 0x68: case 0x69: case 0x6A: case 0x6B:
159  case 0x6C: case 0x6D: case 0x6E: case 0x6F:
160  case 0x70: case 0x71: case 0x72: case 0x73:
161  case 0x74: case 0x75: case 0x76: case 0x77:
162  case 0x78: case 0x79: case 0x7A: case 0x7B:
163  case 0x7C: case 0x7D: case 0x7E: case 0x7F:
164 
165  /* Write controller output port */
166  case 0xD1:
167  /* Write to the first PS/2 port output buffer */
168  case 0xD2:
169  /* Write to the second PS/2 port output buffer */
170  case 0xD3:
171  /* Write to the second PS/2 port input buffer */
172  case 0xD4:
173  {
174  /* These commands require a response */
177  break;
178  }
179 
180  /* Disable second PS/2 port */
181  case 0xA7:
182  {
184  Ports[1].IsEnabled = FALSE;
185  break;
186  }
187 
188  /* Enable second PS/2 port */
189  case 0xA8:
190  {
192  Ports[1].IsEnabled = TRUE;
193  break;
194  }
195 
196  /* Test second PS/2 port */
197  case 0xA9:
198  {
199  OutputBuffer = 0x00; // Success code
201  break;
202  }
203 
204  /* Test PS/2 controller */
205  case 0xAA:
206  {
207  OutputBuffer = 0x55; // Success code
209  break;
210  }
211 
212  /* Test first PS/2 port */
213  case 0xAB:
214  {
215  OutputBuffer = 0x00; // Success code
217  break;
218  }
219 
220  /* Disable first PS/2 port */
221  case 0xAD:
222  {
224  Ports[0].IsEnabled = FALSE;
225  break;
226  }
227 
228  /* Enable first PS/2 port */
229  case 0xAE:
230  {
232  Ports[0].IsEnabled = TRUE;
233  break;
234  }
235 
236  /* Read controller output port */
237  case 0xD0:
238  {
239  /* Bit 0 always set, and bit 1 is the A20 gate state */
241 
242  /* Set IRQ1 state */
245  else
247 
248  /* Set IRQ12 state */
251  else
253 
254  /* Check whether data is already present */
256  {
259  else
261  }
262 
264  break;
265  }
266 
267  /* CPU Reset */
268  case 0xF0: case 0xF2: case 0xF4: case 0xF6:
269  case 0xF8: case 0xFA: case 0xFC: case 0xFE:
270  {
271  /* Stop the VDM */
273  return;
274  }
275  }
276 }
static BYTE Memory[0x20]
Definition: ps2.c:54
static BYTE StatusRegister
Definition: ps2.c:57
CPPORT Port[4]
Definition: headless.c:34
#define TRUE
Definition: types.h:120
BOOLEAN EmulatorGetA20(VOID)
Definition: memory.c:277
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define PS2_CONFIG_KBD_DISABLE
Definition: ps2.h:34
#define PS2_STAT_COMMAND
Definition: ps2.h:23
static BYTE ControllerCommand
Definition: ps2.c:61
#define ControllerConfig
Definition: ps2.c:55
#define PS2_OUT_KBD_DATA
Definition: ps2.h:46
BOOLEAN IsEnabled
Definition: ps2.c:35
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
#define PS2_OUT_IRQ12
Definition: ps2.h:44
#define PS2_OUT_AUX_DATA
Definition: ps2.h:41
#define PS2_CONFIG_AUX_DISABLE
Definition: ps2.h:35
#define PS2_CONFIG_AUX_INT
Definition: ps2.h:31
static PS2_PORT Ports[PS2_PORTS]
Definition: ps2.c:52
static BYTE OutputBuffer
Definition: ps2.c:59
VOID EmulatorTerminate(VOID)
Definition: emulator.c:503
#define PS2_OUT_IRQ01
Definition: ps2.h:43
#define PS2_STAT_OUT_BUF_FULL
Definition: ps2.h:20
#define PS2_CONFIG_KBD_INT
Definition: ps2.h:30
#define PS2_OUT_CPU_NO_RESET
Definition: ps2.h:39
#define PS2_STAT_AUX_OUT_BUF_FULL
Definition: ps2.h:25

Referenced by PS2Initialize().

◆ PS2WriteData()

static VOID WINAPI PS2WriteData ( USHORT  Port,
BYTE  Data 
)
static

Definition at line 278 of file ps2.c.

279 {
280  /* Check if the controller is waiting for a response */
282  {
284 
285  /* Check which command it was */
286  switch (ControllerCommand)
287  {
288  /* Write configuration byte (byte 0 from internal memory) */
289  case 0x60:
290  {
292 
293  /*
294  * Synchronize the enable state of the PS/2 ports
295  * with the flags in the configuration byte.
296  */
299 
300  /*
301  * Update the "System enabled" flag of the status register
302  * with bit 2 of the controller configuration byte.
303  * See: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-11.html#kccb2
304  * for more details.
305  */
308  else
310 
311  /*
312  * Update the "Keyboard enable" flag of the status register
313  * with the "Ignore keyboard lock" flag of the controller
314  * configuration byte (if set), then reset the latter one.
315  * See: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-11.html#kccb3
316  * for more details.
317  */
319  {
322  }
323 
324  break;
325  }
326 
327  /* Write to byte N of internal memory */
328  case 0x61: case 0x62: case 0x63:
329  case 0x64: case 0x65: case 0x66: case 0x67:
330  case 0x68: case 0x69: case 0x6A: case 0x6B:
331  case 0x6C: case 0x6D: case 0x6E: case 0x6F:
332  case 0x70: case 0x71: case 0x72: case 0x73:
333  case 0x74: case 0x75: case 0x76: case 0x77:
334  case 0x78: case 0x79: case 0x7A: case 0x7B:
335  case 0x7C: case 0x7D: case 0x7E: case 0x7F:
336  {
337  Memory[ControllerCommand & 0x1F] = Data;
338  break;
339  }
340 
341  /* Write controller output */
342  case 0xD1:
343  {
344  /* Check if bit 0 is unset */
345  if (!(Data & PS2_OUT_CPU_NO_RESET))
346  {
347  /* CPU disabled - Stop the VDM */
349  return;
350  }
351 
352  /* Update the A20 line setting */
354 
355  // FIXME: Should we need to add the status of IRQ1 and IRQ12??
356 
357  break;
358  }
359 
360  /* Push the data byte into the first PS/2 port queue */
361  case 0xD2:
362  {
363  PS2QueuePush(0, Data);
364  break;
365  }
366 
367  /* Push the data byte into the second PS/2 port queue */
368  case 0xD3:
369  {
370  PS2QueuePush(1, Data);
371  break;
372  }
373 
374  /*
375  * Send a command to the second PS/2 port (by default
376  * it is a command for the first PS/2 port)
377  */
378  case 0xD4:
379  {
380  PS2SendCommand(1, Data);
381  break;
382  }
383  }
384 
385  return;
386  }
387 
388  /* By default, send a command to the first PS/2 port */
389  PS2SendCommand(0, Data);
390 }
static BYTE Memory[0x20]
Definition: ps2.c:54
static BYTE StatusRegister
Definition: ps2.c:57
#define PS2_OUT_A20_SET
Definition: ps2.h:40
#define PS2_STAT_KBD_ENABLE
Definition: ps2.h:24
#define PS2_CONFIG_KBD_DISABLE
Definition: ps2.h:34
#define PS2_STAT_COMMAND
Definition: ps2.h:23
#define PS2_CONFIG_NO_KEYLOCK
Definition: ps2.h:33
static BYTE ControllerCommand
Definition: ps2.c:61
BOOLEAN PS2QueuePush(BYTE PS2Port, BYTE Data)
Definition: ps2.c:486
#define ControllerConfig
Definition: ps2.c:55
#define PS2_CONFIG_SYSTEM
Definition: ps2.h:32
BOOLEAN IsEnabled
Definition: ps2.c:35
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
#define PS2_CONFIG_AUX_DISABLE
Definition: ps2.h:35
VOID EmulatorSetA20(BOOLEAN Enabled)
Definition: memory.c:272
static PS2_PORT Ports[PS2_PORTS]
Definition: ps2.c:52
VOID EmulatorTerminate(VOID)
Definition: emulator.c:503
static VOID PS2SendCommand(BYTE PS2Port, BYTE Command)
Definition: ps2.c:67
#define PS2_OUT_CPU_NO_RESET
Definition: ps2.h:39
#define PS2_STAT_SYSTEM
Definition: ps2.h:22

Referenced by PS2Initialize().

Variable Documentation

◆ ControllerCommand

BYTE ControllerCommand = 0x00
static

Definition at line 61 of file ps2.c.

Referenced by PS2WriteControl(), and PS2WriteData().

◆ IrqTimer

PHARDWARE_TIMER IrqTimer = NULL
static

Definition at line 63 of file ps2.c.

Referenced by PS2Cleanup(), PS2Initialize(), and PS2QueuePush().

◆ Memory

◆ OutputBuffer

BYTE OutputBuffer = 0x00
static

Definition at line 59 of file ps2.c.

Referenced by PS2PortQueueRead(), PS2ReadData(), and PS2WriteControl().

◆ Ports

◆ StatusRegister