Sync with trunk r63283
[reactos.git] / 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 /* PUBLIC FUNCTIONS ***********************************************************/
28
29 CHAR DosReadCharacter(WORD FileHandle)
30 {
31 CHAR Character = '\0';
32 WORD BytesRead;
33
34 /* Use the file reading function */
35 DosReadFile(FileHandle, &Character, 1, &BytesRead);
36
37 return Character;
38 }
39
40 BOOLEAN DosCheckInput(VOID)
41 {
42 HANDLE Handle = DosGetRealHandle(DOS_INPUT_HANDLE);
43
44 if (IsConsoleHandle(Handle))
45 {
46 /* Save AX */
47 USHORT AX = getAX();
48
49 /* Call the BIOS */
50 setAH(0x01); // or 0x11 for enhanced, but what to choose?
51 Int32Call(&DosContext, BIOS_KBD_INTERRUPT);
52
53 /* Restore AX */
54 setAX(AX);
55
56 /* Return keyboard status */
57 return (getZF() == 0);
58 }
59 else
60 {
61 DWORD FileSizeHigh;
62 DWORD FileSize = GetFileSize(Handle, &FileSizeHigh);
63 LONG LocationHigh = 0;
64 DWORD Location = SetFilePointer(Handle, 0, &LocationHigh, FILE_CURRENT);
65
66 return ((Location != FileSize) || (LocationHigh != FileSizeHigh));
67 }
68 }
69
70 VOID DosPrintCharacter(WORD FileHandle, CHAR Character)
71 {
72 WORD BytesWritten;
73
74 /* Use the file writing function */
75 DosWriteFile(FileHandle, &Character, 1, &BytesWritten);
76 }
77
78 BOOLEAN DosBIOSInitialize(VOID)
79 {
80 PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
81
82 LPWSTR SourcePtr, Environment;
83 LPSTR AsciiString;
84 DWORD AsciiSize;
85 LPSTR DestPtr = (LPSTR)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0);
86
87 #if 0
88 UCHAR i;
89 CHAR CurrentDirectory[MAX_PATH];
90 CHAR DosDirectory[DOS_DIR_LENGTH];
91 LPSTR Path;
92
93 FILE *Stream;
94 WCHAR Buffer[256];
95 #endif
96
97 /* Initialize the MCB */
98 Mcb->BlockType = 'Z';
99 Mcb->Size = USER_MEMORY_SIZE;
100 Mcb->OwnerPsp = 0;
101
102 /* Initialize the link MCB to the UMB area */
103 Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT + USER_MEMORY_SIZE + 1);
104 Mcb->BlockType = 'M';
105 Mcb->Size = UMB_START_SEGMENT - FIRST_MCB_SEGMENT - USER_MEMORY_SIZE - 2;
106 Mcb->OwnerPsp = SYSTEM_PSP;
107
108 /* Initialize the UMB area */
109 Mcb = SEGMENT_TO_MCB(UMB_START_SEGMENT);
110 Mcb->BlockType = 'Z';
111 Mcb->Size = UMB_END_SEGMENT - UMB_START_SEGMENT;
112 Mcb->OwnerPsp = 0;
113
114 /* Get the environment strings */
115 SourcePtr = Environment = GetEnvironmentStringsW();
116 if (Environment == NULL) return FALSE;
117
118 /* Fill the DOS system environment block */
119 while (*SourcePtr)
120 {
121 /* Get the size of the ASCII string */
122 AsciiSize = WideCharToMultiByte(CP_ACP,
123 0,
124 SourcePtr,
125 -1,
126 NULL,
127 0,
128 NULL,
129 NULL);
130
131 /* Allocate memory for the ASCII string */
132 AsciiString = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, AsciiSize);
133 if (AsciiString == NULL)
134 {
135 FreeEnvironmentStringsW(Environment);
136 return FALSE;
137 }
138
139 /* Convert to ASCII */
140 WideCharToMultiByte(CP_ACP,
141 0,
142 SourcePtr,
143 -1,
144 AsciiString,
145 AsciiSize,
146 NULL,
147 NULL);
148
149 /* Copy the string into DOS memory */
150 strcpy(DestPtr, AsciiString);
151
152 /* Move to the next string */
153 SourcePtr += wcslen(SourcePtr) + 1;
154 DestPtr += strlen(AsciiString);
155 *(DestPtr++) = 0;
156
157 /* Free the memory */
158 HeapFree(GetProcessHeap(), 0, AsciiString);
159 }
160 *DestPtr = 0;
161
162 /* Free the memory allocated for environment strings */
163 FreeEnvironmentStringsW(Environment);
164
165
166 #if 0
167
168 /* Clear the current directory buffer */
169 ZeroMemory(CurrentDirectories, sizeof(CurrentDirectories));
170
171 /* Get the current directory */
172 if (!GetCurrentDirectoryA(MAX_PATH, CurrentDirectory))
173 {
174 // TODO: Use some kind of default path?
175 return FALSE;
176 }
177
178 /* Convert that to a DOS path */
179 if (!GetShortPathNameA(CurrentDirectory, DosDirectory, DOS_DIR_LENGTH))
180 {
181 // TODO: Use some kind of default path?
182 return FALSE;
183 }
184
185 /* Set the drive */
186 CurrentDrive = DosDirectory[0] - 'A';
187
188 /* Get the directory part of the path */
189 Path = strchr(DosDirectory, '\\');
190 if (Path != NULL)
191 {
192 /* Skip the backslash */
193 Path++;
194 }
195
196 /* Set the directory */
197 if (Path != NULL)
198 {
199 strncpy(CurrentDirectories[CurrentDrive], Path, DOS_DIR_LENGTH);
200 }
201
202 /* Read CONFIG.SYS */
203 Stream = _wfopen(DOS_CONFIG_PATH, L"r");
204 if (Stream != NULL)
205 {
206 while (fgetws(Buffer, sizeof(Buffer)/sizeof(Buffer[0]), Stream))
207 {
208 // TODO: Parse the line
209 }
210 fclose(Stream);
211 }
212
213 #endif
214
215
216 /* Register the DOS 32-bit Interrupts */
217 // RegisterDosInt32(0x20, DosInt20h);
218
219 /* Initialize the DOS kernel */
220 return DosKRNLInitialize();
221 }
222
223 /* EOF */