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