2 #include <internal/halio.h>
5 #include <internal/string.h>
7 #include <ddk/ntddblue.h>
10 #include <internal/debug.h>
14 #define IDMAP_BASE 0xd0000000
15 #define VIDMEM_BASE 0xb8000
20 #define CRTC_COMMAND 0x3d4
21 #define CRTC_DATA 0x3d5
23 #define CRTC_CURSORSTART 0x0a
24 #define CRTC_CURSOREND 0x0b
25 #define CRTC_CURSORPOSLO 0x0f
26 #define CRTC_CURSORPOSHI 0x0e
28 #define ATTRC_WRITEREG 0x3c0
29 #define ATTRC_READREG 0x3c1
36 /* NOTES ******************************************************************/
38 * [[character][attribute]][[character][attribute]]....
42 /* TYPEDEFS ***************************************************************/
44 typedef struct _DEVICE_EXTENSION
53 BYTE ScanLines
; /* Height of a text line */
55 } DEVICE_EXTENSION
, *PDEVICE_EXTENSION
;
61 /* FUNCTIONS **************************************************************/
64 NTSTATUS
ScrCreate (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
66 // PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
67 PDEVICE_EXTENSION DeviceExtension
;
72 DeviceExtension
= DeviceObject
->DeviceExtension
;
74 /* initialize device extension */
75 /* get pointer to video memory */
76 /* FIXME : use MmMapIoSpace() */
77 DeviceExtension
->VideoMemory
= (PBYTE
)(IDMAP_BASE
+ VIDMEM_BASE
);
81 /* get current output position */
82 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
83 offset
= inb_p (CRTC_DATA
);
84 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
85 offset
+= (inb_p (CRTC_DATA
) << 8);
87 /* switch blinking characters off */
89 value
= inb_p (0x3c0);
94 outb_p (0x3c0, value
);
99 DeviceExtension
->CursorX
= (SHORT
)(offset
% NR_COLUMNS
);
100 DeviceExtension
->CursorY
= (SHORT
)(offset
/ NR_COLUMNS
);
101 DeviceExtension
->CursorSize
= 5; /* FIXME: value correct?? */
102 DeviceExtension
->CursorVisible
= TRUE
;
105 DeviceExtension
->ScanLines
= 8; /* FIXME: read it from CRTC */
108 /* more initialization */
109 DeviceExtension
->CharAttribute
= 0x17; /* light grey on blue */
110 DeviceExtension
->Mode
= ENABLE_PROCESSED_OUTPUT
|
111 ENABLE_WRAP_AT_EOL_OUTPUT
;
113 /* FIXME: more initialization?? */
116 /* show blinking cursor */
117 /* FIXME: calculate cursor size */
119 outb_p (CRTC_COMMAND
, CRTC_CURSORSTART
);
120 outb_p (CRTC_DATA
, 0x47);
121 outb_p (CRTC_COMMAND
, CRTC_CURSOREND
);
122 outb_p (CRTC_DATA
, 0x07);
125 Status
= STATUS_SUCCESS
;
127 Irp
->IoStatus
.Status
= Status
;
128 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
134 NTSTATUS
ScrWrite (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
136 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
137 PDEVICE_EXTENSION DeviceExtension
;
139 char *pch
= Irp
->UserBuffer
;
142 int cursorx
, cursory
;
144 DeviceExtension
= DeviceObject
->DeviceExtension
;
145 vidmem
= DeviceExtension
->VideoMemory
;
146 cursorx
= DeviceExtension
->CursorX
;
147 cursory
= DeviceExtension
->CursorY
;
149 for (i
= 0; i
< stk
->Parameters
.Write
.Length
; i
++, pch
++)
158 else if (cursory
> 0)
160 cursorx
= NR_COLUMNS
- 1;
174 offset
= TAB_WIDTH
- (cursorx
% TAB_WIDTH
);
175 for (j
= 0; j
< offset
; j
++)
177 vidmem
[(cursorx
* 2) + (cursory
* NR_COLUMNS
* 2)] = ' ';
180 if (cursorx
>= NR_COLUMNS
)
189 vidmem
[(cursorx
* 2) + (cursory
* NR_COLUMNS
* 2)] = *pch
;
190 vidmem
[(cursorx
* 2) + (cursory
* NR_COLUMNS
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
192 if (cursorx
>= NR_COLUMNS
)
201 if (cursory
>= NR_ROWS
)
203 unsigned short *LinePtr
;
206 &vidmem
[NR_COLUMNS
* 2],
207 NR_COLUMNS
* (NR_ROWS
- 1) * 2);
209 LinePtr
= (unsigned short *) &vidmem
[NR_COLUMNS
* (NR_ROWS
- 1) * 2];
211 for (j
= 0; j
< NR_COLUMNS
; j
++)
213 LinePtr
[j
] = DeviceExtension
->CharAttribute
<< 8;
215 cursory
= NR_ROWS
- 1;
220 /* Set the cursor position */
221 offset
= (cursory
* NR_COLUMNS
) + cursorx
;
223 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
224 outb_p (CRTC_DATA
, offset
);
225 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
227 outb_p (CRTC_DATA
, offset
);
229 DeviceExtension
->CursorX
= cursorx
;
230 DeviceExtension
->CursorY
= cursory
;
232 Status
= STATUS_SUCCESS
;
234 Irp
->IoStatus
.Status
= Status
;
235 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
243 NTSTATUS
ScrIoControl (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
245 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
246 PDEVICE_EXTENSION DeviceExtension
;
249 DeviceExtension
= DeviceObject
->DeviceExtension
;
251 switch (stk
->Parameters
.DeviceIoControl
.IoControlCode
)
253 case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
:
255 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
259 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
260 offset
= inb_p (CRTC_DATA
);
261 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
262 offset
+= (inb_p (CRTC_DATA
) << 8);
265 pcsbi
->dwSize
.X
= NR_ROWS
;
266 pcsbi
->dwSize
.Y
= NR_COLUMNS
;
268 pcsbi
->dwCursorPosition
.X
= (SHORT
)(offset
% NR_COLUMNS
);
269 pcsbi
->dwCursorPosition
.Y
= (SHORT
)(offset
/ NR_COLUMNS
);
271 pcsbi
->wAttributes
= DeviceExtension
->CharAttribute
;
273 pcsbi
->srWindow
.Left
= 0;
274 pcsbi
->srWindow
.Right
= NR_COLUMNS
- 1;
275 pcsbi
->srWindow
.Top
= 0;
276 pcsbi
->srWindow
.Bottom
= NR_ROWS
- 1;
278 pcsbi
->dwMaximumWindowSize
.X
= NR_COLUMNS
;
279 pcsbi
->dwMaximumWindowSize
.Y
= NR_ROWS
;
281 Irp
->IoStatus
.Information
= sizeof (CONSOLE_SCREEN_BUFFER_INFO
);
282 Status
= STATUS_SUCCESS
;
286 case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
:
288 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
291 DeviceExtension
->CursorX
= pcsbi
->dwCursorPosition
.X
;
292 DeviceExtension
->CursorY
= pcsbi
->dwCursorPosition
.Y
;
294 DeviceExtension
->CharAttribute
= pcsbi
->wAttributes
;
296 offset
= (pcsbi
->dwCursorPosition
.Y
* NR_COLUMNS
) +
297 pcsbi
->dwCursorPosition
.X
;
300 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
301 outb_p (CRTC_DATA
, offset
);
302 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
303 outb_p (CRTC_DATA
, offset
>>8);
306 Irp
->IoStatus
.Information
= 0;
307 Status
= STATUS_SUCCESS
;
311 case IOCTL_CONSOLE_GET_CURSOR_INFO
:
313 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
315 pcci
->dwSize
= DeviceExtension
->CursorSize
;
316 pcci
->bVisible
= DeviceExtension
->CursorVisible
;
318 Irp
->IoStatus
.Information
= sizeof (CONSOLE_CURSOR_INFO
);
319 Status
= STATUS_SUCCESS
;
323 case IOCTL_CONSOLE_SET_CURSOR_INFO
:
325 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
329 DeviceExtension
->CursorSize
= pcci
->dwSize
;
330 DeviceExtension
->CursorVisible
= pcci
->bVisible
;
331 height
= DeviceExtension
->ScanLines
;
332 data
= (pcci
->bVisible
) ? 0x40 : 0x20;
334 size
= (pcci
->dwSize
* height
) / 100;
338 data
|= (BYTE
)(height
- size
);
341 outb_p (CRTC_COMMAND
, CRTC_CURSORSTART
);
342 outb_p (CRTC_DATA
, data
);
343 outb_p (CRTC_COMMAND
, CRTC_CURSOREND
);
344 outb_p (CRTC_DATA
, height
- 1);
347 Irp
->IoStatus
.Information
= 0;
348 Status
= STATUS_SUCCESS
;
352 case IOCTL_CONSOLE_GET_MODE
:
354 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
356 pcm
->dwMode
= DeviceExtension
->Mode
;
358 Irp
->IoStatus
.Information
= sizeof(CONSOLE_MODE
);
359 Status
= STATUS_SUCCESS
;
363 case IOCTL_CONSOLE_SET_MODE
:
365 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
367 DeviceExtension
->Mode
= pcm
->dwMode
;
369 Irp
->IoStatus
.Information
= 0;
370 Status
= STATUS_SUCCESS
;
374 case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE
:
376 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
381 vidmem
= DeviceExtension
->VideoMemory
;
382 offset
= (Buf
->dwCoord
.Y
* NR_COLUMNS
* 2) +
383 (Buf
->dwCoord
.X
* 2) + 1;
387 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
389 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->wAttribute
;
392 Buf
->dwTransfered
= Buf
->nLength
;
394 Irp
->IoStatus
.Information
= 0;
395 Status
= STATUS_SUCCESS
;
399 case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE
:
401 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
402 LPWORD pAttr
= (LPWORD
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
407 vidmem
= DeviceExtension
->VideoMemory
;
408 offset
= (Buf
->dwCoord
.Y
* NR_COLUMNS
* 2) +
409 (Buf
->dwCoord
.X
* 2) + 1;
411 for (dwCount
= 0; dwCount
< stk
->Parameters
.Write
.Length
; dwCount
++, pAttr
++)
413 (char) *pAttr
= vidmem
[offset
+ (dwCount
* 2)];
416 Buf
->dwTransfered
= dwCount
;
418 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
419 Status
= STATUS_SUCCESS
;
423 case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE
:
425 POUTPUT_ATTRIBUTE Buf
= (POUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
426 LPWORD pAttr
= (LPWORD
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
431 vidmem
= DeviceExtension
->VideoMemory
;
432 offset
= (Buf
->dwCoord
.Y
* NR_COLUMNS
* 2) +
433 (Buf
->dwCoord
.X
* 2) + 1;
435 for (dwCount
= 0; dwCount
< stk
->Parameters
.Write
.Length
; dwCount
++, pAttr
++)
437 vidmem
[offset
+ (dwCount
* 2)] = (char) *pAttr
;
440 Buf
->dwTransfered
= dwCount
;
442 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
443 Status
= STATUS_SUCCESS
;
447 case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
:
448 DeviceExtension
->CharAttribute
= (WORD
)*(LPWORD
)Irp
->AssociatedIrp
.SystemBuffer
;
449 Irp
->IoStatus
.Information
= 0;
450 Status
= STATUS_SUCCESS
;
454 case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER
:
456 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
461 vidmem
= DeviceExtension
->VideoMemory
;
462 offset
= (Buf
->dwCoord
.Y
* NR_COLUMNS
* 2) +
463 (Buf
->dwCoord
.X
* 2);
467 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
469 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->cCharacter
;
472 Buf
->dwTransfered
= Buf
->nLength
;
474 Irp
->IoStatus
.Information
= 0;
475 Status
= STATUS_SUCCESS
;
479 case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER
:
481 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
482 LPSTR pChar
= (LPSTR
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
487 vidmem
= DeviceExtension
->VideoMemory
;
488 offset
= (Buf
->dwCoord
.Y
* NR_COLUMNS
* 2) +
489 (Buf
->dwCoord
.X
* 2);
491 for (dwCount
= 0; dwCount
< stk
->Parameters
.Write
.Length
; dwCount
++, pChar
++)
493 *pChar
= vidmem
[offset
+ (dwCount
* 2)];
496 Buf
->dwTransfered
= dwCount
;
498 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
499 Status
= STATUS_SUCCESS
;
503 case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
:
505 POUTPUT_CHARACTER Buf
= (POUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
506 LPSTR pChar
= (LPSTR
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
511 vidmem
= DeviceExtension
->VideoMemory
;
512 offset
= (Buf
->dwCoord
.Y
* NR_COLUMNS
* 2) +
513 (Buf
->dwCoord
.X
* 2) + 1;
515 for (dwCount
= 0; dwCount
< stk
->Parameters
.Write
.Length
; dwCount
++, pChar
++)
517 vidmem
[offset
+ (dwCount
* 2)] = (char) *pChar
;
520 Buf
->dwTransfered
= dwCount
;
522 Irp
->IoStatus
.Information
= sizeof(OUTPUT_ATTRIBUTE
);
523 Status
= STATUS_SUCCESS
;
529 Status
= STATUS_NOT_IMPLEMENTED
;
532 Irp
->IoStatus
.Status
= Status
;
533 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
543 VOID
ScrStartIo(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
545 // PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
550 NTSTATUS
ScrDispatch (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
552 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation(Irp
);
555 switch (stk
->MajorFunction
)
558 Status
= STATUS_SUCCESS
;
562 Status
= STATUS_NOT_IMPLEMENTED
;
567 Irp
->IoStatus
.Status
= Status
;
568 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
578 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
580 PDEVICE_OBJECT DeviceObject
;
581 ANSI_STRING adevice_name
;
582 UNICODE_STRING device_name
;
583 ANSI_STRING asymlink_name
;
584 UNICODE_STRING symlink_name
;
586 DbgPrint ("Screen Driver 0.0.6\n");
588 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = ScrCreate
;
589 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = ScrDispatch
;
590 DriverObject
->MajorFunction
[IRP_MJ_READ
] = ScrDispatch
;
591 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = ScrWrite
;
592 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ScrIoControl
;
593 DriverObject
->DriverStartIo
= ScrStartIo
;
595 RtlInitAnsiString (&adevice_name
, "\\Device\\BlueScreen");
596 RtlAnsiStringToUnicodeString (&device_name
, &adevice_name
, TRUE
);
597 IoCreateDevice (DriverObject
,
598 sizeof(DEVICE_EXTENSION
),
605 RtlInitAnsiString (&asymlink_name
, "\\??\\BlueScreen");
606 RtlAnsiStringToUnicodeString (&symlink_name
, &asymlink_name
, TRUE
);
607 IoCreateSymbolicLink (&symlink_name
, &device_name
);
609 return (STATUS_SUCCESS
);