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