Fix build; sorry, I was waiting for Filip.
[reactos.git] / reactos / drivers / dd / blue / blue.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/dd/blue/blue.c
6 * PURPOSE: Console (blue screen) device driver
7 * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
8 * UPDATE HISTORY:
9 * ??? Created
10 */
11
12 /* INCLUDES ******************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <wincon.h>
16 #include <blue/ntddblue.h>
17 #include <ndk/halfuncs.h>
18
19 #define NDEBUG
20 #include <debug.h>
21
22
23 /* DEFINITIONS ***************************************************************/
24
25 #define VIDMEM_BASE 0xb8000
26
27 #define CRTC_COMMAND ((PUCHAR)0x3d4)
28 #define CRTC_DATA ((PUCHAR)0x3d5)
29
30 #define CRTC_COLUMNS 0x01
31 #define CRTC_OVERFLOW 0x07
32 #define CRTC_ROWS 0x12
33 #define CRTC_SCANLINES 0x09
34 #define CRTC_CURSORSTART 0x0a
35 #define CRTC_CURSOREND 0x0b
36 #define CRTC_CURSORPOSHI 0x0e
37 #define CRTC_CURSORPOSLO 0x0f
38
39 #define ATTRC_WRITEREG ((PUCHAR)0x3c0)
40 #define ATTRC_READREG ((PUCHAR)0x3c1)
41 #define ATTRC_INPST1 ((PUCHAR)0x3da)
42
43 #define TAB_WIDTH 8
44
45
46 /* NOTES ******************************************************************/
47 /*
48 * [[character][attribute]][[character][attribute]]....
49 */
50
51
52 /* TYPEDEFS ***************************************************************/
53
54 typedef struct _DEVICE_EXTENSION
55 {
56 PBYTE VideoMemory; /* Pointer to video memory */
57 DWORD CursorSize;
58 BOOL CursorVisible;
59 WORD CharAttribute;
60 DWORD Mode;
61 BYTE ScanLines; /* Height of a text line */
62 WORD Rows; /* Number of rows */
63 WORD Columns; /* Number of columns */
64 } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
65
66
67 /* FUNCTIONS **************************************************************/
68
69 NTSTATUS STDCALL
70 ScrCreate(PDEVICE_OBJECT DeviceObject,
71 PIRP Irp)
72 {
73 PDEVICE_EXTENSION DeviceExtension;
74 PHYSICAL_ADDRESS BaseAddress;
75 NTSTATUS Status;
76 unsigned int offset;
77 BYTE data, value;
78
79 DeviceExtension = DeviceObject->DeviceExtension;
80
81 /* disable interrupts */
82 __asm__("cli\n\t");
83
84 /* get current output position */
85 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
86 offset = READ_PORT_UCHAR (CRTC_DATA);
87 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
88 offset += (READ_PORT_UCHAR (CRTC_DATA) << 8);
89
90 /* switch blinking characters off */
91 READ_PORT_UCHAR (ATTRC_INPST1);
92 value = READ_PORT_UCHAR (ATTRC_WRITEREG);
93 WRITE_PORT_UCHAR (ATTRC_WRITEREG, 0x10);
94 data = READ_PORT_UCHAR (ATTRC_READREG);
95 data = data & ~0x08;
96 WRITE_PORT_UCHAR (ATTRC_WRITEREG, data);
97 WRITE_PORT_UCHAR (ATTRC_WRITEREG, value);
98 READ_PORT_UCHAR (ATTRC_INPST1);
99
100 /* read screen information from crt controller */
101 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_COLUMNS);
102 DeviceExtension->Columns = READ_PORT_UCHAR (CRTC_DATA) + 1;
103 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_ROWS);
104 DeviceExtension->Rows = READ_PORT_UCHAR (CRTC_DATA);
105 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_OVERFLOW);
106 data = READ_PORT_UCHAR (CRTC_DATA);
107 DeviceExtension->Rows |= (((data & 0x02) << 7) | ((data & 0x40) << 3));
108 DeviceExtension->Rows++;
109 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_SCANLINES);
110 DeviceExtension->ScanLines = (READ_PORT_UCHAR (CRTC_DATA) & 0x1F) + 1;
111
112 /* enable interrupts */
113 __asm__("sti\n\t");
114
115 /* calculate number of text rows */
116 DeviceExtension->Rows =
117 DeviceExtension->Rows / DeviceExtension->ScanLines;
118 #ifdef BOCHS_30ROWS
119 DeviceExtension->Rows = 30;
120 #endif
121
122 DPRINT ("%d Columns %d Rows %d Scanlines\n",
123 DeviceExtension->Columns,
124 DeviceExtension->Rows,
125 DeviceExtension->ScanLines);
126
127 /* get pointer to video memory */
128 BaseAddress.QuadPart = VIDMEM_BASE;
129 DeviceExtension->VideoMemory =
130 (PBYTE)MmMapIoSpace (BaseAddress, DeviceExtension->Rows * DeviceExtension->Columns * 2, MmNonCached);
131
132 DeviceExtension->CursorSize = 5; /* FIXME: value correct?? */
133 DeviceExtension->CursorVisible = TRUE;
134
135 /* more initialization */
136 DeviceExtension->CharAttribute = 0x17; /* light grey on blue */
137 DeviceExtension->Mode = ENABLE_PROCESSED_OUTPUT |
138 ENABLE_WRAP_AT_EOL_OUTPUT;
139
140 /* show blinking cursor */
141 __asm__("cli\n\t");
142 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORSTART);
143 WRITE_PORT_UCHAR (CRTC_DATA, (DeviceExtension->ScanLines - 1) & 0x1F);
144 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSOREND);
145 data = READ_PORT_UCHAR (CRTC_DATA) & 0xE0;
146 WRITE_PORT_UCHAR (CRTC_DATA,
147 data | ((DeviceExtension->ScanLines - 1) & 0x1F));
148 __asm__("sti\n\t");
149
150 Status = STATUS_SUCCESS;
151
152 Irp->IoStatus.Status = Status;
153 IoCompleteRequest (Irp, IO_NO_INCREMENT);
154
155 return (Status);
156 }
157
158
159 NTSTATUS STDCALL
160 ScrWrite(PDEVICE_OBJECT DeviceObject,
161 PIRP Irp)
162 {
163 PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
164 PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
165 NTSTATUS Status;
166 char *pch = Irp->UserBuffer;
167 PBYTE vidmem;
168 unsigned int i;
169 int j, offset;
170 int cursorx, cursory;
171 int rows, columns;
172 int processed = DeviceExtension->Mode & ENABLE_PROCESSED_OUTPUT;
173
174 if (HalQueryDisplayOwnership())
175 {
176 /* Display is in graphics mode, we're not allowed to touch it */
177 Status = STATUS_SUCCESS;
178
179 Irp->IoStatus.Status = Status;
180 IoCompleteRequest (Irp, IO_NO_INCREMENT);
181
182 return Status;
183 }
184
185 vidmem = DeviceExtension->VideoMemory;
186 rows = DeviceExtension->Rows;
187 columns = DeviceExtension->Columns;
188
189 __asm__ ("cli\n\t");
190 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
191 offset = READ_PORT_UCHAR (CRTC_DATA)<<8;
192 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
193 offset += READ_PORT_UCHAR (CRTC_DATA);
194 __asm__ ("sti\n\t");
195
196 cursory = offset / columns;
197 cursorx = offset % columns;
198 if( processed == 0 )
199 {
200 /* raw output mode */
201 memcpy( &vidmem[(cursorx * 2) + (cursory * columns * 2)], pch, stk->Parameters.Write.Length );
202 offset += (stk->Parameters.Write.Length / 2);
203 }
204 else {
205 for (i = 0; i < stk->Parameters.Write.Length; i++, pch++)
206 {
207 switch (*pch)
208 {
209 case '\b':
210 if (cursorx > 0)
211 {
212 cursorx--;
213 }
214 else if (cursory > 0)
215 {
216 cursorx = columns - 1;
217 cursory--;
218 }
219 vidmem[(cursorx * 2) + (cursory * columns * 2)] = ' ';
220 vidmem[(cursorx * 2) + (cursory * columns * 2) + 1] = (char) DeviceExtension->CharAttribute;
221 break;
222
223 case '\n':
224 cursory++;
225 cursorx = 0;
226 break;
227
228 case '\r':
229 cursorx = 0;
230 break;
231
232 case '\t':
233 offset = TAB_WIDTH - (cursorx % TAB_WIDTH);
234 for (j = 0; j < offset; j++)
235 {
236 vidmem[(cursorx * 2) + (cursory * columns * 2)] = ' ';
237 cursorx++;
238
239 if (cursorx >= columns)
240 {
241 cursory++;
242 cursorx = 0;
243 }
244 }
245 break;
246
247 default:
248 vidmem[(cursorx * 2) + (cursory * columns * 2)] = *pch;
249 vidmem[(cursorx * 2) + (cursory * columns * 2) + 1] = (char) DeviceExtension->CharAttribute;
250 cursorx++;
251 if (cursorx >= columns)
252 {
253 cursory++;
254 cursorx = 0;
255 }
256 break;
257 }
258 if (cursory >= rows)
259 {
260 unsigned short *LinePtr;
261
262 memcpy (vidmem,
263 &vidmem[columns * 2],
264 columns * (rows - 1) * 2);
265
266 LinePtr = (unsigned short *) &vidmem[columns * (rows - 1) * 2];
267
268 for (j = 0; j < columns; j++)
269 {
270 LinePtr[j] = DeviceExtension->CharAttribute << 8;
271 }
272 cursory = rows - 1;
273 for (j = 0; j < columns; j++)
274 {
275 vidmem[(j * 2) + (cursory * columns * 2)] = ' ';
276 vidmem[(j * 2) + (cursory * columns * 2) + 1] = (char)DeviceExtension->CharAttribute;
277 }
278 }
279 }
280
281 /* Set the cursor position */
282 offset = (cursory * columns) + cursorx;
283 }
284 __asm__ ("cli\n\t");
285 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
286 WRITE_PORT_UCHAR (CRTC_DATA, offset);
287 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
288 offset >>= 8;
289 WRITE_PORT_UCHAR (CRTC_DATA, offset);
290 __asm__ ("sti\n\t");
291
292 Status = STATUS_SUCCESS;
293
294 Irp->IoStatus.Status = Status;
295 IoCompleteRequest (Irp, IO_NO_INCREMENT);
296
297 return (Status);
298 }
299
300
301 NTSTATUS STDCALL
302 ScrIoControl(PDEVICE_OBJECT DeviceObject,
303 PIRP Irp)
304 {
305 PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
306 PDEVICE_EXTENSION DeviceExtension;
307 NTSTATUS Status;
308
309 DeviceExtension = DeviceObject->DeviceExtension;
310 switch (stk->Parameters.DeviceIoControl.IoControlCode)
311 {
312 case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO:
313 {
314 PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
315 int rows = DeviceExtension->Rows;
316 int columns = DeviceExtension->Columns;
317 unsigned int offset;
318
319 /* read cursor position from crtc */
320 __asm__("cli\n\t");
321 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
322 offset = READ_PORT_UCHAR (CRTC_DATA);
323 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
324 offset += (READ_PORT_UCHAR (CRTC_DATA) << 8);
325 __asm__("sti\n\t");
326
327 pcsbi->dwSize.X = columns;
328 pcsbi->dwSize.Y = rows;
329
330 pcsbi->dwCursorPosition.X = (SHORT)(offset % columns);
331 pcsbi->dwCursorPosition.Y = (SHORT)(offset / columns);
332
333 pcsbi->wAttributes = DeviceExtension->CharAttribute;
334
335 pcsbi->srWindow.Left = 0;
336 pcsbi->srWindow.Right = columns - 1;
337 pcsbi->srWindow.Top = 0;
338 pcsbi->srWindow.Bottom = rows - 1;
339
340 pcsbi->dwMaximumWindowSize.X = columns;
341 pcsbi->dwMaximumWindowSize.Y = rows;
342
343 Irp->IoStatus.Information = sizeof (CONSOLE_SCREEN_BUFFER_INFO);
344 Status = STATUS_SUCCESS;
345 }
346 break;
347
348 case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO:
349 {
350 PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
351 unsigned int offset;
352
353 DeviceExtension->CharAttribute = pcsbi->wAttributes;
354 offset = (pcsbi->dwCursorPosition.Y * DeviceExtension->Columns) +
355 pcsbi->dwCursorPosition.X;
356
357 __asm__("cli\n\t");
358 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
359 WRITE_PORT_UCHAR (CRTC_DATA, offset);
360 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
361 WRITE_PORT_UCHAR (CRTC_DATA, offset>>8);
362 __asm__("sti\n\t");
363
364 Irp->IoStatus.Information = 0;
365 Status = STATUS_SUCCESS;
366 }
367 break;
368
369 case IOCTL_CONSOLE_GET_CURSOR_INFO:
370 {
371 PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
372
373 pcci->dwSize = DeviceExtension->CursorSize;
374 pcci->bVisible = DeviceExtension->CursorVisible;
375
376 Irp->IoStatus.Information = sizeof (CONSOLE_CURSOR_INFO);
377 Status = STATUS_SUCCESS;
378 }
379 break;
380
381 case IOCTL_CONSOLE_SET_CURSOR_INFO:
382 {
383 PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
384 BYTE data, value;
385 DWORD size, height;
386
387 DeviceExtension->CursorSize = pcci->dwSize;
388 DeviceExtension->CursorVisible = pcci->bVisible;
389 height = DeviceExtension->ScanLines;
390 data = (pcci->bVisible) ? 0x00 : 0x20;
391
392 size = (pcci->dwSize * height) / 100;
393 if (size < 1)
394 {
395 size = 1;
396 }
397
398 data |= (BYTE)(height - size);
399
400 __asm__("cli\n\t");
401 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORSTART);
402 WRITE_PORT_UCHAR (CRTC_DATA, data);
403 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSOREND);
404 value = READ_PORT_UCHAR (CRTC_DATA) & 0xE0;
405 WRITE_PORT_UCHAR (CRTC_DATA, value | (height - 1));
406
407 __asm__("sti\n\t");
408
409 Irp->IoStatus.Information = 0;
410 Status = STATUS_SUCCESS;
411 }
412 break;
413
414 case IOCTL_CONSOLE_GET_MODE:
415 {
416 PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
417
418 pcm->dwMode = DeviceExtension->Mode;
419
420 Irp->IoStatus.Information = sizeof(CONSOLE_MODE);
421 Status = STATUS_SUCCESS;
422 }
423 break;
424
425 case IOCTL_CONSOLE_SET_MODE:
426 {
427 PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
428
429 DeviceExtension->Mode = pcm->dwMode;
430
431 Irp->IoStatus.Information = 0;
432 Status = STATUS_SUCCESS;
433 }
434 break;
435
436 case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE:
437 {
438 POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
439 PBYTE vidmem;
440 int offset;
441 DWORD dwCount;
442
443 vidmem = DeviceExtension->VideoMemory;
444 offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
445 (Buf->dwCoord.X * 2) + 1;
446
447 for (dwCount = 0; dwCount < Buf->nLength; dwCount++)
448 {
449 vidmem[offset + (dwCount * 2)] = (char) Buf->wAttribute;
450 }
451
452 Buf->dwTransfered = Buf->nLength;
453
454 Irp->IoStatus.Information = 0;
455 Status = STATUS_SUCCESS;
456 }
457 break;
458
459 case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE:
460 {
461 POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
462 PWORD pAttr = (PWORD)MmGetSystemAddressForMdl(Irp->MdlAddress);
463 PBYTE vidmem;
464 int offset;
465 DWORD dwCount;
466
467 vidmem = DeviceExtension->VideoMemory;
468 offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
469 (Buf->dwCoord.X * 2) + 1;
470
471 for (dwCount = 0; dwCount < stk->Parameters.DeviceIoControl.OutputBufferLength; dwCount++, pAttr++)
472 {
473 *((char *) pAttr) = vidmem[offset + (dwCount * 2)];
474 }
475
476 Buf->dwTransfered = dwCount;
477
478 Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
479 Status = STATUS_SUCCESS;
480 }
481 break;
482
483 case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE:
484 {
485 COORD *pCoord = (COORD *)MmGetSystemAddressForMdl(Irp->MdlAddress);
486 CHAR *pAttr = (CHAR *)(pCoord + 1);
487 PBYTE vidmem;
488 int offset;
489 DWORD dwCount;
490
491 vidmem = DeviceExtension->VideoMemory;
492 offset = (pCoord->Y * DeviceExtension->Columns * 2) +
493 (pCoord->X * 2) + 1;
494
495 for (dwCount = 0; dwCount < (stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof( COORD )); dwCount++, pAttr++)
496 {
497 vidmem[offset + (dwCount * 2)] = *pAttr;
498 }
499 Irp->IoStatus.Information = 0;
500 Status = STATUS_SUCCESS;
501 }
502 break;
503
504 case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE:
505 DeviceExtension->CharAttribute = (WORD)*(PWORD)Irp->AssociatedIrp.SystemBuffer;
506 Irp->IoStatus.Information = 0;
507 Status = STATUS_SUCCESS;
508 break;
509
510 case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER:
511 {
512 POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
513 PBYTE vidmem;
514 int offset;
515 DWORD dwCount;
516
517 vidmem = DeviceExtension->VideoMemory;
518 offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
519 (Buf->dwCoord.X * 2);
520
521 CHECKPOINT
522
523 for (dwCount = 0; dwCount < Buf->nLength; dwCount++)
524 {
525 vidmem[offset + (dwCount * 2)] = (char) Buf->cCharacter;
526 }
527
528 Buf->dwTransfered = Buf->nLength;
529
530 Irp->IoStatus.Information = 0;
531 Status = STATUS_SUCCESS;
532 }
533 break;
534
535 case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER:
536 {
537 POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
538 LPSTR pChar = (LPSTR)MmGetSystemAddressForMdl(Irp->MdlAddress);
539 PBYTE vidmem;
540 int offset;
541 DWORD dwCount;
542
543 vidmem = DeviceExtension->VideoMemory;
544 offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
545 (Buf->dwCoord.X * 2);
546
547 for (dwCount = 0; dwCount < stk->Parameters.DeviceIoControl.OutputBufferLength; dwCount++, pChar++)
548 {
549 *pChar = vidmem[offset + (dwCount * 2)];
550 }
551
552 Buf->dwTransfered = dwCount;
553
554 Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
555 Status = STATUS_SUCCESS;
556 }
557 break;
558
559 case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER:
560 {
561 COORD *pCoord;
562 LPSTR pChar;
563 PBYTE vidmem;
564 int offset;
565 DWORD dwCount;
566
567 pCoord = (COORD *)MmGetSystemAddressForMdl(Irp->MdlAddress);
568 pChar = (CHAR *)(pCoord + 1);
569 vidmem = DeviceExtension->VideoMemory;
570 offset = (pCoord->Y * DeviceExtension->Columns * 2) +
571 (pCoord->X * 2);
572
573 for (dwCount = 0; dwCount < (stk->Parameters.DeviceIoControl.OutputBufferLength - sizeof( COORD )); dwCount++, pChar++)
574 {
575 vidmem[offset + (dwCount * 2)] = *pChar;
576 }
577
578 Irp->IoStatus.Information = 0;
579 Status = STATUS_SUCCESS;
580 }
581 break;
582
583 case IOCTL_CONSOLE_DRAW:
584 {
585 PCONSOLE_DRAW ConsoleDraw;
586 PBYTE Src, Dest;
587 UINT SrcDelta, DestDelta, i, Offset;
588
589 ConsoleDraw = (PCONSOLE_DRAW) MmGetSystemAddressForMdl(Irp->MdlAddress);
590 Src = (PBYTE) (ConsoleDraw + 1);
591 SrcDelta = ConsoleDraw->SizeX * 2;
592 Dest = DeviceExtension->VideoMemory +
593 (ConsoleDraw->Y * DeviceExtension->Columns + ConsoleDraw->X) * 2;
594 DestDelta = DeviceExtension->Columns * 2;
595
596 for (i = 0; i < ConsoleDraw->SizeY; i++)
597 {
598 RtlCopyMemory(Dest, Src, SrcDelta);
599 Src += SrcDelta;
600 Dest += DestDelta;
601 }
602
603 Offset = (ConsoleDraw->CursorY * DeviceExtension->Columns) +
604 ConsoleDraw->CursorX;
605
606 __asm__("cli\n\t");
607 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
608 WRITE_PORT_UCHAR (CRTC_DATA, Offset);
609 WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
610 WRITE_PORT_UCHAR (CRTC_DATA, Offset >> 8);
611 __asm__("sti\n\t");
612
613 Irp->IoStatus.Information = 0;
614 Status = STATUS_SUCCESS;
615 }
616 break;
617
618 default:
619 Status = STATUS_NOT_IMPLEMENTED;
620 }
621
622 Irp->IoStatus.Status = Status;
623 IoCompleteRequest (Irp, IO_NO_INCREMENT);
624
625 return Status;
626 }
627
628
629 NTSTATUS STDCALL
630 ScrDispatch(PDEVICE_OBJECT DeviceObject,
631 PIRP Irp)
632 {
633 PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
634 NTSTATUS Status;
635
636 switch (stk->MajorFunction)
637 {
638 case IRP_MJ_CLOSE:
639 Status = STATUS_SUCCESS;
640 break;
641
642 default:
643 Status = STATUS_NOT_IMPLEMENTED;
644 break;
645 }
646
647
648 Irp->IoStatus.Status = Status;
649 IoCompleteRequest (Irp, IO_NO_INCREMENT);
650
651 return (Status);
652 }
653
654
655 /*
656 * Module entry point
657 */
658 NTSTATUS STDCALL
659 DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
660 {
661 PDEVICE_OBJECT DeviceObject;
662 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\BlueScreen");
663 UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\??\\BlueScreen");
664
665 DPRINT ("Screen Driver 0.0.6\n");
666
667 DriverObject->MajorFunction[IRP_MJ_CREATE] = ScrCreate;
668 DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScrDispatch;
669 DriverObject->MajorFunction[IRP_MJ_READ] = ScrDispatch;
670 DriverObject->MajorFunction[IRP_MJ_WRITE] = ScrWrite;
671 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL ] = ScrIoControl;
672
673 IoCreateDevice (DriverObject,
674 sizeof(DEVICE_EXTENSION),
675 &DeviceName,
676 FILE_DEVICE_SCREEN,
677 0,
678 TRUE,
679 &DeviceObject);
680
681 IoCreateSymbolicLink (&SymlinkName, &DeviceName);
682
683 return (STATUS_SUCCESS);
684 }
685
686 /* EOF */