Changes to be able to build system
[reactos.git] / reactos / drivers / dd / blue / blue.c
1
2 #include <internal/mmhal.h>
3 #include <internal/halio.h>
4 #include <internal/hal/page.h>
5 #include <ddk/ntddk.h>
6 #include <string.h>
7 #include <internal/string.h>
8 #include <defines.h>
9 #include <ddk/ntddblue.h>
10
11 //#define NDEBUG
12 #include <internal/debug.h>
13
14
15
16 #define VIDMEM_BASE 0xb8000
17
18 #define NR_ROWS 50
19 #define NR_COLUMNS 80
20
21 #define CRTC_COMMAND 0x3d4
22 #define CRTC_DATA 0x3d5
23
24 #define CRTC_CURSORSTART 0x0a
25 #define CRTC_CURSOREND 0x0b
26 #define CRTC_CURSORPOSLO 0x0f
27 #define CRTC_CURSORPOSHI 0x0e
28
29
30
31
32 #define TAB_WIDTH 8
33
34
35 /* NOTES ******************************************************************/
36 /*
37 * [[character][attribute]][[character][attribute]]....
38 */
39
40
41 /* TYPEDEFS ***************************************************************/
42
43 typedef struct _DEVICE_EXTENSION
44 {
45 PBYTE VideoMemory;
46 SHORT CursorX;
47 SHORT CursorY;
48 DWORD CursorSize;
49 BOOL CursorVisible;
50 WORD CharAttribute;
51 DWORD Mode;
52 BYTE ScanLines; /* Height of a text line */
53
54 } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
55
56
57
58
59
60 /* FUNCTIONS **************************************************************/
61
62
63 NTSTATUS ScrCreate (PDEVICE_OBJECT DeviceObject, PIRP Irp)
64 {
65 // PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
66 PDEVICE_EXTENSION DeviceExtension;
67 NTSTATUS Status;
68 unsigned int offset;
69
70 DeviceExtension = DeviceObject->DeviceExtension;
71
72 /* initialize device extension */
73 /* get pointer to video memory */
74 DeviceExtension->VideoMemory = (PBYTE)physical_to_linear (VIDMEM_BASE);
75
76 /* get current output position */
77 __asm__("cli\n\t");
78 outb_p (CRTC_COMMAND, CRTC_CURSORPOSLO);
79 offset = inb_p (CRTC_DATA);
80 outb_p (CRTC_COMMAND, CRTC_CURSORPOSHI);
81 offset += (inb_p (CRTC_DATA) << 8);
82 __asm__("sti\n\t");
83
84 DeviceExtension->CursorX = (SHORT)(offset % NR_COLUMNS);
85 DeviceExtension->CursorY = (SHORT)(offset / NR_COLUMNS);
86 DeviceExtension->CursorSize = 5; /* FIXME: value correct?? */
87 DeviceExtension->CursorVisible = TRUE;
88
89
90 DeviceExtension->ScanLines = 8; /* FIXME: read it from CRTC */
91
92
93 /* more initialization */
94 DeviceExtension->CharAttribute = 0x17; /* light grey on blue */
95 DeviceExtension->Mode = ENABLE_PROCESSED_OUTPUT |
96 ENABLE_WRAP_AT_EOL_OUTPUT;
97
98 /* FIXME: more initialization?? */
99
100
101 /* show blinking cursor */
102 /* FIXME: calculate cursor size */
103 __asm__("cli\n\t");
104 outb_p (CRTC_COMMAND, CRTC_CURSORSTART);
105 outb_p (CRTC_DATA, 0x47);
106 outb_p (CRTC_COMMAND, CRTC_CURSOREND);
107 outb_p (CRTC_DATA, 0x07);
108 __asm__("sti\n\t");
109
110
111 Status = STATUS_SUCCESS;
112
113 Irp->IoStatus.Status = Status;
114 IoCompleteRequest (Irp, IO_NO_INCREMENT);
115
116 return (Status);
117 }
118
119
120 NTSTATUS ScrWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
121 {
122 PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
123 PDEVICE_EXTENSION DeviceExtension;
124 NTSTATUS Status;
125 char *pch = Irp->UserBuffer;
126 char *vidmem;
127 int i, j, offset;
128 int cursorx, cursory;
129
130 DeviceExtension = DeviceObject->DeviceExtension;
131 vidmem = DeviceExtension->VideoMemory;
132 cursorx = DeviceExtension->CursorX;
133 cursory = DeviceExtension->CursorY;
134
135 for (i = 0; i < stk->Parameters.Write.Length; i++, pch++)
136 {
137 switch (*pch)
138 {
139 case '\b':
140 if (cursorx > 0)
141 {
142 cursorx--;
143 }
144 else if (cursory > 0)
145 {
146 cursorx = NR_COLUMNS - 1;
147 cursory--;
148 }
149 break;
150
151 case '\n':
152 cursory++;
153 cursorx = 0;
154 break;
155
156 case '\r':
157 break;
158
159 case '\t':
160 offset = TAB_WIDTH - (cursorx % TAB_WIDTH);
161 for (j = 0; j < offset; j++)
162 {
163 vidmem[(cursorx * 2) + (cursory * NR_COLUMNS * 2)] = ' ';
164 cursorx++;
165 /*
166 if (cursorx >= NR_COLUMNS)
167 {
168 cursory++;
169 cursorx = 0;
170 }
171 */
172 }
173 break;
174
175 default:
176 vidmem[(cursorx * 2) + (cursory * NR_COLUMNS * 2)] = *pch;
177 vidmem[(cursorx * 2) + (cursory * NR_COLUMNS * 2) + 1] = (char) DeviceExtension->CharAttribute;
178 cursorx++;
179 if (cursorx >= NR_COLUMNS)
180 {
181 cursory++;
182 cursorx = 0;
183 }
184 }
185
186
187 if (cursory >= NR_ROWS)
188 {
189 unsigned short *LinePtr;
190
191 memcpy (vidmem,
192 &vidmem[NR_COLUMNS * 2],
193 NR_COLUMNS * (NR_ROWS - 1) * 2);
194
195 LinePtr = (unsigned short *) &vidmem[NR_COLUMNS * (NR_ROWS - 1) * 2];
196
197 for (j = 0; j < NR_COLUMNS; j++)
198 {
199 LinePtr[j] = DeviceExtension->CharAttribute << 8;
200 }
201 cursory = NR_ROWS - 1;
202 }
203 }
204
205
206 /* Set the cursor position */
207
208 offset = (cursory * NR_COLUMNS) + cursorx;
209
210 outb_p (CRTC_COMMAND, CRTC_CURSORPOSLO);
211 outb_p (CRTC_DATA, offset);
212 outb_p (CRTC_COMMAND, CRTC_CURSORPOSHI);
213 offset >>= 8;
214 outb_p (CRTC_DATA, offset);
215
216 DeviceExtension->CursorX = cursorx;
217 DeviceExtension->CursorY = cursory;
218
219
220 Status = STATUS_SUCCESS;
221
222 Irp->IoStatus.Status = Status;
223 IoCompleteRequest (Irp, IO_NO_INCREMENT);
224
225 return (Status);
226 }
227
228
229
230
231 NTSTATUS ScrIoControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
232 {
233 PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
234 PDEVICE_EXTENSION DeviceExtension;
235 NTSTATUS Status;
236
237
238 DeviceExtension = DeviceObject->DeviceExtension;
239
240 switch (stk->Parameters.DeviceIoControl.IoControlCode)
241 {
242 case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO:
243 {
244 PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
245 unsigned int offset;
246
247 __asm__("cli\n\t");
248 outb_p (CRTC_COMMAND, CRTC_CURSORPOSLO);
249 offset = inb_p (CRTC_DATA);
250 outb_p (CRTC_COMMAND, CRTC_CURSORPOSHI);
251 offset += (inb_p (CRTC_DATA) << 8);
252 __asm__("sti\n\t");
253
254 pcsbi->dwCursorPosition.X = (SHORT)(offset % NR_COLUMNS);
255 pcsbi->dwCursorPosition.Y = (SHORT)(offset / NR_COLUMNS);
256
257 pcsbi->dwSize.X = NR_ROWS;
258 pcsbi->dwSize.Y = NR_COLUMNS;
259
260 Irp->IoStatus.Information = sizeof (CONSOLE_SCREEN_BUFFER_INFO);
261 Status = STATUS_SUCCESS;
262 }
263 break;
264
265 case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO:
266 {
267 PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
268 unsigned int offset;
269
270 DeviceExtension->CursorX = pcsbi->dwCursorPosition.X;
271 DeviceExtension->CursorY = pcsbi->dwCursorPosition.Y;
272
273 offset = (pcsbi->dwCursorPosition.Y * NR_COLUMNS) +
274 pcsbi->dwCursorPosition.X;
275
276 __asm__("cli\n\t");
277 outb_p (CRTC_COMMAND, CRTC_CURSORPOSLO);
278 outb_p (CRTC_DATA, offset);
279 outb_p (CRTC_COMMAND, CRTC_CURSORPOSHI);
280 outb_p (CRTC_DATA, offset>>8);
281 __asm__("sti\n\t");
282
283 Irp->IoStatus.Information = 0;
284 Status = STATUS_SUCCESS;
285 }
286 break;
287
288 case IOCTL_CONSOLE_GET_CURSOR_INFO:
289 {
290 // PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
291
292 // DPRINT("GetConsoleCursorInfo: pcci=%p\n", pcci);
293 // DPRINT("GetConsoleCursorInfo\n");
294 // pcci->dwSize = 10;
295 // pcci->bVisible = FALSE;
296
297 Irp->IoStatus.Information = 0;
298 Status = STATUS_SUCCESS;
299 }
300 break;
301
302 case IOCTL_CONSOLE_SET_CURSOR_INFO:
303 {
304 PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
305 BYTE data;
306 DWORD size, height;
307
308 DeviceExtension->CursorSize = pcci->dwSize;
309 DeviceExtension->CursorVisible = pcci->bVisible;
310 height = DeviceExtension->ScanLines;
311 data = (pcci->bVisible) ? 0x40 : 0x20;
312
313 size = (pcci->dwSize * height) / 100;
314 if (size < 1)
315 size = 1;
316
317 data |= (BYTE)(height - size);
318
319 __asm__("cli\n\t");
320 outb_p (CRTC_COMMAND, CRTC_CURSORSTART);
321 outb_p (CRTC_DATA, data);
322 outb_p (CRTC_COMMAND, CRTC_CURSOREND);
323 outb_p (CRTC_DATA, height - 1);
324 __asm__("sti\n\t");
325
326 Irp->IoStatus.Information = 0;
327 Status = STATUS_SUCCESS;
328 }
329 break;
330
331
332
333 case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE:
334 {
335 PFILL_OUTPUT_ATTRIBUTE Buf = (PFILL_OUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
336 char *vidmem;
337 int offset;
338 DWORD dwCount;
339
340 vidmem = DeviceExtension->VideoMemory;
341 offset = (DeviceExtension->CursorY * NR_COLUMNS * 2) +
342 (DeviceExtension->CursorX * 2) + 1;
343
344 CHECKPOINT
345
346 for (dwCount = 0; dwCount < Buf->nLength; dwCount++)
347 {
348 vidmem[offset + (dwCount * 2)] = (char) Buf->wAttribute;
349 }
350
351 Irp->IoStatus.Information = 0;
352 Status = STATUS_SUCCESS;
353 }
354 break;
355
356 #if 0
357 case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE:
358 case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE:
359 break;
360 #endif
361
362 case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE:
363 DeviceExtension->CharAttribute = (WORD)Irp->AssociatedIrp.SystemBuffer;
364 Irp->IoStatus.Information = 0;
365 Status = STATUS_SUCCESS;
366 break;
367
368
369 case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER:
370 {
371 PFILL_OUTPUT_CHARACTER Buf = (PFILL_OUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
372 char *vidmem;
373 int offset;
374 DWORD dwCount;
375
376 vidmem = DeviceExtension->VideoMemory;
377 offset = (DeviceExtension->CursorY * NR_COLUMNS * 2) +
378 (DeviceExtension->CursorX * 2);
379
380 CHECKPOINT
381
382 for (dwCount = 0; dwCount < Buf->nLength; dwCount++)
383 {
384 vidmem[offset + (dwCount * 2)] = (char) Buf->cCharacter;
385 }
386
387 Irp->IoStatus.Information = 0;
388 Status = STATUS_SUCCESS;
389 }
390 break;
391
392
393
394 default:
395 Status = STATUS_NOT_IMPLEMENTED;
396 }
397
398 Irp->IoStatus.Status = Status;
399 IoCompleteRequest (Irp, IO_NO_INCREMENT);
400
401 return (Status);
402 }
403
404
405
406
407
408
409 VOID ScrStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
410 {
411 // PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
412
413 }
414
415
416 NTSTATUS ScrDispatch (PDEVICE_OBJECT DeviceObject, PIRP Irp)
417 {
418 PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
419 NTSTATUS Status;
420
421 switch (stk->MajorFunction)
422 {
423 case IRP_MJ_CLOSE:
424 Status = STATUS_SUCCESS;
425 break;
426
427 default:
428 Status = STATUS_NOT_IMPLEMENTED;
429 break;
430 }
431
432
433 Irp->IoStatus.Status = Status;
434 IoCompleteRequest (Irp, IO_NO_INCREMENT);
435
436 return (Status);
437 }
438
439
440 /*
441 * Module entry point
442 */
443 STDCALL NTSTATUS
444 DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
445 {
446 PDEVICE_OBJECT DeviceObject;
447 ANSI_STRING adevice_name;
448 UNICODE_STRING device_name;
449 ANSI_STRING asymlink_name;
450 UNICODE_STRING symlink_name;
451
452 DbgPrint ("Screen Driver 0.0.5\n");
453
454 DriverObject->MajorFunction[IRP_MJ_CREATE] = ScrCreate;
455 DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScrDispatch;
456 DriverObject->MajorFunction[IRP_MJ_READ] = ScrDispatch;
457 DriverObject->MajorFunction[IRP_MJ_WRITE] = ScrWrite;
458 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL ] = ScrIoControl;
459 DriverObject->DriverStartIo = ScrStartIo;
460
461 RtlInitAnsiString (&adevice_name, "\\Device\\BlueScreen");
462 RtlAnsiStringToUnicodeString (&device_name, &adevice_name, TRUE);
463 IoCreateDevice (DriverObject,
464 sizeof(DEVICE_EXTENSION),
465 &device_name,
466 FILE_DEVICE_SCREEN,
467 0,
468 TRUE,
469 &DeviceObject);
470
471 RtlInitAnsiString (&asymlink_name, "\\??\\BlueScreen");
472 RtlAnsiStringToUnicodeString (&symlink_name, &asymlink_name, TRUE);
473 IoCreateSymbolicLink (&symlink_name, &device_name);
474
475 return (STATUS_SUCCESS);
476 }
477