[NTVDM]
[reactos.git] / reactos / subsystems / mvdm / ntvdm / dos / dos32krnl / bios.c
1 /*
2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: dos/dos32krnl/bios.c
5 * PURPOSE: DOS32 Bios
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #define NDEBUG
12
13 #include "ntvdm.h"
14 #include "emulator.h"
15 #include "int32.h"
16
17 #include "dos.h"
18 #include "dosfiles.h"
19 #include "memory.h"
20 #include "bios/bios.h"
21
22 // This is needed because on UNICODE this symbol is redirected to
23 // GetEnvironmentStringsW whereas on ANSI it corresponds to the real
24 // "ANSI" function (and GetEnvironmentStringsA is aliased to it).
25 #undef GetEnvironmentStrings
26
27 // Symmetrize the dumbness of the previous symbol: on UNICODE
28 // FreeEnvironmentStrings aliases to FreeEnvironmentStringsW but
29 // on "ANSI" FreeEnvironmentStrings aliases to FreeEnvironmentStringsA
30 #undef FreeEnvironmentStrings
31 #define FreeEnvironmentStrings FreeEnvironmentStringsA
32
33 #define CHARACTER_ADDRESS 0x007000FF /* 0070:00FF */
34
35 /* PRIVATE VARIABLES **********************************************************/
36
37 // static BYTE CurrentDrive;
38 // static CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
39
40 /* PRIVATE FUNCTIONS **********************************************************/
41
42 /* PUBLIC FUNCTIONS ***********************************************************/
43
44 CHAR DosReadCharacter(WORD FileHandle)
45 {
46 PCHAR Character = (PCHAR)FAR_POINTER(CHARACTER_ADDRESS);
47 WORD BytesRead;
48
49 *Character = '\0';
50 DPRINT("DosReadCharacter\n");
51
52 /* Use the file reading function */
53 DosReadFile(FileHandle, CHARACTER_ADDRESS, 1, &BytesRead);
54
55 return *Character;
56 }
57
58 BOOLEAN DosCheckInput(VOID)
59 {
60 PDOS_FILE_DESCRIPTOR Descriptor = DosGetHandleFileDescriptor(DOS_INPUT_HANDLE);
61
62 if (Descriptor == NULL)
63 {
64 /* Invalid handle */
65 DosLastError = ERROR_INVALID_HANDLE; // ERROR_FILE_NOT_FOUND
66 return FALSE;
67 }
68
69 if (Descriptor->DeviceInfo & (1 << 7))
70 {
71 WORD Result;
72 PDOS_DEVICE_NODE Node = DosGetDriverNode(Descriptor->DevicePointer);
73
74 if (!Node->InputStatusRoutine) return FALSE;
75
76 Result = Node->InputStatusRoutine(Node);
77 return !(Result & DOS_DEVSTAT_BUSY);
78 }
79 else
80 {
81 DWORD FileSizeHigh;
82 DWORD FileSize = GetFileSize(Descriptor->Win32Handle, &FileSizeHigh);
83 LONG LocationHigh = 0;
84 DWORD Location = SetFilePointer(Descriptor->Win32Handle, 0, &LocationHigh, FILE_CURRENT);
85
86 return ((Location != FileSize) || (LocationHigh != FileSizeHigh));
87 }
88 }
89
90 VOID DosPrintCharacter(WORD FileHandle, CHAR Character)
91 {
92 WORD BytesWritten;
93 *((PCHAR)FAR_POINTER(CHARACTER_ADDRESS)) = Character;
94
95 /* Use the file writing function */
96 DosWriteFile(FileHandle, CHARACTER_ADDRESS, 1, &BytesWritten);
97 }
98
99 BOOLEAN DosBIOSInitialize(VOID)
100 {
101 PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
102
103 LPSTR SourcePtr, Environment;
104 LPSTR DestPtr = (LPSTR)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0);
105
106 #if 0
107 UCHAR i;
108 CHAR CurrentDirectory[MAX_PATH];
109 CHAR DosDirectory[DOS_DIR_LENGTH];
110 LPSTR Path;
111
112 FILE *Stream;
113 WCHAR Buffer[256];
114 #endif
115
116 /* Initialize the MCB */
117 Mcb->BlockType = 'Z';
118 Mcb->Size = USER_MEMORY_SIZE;
119 Mcb->OwnerPsp = 0;
120
121 /* Initialize the link MCB to the UMB area */
122 Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT + USER_MEMORY_SIZE + 1);
123 Mcb->BlockType = 'M';
124 Mcb->Size = UMB_START_SEGMENT - FIRST_MCB_SEGMENT - USER_MEMORY_SIZE - 2;
125 Mcb->OwnerPsp = SYSTEM_PSP;
126
127 /* Initialize the UMB area */
128 Mcb = SEGMENT_TO_MCB(UMB_START_SEGMENT);
129 Mcb->BlockType = 'Z';
130 Mcb->Size = UMB_END_SEGMENT - UMB_START_SEGMENT;
131 Mcb->OwnerPsp = 0;
132
133 /* Get the environment strings */
134 SourcePtr = Environment = GetEnvironmentStrings();
135 if (Environment == NULL) return FALSE;
136
137 /* Fill the DOS system environment block */
138 while (*SourcePtr)
139 {
140 /*
141 * - Ignore environment strings starting with a '=',
142 * they describe current directories.
143 * - Ignore also the WINDIR environment variable since
144 * DOS apps should ignore that we started from ReactOS.
145 * - Upper-case the environment names, not their values.
146 */
147 if (*SourcePtr != '=' && _strnicmp(SourcePtr, "WINDIR", 6) != 0)
148 {
149 PCHAR Delim = NULL;
150
151 /* Copy the environment string */
152 strcpy(DestPtr, SourcePtr);
153
154 /* Upper-case the environment name */
155 Delim = strchr(DestPtr, '='); // Find the '=' delimiter
156 if (Delim) *Delim = '\0'; // Temporarily replace it by NULL
157 _strupr(DestPtr); // Upper-case
158 if (Delim) *Delim = '='; // Restore the delimiter
159
160 DestPtr += strlen(SourcePtr);
161
162 /* NULL-terminate the environment string */
163 *(DestPtr++) = '\0';
164 }
165
166 /* Move to the next string */
167 SourcePtr += strlen(SourcePtr) + 1;
168 }
169 /* NULL-terminate the environment block */
170 *DestPtr = '\0';
171
172 /* Free the memory allocated for environment strings */
173 FreeEnvironmentStrings(Environment);
174
175
176 #if 0
177
178 /* Clear the current directory buffer */
179 RtlZeroMemory(CurrentDirectories, sizeof(CurrentDirectories));
180
181 /* Get the current directory */
182 if (!GetCurrentDirectoryA(MAX_PATH, CurrentDirectory))
183 {
184 // TODO: Use some kind of default path?
185 return FALSE;
186 }
187
188 /* Convert that to a DOS path */
189 if (!GetShortPathNameA(CurrentDirectory, DosDirectory, DOS_DIR_LENGTH))
190 {
191 // TODO: Use some kind of default path?
192 return FALSE;
193 }
194
195 /* Set the drive */
196 CurrentDrive = DosDirectory[0] - 'A';
197
198 /* Get the directory part of the path */
199 Path = strchr(DosDirectory, '\\');
200 if (Path != NULL)
201 {
202 /* Skip the backslash */
203 Path++;
204 }
205
206 /* Set the directory */
207 if (Path != NULL)
208 {
209 strncpy(CurrentDirectories[CurrentDrive], Path, DOS_DIR_LENGTH);
210 }
211
212 /* Read CONFIG.SYS */
213 Stream = _wfopen(DOS_CONFIG_PATH, L"r");
214 if (Stream != NULL)
215 {
216 while (fgetws(Buffer, ARRAYSIZE(Buffer), Stream))
217 {
218 // TODO: Parse the line
219 }
220 fclose(Stream);
221 }
222
223 #endif
224
225
226 /* Register the DOS 32-bit Interrupts */
227 // RegisterDosInt32(0x20, DosInt20h);
228
229 /* Initialize the DOS kernel */
230 return DosKRNLInitialize();
231 }
232
233 /* EOF */