Reverted latest changes.
[reactos.git] / reactos / hal / halx86 / display.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id: display.c,v 1.4 2002/09/08 10:22:24 chorns Exp $
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * FILE: ntoskrnl/hal/x86/display.c
24 * PURPOSE: Blue screen display
25 * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
26 * UPDATE HISTORY:
27 * Created 08/10/99
28 */
29
30 #include <ddk/ntddk.h>
31 #include <mps.h>
32
33 #define SCREEN_SYNCHRONIZATION
34
35
36 #define CRTC_COMMAND 0x3d4
37 #define CRTC_DATA 0x3d5
38
39 #define CRTC_COLUMNS 0x01
40 #define CRTC_OVERFLOW 0x07
41 #define CRTC_ROWS 0x12
42 #define CRTC_SCANLINES 0x09
43
44 #define CRTC_CURHI 0x0e
45 #define CRTC_CURLO 0x0f
46
47
48 #define CHAR_ATTRIBUTE 0x17 /* grey on blue */
49
50
51 /* VARIABLES ****************************************************************/
52
53 static ULONG CursorX = 0; /* Cursor Position */
54 static ULONG CursorY = 0;
55 static ULONG SizeX = 80; /* Display size */
56 static ULONG SizeY = 25;
57
58 static BOOLEAN DisplayInitialized = FALSE;
59 static BOOLEAN HalOwnsDisplay = TRUE;
60
61 static WORD *VideoBuffer = NULL;
62
63 static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL;
64
65
66 /* STATIC FUNCTIONS *********************************************************/
67
68 static VOID
69 HalClearDisplay (VOID)
70 {
71 WORD *ptr = (WORD*)VideoBuffer;
72 ULONG i;
73
74 for (i = 0; i < SizeX * SizeY; i++, ptr++)
75 *ptr = ((CHAR_ATTRIBUTE << 8) + ' ');
76
77 CursorX = 0;
78 CursorY = 0;
79 }
80
81
82 VOID
83 HalScrollDisplay (VOID)
84 {
85 WORD *ptr;
86 int i;
87
88 ptr = VideoBuffer + SizeX;
89 RtlMoveMemory(VideoBuffer,
90 ptr,
91 SizeX * (SizeY - 1) * 2);
92
93 ptr = VideoBuffer + (SizeX * (SizeY - 1));
94 for (i = 0; i < SizeX; i++, ptr++)
95 {
96 *ptr = (CHAR_ATTRIBUTE << 8) + ' ';
97 }
98 }
99
100
101 static VOID
102 HalPutCharacter (CHAR Character)
103 {
104 WORD *ptr;
105
106 ptr = VideoBuffer + ((CursorY * SizeX) + CursorX);
107 *ptr = (CHAR_ATTRIBUTE << 8) + Character;
108 }
109
110
111 /* PRIVATE FUNCTIONS ********************************************************/
112
113 VOID
114 HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock)
115 /*
116 * FUNCTION: Initalize the display
117 * ARGUMENTS:
118 * InitParameters = Parameters setup by the boot loader
119 */
120 {
121 if (DisplayInitialized == FALSE)
122 {
123 ULONG ScanLines;
124 ULONG Data;
125
126 VideoBuffer = (WORD *)(0xd0000000 + 0xb8000);
127 // VideoBuffer = HalMapPhysicalMemory (0xb8000, 2);
128
129 /* Set cursor position */
130 // CursorX = LoaderBlock->cursorx;
131 // CursorY = LoaderBlock->cursory;
132 CursorX = 0;
133 CursorY = 0;
134
135 /* read screen size from the crtc */
136 /* FIXME: screen size should be read from the boot parameters */
137 WRITE_PORT_UCHAR((PUCHAR)CRTC_COMMAND, CRTC_COLUMNS);
138 SizeX = READ_PORT_UCHAR((PUCHAR)CRTC_DATA) + 1;
139 WRITE_PORT_UCHAR((PUCHAR)CRTC_COMMAND, CRTC_ROWS);
140 SizeY = READ_PORT_UCHAR((PUCHAR)CRTC_DATA);
141 WRITE_PORT_UCHAR((PUCHAR)CRTC_COMMAND, CRTC_OVERFLOW);
142 Data = READ_PORT_UCHAR((PUCHAR)CRTC_DATA);
143 SizeY |= (((Data & 0x02) << 7) | ((Data & 0x40) << 3));
144 SizeY++;
145 WRITE_PORT_UCHAR((PUCHAR)CRTC_COMMAND, CRTC_SCANLINES);
146 ScanLines = (READ_PORT_UCHAR((PUCHAR)CRTC_DATA) & 0x1F) + 1;
147 SizeY = SizeY / ScanLines;
148
149 #ifdef BOCHS_30ROWS
150 SizeY=30;
151 #endif
152 HalClearDisplay();
153
154 DisplayInitialized = TRUE;
155 }
156 }
157
158
159 VOID
160 HalResetDisplay(VOID)
161 /*
162 * FUNCTION: Reset the display
163 * ARGUMENTS:
164 * None
165 */
166 {
167 if (HalResetDisplayParameters == NULL)
168 return;
169
170 if (HalOwnsDisplay == TRUE)
171 return;
172
173 if (HalResetDisplayParameters(SizeX, SizeY) == TRUE)
174 {
175 HalOwnsDisplay = TRUE;
176 HalClearDisplay();
177 }
178 }
179
180
181 /* PUBLIC FUNCTIONS *********************************************************/
182
183 VOID STDCALL
184 HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters)
185 /*
186 * FUNCTION:
187 * ARGUMENTS:
188 * ResetDisplayParameters = Pointer to a driver specific
189 * reset routine.
190 */
191 {
192 HalOwnsDisplay = FALSE;
193 HalResetDisplayParameters = ResetDisplayParameters;
194 }
195
196
197 VOID STDCALL
198 HalDisplayString(IN PCH String)
199 /*
200 * FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
201 * already and displays a string
202 * ARGUMENT:
203 * string = ASCII string to display
204 * NOTE: Use with care because there is no support for returning from BSOD
205 * mode
206 */
207 {
208 PCH pch;
209 #ifdef SCREEN_SYNCHRONIZATION
210 int offset;
211 #endif
212 static KSPIN_LOCK Lock;
213 ULONG Flags;
214
215 pch = String;
216
217 pushfl(Flags);
218 __asm__ ("cli\n\t");
219 KeAcquireSpinLockAtDpcLevel(&Lock);
220
221 if (HalOwnsDisplay == FALSE)
222 {
223 HalResetDisplay ();
224 }
225
226 #ifdef SCREEN_SYNCHRONIZATION
227 WRITE_PORT_UCHAR((PUCHAR)CRTC_COMMAND, CRTC_CURHI);
228 offset = READ_PORT_UCHAR((PUCHAR)CRTC_DATA)<<8;
229 WRITE_PORT_UCHAR((PUCHAR)CRTC_COMMAND, CRTC_CURLO);
230 offset += READ_PORT_UCHAR((PUCHAR)CRTC_DATA);
231
232 CursorY = offset / SizeX;
233 CursorX = offset % SizeX;
234 #endif
235
236 while (*pch != 0)
237 {
238 if (*pch == '\n')
239 {
240 CursorY++;
241 CursorX = 0;
242 }
243 else if (*pch != '\r')
244 {
245 HalPutCharacter (*pch);
246 CursorX++;
247
248 if (CursorX >= SizeX)
249 {
250 CursorY++;
251 CursorX = 0;
252 }
253 }
254
255 if (CursorY >= SizeY)
256 {
257 HalScrollDisplay ();
258 CursorY = SizeY - 1;
259 }
260
261 pch++;
262 }
263
264 #ifdef SCREEN_SYNCHRONIZATION
265 offset = (CursorY * SizeX) + CursorX;
266
267 WRITE_PORT_UCHAR((PUCHAR)CRTC_COMMAND, CRTC_CURLO);
268 WRITE_PORT_UCHAR((PUCHAR)CRTC_DATA, offset & 0xff);
269 WRITE_PORT_UCHAR((PUCHAR)CRTC_COMMAND, CRTC_CURHI);
270 WRITE_PORT_UCHAR((PUCHAR)CRTC_DATA, (offset >> 8) & 0xff);
271 #endif
272 KeReleaseSpinLockFromDpcLevel(&Lock);
273 popfl(Flags);
274 }
275
276
277 VOID STDCALL
278 HalQueryDisplayParameters(OUT PULONG DispSizeX,
279 OUT PULONG DispSizeY,
280 OUT PULONG CursorPosX,
281 OUT PULONG CursorPosY)
282 {
283 if (DispSizeX)
284 *DispSizeX = SizeX;
285 if (DispSizeY)
286 *DispSizeY = SizeY;
287 if (CursorPosX)
288 *CursorPosX = CursorX;
289 if (CursorPosY)
290 *CursorPosY = CursorY;
291 }
292
293
294 VOID STDCALL
295 HalSetDisplayParameters(IN ULONG CursorPosX,
296 IN ULONG CursorPosY)
297 {
298 CursorX = (CursorPosX < SizeX) ? CursorPosX : SizeX - 1;
299 CursorY = (CursorPosY < SizeY) ? CursorPosY : SizeY - 1;
300 }
301
302 /* EOF */