[BRANCHES]
[reactos.git] / reactos / subsystems / 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.c
5 * PURPOSE: VDM DOS Kernel
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #define NDEBUG
12
13 #include "emulator.h"
14 #include "callback.h"
15
16 #include "dos.h"
17
18 #include "bios/bios.h"
19
20 /* PRIVATE VARIABLES **********************************************************/
21
22 // static BYTE CurrentDrive;
23 // static CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
24
25 /* PRIVATE FUNCTIONS **********************************************************/
26
27 #if 0
28 static WORD DosWriteFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesWritten)
29 {
30 WORD Result = ERROR_SUCCESS;
31 DWORD BytesWritten32 = 0;
32 HANDLE Handle = DosGetRealHandle(FileHandle);
33 WORD i;
34
35 DPRINT("DosWriteFile: FileHandle 0x%04X, Count 0x%04X\n",
36 FileHandle,
37 Count);
38
39 /* Make sure the handle is valid */
40 if (Handle == INVALID_HANDLE_VALUE) return ERROR_INVALID_HANDLE;
41
42 if (IsConsoleHandle(Handle))
43 {
44 for (i = 0; i < Count; i++)
45 {
46 /* Call the BIOS to print the character */
47 VidBiosPrintCharacter(((LPBYTE)Buffer)[i], DOS_CHAR_ATTRIBUTE, Bda->VideoPage);
48 BytesWritten32++;
49 }
50 }
51 else
52 {
53 /* Write the file */
54 if (!WriteFile(Handle, Buffer, Count, &BytesWritten32, NULL))
55 {
56 /* Store the error code */
57 Result = (WORD)GetLastError();
58 }
59 }
60
61 /* The number of bytes written is always 16-bit */
62 *BytesWritten = LOWORD(BytesWritten32);
63
64 /* Return the error code */
65 return Result;
66 }
67 #endif
68
69 /* PUBLIC FUNCTIONS ***********************************************************/
70
71 CHAR DosReadCharacter(VOID)
72 {
73 CHAR Character = '\0';
74 WORD BytesRead;
75
76 if (IsConsoleHandle(DosGetRealHandle(DOS_INPUT_HANDLE)))
77 {
78 /* Call the BIOS */
79 Character = LOBYTE(BiosGetCharacter());
80 }
81 else
82 {
83 /* Use the file reading function */
84 DosReadFile(DOS_INPUT_HANDLE, &Character, sizeof(CHAR), &BytesRead);
85 }
86
87 return Character;
88 }
89
90 BOOLEAN DosCheckInput(VOID)
91 {
92 HANDLE Handle = DosGetRealHandle(DOS_INPUT_HANDLE);
93
94 if (IsConsoleHandle(Handle))
95 {
96 /* Save AX */
97 USHORT AX = getAX();
98
99 /* Call the BIOS */
100 setAH(0x01); // or 0x11 for enhanced, but what to choose?
101 Int32Call(&DosContext, BIOS_KBD_INTERRUPT);
102
103 /* Restore AX */
104 setAX(AX);
105
106 /* Return keyboard status */
107 return (getZF() == 0);
108 }
109 else
110 {
111 DWORD FileSizeHigh;
112 DWORD FileSize = GetFileSize(Handle, &FileSizeHigh);
113 LONG LocationHigh = 0;
114 DWORD Location = SetFilePointer(Handle, 0, &LocationHigh, FILE_CURRENT);
115
116 return ((Location != FileSize) || (LocationHigh != FileSizeHigh));
117 }
118 }
119
120 VOID DosPrintCharacter(CHAR Character)
121 {
122 WORD BytesWritten;
123
124 /* Use the file writing function */
125 DosWriteFile(DOS_OUTPUT_HANDLE, &Character, sizeof(CHAR), &BytesWritten);
126 }
127
128 BOOLEAN DosBIOSInitialize(VOID)
129 {
130 PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
131
132 LPWSTR SourcePtr, Environment;
133 LPSTR AsciiString;
134 DWORD AsciiSize;
135 LPSTR DestPtr = (LPSTR)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0);
136
137 #if 0
138 UCHAR i;
139 CHAR CurrentDirectory[MAX_PATH];
140 CHAR DosDirectory[DOS_DIR_LENGTH];
141 LPSTR Path;
142
143 FILE *Stream;
144 WCHAR Buffer[256];
145 #endif
146
147 /* Initialize the MCB */
148 Mcb->BlockType = 'Z';
149 Mcb->Size = USER_MEMORY_SIZE;
150 Mcb->OwnerPsp = 0;
151
152 /* Initialize the link MCB to the UMB area */
153 Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT + USER_MEMORY_SIZE + 1);
154 Mcb->BlockType = 'M';
155 Mcb->Size = UMB_START_SEGMENT - FIRST_MCB_SEGMENT - USER_MEMORY_SIZE - 2;
156 Mcb->OwnerPsp = SYSTEM_PSP;
157
158 /* Initialize the UMB area */
159 Mcb = SEGMENT_TO_MCB(UMB_START_SEGMENT);
160 Mcb->BlockType = 'Z';
161 Mcb->Size = UMB_END_SEGMENT - UMB_START_SEGMENT;
162 Mcb->OwnerPsp = 0;
163
164 /* Get the environment strings */
165 SourcePtr = Environment = GetEnvironmentStringsW();
166 if (Environment == NULL) return FALSE;
167
168 /* Fill the DOS system environment block */
169 while (*SourcePtr)
170 {
171 /* Get the size of the ASCII string */
172 AsciiSize = WideCharToMultiByte(CP_ACP,
173 0,
174 SourcePtr,
175 -1,
176 NULL,
177 0,
178 NULL,
179 NULL);
180
181 /* Allocate memory for the ASCII string */
182 AsciiString = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, AsciiSize);
183 if (AsciiString == NULL)
184 {
185 FreeEnvironmentStringsW(Environment);
186 return FALSE;
187 }
188
189 /* Convert to ASCII */
190 WideCharToMultiByte(CP_ACP,
191 0,
192 SourcePtr,
193 -1,
194 AsciiString,
195 AsciiSize,
196 NULL,
197 NULL);
198
199 /* Copy the string into DOS memory */
200 strcpy(DestPtr, AsciiString);
201
202 /* Move to the next string */
203 SourcePtr += wcslen(SourcePtr) + 1;
204 DestPtr += strlen(AsciiString);
205 *(DestPtr++) = 0;
206
207 /* Free the memory */
208 HeapFree(GetProcessHeap(), 0, AsciiString);
209 }
210 *DestPtr = 0;
211
212 /* Free the memory allocated for environment strings */
213 FreeEnvironmentStringsW(Environment);
214
215
216 #if 0
217
218 /* Clear the current directory buffer */
219 ZeroMemory(CurrentDirectories, sizeof(CurrentDirectories));
220
221 /* Get the current directory */
222 if (!GetCurrentDirectoryA(MAX_PATH, CurrentDirectory))
223 {
224 // TODO: Use some kind of default path?
225 return FALSE;
226 }
227
228 /* Convert that to a DOS path */
229 if (!GetShortPathNameA(CurrentDirectory, DosDirectory, DOS_DIR_LENGTH))
230 {
231 // TODO: Use some kind of default path?
232 return FALSE;
233 }
234
235 /* Set the drive */
236 CurrentDrive = DosDirectory[0] - 'A';
237
238 /* Get the directory part of the path */
239 Path = strchr(DosDirectory, '\\');
240 if (Path != NULL)
241 {
242 /* Skip the backslash */
243 Path++;
244 }
245
246 /* Set the directory */
247 if (Path != NULL)
248 {
249 strncpy(CurrentDirectories[CurrentDrive], Path, DOS_DIR_LENGTH);
250 }
251
252 /* Read CONFIG.SYS */
253 Stream = _wfopen(DOS_CONFIG_PATH, L"r");
254 if (Stream != NULL)
255 {
256 while (fgetws(Buffer, sizeof(Buffer)/sizeof(Buffer[0]), Stream))
257 {
258 // TODO: Parse the line
259 }
260 fclose(Stream);
261 }
262
263 #endif
264
265
266 /* Register the DOS 32-bit Interrupts */
267 // RegisterDosInt32(0x20, DosInt20h);
268
269 /* Initialize the DOS kernel */
270 return DosKRNLInitialize();
271 }
272
273 /* EOF */