1*c2c66affSColin Finck /*
2*c2c66affSColin Finck * COPYRIGHT: GPL - See COPYING in the top level directory
3*c2c66affSColin Finck * PROJECT: ReactOS Virtual DOS Machine
4*c2c66affSColin Finck * FILE: subsystems/mvdm/ntvdm/bios/bios32/moubios32.c
5*c2c66affSColin Finck * PURPOSE: VDM 32-bit PS/2 Mouse BIOS
6*c2c66affSColin Finck * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7*c2c66affSColin Finck * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
8*c2c66affSColin Finck *
9*c2c66affSColin Finck * NOTE: Based from VirtualBox OSE ROM BIOS, and SeaBIOS.
10*c2c66affSColin Finck */
11*c2c66affSColin Finck
12*c2c66affSColin Finck /* INCLUDES *******************************************************************/
13*c2c66affSColin Finck
14*c2c66affSColin Finck #include "ntvdm.h"
15*c2c66affSColin Finck
16*c2c66affSColin Finck #define NDEBUG
17*c2c66affSColin Finck #include <debug.h>
18*c2c66affSColin Finck
19*c2c66affSColin Finck #include "emulator.h"
20*c2c66affSColin Finck #include "cpu/cpu.h" // for EMULATOR_FLAG_CF
21*c2c66affSColin Finck
22*c2c66affSColin Finck #include "moubios32.h"
23*c2c66affSColin Finck #include "bios32p.h"
24*c2c66affSColin Finck
25*c2c66affSColin Finck #include "io.h"
26*c2c66affSColin Finck #include "hardware/mouse.h"
27*c2c66affSColin Finck #include "hardware/ps2.h"
28*c2c66affSColin Finck
29*c2c66affSColin Finck /* PRIVATE VARIABLES **********************************************************/
30*c2c66affSColin Finck
31*c2c66affSColin Finck #define MOUSE_IRQ_INT 0x74
32*c2c66affSColin Finck
33*c2c66affSColin Finck static BOOLEAN MouseEnabled = FALSE;
34*c2c66affSColin Finck static DWORD OldIrqHandler;
35*c2c66affSColin Finck
36*c2c66affSColin Finck /*
37*c2c66affSColin Finck * Far pointer to a device handler. In compatible PS/2, it is stored in the EBDA.
38*c2c66affSColin Finck *
39*c2c66affSColin Finck * See Ralf Brown: http://www.ctyme.com/intr/rb-1603.htm
40*c2c66affSColin Finck * for more information. In particular:
41*c2c66affSColin Finck * when the subroutine is called, it is given 4 WORD values on the stack;
42*c2c66affSColin Finck * the handler should return with a FAR return without popping the stack.
43*c2c66affSColin Finck */
44*c2c66affSColin Finck static ULONG DeviceHandler = 0;
45*c2c66affSColin Finck
46*c2c66affSColin Finck /* PRIVATE FUNCTIONS **********************************************************/
47*c2c66affSColin Finck
DisableMouseInt(VOID)48*c2c66affSColin Finck static VOID DisableMouseInt(VOID)
49*c2c66affSColin Finck {
50*c2c66affSColin Finck BYTE ControllerConfig;
51*c2c66affSColin Finck
52*c2c66affSColin Finck /* Clear the mouse queue */
53*c2c66affSColin Finck while (PS2PortQueueRead(1)) ; // NOTE: Should be a IOReadB! But see r67231
54*c2c66affSColin Finck
55*c2c66affSColin Finck /* Disable mouse interrupt and events */
56*c2c66affSColin Finck IOWriteB(PS2_CONTROL_PORT, 0x20);
57*c2c66affSColin Finck ControllerConfig = IOReadB(PS2_DATA_PORT);
58*c2c66affSColin Finck ControllerConfig &= ~0x02; // Turn off IRQ12
59*c2c66affSColin Finck ControllerConfig |= 0x20; // Disable mouse clock line
60*c2c66affSColin Finck IOWriteB(PS2_CONTROL_PORT, 0x60);
61*c2c66affSColin Finck IOWriteB(PS2_DATA_PORT, ControllerConfig);
62*c2c66affSColin Finck }
63*c2c66affSColin Finck
EnableMouseInt(VOID)64*c2c66affSColin Finck static VOID EnableMouseInt(VOID)
65*c2c66affSColin Finck {
66*c2c66affSColin Finck BYTE ControllerConfig;
67*c2c66affSColin Finck
68*c2c66affSColin Finck /* Clear the mouse queue */
69*c2c66affSColin Finck while (PS2PortQueueRead(1)) ; // NOTE: Should be a IOReadB! But see r67231
70*c2c66affSColin Finck
71*c2c66affSColin Finck /* Enable mouse interrupt and events */
72*c2c66affSColin Finck IOWriteB(PS2_CONTROL_PORT, 0x20);
73*c2c66affSColin Finck ControllerConfig = IOReadB(PS2_DATA_PORT);
74*c2c66affSColin Finck ControllerConfig |= 0x02; // Turn on IRQ12
75*c2c66affSColin Finck ControllerConfig &= ~0x20; // Enable mouse clock line
76*c2c66affSColin Finck IOWriteB(PS2_CONTROL_PORT, 0x60);
77*c2c66affSColin Finck IOWriteB(PS2_DATA_PORT, ControllerConfig);
78*c2c66affSColin Finck }
79*c2c66affSColin Finck
80*c2c66affSColin Finck static inline
SendMouseCommand(UCHAR Command)81*c2c66affSColin Finck VOID SendMouseCommand(UCHAR Command)
82*c2c66affSColin Finck {
83*c2c66affSColin Finck /* Clear the mouse queue */
84*c2c66affSColin Finck while (PS2PortQueueRead(1)) ; // NOTE: Should be a IOReadB! But see r67231
85*c2c66affSColin Finck
86*c2c66affSColin Finck /* Send the command */
87*c2c66affSColin Finck IOWriteB(PS2_CONTROL_PORT, 0xD4);
88*c2c66affSColin Finck IOWriteB(PS2_DATA_PORT, Command);
89*c2c66affSColin Finck }
90*c2c66affSColin Finck
91*c2c66affSColin Finck static inline
ReadMouseData(VOID)92*c2c66affSColin Finck UCHAR ReadMouseData(VOID)
93*c2c66affSColin Finck {
94*c2c66affSColin Finck PS2PortQueueRead(1); // NOTE: Should be a IOReadB! But see r67231
95*c2c66affSColin Finck return IOReadB(PS2_DATA_PORT);
96*c2c66affSColin Finck }
97*c2c66affSColin Finck
98*c2c66affSColin Finck
99*c2c66affSColin Finck static
BiosMouseEnable(VOID)100*c2c66affSColin Finck VOID BiosMouseEnable(VOID)
101*c2c66affSColin Finck {
102*c2c66affSColin Finck if (MouseEnabled) return;
103*c2c66affSColin Finck
104*c2c66affSColin Finck MouseEnabled = TRUE;
105*c2c66affSColin Finck
106*c2c66affSColin Finck /* Get the old IRQ handler */
107*c2c66affSColin Finck OldIrqHandler = ((PDWORD)BaseAddress)[MOUSE_IRQ_INT];
108*c2c66affSColin Finck
109*c2c66affSColin Finck /* Set the IRQ handler */
110*c2c66affSColin Finck //RegisterInt32(MAKELONG(FIELD_OFFSET(MOUSE_DRIVER, MouseIrqInt16Stub), MouseDataSegment),
111*c2c66affSColin Finck // MOUSE_IRQ_INT, DosMouseIrq, NULL);
112*c2c66affSColin Finck }
113*c2c66affSColin Finck
114*c2c66affSColin Finck static
BiosMouseDisable(VOID)115*c2c66affSColin Finck VOID BiosMouseDisable(VOID)
116*c2c66affSColin Finck {
117*c2c66affSColin Finck if (!MouseEnabled) return;
118*c2c66affSColin Finck
119*c2c66affSColin Finck /* Restore the old IRQ handler */
120*c2c66affSColin Finck // ((PDWORD)BaseAddress)[MOUSE_IRQ_INT] = OldIrqHandler;
121*c2c66affSColin Finck
122*c2c66affSColin Finck MouseEnabled = FALSE;
123*c2c66affSColin Finck }
124*c2c66affSColin Finck
125*c2c66affSColin Finck
126*c2c66affSColin Finck // Mouse IRQ 12
BiosMouseIrq(LPWORD Stack)127*c2c66affSColin Finck static VOID WINAPI BiosMouseIrq(LPWORD Stack)
128*c2c66affSColin Finck {
129*c2c66affSColin Finck DPRINT1("PS/2 Mouse IRQ! DeviceHandler = 0x%04X:0x%04X\n",
130*c2c66affSColin Finck HIWORD(DeviceHandler), LOWORD(DeviceHandler));
131*c2c66affSColin Finck
132*c2c66affSColin Finck if (DeviceHandler != 0)
133*c2c66affSColin Finck {
134*c2c66affSColin Finck /*
135*c2c66affSColin Finck * Prepare the stack for the mouse device handler:
136*c2c66affSColin Finck * push Status, X and Y data, and a zero word.
137*c2c66affSColin Finck */
138*c2c66affSColin Finck setSP(getSP() - sizeof(WORD));
139*c2c66affSColin Finck *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = 0; // Status
140*c2c66affSColin Finck setSP(getSP() - sizeof(WORD));
141*c2c66affSColin Finck *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = 0; // X data (high byte = 0)
142*c2c66affSColin Finck setSP(getSP() - sizeof(WORD));
143*c2c66affSColin Finck *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = 0; // Y data (high byte = 0)
144*c2c66affSColin Finck setSP(getSP() - sizeof(WORD));
145*c2c66affSColin Finck *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = 0; // Zero
146*c2c66affSColin Finck
147*c2c66affSColin Finck /* Call the device handler */
148*c2c66affSColin Finck RunCallback16(&BiosContext, DeviceHandler);
149*c2c66affSColin Finck
150*c2c66affSColin Finck /* Pop the stack */
151*c2c66affSColin Finck setSP(getSP() + 4*sizeof(WORD));
152*c2c66affSColin Finck }
153*c2c66affSColin Finck
154*c2c66affSColin Finck PicIRQComplete(LOBYTE(Stack[STACK_INT_NUM]));
155*c2c66affSColin Finck }
156*c2c66affSColin Finck
BiosMousePs2Interface(LPWORD Stack)157*c2c66affSColin Finck VOID BiosMousePs2Interface(LPWORD Stack)
158*c2c66affSColin Finck {
159*c2c66affSColin Finck /* Disable mouse interrupt and events */
160*c2c66affSColin Finck DisableMouseInt();
161*c2c66affSColin Finck
162*c2c66affSColin Finck switch (getAL())
163*c2c66affSColin Finck {
164*c2c66affSColin Finck /* Enable / Disable */
165*c2c66affSColin Finck case 0x00:
166*c2c66affSColin Finck {
167*c2c66affSColin Finck UCHAR State = getBH();
168*c2c66affSColin Finck
169*c2c66affSColin Finck if (State > 2)
170*c2c66affSColin Finck {
171*c2c66affSColin Finck /* Invalid function */
172*c2c66affSColin Finck setAH(0x01);
173*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
174*c2c66affSColin Finck break;
175*c2c66affSColin Finck }
176*c2c66affSColin Finck
177*c2c66affSColin Finck if (State == 0x00)
178*c2c66affSColin Finck {
179*c2c66affSColin Finck BiosMouseDisable();
180*c2c66affSColin Finck
181*c2c66affSColin Finck /* Disable packet reporting */
182*c2c66affSColin Finck SendMouseCommand(0xF5);
183*c2c66affSColin Finck }
184*c2c66affSColin Finck else // if (State == 0x01)
185*c2c66affSColin Finck {
186*c2c66affSColin Finck /* Check for the presence of the device handler */
187*c2c66affSColin Finck if (DeviceHandler == 0)
188*c2c66affSColin Finck {
189*c2c66affSColin Finck /* No device handler installed */
190*c2c66affSColin Finck setAH(0x05);
191*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
192*c2c66affSColin Finck break;
193*c2c66affSColin Finck }
194*c2c66affSColin Finck
195*c2c66affSColin Finck BiosMouseEnable();
196*c2c66affSColin Finck
197*c2c66affSColin Finck /* Enable packet reporting */
198*c2c66affSColin Finck SendMouseCommand(0xF4);
199*c2c66affSColin Finck }
200*c2c66affSColin Finck
201*c2c66affSColin Finck if (ReadMouseData() != MOUSE_ACK)
202*c2c66affSColin Finck {
203*c2c66affSColin Finck /* Failure */
204*c2c66affSColin Finck setAH(0x03);
205*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
206*c2c66affSColin Finck break;
207*c2c66affSColin Finck }
208*c2c66affSColin Finck
209*c2c66affSColin Finck /* Success */
210*c2c66affSColin Finck setAH(0x00);
211*c2c66affSColin Finck Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
212*c2c66affSColin Finck break;
213*c2c66affSColin Finck }
214*c2c66affSColin Finck
215*c2c66affSColin Finck /* Initialize */
216*c2c66affSColin Finck case 0x05:
217*c2c66affSColin Finck {
218*c2c66affSColin Finck // Fall through
219*c2c66affSColin Finck }
220*c2c66affSColin Finck
221*c2c66affSColin Finck /* Reset */
222*c2c66affSColin Finck case 0x01:
223*c2c66affSColin Finck {
224*c2c66affSColin Finck UCHAR Answer;
225*c2c66affSColin Finck
226*c2c66affSColin Finck SendMouseCommand(0xFF);
227*c2c66affSColin Finck Answer = ReadMouseData();
228*c2c66affSColin Finck /* A "Resend" signal (0xFE) is sent if no mouse is attached */
229*c2c66affSColin Finck if (Answer == 0xFE)
230*c2c66affSColin Finck {
231*c2c66affSColin Finck /* Resend */
232*c2c66affSColin Finck setAH(0x04);
233*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
234*c2c66affSColin Finck break;
235*c2c66affSColin Finck }
236*c2c66affSColin Finck else if (Answer != MOUSE_ACK)
237*c2c66affSColin Finck {
238*c2c66affSColin Finck /* Failure */
239*c2c66affSColin Finck setAH(0x03);
240*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
241*c2c66affSColin Finck break;
242*c2c66affSColin Finck }
243*c2c66affSColin Finck
244*c2c66affSColin Finck setBL(ReadMouseData()); // Should be MOUSE_BAT_SUCCESS
245*c2c66affSColin Finck setBH(ReadMouseData()); // Mouse ID
246*c2c66affSColin Finck
247*c2c66affSColin Finck /* Success */
248*c2c66affSColin Finck setAH(0x00);
249*c2c66affSColin Finck Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
250*c2c66affSColin Finck break;
251*c2c66affSColin Finck }
252*c2c66affSColin Finck
253*c2c66affSColin Finck /* Set Sampling Rate */
254*c2c66affSColin Finck case 0x02:
255*c2c66affSColin Finck {
256*c2c66affSColin Finck UCHAR SampleRate = 0;
257*c2c66affSColin Finck
258*c2c66affSColin Finck switch (getBH())
259*c2c66affSColin Finck {
260*c2c66affSColin Finck case 0x00: SampleRate = 10; break; // 10 reports/sec
261*c2c66affSColin Finck case 0x01: SampleRate = 20; break; // 20 " "
262*c2c66affSColin Finck case 0x02: SampleRate = 40; break; // 40 " "
263*c2c66affSColin Finck case 0x03: SampleRate = 60; break; // 60 " "
264*c2c66affSColin Finck case 0x04: SampleRate = 80; break; // 80 " "
265*c2c66affSColin Finck case 0x05: SampleRate = 100; break; // 100 " "
266*c2c66affSColin Finck case 0x06: SampleRate = 200; break; // 200 " "
267*c2c66affSColin Finck default: SampleRate = 0;
268*c2c66affSColin Finck }
269*c2c66affSColin Finck
270*c2c66affSColin Finck if (SampleRate == 0)
271*c2c66affSColin Finck {
272*c2c66affSColin Finck /* Invalid input */
273*c2c66affSColin Finck setAH(0x02);
274*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
275*c2c66affSColin Finck break;
276*c2c66affSColin Finck }
277*c2c66affSColin Finck
278*c2c66affSColin Finck SendMouseCommand(0xF3);
279*c2c66affSColin Finck if (ReadMouseData() != MOUSE_ACK)
280*c2c66affSColin Finck {
281*c2c66affSColin Finck /* Failure */
282*c2c66affSColin Finck setAH(0x03);
283*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
284*c2c66affSColin Finck break;
285*c2c66affSColin Finck }
286*c2c66affSColin Finck
287*c2c66affSColin Finck SendMouseCommand(SampleRate);
288*c2c66affSColin Finck if (ReadMouseData() != MOUSE_ACK)
289*c2c66affSColin Finck {
290*c2c66affSColin Finck /* Failure */
291*c2c66affSColin Finck setAH(0x03);
292*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
293*c2c66affSColin Finck break;
294*c2c66affSColin Finck }
295*c2c66affSColin Finck
296*c2c66affSColin Finck /* Success */
297*c2c66affSColin Finck setAH(0x00);
298*c2c66affSColin Finck Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
299*c2c66affSColin Finck break;
300*c2c66affSColin Finck }
301*c2c66affSColin Finck
302*c2c66affSColin Finck /* Set Resolution */
303*c2c66affSColin Finck case 0x03:
304*c2c66affSColin Finck {
305*c2c66affSColin Finck UCHAR Resolution = getBH();
306*c2c66affSColin Finck
307*c2c66affSColin Finck /*
308*c2c66affSColin Finck * 0: 25 dpi, 1 count per millimeter
309*c2c66affSColin Finck * 1: 50 dpi, 2 counts per millimeter
310*c2c66affSColin Finck * 2: 100 dpi, 4 counts per millimeter
311*c2c66affSColin Finck * 3: 200 dpi, 8 counts per millimeter
312*c2c66affSColin Finck */
313*c2c66affSColin Finck if (Resolution > 3)
314*c2c66affSColin Finck {
315*c2c66affSColin Finck /* Invalid input */
316*c2c66affSColin Finck setAH(0x02);
317*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
318*c2c66affSColin Finck break;
319*c2c66affSColin Finck }
320*c2c66affSColin Finck
321*c2c66affSColin Finck SendMouseCommand(0xE8);
322*c2c66affSColin Finck if (ReadMouseData() != MOUSE_ACK)
323*c2c66affSColin Finck {
324*c2c66affSColin Finck /* Failure */
325*c2c66affSColin Finck setAH(0x03);
326*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
327*c2c66affSColin Finck break;
328*c2c66affSColin Finck }
329*c2c66affSColin Finck
330*c2c66affSColin Finck SendMouseCommand(Resolution);
331*c2c66affSColin Finck if (ReadMouseData() != MOUSE_ACK)
332*c2c66affSColin Finck {
333*c2c66affSColin Finck /* Failure */
334*c2c66affSColin Finck setAH(0x03);
335*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
336*c2c66affSColin Finck break;
337*c2c66affSColin Finck }
338*c2c66affSColin Finck
339*c2c66affSColin Finck /* Success */
340*c2c66affSColin Finck setAH(0x00);
341*c2c66affSColin Finck Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
342*c2c66affSColin Finck break;
343*c2c66affSColin Finck }
344*c2c66affSColin Finck
345*c2c66affSColin Finck /* Get Type */
346*c2c66affSColin Finck case 0x04:
347*c2c66affSColin Finck {
348*c2c66affSColin Finck SendMouseCommand(0xF2);
349*c2c66affSColin Finck if (ReadMouseData() != MOUSE_ACK)
350*c2c66affSColin Finck {
351*c2c66affSColin Finck /* Failure */
352*c2c66affSColin Finck setAH(0x03);
353*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
354*c2c66affSColin Finck break;
355*c2c66affSColin Finck }
356*c2c66affSColin Finck
357*c2c66affSColin Finck setBH(ReadMouseData());
358*c2c66affSColin Finck
359*c2c66affSColin Finck /* Success */
360*c2c66affSColin Finck setAH(0x00);
361*c2c66affSColin Finck Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
362*c2c66affSColin Finck break;
363*c2c66affSColin Finck }
364*c2c66affSColin Finck
365*c2c66affSColin Finck /* Extended Commands (Return Status and Set Scaling Factor) */
366*c2c66affSColin Finck case 0x06:
367*c2c66affSColin Finck {
368*c2c66affSColin Finck UCHAR Command = getBH();
369*c2c66affSColin Finck
370*c2c66affSColin Finck switch (Command)
371*c2c66affSColin Finck {
372*c2c66affSColin Finck /* Return Status */
373*c2c66affSColin Finck case 0x00:
374*c2c66affSColin Finck {
375*c2c66affSColin Finck SendMouseCommand(0xE9);
376*c2c66affSColin Finck if (ReadMouseData() != MOUSE_ACK)
377*c2c66affSColin Finck {
378*c2c66affSColin Finck /* Failure */
379*c2c66affSColin Finck setAH(0x03);
380*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
381*c2c66affSColin Finck break;
382*c2c66affSColin Finck }
383*c2c66affSColin Finck
384*c2c66affSColin Finck setBL(ReadMouseData()); // Status
385*c2c66affSColin Finck setCL(ReadMouseData()); // Resolution
386*c2c66affSColin Finck setDL(ReadMouseData()); // Sample rate
387*c2c66affSColin Finck
388*c2c66affSColin Finck /* Success */
389*c2c66affSColin Finck setAH(0x00);
390*c2c66affSColin Finck Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
391*c2c66affSColin Finck break;
392*c2c66affSColin Finck }
393*c2c66affSColin Finck
394*c2c66affSColin Finck /* Set Scaling Factor to 1:1 */
395*c2c66affSColin Finck case 0x01:
396*c2c66affSColin Finck /* Set Scaling Factor to 2:1 */
397*c2c66affSColin Finck case 0x02:
398*c2c66affSColin Finck {
399*c2c66affSColin Finck SendMouseCommand(Command == 0x01 ? 0xE6 : 0xE7);
400*c2c66affSColin Finck if (ReadMouseData() != MOUSE_ACK)
401*c2c66affSColin Finck {
402*c2c66affSColin Finck /* Failure */
403*c2c66affSColin Finck setAH(0x03);
404*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
405*c2c66affSColin Finck break;
406*c2c66affSColin Finck }
407*c2c66affSColin Finck
408*c2c66affSColin Finck /* Success */
409*c2c66affSColin Finck setAH(0x00);
410*c2c66affSColin Finck Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
411*c2c66affSColin Finck break;
412*c2c66affSColin Finck }
413*c2c66affSColin Finck
414*c2c66affSColin Finck default:
415*c2c66affSColin Finck {
416*c2c66affSColin Finck /* Invalid function */
417*c2c66affSColin Finck setAH(0x01);
418*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
419*c2c66affSColin Finck break;
420*c2c66affSColin Finck }
421*c2c66affSColin Finck }
422*c2c66affSColin Finck
423*c2c66affSColin Finck break;
424*c2c66affSColin Finck }
425*c2c66affSColin Finck
426*c2c66affSColin Finck /* Set Device Handler Address */
427*c2c66affSColin Finck case 0x07:
428*c2c66affSColin Finck {
429*c2c66affSColin Finck /* ES:BX == 0000h:0000h removes the device handler */
430*c2c66affSColin Finck DeviceHandler = MAKELONG(getBX(), getES());
431*c2c66affSColin Finck
432*c2c66affSColin Finck /* Success */
433*c2c66affSColin Finck setAH(0x00);
434*c2c66affSColin Finck Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
435*c2c66affSColin Finck break;
436*c2c66affSColin Finck }
437*c2c66affSColin Finck
438*c2c66affSColin Finck /* Write to Pointer Port */
439*c2c66affSColin Finck case 0x08:
440*c2c66affSColin Finck {
441*c2c66affSColin Finck SendMouseCommand(getBL());
442*c2c66affSColin Finck if (ReadMouseData() != MOUSE_ACK)
443*c2c66affSColin Finck {
444*c2c66affSColin Finck /* Failure */
445*c2c66affSColin Finck setAH(0x03);
446*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
447*c2c66affSColin Finck break;
448*c2c66affSColin Finck }
449*c2c66affSColin Finck
450*c2c66affSColin Finck /* Success */
451*c2c66affSColin Finck setAH(0x00);
452*c2c66affSColin Finck Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
453*c2c66affSColin Finck break;
454*c2c66affSColin Finck }
455*c2c66affSColin Finck
456*c2c66affSColin Finck /* Read from Pointer Port */
457*c2c66affSColin Finck case 0x09:
458*c2c66affSColin Finck {
459*c2c66affSColin Finck setBL(ReadMouseData());
460*c2c66affSColin Finck setCL(ReadMouseData());
461*c2c66affSColin Finck setDL(ReadMouseData());
462*c2c66affSColin Finck
463*c2c66affSColin Finck /* Success */
464*c2c66affSColin Finck setAH(0x00);
465*c2c66affSColin Finck Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
466*c2c66affSColin Finck break;
467*c2c66affSColin Finck }
468*c2c66affSColin Finck
469*c2c66affSColin Finck default:
470*c2c66affSColin Finck {
471*c2c66affSColin Finck DPRINT1("INT 15h, AH = C2h, AL = %02Xh NOT IMPLEMENTED\n",
472*c2c66affSColin Finck getAL());
473*c2c66affSColin Finck
474*c2c66affSColin Finck /* Unknown function */
475*c2c66affSColin Finck setAH(0x01);
476*c2c66affSColin Finck Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
477*c2c66affSColin Finck }
478*c2c66affSColin Finck }
479*c2c66affSColin Finck
480*c2c66affSColin Finck /* Reenable mouse interrupt and events */
481*c2c66affSColin Finck EnableMouseInt();
482*c2c66affSColin Finck }
483*c2c66affSColin Finck
484*c2c66affSColin Finck /* PUBLIC FUNCTIONS ***********************************************************/
485*c2c66affSColin Finck
MouseBios32Post(VOID)486*c2c66affSColin Finck VOID MouseBios32Post(VOID)
487*c2c66affSColin Finck {
488*c2c66affSColin Finck UCHAR Answer;
489*c2c66affSColin Finck
490*c2c66affSColin Finck /* Initialize PS/2 mouse port */
491*c2c66affSColin Finck // Enable the port
492*c2c66affSColin Finck IOWriteB(PS2_CONTROL_PORT, 0xA8);
493*c2c66affSColin Finck
494*c2c66affSColin Finck /* Detect mouse presence by attempting a reset */
495*c2c66affSColin Finck SendMouseCommand(0xFF);
496*c2c66affSColin Finck Answer = ReadMouseData();
497*c2c66affSColin Finck /* A "Resend" signal (0xFE) is sent if no mouse is attached */
498*c2c66affSColin Finck if (Answer == 0xFE)
499*c2c66affSColin Finck {
500*c2c66affSColin Finck DPRINT1("No mouse present!\n");
501*c2c66affSColin Finck }
502*c2c66affSColin Finck else if (Answer != MOUSE_ACK)
503*c2c66affSColin Finck {
504*c2c66affSColin Finck DPRINT1("Mouse reset failure!\n");
505*c2c66affSColin Finck }
506*c2c66affSColin Finck else
507*c2c66affSColin Finck {
508*c2c66affSColin Finck /* Mouse present, try to completely enable it */
509*c2c66affSColin Finck
510*c2c66affSColin Finck // FIXME: The following is temporary until
511*c2c66affSColin Finck // this is moved into the mouse driver!!
512*c2c66affSColin Finck
513*c2c66affSColin Finck /* Enable packet reporting */
514*c2c66affSColin Finck SendMouseCommand(0xF4);
515*c2c66affSColin Finck if (ReadMouseData() != MOUSE_ACK)
516*c2c66affSColin Finck {
517*c2c66affSColin Finck DPRINT1("Failed to enable mouse!\n");
518*c2c66affSColin Finck }
519*c2c66affSColin Finck else
520*c2c66affSColin Finck {
521*c2c66affSColin Finck /* Enable mouse interrupt and events */
522*c2c66affSColin Finck EnableMouseInt();
523*c2c66affSColin Finck }
524*c2c66affSColin Finck }
525*c2c66affSColin Finck
526*c2c66affSColin Finck /* No mouse driver available so far */
527*c2c66affSColin Finck RegisterBiosInt32(0x33, NULL);
528*c2c66affSColin Finck
529*c2c66affSColin Finck /* Set up the HW vector interrupts */
530*c2c66affSColin Finck EnableHwIRQ(12, BiosMouseIrq);
531*c2c66affSColin Finck }
532*c2c66affSColin Finck
MouseBiosInitialize(VOID)533*c2c66affSColin Finck BOOLEAN MouseBiosInitialize(VOID)
534*c2c66affSColin Finck {
535*c2c66affSColin Finck return TRUE;
536*c2c66affSColin Finck }
537*c2c66affSColin Finck
MouseBios32Cleanup(VOID)538*c2c66affSColin Finck VOID MouseBios32Cleanup(VOID)
539*c2c66affSColin Finck {
540*c2c66affSColin Finck }
541