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