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