[NTVDM] Improve the PCH situation.
[reactos.git] / reactos / subsystems / mvdm / ntvdm / dos / dos32krnl / condrv.c
1 /*
2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: subsystems/mvdm/ntvdm/dos/dos32krnl/condrv.c
5 * PURPOSE: DOS32 CON Driver
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
8 */
9
10 #include "ntvdm.h"
11
12 #define NDEBUG
13 #include <debug.h>
14
15 /* PRIVATE VARIABLES **********************************************************/
16
17 PDOS_DEVICE_NODE Con = NULL;
18 BYTE ExtendedCode = 0;
19
20 /* PRIVATE FUNCTIONS **********************************************************/
21
22 WORD NTAPI ConDrvReadInput(PDOS_DEVICE_NODE Device, DWORD Buffer, PWORD Length)
23 {
24 CHAR Character;
25 WORD BytesRead = 0;
26 PCHAR Pointer = (PCHAR)FAR_POINTER(Buffer);
27
28 /* Save AX */
29 USHORT AX = getAX();
30
31 /*
32 * Use BIOS Get Keystroke function
33 */
34 while (BytesRead < *Length)
35 {
36 if (!ExtendedCode)
37 {
38 /* Call the BIOS INT 16h, AH=00h "Get Keystroke" */
39 setAH(0x00);
40 Int32Call(&DosContext, BIOS_KBD_INTERRUPT);
41
42 /* Retrieve the character in AL (scan code is in AH) */
43 Character = getAL();
44 }
45 else
46 {
47 /* Return the extended code */
48 Character = ExtendedCode;
49
50 /* And then clear it */
51 ExtendedCode = 0;
52 }
53
54 /* Check if this is a special character */
55 if (Character == 0) ExtendedCode = getAH();
56
57 Pointer[BytesRead++] = Character;
58
59 /* Stop on first carriage return */
60 if (Character == '\r') break;
61 }
62
63 *Length = BytesRead;
64
65 /* Restore AX */
66 setAX(AX);
67 return DOS_DEVSTAT_DONE;
68 }
69
70 WORD NTAPI ConDrvInputStatus(PDOS_DEVICE_NODE Device)
71 {
72 /* Save AX */
73 USHORT AX = getAX();
74
75 /* Call the BIOS */
76 setAH(0x01); // or 0x11 for enhanced, but what to choose?
77 Int32Call(&DosContext, BIOS_KBD_INTERRUPT);
78
79 /* Restore AX */
80 setAX(AX);
81
82 /* If ZF is set, set the busy bit */
83 if (getZF() && !ExtendedCode) return DOS_DEVSTAT_BUSY;
84 else return DOS_DEVSTAT_DONE;
85 }
86
87 WORD NTAPI ConDrvWriteOutput(PDOS_DEVICE_NODE Device, DWORD Buffer, PWORD Length)
88 {
89 WORD BytesWritten;
90 PCHAR Pointer = (PCHAR)FAR_POINTER(Buffer);
91
92 /* Save AX */
93 USHORT AX = getAX();
94
95 for (BytesWritten = 0; BytesWritten < *Length; BytesWritten++)
96 {
97 /* Set the character */
98 setAL(Pointer[BytesWritten]);
99
100 /* Call the BIOS INT 29h "Fast Console Output" function */
101 Int32Call(&DosContext, 0x29);
102 }
103
104 /* Restore AX */
105 setAX(AX);
106 return DOS_DEVSTAT_DONE;
107 }
108
109 WORD NTAPI ConDrvOpen(PDOS_DEVICE_NODE Device)
110 {
111 DPRINT("Handle to %Z opened\n", &Device->Name);
112 return DOS_DEVSTAT_DONE;
113 }
114
115 WORD NTAPI ConDrvClose(PDOS_DEVICE_NODE Device)
116 {
117 DPRINT("Handle to %Z closed\n", &Device->Name);
118 return DOS_DEVSTAT_DONE;
119 }
120
121 /* PUBLIC FUNCTIONS ***********************************************************/
122
123 VOID ConDrvInitialize(VOID)
124 {
125 Con = DosCreateDevice(DOS_DEVATTR_STDIN
126 | DOS_DEVATTR_STDOUT
127 | DOS_DEVATTR_CON
128 | DOS_DEVATTR_CHARACTER,
129 "CON");
130
131 Con->ReadRoutine = ConDrvReadInput;
132 Con->InputStatusRoutine = ConDrvInputStatus;
133 Con->WriteRoutine = ConDrvWriteOutput;
134 Con->OpenRoutine = ConDrvOpen;
135 Con->CloseRoutine = ConDrvClose;
136 }
137
138 VOID ConDrvCleanup(VOID)
139 {
140 if (Con) DosDeleteDevice(Con);
141 }