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