[BASESRV][NTVDM][TESTVDD] Improve the FILE header section. Brought to you by Adam...
[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 /* INCLUDES *******************************************************************/
11
12 #define NDEBUG
13
14 #include "ntvdm.h"
15 #include "emulator.h"
16
17 #include "dos.h"
18 #include "dos/dem.h"
19
20 #include "bios/bios.h"
21
22 /* PRIVATE VARIABLES **********************************************************/
23
24 PDOS_DEVICE_NODE Con = NULL;
25 BYTE ExtendedCode = 0;
26
27 /* PRIVATE FUNCTIONS **********************************************************/
28
29 WORD NTAPI ConDrvReadInput(PDOS_DEVICE_NODE Device, DWORD Buffer, PWORD Length)
30 {
31 CHAR Character;
32 WORD BytesRead = 0;
33 PCHAR Pointer = (PCHAR)FAR_POINTER(Buffer);
34
35 /* Save AX */
36 USHORT AX = getAX();
37
38 /*
39 * Use BIOS Get Keystroke function
40 */
41 while (BytesRead < *Length)
42 {
43 if (!ExtendedCode)
44 {
45 /* Call the BIOS INT 16h, AH=00h "Get Keystroke" */
46 setAH(0x00);
47 Int32Call(&DosContext, BIOS_KBD_INTERRUPT);
48
49 /* Retrieve the character in AL (scan code is in AH) */
50 Character = getAL();
51 }
52 else
53 {
54 /* Return the extended code */
55 Character = ExtendedCode;
56
57 /* And then clear it */
58 ExtendedCode = 0;
59 }
60
61 /* Check if this is a special character */
62 if (Character == 0) ExtendedCode = getAH();
63
64 Pointer[BytesRead++] = Character;
65
66 if (Character != 0 && DoEcho)
67 DosPrintCharacter(DOS_OUTPUT_HANDLE, Character);
68
69 /* Stop on first carriage return */
70 if (Character == '\r')
71 {
72 if (DoEcho) DosPrintCharacter(DOS_OUTPUT_HANDLE, '\n');
73 break;
74 }
75 }
76
77 *Length = BytesRead;
78
79 /* Restore AX */
80 setAX(AX);
81 return DOS_DEVSTAT_DONE;
82 }
83
84 WORD NTAPI ConDrvInputStatus(PDOS_DEVICE_NODE Device)
85 {
86 /* Save AX */
87 USHORT AX = getAX();
88
89 /* Call the BIOS */
90 setAH(0x01); // or 0x11 for enhanced, but what to choose?
91 Int32Call(&DosContext, BIOS_KBD_INTERRUPT);
92
93 /* Restore AX */
94 setAX(AX);
95
96 /* If ZF is set, set the busy bit */
97 if (getZF() && !ExtendedCode) return DOS_DEVSTAT_BUSY;
98 else return DOS_DEVSTAT_DONE;
99 }
100
101 WORD NTAPI ConDrvWriteOutput(PDOS_DEVICE_NODE Device, DWORD Buffer, PWORD Length)
102 {
103 WORD BytesWritten;
104 PCHAR Pointer = (PCHAR)FAR_POINTER(Buffer);
105
106 /* Save AX */
107 USHORT AX = getAX();
108
109 for (BytesWritten = 0; BytesWritten < *Length; BytesWritten++)
110 {
111 /* Set the character */
112 setAL(Pointer[BytesWritten]);
113
114 /* Call the BIOS INT 29h "Fast Console Output" function */
115 Int32Call(&DosContext, 0x29);
116 }
117
118 /* Restore AX */
119 setAX(AX);
120 return DOS_DEVSTAT_DONE;
121 }
122
123 WORD NTAPI ConDrvOpen(PDOS_DEVICE_NODE Device)
124 {
125 DPRINT("Handle to %Z opened\n", &Device->Name);
126 return DOS_DEVSTAT_DONE;
127 }
128
129 WORD NTAPI ConDrvClose(PDOS_DEVICE_NODE Device)
130 {
131 DPRINT("Handle to %Z closed\n", &Device->Name);
132 return DOS_DEVSTAT_DONE;
133 }
134
135 /* PUBLIC FUNCTIONS ***********************************************************/
136
137 VOID ConDrvInitialize(VOID)
138 {
139 Con = DosCreateDevice(DOS_DEVATTR_STDIN
140 | DOS_DEVATTR_STDOUT
141 | DOS_DEVATTR_CON
142 | DOS_DEVATTR_CHARACTER,
143 "CON");
144
145 Con->ReadRoutine = ConDrvReadInput;
146 Con->InputStatusRoutine = ConDrvInputStatus;
147 Con->WriteRoutine = ConDrvWriteOutput;
148 Con->OpenRoutine = ConDrvOpen;
149 Con->CloseRoutine = ConDrvClose;
150 }
151
152 VOID ConDrvCleanup(VOID)
153 {
154 if (Con) DosDeleteDevice(Con);
155 }