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