ReactOS 0.4.16-dev-319-g6cf4263
io.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/io.c
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)
8 */
9
10/* INCLUDES *******************************************************************/
11
12#include "ntvdm.h"
13
14#define NDEBUG
15#include <debug.h>
16
17#include "emulator.h"
18#include "io.h"
19
20/* PRIVATE VARIABLES **********************************************************/
21
23{
27
31
35
40
42{
43 HANDLE hVdd; // == NULL if unused,
44 // INVALID_HANDLE_VALUE if handled internally,
45 // a valid VDD handle if handled externally.
46 union
47 {
48 /* For Windows compatibility only, not used internally... */
50
51 /* ... we use these members internally */
53 };
55
56/*
57 * This is the list of registered I/O Port handlers.
58 */
60
61/* PUBLIC FUNCTIONS ***********************************************************/
62
65{
67 IoPortProc[Port].IoHandlers.InB)
68 {
70 }
72 IoPortProc[Port].VddIoHandlers.inb_handler)
73 {
74 UCHAR Data;
77 return Data;
78 }
79 else
80 {
81 /* Return an empty port byte value */
82 DPRINT("Read from unknown port: 0x%X\n", Port);
83 return 0xFF;
84 }
85}
86
87VOID
91{
93 IoPortProc[Port].IoHandlers.InsB)
94 {
96 }
98 IoPortProc[Port].VddIoHandlers.insb_handler)
99 {
100 ASSERT(Port <= MAXWORD);
101 ASSERT(Count <= MAXWORD);
103 }
104 else
105 {
106 while (Count--) *Buffer++ = IOReadB(Port);
107 }
108}
109
110VOID
113{
115 IoPortProc[Port].IoHandlers.OutB)
116 {
118 }
120 IoPortProc[Port].VddIoHandlers.outb_handler)
121 {
122 ASSERT(Port <= MAXWORD);
124 }
125 else
126 {
127 /* Do nothing */
128 DPRINT("Write to unknown port: 0x%X\n", Port);
129 }
130}
131
132VOID
135 ULONG Count)
136{
138 IoPortProc[Port].IoHandlers.OutsB)
139 {
141 }
143 IoPortProc[Port].VddIoHandlers.outsb_handler)
144 {
145 ASSERT(Port <= MAXWORD);
146 ASSERT(Count <= MAXWORD);
148 }
149 else
150 {
151 while (Count--) IOWriteB(Port, *Buffer++);
152 }
153}
154
155USHORT
157{
159 IoPortProc[Port].IoHandlers.InW)
160 {
162 }
164 IoPortProc[Port].VddIoHandlers.inw_handler)
165 {
166 USHORT Data;
167 ASSERT(Port <= MAXWORD);
169 return Data;
170 }
171 else
172 {
173 UCHAR Low, High;
174
175 // FIXME: Is it ok on Little endian and Big endian ??
176 Low = IOReadB(Port);
177 High = IOReadB(Port + sizeof(UCHAR));
178 return MAKEWORD(Low, High);
179 }
180}
181
182VOID
185 ULONG Count)
186{
188 IoPortProc[Port].IoHandlers.InsW)
189 {
191 }
193 IoPortProc[Port].VddIoHandlers.insw_handler)
194 {
195 ASSERT(Port <= MAXWORD);
196 ASSERT(Count <= MAXWORD);
198 }
199 else
200 {
201 while (Count--) *Buffer++ = IOReadW(Port);
202 }
203}
204
205VOID
208{
210 IoPortProc[Port].IoHandlers.OutW)
211 {
213 }
215 IoPortProc[Port].VddIoHandlers.outw_handler)
216 {
217 ASSERT(Port <= MAXWORD);
219 }
220 else
221 {
222 // FIXME: Is it ok on Little endian and Big endian ??
224 IOWriteB(Port + sizeof(UCHAR), HIBYTE(Buffer));
225 }
226}
227
228VOID
231 ULONG Count)
232{
234 IoPortProc[Port].IoHandlers.OutsW)
235 {
237 }
239 IoPortProc[Port].VddIoHandlers.outsw_handler)
240 {
241 ASSERT(Port <= MAXWORD);
242 ASSERT(Count <= MAXWORD);
244 }
245 else
246 {
247 while (Count--) IOWriteW(Port, *Buffer++);
248 }
249}
250
251ULONG
253{
255 IoPortProc[Port].IoHandlers.InD)
256 {
258 }
259 else
260 {
261 USHORT Low, High;
262
263 // FIXME: Is it ok on Little endian and Big endian ??
264 Low = IOReadW(Port);
265 High = IOReadW(Port + sizeof(USHORT));
266 return MAKELONG(Low, High);
267 }
268}
269
270VOID
273 ULONG Count)
274{
276 IoPortProc[Port].IoHandlers.InsD)
277 {
279 }
280 else
281 {
282 while (Count--) *Buffer++ = IOReadD(Port);
283 }
284}
285
286VOID
289{
291 IoPortProc[Port].IoHandlers.OutD)
292 {
294 }
295 else
296 {
297 // FIXME: Is it ok on Little endian and Big endian ??
299 IOWriteW(Port + sizeof(USHORT), HIWORD(Buffer));
300 }
301}
302
303VOID
306 ULONG Count)
307{
309 IoPortProc[Port].IoHandlers.OutsD)
310 {
312 }
313 else
314 {
315 while (Count--) IOWriteD(Port, *Buffer++);
316 }
317}
318
319
321 EMULATOR_INB_PROC InHandler,
322 EMULATOR_OUTB_PROC OutHandler)
323{
324 if (IoPortProc[Port].IoHandlers.InB == NULL)
325 IoPortProc[Port].IoHandlers.InB = InHandler;
326 else
327 DPRINT1("IoPortProc[0x%X].IoHandlers.InB already registered\n", Port);
328
329 if (IoPortProc[Port].IoHandlers.OutB == NULL)
330 IoPortProc[Port].IoHandlers.OutB = OutHandler;
331 else
332 DPRINT1("IoPortProc[0x%X].IoHandlers.OutB already registered\n", Port);
333
334 /* We hold the I/O port internally */
336}
337
339{
340 /*
341 * Put automagically all the fields to zero:
342 * the hVdd gets unregistered as well as all the handlers.
343 */
344 // IoPortProc[Port] = {NULL};
346}
347
349EmulatorReadIo(PFAST486_STATE State,
350 USHORT Port,
352 ULONG DataCount,
354{
356
357 if (DataSize == 0 || DataCount == 0) return;
358
359 if (DataSize == sizeof(UCHAR))
360 {
361 if (DataCount == 1)
363 else
364 IOReadStrB(Port, Buffer, DataCount);
365 }
366 else if (DataSize == sizeof(USHORT))
367 {
368 if (DataCount == 1)
370 else
371 IOReadStrW(Port, Buffer, DataCount);
372 }
373 else if (DataSize == sizeof(ULONG))
374 {
375 if (DataCount == 1)
377 else
378 IOReadStrD(Port, Buffer, DataCount);
379 }
380 else
381 {
383
384 while (DataCount--)
385 {
386 ULONG CurrentPort = Port;
387 ULONG Count;
388 UCHAR NewDataSize = DataSize;
389
390 /* Read dword */
391 Count = NewDataSize >> 2; // NewDataSize / sizeof(ULONG);
392 NewDataSize = NewDataSize & 3; // NewDataSize % sizeof(ULONG);
393 while (Count--)
394 {
395 *(PULONG)Address = IOReadD(CurrentPort);
396 CurrentPort += sizeof(ULONG);
397 Address += sizeof(ULONG);
398 }
399
400 /* Read word */
401 Count = NewDataSize >> 1; // NewDataSize / sizeof(USHORT);
402 NewDataSize = NewDataSize & 1; // NewDataSize % sizeof(USHORT);
403 while (Count--)
404 {
405 *(PUSHORT)Address = IOReadW(CurrentPort);
406 CurrentPort += sizeof(USHORT);
407 Address += sizeof(USHORT);
408 }
409
410 /* Read byte */
411 Count = NewDataSize; // NewDataSize / sizeof(UCHAR);
412 // NewDataSize = NewDataSize % sizeof(UCHAR);
413 while (Count--)
414 {
415 *(PUCHAR)Address = IOReadB(CurrentPort);
416 CurrentPort += sizeof(UCHAR);
417 Address += sizeof(UCHAR);
418 }
419 }
420 }
421}
422
424EmulatorWriteIo(PFAST486_STATE State,
425 USHORT Port,
427 ULONG DataCount,
429{
431
432 if (DataSize == 0 || DataCount == 0) return;
433
434 if (DataSize == sizeof(UCHAR))
435 {
436 if (DataCount == 1)
438 else
439 IOWriteStrB(Port, Buffer, DataCount);
440 }
441 else if (DataSize == sizeof(USHORT))
442 {
443 if (DataCount == 1)
445 else
446 IOWriteStrW(Port, Buffer, DataCount);
447 }
448 else if (DataSize == sizeof(ULONG))
449 {
450 if (DataCount == 1)
452 else
453 IOWriteStrD(Port, Buffer, DataCount);
454 }
455 else
456 {
458
459 while (DataCount--)
460 {
461 ULONG CurrentPort = Port;
462 ULONG Count;
463 UCHAR NewDataSize = DataSize;
464
465 /* Write dword */
466 Count = NewDataSize >> 2; // NewDataSize / sizeof(ULONG);
467 NewDataSize = NewDataSize & 3; // NewDataSize % sizeof(ULONG);
468 while (Count--)
469 {
470 IOWriteD(CurrentPort, *(PULONG)Address);
471 CurrentPort += sizeof(ULONG);
472 Address += sizeof(ULONG);
473 }
474
475 /* Write word */
476 Count = NewDataSize >> 1; // NewDataSize / sizeof(USHORT);
477 NewDataSize = NewDataSize & 1; // NewDataSize % sizeof(USHORT);
478 while (Count--)
479 {
480 IOWriteW(CurrentPort, *(PUSHORT)Address);
481 CurrentPort += sizeof(USHORT);
482 Address += sizeof(USHORT);
483 }
484
485 /* Write byte */
486 Count = NewDataSize; // NewDataSize / sizeof(UCHAR);
487 // NewDataSize = NewDataSize % sizeof(UCHAR);
488 while (Count--)
489 {
490 IOWriteB(CurrentPort, *(PUCHAR)Address);
491 CurrentPort += sizeof(UCHAR);
492 Address += sizeof(UCHAR);
493 }
494 }
495 }
496}
497
498
499
500BOOL
501WINAPI
503 IN WORD cPortRange,
504 IN PVDD_IO_PORTRANGE pPortRange,
505 IN PVDD_IO_HANDLERS IoHandlers)
506{
507 WORD i;
508
509 /* Check validity of the VDD handle */
510 if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE)
511 {
513 return FALSE;
514 }
515
516 /* Loop for each range of I/O ports */
517 while (cPortRange--)
518 {
519 /* Register the range of I/O ports */
520 for (i = pPortRange->First; i <= pPortRange->Last; ++i)
521 {
522 /*
523 * Don't do anything if the I/O port is already
524 * handled internally or externally.
525 */
526 if (IoPortProc[i].hVdd != NULL)
527 {
528 DPRINT1("IoPortProc[0x%X] already registered\n", i);
529 continue;
530 }
531
532 /* Register wrt. the VDD */
534
535 /* Disable the internal handlers */
539
543
547
551
552 /* Save our handlers */
553 IoPortProc[i].VddIoHandlers = *IoHandlers;
554 }
555
556 /* Go to the next range */
557 ++pPortRange;
558 }
559
560 return TRUE;
561}
562
563VOID
564WINAPI
566 IN WORD cPortRange,
567 IN PVDD_IO_PORTRANGE pPortRange)
568{
569 WORD i;
570
571 /* Check validity of the VDD handle */
572 if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE)
573 {
575 return;
576 }
577
578 /* Loop for each range of I/O ports */
579 while (cPortRange--)
580 {
581 /* Unregister the range of I/O ports */
582 for (i = pPortRange->First; i <= pPortRange->Last; ++i)
583 {
584 /*
585 * Don't do anything if we don't own the I/O port.
586 */
587 if (IoPortProc[i].hVdd != hVdd)
588 {
589 DPRINT1("IoPortProc[0x%X] owned by somebody else\n", i);
590 continue;
591 }
592
593 /*
594 * Put automagically all the fields to zero:
595 * the hVdd gets unregistered as well as all the handlers.
596 */
597 // IoPortProc[i] = {NULL};
599 }
600
601 /* Go to the next range */
602 ++pPortRange;
603 }
604}
605
606/* EOF */
#define DPRINT1
Definition: precomp.h:8
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
unsigned int BOOL
Definition: ntddk_ex.h:94
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
CPPORT Port[4]
Definition: headless.c:35
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define ASSERT(a)
Definition: mode.c:44
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
int Count
Definition: noreturn.cpp:7
#define FASTCALL
Definition: nt_native.h:50
#define MAXWORD
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
#define LOWORD(l)
Definition: pedump.c:82
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
#define DPRINT
Definition: sndvol32.h:73
@ High
Definition: strmini.h:378
@ Low
Definition: strmini.h:380
VDD_IO_HANDLERS VddIoHandlers
Definition: io.c:49
EMULATOR_IO_HANDLERS IoHandlers
Definition: io.c:52
EMULATOR_OUTW_PROC OutW
Definition: io.c:33
EMULATOR_OUTD_PROC OutD
Definition: io.c:34
EMULATOR_OUTSD_PROC OutsD
Definition: io.c:38
EMULATOR_OUTB_PROC OutB
Definition: io.c:32
EMULATOR_INSD_PROC InsD
Definition: io.c:30
EMULATOR_INSW_PROC InsW
Definition: io.c:29
EMULATOR_INB_PROC InB
Definition: io.c:24
EMULATOR_INW_PROC InW
Definition: io.c:25
EMULATOR_OUTSW_PROC OutsW
Definition: io.c:37
EMULATOR_IND_PROC InD
Definition: io.c:26
EMULATOR_OUTSB_PROC OutsB
Definition: io.c:36
EMULATOR_INSB_PROC InsB
Definition: io.c:28
PFNVDD_INW inw_handler
Definition: nt_vdd.h:146
PFNVDD_OUTSB outsb_handler
Definition: nt_vdd.h:151
PFNVDD_OUTW outw_handler
Definition: nt_vdd.h:150
PFNVDD_OUTB outb_handler
Definition: nt_vdd.h:149
PFNVDD_INSW insw_handler
Definition: nt_vdd.h:148
PFNVDD_INB inb_handler
Definition: nt_vdd.h:145
PFNVDD_INSB insb_handler
Definition: nt_vdd.h:147
PFNVDD_OUTSW outsw_handler
Definition: nt_vdd.h:152
struct _EMULATOR_IOPORT_HANDLERS EMULATOR_IOPORT_HANDLERS
VOID FASTCALL EmulatorReadIo(PFAST486_STATE State, USHORT Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize)
Definition: io.c:349
BOOL WINAPI VDDInstallIOHook(IN HANDLE hVdd, IN WORD cPortRange, IN PVDD_IO_PORTRANGE pPortRange, IN PVDD_IO_HANDLERS IoHandlers)
Definition: io.c:502
struct _EMULATOR_IO_HANDLERS * PEMULATOR_IO_HANDLERS
ULONG IOReadD(USHORT Port)
Definition: io.c:252
VOID IOWriteB(USHORT Port, UCHAR Buffer)
Definition: io.c:111
VOID IOWriteW(USHORT Port, USHORT Buffer)
Definition: io.c:206
VOID IOReadStrB(USHORT Port, PUCHAR Buffer, ULONG Count)
Definition: io.c:88
USHORT IOReadW(USHORT Port)
Definition: io.c:156
VOID IOWriteD(USHORT Port, ULONG Buffer)
Definition: io.c:287
EMULATOR_IOPORT_HANDLERS IoPortProc[EMULATOR_MAX_IOPORTS_NUM]
Definition: io.c:59
VOID IOReadStrW(USHORT Port, PUSHORT Buffer, ULONG Count)
Definition: io.c:183
VOID IOWriteStrW(USHORT Port, PUSHORT Buffer, ULONG Count)
Definition: io.c:229
VOID WINAPI VDDDeInstallIOHook(IN HANDLE hVdd, IN WORD cPortRange, IN PVDD_IO_PORTRANGE pPortRange)
Definition: io.c:565
struct _EMULATOR_IOPORT_HANDLERS * PEMULATOR_IOPORT_HANDLERS
VOID IOReadStrD(USHORT Port, PULONG Buffer, ULONG Count)
Definition: io.c:271
VOID UnregisterIoPort(USHORT Port)
Definition: io.c:338
struct _EMULATOR_IO_HANDLERS EMULATOR_IO_HANDLERS
UCHAR IOReadB(USHORT Port)
Definition: io.c:64
VOID FASTCALL EmulatorWriteIo(PFAST486_STATE State, USHORT Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize)
Definition: io.c:424
VOID IOWriteStrD(USHORT Port, PULONG Buffer, ULONG Count)
Definition: io.c:304
VOID IOWriteStrB(USHORT Port, PUCHAR Buffer, ULONG Count)
Definition: io.c:133
VOID RegisterIoPort(USHORT Port, EMULATOR_INB_PROC InHandler, EMULATOR_OUTB_PROC OutHandler)
Definition: io.c:320
#define EMULATOR_MAX_IOPORTS_NUM
Definition: io.h:15
USHORT(WINAPI * EMULATOR_INW_PROC)(USHORT Port)
Definition: io.h:20
VOID(WINAPI * EMULATOR_OUTB_PROC)(USHORT Port, UCHAR Data)
Definition: io.h:27
VOID(WINAPI * EMULATOR_OUTSD_PROC)(USHORT Port, PULONG Buffer, ULONG Count)
Definition: io.h:33
VOID(WINAPI * EMULATOR_INSW_PROC)(USHORT Port, PUSHORT Buffer, ULONG Count)
Definition: io.h:24
VOID(WINAPI * EMULATOR_OUTD_PROC)(USHORT Port, ULONG Data)
Definition: io.h:29
VOID(WINAPI * EMULATOR_OUTSB_PROC)(USHORT Port, PUCHAR Buffer, ULONG Count)
Definition: io.h:31
ULONG(WINAPI * EMULATOR_IND_PROC)(USHORT Port)
Definition: io.h:21
VOID(WINAPI * EMULATOR_OUTSW_PROC)(USHORT Port, PUSHORT Buffer, ULONG Count)
Definition: io.h:32
VOID(WINAPI * EMULATOR_INSD_PROC)(USHORT Port, PULONG Buffer, ULONG Count)
Definition: io.h:25
VOID(WINAPI * EMULATOR_OUTW_PROC)(USHORT Port, USHORT Data)
Definition: io.h:28
VOID(WINAPI * EMULATOR_INSB_PROC)(USHORT Port, PUCHAR Buffer, ULONG Count)
Definition: io.h:23
UCHAR(WINAPI * EMULATOR_INB_PROC)(USHORT Port)
Definition: io.h:19
HANDLE hVdd
Definition: testvdd.c:87
uint32_t * PULONG
Definition: typedefs.h:59
#define MAKEWORD(a, b)
Definition: typedefs.h:248
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
#define MAKELONG(a, b)
Definition: typedefs.h:249
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
#define WINAPI
Definition: msvc.h:6
unsigned char UCHAR
Definition: xmlstorage.h:181