2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
5 * PURPOSE: I/O Port Handlers
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
10 /* INCLUDES *******************************************************************/
17 /* PRIVATE VARIABLES **********************************************************/
19 typedef struct _EMULATOR_IOPORT_HANDLERS
21 /* For Windows compatibility only, not used internally */
22 HANDLE hVdd
; // == 0 if unused,
23 // INVALID_HANDLE_VALUE if handled internally,
24 // a valid VDD handle if handled externally.
25 VDD_IO_HANDLERS VddIoHandlers
;
27 /* We use internally these members */
28 // EMULATOR_IN_PROC In;
29 // EMULATOR_OUT_PROC Out;
32 EMULATOR_INB_PROC InB
;
33 EMULATOR_INW_PROC InW
;
34 EMULATOR_IND_PROC InD
;
36 EMULATOR_INSB_PROC InsB
;
37 EMULATOR_INSW_PROC InsW
;
38 EMULATOR_INSD_PROC InsD
;
40 EMULATOR_OUTB_PROC OutB
;
41 EMULATOR_OUTW_PROC OutW
;
42 EMULATOR_OUTD_PROC OutD
;
44 EMULATOR_OUTSB_PROC OutsB
;
45 EMULATOR_OUTSW_PROC OutsW
;
46 EMULATOR_OUTSD_PROC OutsD
;
47 } EMULATOR_IOPORT_HANDLERS
, *PEMULATOR_IOPORT_HANDLERS
;
50 * This is the list of registered I/O Port handlers.
52 EMULATOR_IOPORT_HANDLERS IoPortProc
[EMULATOR_MAX_IOPORTS_NUM
] = {{NULL
}};
54 /* PRIVATE FUNCTIONS **********************************************************/
60 if (IoPortProc
[Port
].InB
)
62 *Buffer
= IoPortProc
[Port
].InB(Port
);
66 /* Return an empty port byte value */
67 DPRINT1("Read from unknown port: 0x%X\n", Port
);
73 IOReadStrB(ULONG Port
,
77 if (IoPortProc
[Port
].InsB
)
79 IoPortProc
[Port
].InsB(Port
, Buffer
, Count
);
85 IOReadB(Port
, Buffer
++);
94 if (IoPortProc
[Port
].OutB
)
96 IoPortProc
[Port
].OutB(Port
, *Buffer
);
101 DPRINT1("Write to unknown port: 0x%X\n", Port
);
106 IOWriteStrB(ULONG Port
,
110 if (IoPortProc
[Port
].OutsB
)
112 IoPortProc
[Port
].OutsB(Port
, Buffer
, Count
);
118 IOWriteB(Port
, Buffer
++);
127 if (IoPortProc
[Port
].InW
)
129 *Buffer
= IoPortProc
[Port
].InW(Port
);
135 // FIXME: Is it ok on Little endian and Big endian ??
137 IOReadB(Port
+ sizeof(UCHAR
), &High
);
138 *Buffer
= MAKEWORD(Low
, High
);
143 IOReadStrW(ULONG Port
,
147 if (IoPortProc
[Port
].InsW
)
149 IoPortProc
[Port
].InsW(Port
, Buffer
, Count
);
155 IOReadW(Port
, Buffer
++);
164 if (IoPortProc
[Port
].OutW
)
166 IoPortProc
[Port
].OutW(Port
, *Buffer
);
172 // FIXME: Is it ok on Little endian and Big endian ??
173 Low
= LOBYTE(*Buffer
);
174 High
= HIBYTE(*Buffer
);
175 IOWriteB(Port
, &Low
);
176 IOWriteB(Port
+ sizeof(UCHAR
), &High
);
181 IOWriteStrW(ULONG Port
,
185 if (IoPortProc
[Port
].OutsW
)
187 IoPortProc
[Port
].OutsW(Port
, Buffer
, Count
);
193 IOWriteW(Port
, Buffer
++);
202 if (IoPortProc
[Port
].InD
)
204 *Buffer
= IoPortProc
[Port
].InD(Port
);
210 // FIXME: Is it ok on Little endian and Big endian ??
212 IOReadW(Port
+ sizeof(USHORT
), &High
);
213 *Buffer
= MAKELONG(Low
, High
);
218 IOReadStrD(ULONG Port
,
222 if (IoPortProc
[Port
].InsD
)
224 IoPortProc
[Port
].InsD(Port
, Buffer
, Count
);
230 IOReadD(Port
, Buffer
++);
239 if (IoPortProc
[Port
].OutD
)
241 IoPortProc
[Port
].OutD(Port
, *Buffer
);
247 // FIXME: Is it ok on Little endian and Big endian ??
248 Low
= LOWORD(*Buffer
);
249 High
= HIWORD(*Buffer
);
250 IOWriteW(Port
, &Low
);
251 IOWriteW(Port
+ sizeof(USHORT
), &High
);
256 IOWriteStrD(ULONG Port
,
260 if (IoPortProc
[Port
].OutsD
)
262 IoPortProc
[Port
].OutsD(Port
, Buffer
, Count
);
268 IOWriteD(Port
, Buffer
++);
273 /* PUBLIC FUNCTIONS ***********************************************************/
275 VOID
RegisterIoPort(ULONG Port
,
276 EMULATOR_INB_PROC InHandler
,
277 EMULATOR_OUTB_PROC OutHandler
)
279 if (IoPortProc
[Port
].InB
== NULL
)
280 IoPortProc
[Port
].InB
= InHandler
;
282 DPRINT1("IoPortProc[0x%X].InB already registered\n", Port
);
284 if (IoPortProc
[Port
].OutB
== NULL
)
285 IoPortProc
[Port
].OutB
= OutHandler
;
287 DPRINT1("IoPortProc[0x%X].OutB already registered\n", Port
);
290 VOID
UnregisterIoPort(ULONG Port
)
292 IoPortProc
[Port
].InB
= NULL
;
293 IoPortProc
[Port
].OutB
= NULL
;
297 EmulatorReadIo(PFAST486_STATE State
,
303 UNREFERENCED_PARAMETER(State
);
305 if (DataSize
== 0 || DataCount
== 0) return;
307 if (DataSize
== sizeof(UCHAR
))
310 IOReadB(Port
, Buffer
);
312 IOReadStrB(Port
, Buffer
, DataCount
);
314 else if (DataSize
== sizeof(USHORT
))
317 IOReadW(Port
, Buffer
);
319 IOReadStrW(Port
, Buffer
, DataCount
);
321 else if (DataSize
== sizeof(ULONG
))
324 IOReadD(Port
, Buffer
);
326 IOReadStrD(Port
, Buffer
, DataCount
);
330 PBYTE Address
= (PBYTE
)Buffer
;
334 ULONG CurrentPort
= Port
;
336 UCHAR NewDataSize
= DataSize
;
339 Count
= NewDataSize
/ sizeof(ULONG
);
340 NewDataSize
= NewDataSize
% sizeof(ULONG
);
343 IOReadD(CurrentPort
, (PULONG
)Address
);
344 CurrentPort
+= sizeof(ULONG
);
345 Address
+= sizeof(ULONG
);
349 Count
= NewDataSize
/ sizeof(USHORT
);
350 NewDataSize
= NewDataSize
% sizeof(USHORT
);
353 IOReadW(CurrentPort
, (PUSHORT
)Address
);
354 CurrentPort
+= sizeof(USHORT
);
355 Address
+= sizeof(USHORT
);
359 Count
= NewDataSize
/ sizeof(UCHAR
);
360 NewDataSize
= NewDataSize
% sizeof(UCHAR
);
363 IOReadB(CurrentPort
, (PUCHAR
)Address
);
364 CurrentPort
+= sizeof(UCHAR
);
365 Address
+= sizeof(UCHAR
);
369 ASSERT(NewDataSize
== 0);
375 EmulatorWriteIo(PFAST486_STATE State
,
381 UNREFERENCED_PARAMETER(State
);
383 if (DataSize
== 0 || DataCount
== 0) return;
385 if (DataSize
== sizeof(UCHAR
))
388 IOWriteB(Port
, Buffer
);
390 IOWriteStrB(Port
, Buffer
, DataCount
);
392 else if (DataSize
== sizeof(USHORT
))
395 IOWriteW(Port
, Buffer
);
397 IOWriteStrW(Port
, Buffer
, DataCount
);
399 else if (DataSize
== sizeof(ULONG
))
402 IOWriteD(Port
, Buffer
);
404 IOWriteStrD(Port
, Buffer
, DataCount
);
408 PBYTE Address
= (PBYTE
)Buffer
;
412 ULONG CurrentPort
= Port
;
414 UCHAR NewDataSize
= DataSize
;
417 Count
= NewDataSize
/ sizeof(ULONG
);
418 NewDataSize
= NewDataSize
% sizeof(ULONG
);
421 IOWriteD(CurrentPort
, (PULONG
)Address
);
422 CurrentPort
+= sizeof(ULONG
);
423 Address
+= sizeof(ULONG
);
427 Count
= NewDataSize
/ sizeof(USHORT
);
428 NewDataSize
= NewDataSize
% sizeof(USHORT
);
431 IOWriteW(CurrentPort
, (PUSHORT
)Address
);
432 CurrentPort
+= sizeof(USHORT
);
433 Address
+= sizeof(USHORT
);
437 Count
= NewDataSize
/ sizeof(UCHAR
);
438 NewDataSize
= NewDataSize
% sizeof(UCHAR
);
441 IOWriteB(CurrentPort
, (PUCHAR
)Address
);
442 CurrentPort
+= sizeof(UCHAR
);
443 Address
+= sizeof(UCHAR
);
447 ASSERT(NewDataSize
== 0);
456 VDDInstallIOHook(HANDLE hVdd
,
458 PVDD_IO_PORTRANGE pPortRange
,
459 PVDD_IO_HANDLERS IOhandler
)
461 /* Check possible validity of the VDD handle */
462 if (hVdd
== 0 || hVdd
== INVALID_HANDLE_VALUE
) return FALSE
;
464 /* Loop for each range of I/O ports */
469 /* Register the range of I/O ports */
470 for (i
= pPortRange
->First
; i
<= pPortRange
->Last
; ++i
)
473 * Don't do anything if the I/O port is already
474 * handled internally or externally.
476 if (IoPortProc
[i
].hVdd
!= 0)
478 DPRINT1("IoPortProc[0x%X] already registered\n", i
);
482 /* Register wrt. the VDD */
483 IoPortProc
[i
].hVdd
= hVdd
;
485 /* Disable the internal handlers */
486 IoPortProc
[i
].InB
= NULL
;
487 IoPortProc
[i
].InW
= NULL
;
488 IoPortProc
[i
].InD
= NULL
;
490 IoPortProc
[i
].InsB
= NULL
;
491 IoPortProc
[i
].InsW
= NULL
;
492 IoPortProc
[i
].InsD
= NULL
;
494 IoPortProc
[i
].OutB
= NULL
;
495 IoPortProc
[i
].OutW
= NULL
;
496 IoPortProc
[i
].OutD
= NULL
;
498 IoPortProc
[i
].OutsB
= NULL
;
499 IoPortProc
[i
].OutsW
= NULL
;
500 IoPortProc
[i
].OutsD
= NULL
;
502 /* Save our handlers */
503 IoPortProc
[i
].VddIoHandlers
= *IOhandler
; // IOhandler[i]; ?????????
506 /* Go to next range */
515 VDDDeInstallIOHook(HANDLE hVdd
,
517 PVDD_IO_PORTRANGE pPortRange
)
519 /* Check possible validity of the VDD handle */
520 if (hVdd
== 0 || hVdd
== INVALID_HANDLE_VALUE
) return;
522 /* Loop for each range of I/O ports */
527 /* Unregister the range of I/O ports */
528 for (i
= pPortRange
->First
; i
<= pPortRange
->Last
; ++i
)
531 * Don't do anything if we don't own the I/O port.
533 if (IoPortProc
[i
].hVdd
!= hVdd
)
535 DPRINT1("IoPortProc[0x%X] owned by somebody else\n", i
);
540 * Put automagically all the fields to zero:
541 * the hVdd gets unregistered as well as all the handlers.
543 // IoPortProc[i] = {NULL};
544 ZeroMemory(&IoPortProc
[i
], sizeof(IoPortProc
[i
]));
547 /* Go to next range */