3 /* PRIVATE FUNCTIONS *********************************************************/
7 VgaInterpretCmdStream(IN PUSHORT CmdStream
)
9 PUCHAR Base
= (PUCHAR
)VgaRegisterBase
;
20 /* First make sure that we have a Command Stream */
21 if (!CmdStream
) return TRUE
;
23 /* Loop as long as we have commands */
26 /* Get the Major and Minor Function */
31 /* Move to the next command */
34 /* Check which major function this was */
37 /* Now let's see the minor function */
38 if (Minor
& CMD_STREAM_READ
)
40 /* Now check the sub-type */
41 if (Minor
& CMD_STREAM_USHORT
)
43 /* The port is what is in the stream right now */
44 ShortPort
= UlongToPtr((ULONG
)*CmdStream
);
46 /* Move to the next command */
49 /* Read USHORT from the port */
50 READ_PORT_USHORT(PtrToUlong(Base
) + ShortPort
);
54 /* The port is what is in the stream right now */
55 Port
= UlongToPtr((ULONG
)*CmdStream
);
57 /* Move to the next command */
60 /* Read UCHAR from the port */
61 READ_PORT_UCHAR(PtrToUlong(Base
) + Port
);
64 else if (Minor
& CMD_STREAM_WRITE_ARRAY
)
66 /* Now check the sub-type */
67 if (Minor
& CMD_STREAM_USHORT
)
69 /* The port is what is in the stream right now */
70 ShortPort
= UlongToPtr(Cmd
);
72 /* Move to the next command and get the count */
73 Count
= *(CmdStream
++);
75 /* The buffer is what's next in the command stream */
78 /* Write USHORT to the port */
79 WRITE_PORT_BUFFER_USHORT(PtrToUshort(Base
) + ShortPort
, Buffer
, Count
);
81 /* Move past the buffer in the command stream */
86 /* The port is what is in the stream right now */
87 Port
= UlongToPtr(Cmd
);
89 /* Move to the next command and get the count */
90 Count
= *(CmdStream
++);
92 /* Add the base to the port */
93 Port
= PtrToUlong(Port
) + Base
;
95 /* Move to next command */
98 /* Loop the cmd array */
99 for (; Count
; Count
--, CmdStream
++)
101 /* Get the byte we're writing */
102 Value
= (UCHAR
)*CmdStream
;
104 /* Write UCHAR to the port */
105 WRITE_PORT_UCHAR(Port
, Value
);
109 else if (Minor
& CMD_STREAM_USHORT
)
111 /* Get the ushort we're writing and advance in the stream */
112 ShortValue
= *CmdStream
;
115 /* Write USHORT to the port (which is in cmd) */
116 WRITE_PORT_USHORT((PUSHORT
)Base
+ Cmd
, ShortValue
);
120 /* The port is what is in the stream right now */
121 Port
= UlongToPtr((ULONG
)*CmdStream
);
123 /* Get the uchar we're writing */
124 Value
= (UCHAR
)*++CmdStream
;
126 /* Move to the next command */
129 /* Write UCHAR to the port (which is in cmd) */
130 WRITE_PORT_UCHAR(PtrToUlong(Base
) + Port
, Value
);
133 else if (Major
== 0x20)
135 /* Check the minor function. Note these are not flags anymore. */
139 /* The port is what is in the stream right now */
140 ShortPort
= UlongToPtr(*CmdStream
);
142 /* Move to the next command and get the count */
143 Count
= *(CmdStream
++);
145 /* Move to the next command and get the value to write */
146 ShortValue
= *(CmdStream
++);
148 /* Add the base to the port */
149 ShortPort
= PtrToUlong(ShortPort
) + (PUSHORT
)Base
;
151 /* Move to next command */
154 /* Make sure we have data */
155 if (!ShortValue
) continue;
157 /* Loop the cmd array */
158 for (; Count
; Count
--, CmdStream
++)
160 /* Get the byte we're writing */
161 ShortValue
+= (*CmdStream
) << 8;
163 /* Write USHORT to the port */
164 WRITE_PORT_USHORT(ShortPort
, ShortValue
);
168 /* The port is what is in the stream right now. Add the base too */
169 Port
= *CmdStream
+ Base
;
171 /* Move to the next command and get the count */
172 Count
= *++CmdStream
;
174 /* Move to the next command and get the index to write */
175 Index
= (UCHAR
)*++CmdStream
;
177 /* Move to next command */
180 /* Loop the cmd array */
181 for (; Count
; Count
--, Index
++)
183 /* Write the index */
184 WRITE_PORT_UCHAR(Port
, Index
);
186 /* Get the byte we're writing */
187 Value
= (UCHAR
)*CmdStream
;
189 /* Move to next command */
192 /* Write UCHAR value to the port */
193 WRITE_PORT_UCHAR(Port
, Value
);
197 /* The port is what is in the stream right now. Add the base too */
198 Port
= *CmdStream
+ Base
;
200 /* Read the current value and add the stream data */
201 Value
= READ_PORT_UCHAR(Port
);
202 Value
&= *CmdStream
++;
203 Value
^= *CmdStream
++;
205 /* Write the value */
206 WRITE_PORT_UCHAR(Port
, Value
);
209 /* Unknown command, fail */
213 else if (Major
!= 0xF0)
215 /* Unknown major function, fail */
219 /* Get the next command */
223 /* If we got here, return success */
231 UCHAR VgaReg
, VgaReg2
, VgaReg3
;
232 UCHAR SeqReg
, SeqReg2
;
235 /* Read the VGA Address Register */
236 VgaReg
= READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE);
238 /* Select Read Map Select Register */
239 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 4);
241 /* Read it back...it should be 4 */
242 if (((READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE)) & 0xF) != 4) return FALSE
;
244 /* Read the VGA Data Register */
245 VgaReg2
= READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF);
247 /* Enable all planes */
248 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 3);
250 /* Read it back...it should be 3 */
251 if (READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF) != 0x3)
253 /* Reset the registers and fail */
254 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0);
258 /* Select Bit Mask Register */
259 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 8);
261 /* Read it back...it should be 8 */
262 if (((READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE)) & 0xF) != 8)
264 /* Reset the registers and fail */
265 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 4);
266 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0);
270 /* Read the VGA Data Register */
271 VgaReg3
= READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF);
274 for (i
= 0xBB; i
; i
>>= 1)
277 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, i
);
279 /* Read it back...it should be the same */
280 if (READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF) != i
)
282 /* Reset the registers and fail */
283 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0xFF);
284 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 4);
285 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0);
290 /* Select Read Map Select Register */
291 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 4);
293 /* Read it back...it should be 3 */
294 if (READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF) != 3)
296 /* Reset the registers and fail */
297 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0);
298 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 8);
299 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0xFF);
303 /* Write the registers we read earlier */
304 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, VgaReg2
);
305 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 8);
306 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, VgaReg3
);
307 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, VgaReg
);
309 /* Read sequencer address */
310 SeqReg
= READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C4);
312 /* Select memory mode register */
313 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C4, 4);
315 /* Read it back...it should still be 4 */
316 if (((READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C4)) & 7) != 4)
322 /* Read sequencer Data */
323 SeqReg2
= READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C5);
325 /* Write null plane */
326 WRITE_PORT_USHORT((PUSHORT
)VgaRegisterBase
+ 0x3C4, 0x100);
328 /* Write sequencer flag */
329 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C5, SeqReg2
^ 8);
332 if ((READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C5)) != (SeqReg2
^ 8))
334 /* Not the same value...restore registers and fail */
335 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C5, 2);
336 WRITE_PORT_USHORT((PUSHORT
)VgaRegisterBase
+ 0x3C4, 0x300);
340 /* Now write the registers we read */
341 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C5, SeqReg2
);
342 WRITE_PORT_USHORT((PUSHORT
)VgaRegisterBase
+ 0x3C4, 0x300);
343 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C4, SeqReg
);
345 /* VGA is present! */
349 /* PUBLIC FUNCTIONS **********************************************************/
356 VidInitialize(IN BOOLEAN SetMode
)
358 ULONG_PTR Context
= 0;
359 PHYSICAL_ADDRESS TranslatedAddress
;
360 PHYSICAL_ADDRESS NullAddress
= {{0, 0}}, VgaAddress
;
361 ULONG AddressSpace
= 1;
365 /* Make sure that we have a bus translation function */
366 if (!HalFindBusAddressTranslation
) return FALSE
;
368 /* Get the VGA Register address */
369 Result
= HalFindBusAddressTranslation(NullAddress
,
374 if (!Result
) return FALSE
;
376 /* Loop trying to find posssible VGA base addresses */
379 /* See if this is I/O Space, which we need to map */
383 Base
= (ULONG_PTR
)MmMapIoSpace(TranslatedAddress
, 0x400, MmNonCached
);
387 /* The base is the translated address, no need to map I/O space */
388 Base
= TranslatedAddress
.LowPart
;
391 /* Try to see if this is VGA */
392 VgaRegisterBase
= Base
;
395 /* Translate the VGA Memory Address */
396 VgaAddress
.LowPart
= 0xA0000;
397 VgaAddress
.HighPart
= 0;
399 Result
= HalFindBusAddressTranslation(VgaAddress
,
406 /* Try to see if there's any other address */
407 Result
= HalFindBusAddressTranslation(NullAddress
,
412 if (!Result
) return FALSE
;
416 /* It's not, so unmap the I/O space if we mapped it */
417 if (!AddressSpace
) MmUnmapIoSpace((PVOID
)VgaRegisterBase
, 0x400);
421 /* Success! See if this is I/O Space, which we need to map */
425 Base
= (ULONG_PTR
)MmMapIoSpace(TranslatedAddress
,
431 /* The base is the translated address, no need to map I/O space */
432 Base
= TranslatedAddress
.LowPart
;
435 /* Set the VGA Memory Base */
438 /* Now check if we have to set the mode */
441 /* Reset the display */
447 VgaInterpretCmdStream(AT_Initialization
);
459 VidResetDisplay(IN BOOLEAN HalReset
)
461 /* Clear the current position */
465 /* Clear the screen with HAL if we were asked to */
466 if (HalReset
) HalResetDisplay();
468 /* Re-initialize the VGA Display */
469 VgaInterpretCmdStream(AT_Initialization
);
471 /* Re-initialize the palette and fill the screen black */
473 VidSolidColorFill(0, 0, 639, 479, 0);