2 #include <internal/mmhal.h>
3 #include <internal/halio.h>
6 #include <internal/string.h>
8 #include <ddk/ntddblue.h>
11 #include <internal/debug.h>
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
34 /* NOTES ******************************************************************/
36 * [[character][attribute]][[character][attribute]]....
40 /* TYPEDEFS ***************************************************************/
42 typedef struct _DEVICE_EXTENSION
51 BYTE ScanLines
; /* Height of a text line */
53 } DEVICE_EXTENSION
, *PDEVICE_EXTENSION
;
59 /* FUNCTIONS **************************************************************/
62 NTSTATUS
ScrCreate (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
64 // PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
65 PDEVICE_EXTENSION DeviceExtension
;
69 DeviceExtension
= DeviceObject
->DeviceExtension
;
71 /* initialize device extension */
72 /* get pointer to video memory */
73 DeviceExtension
->VideoMemory
= (PBYTE
)physical_to_linear (VIDMEM_BASE
);
75 /* get current output position */
77 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
78 offset
= inb_p (CRTC_DATA
);
79 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
80 offset
+= (inb_p (CRTC_DATA
) << 8);
83 DeviceExtension
->CursorX
= (SHORT
)(offset
% NR_COLUMNS
);
84 DeviceExtension
->CursorY
= (SHORT
)(offset
/ NR_COLUMNS
);
85 DeviceExtension
->CursorSize
= 5; /* FIXME: value correct?? */
86 DeviceExtension
->CursorVisible
= TRUE
;
89 DeviceExtension
->ScanLines
= 8; /* FIXME: read it from CRTC */
92 /* more initialization */
93 DeviceExtension
->CharAttribute
= 0x17; /* light grey on blue */
94 DeviceExtension
->Mode
= ENABLE_PROCESSED_OUTPUT
|
95 ENABLE_WRAP_AT_EOL_OUTPUT
;
97 /* FIXME: more initialization?? */
100 /* show blinking cursor */
101 /* FIXME: calculate cursor size */
103 outb_p (CRTC_COMMAND
, CRTC_CURSORSTART
);
104 outb_p (CRTC_DATA
, 0x47);
105 outb_p (CRTC_COMMAND
, CRTC_CURSOREND
);
106 outb_p (CRTC_DATA
, 0x07);
110 Status
= STATUS_SUCCESS
;
112 Irp
->IoStatus
.Status
= Status
;
113 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
119 NTSTATUS
ScrWrite (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
121 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
122 PDEVICE_EXTENSION DeviceExtension
;
124 char *pch
= Irp
->UserBuffer
;
127 int cursorx
, cursory
;
129 DeviceExtension
= DeviceObject
->DeviceExtension
;
130 vidmem
= DeviceExtension
->VideoMemory
;
131 cursorx
= DeviceExtension
->CursorX
;
132 cursory
= DeviceExtension
->CursorY
;
134 for (i
= 0; i
< stk
->Parameters
.Write
.Length
; i
++, pch
++)
143 else if (cursory
> 0)
145 cursorx
= NR_COLUMNS
- 1;
159 offset
= TAB_WIDTH
- (cursorx
% TAB_WIDTH
);
160 for (j
= 0; j
< offset
; j
++)
162 vidmem
[(cursorx
* 2) + (cursory
* NR_COLUMNS
* 2)] = ' ';
165 if (cursorx >= NR_COLUMNS)
175 vidmem
[(cursorx
* 2) + (cursory
* NR_COLUMNS
* 2)] = *pch
;
176 vidmem
[(cursorx
* 2) + (cursory
* NR_COLUMNS
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
178 if (cursorx
>= NR_COLUMNS
)
186 if (cursory
>= NR_ROWS
)
188 unsigned short *LinePtr
;
191 &vidmem
[NR_COLUMNS
* 2],
192 NR_COLUMNS
* (NR_ROWS
- 1) * 2);
194 LinePtr
= (unsigned short *) &vidmem
[NR_COLUMNS
* (NR_ROWS
- 1) * 2];
196 for (j
= 0; j
< NR_COLUMNS
; j
++)
198 LinePtr
[j
] = DeviceExtension
->CharAttribute
<< 8;
200 cursory
= NR_ROWS
- 1;
205 /* Set the cursor position */
207 offset
= (cursory
* NR_COLUMNS
) + cursorx
;
209 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
210 outb_p (CRTC_DATA
, offset
);
211 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
213 outb_p (CRTC_DATA
, offset
);
215 DeviceExtension
->CursorX
= cursorx
;
216 DeviceExtension
->CursorY
= cursory
;
219 Status
= STATUS_SUCCESS
;
221 Irp
->IoStatus
.Status
= Status
;
222 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
230 NTSTATUS
ScrIoControl (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
232 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
233 PDEVICE_EXTENSION DeviceExtension
;
237 DeviceExtension
= DeviceObject
->DeviceExtension
;
239 switch (stk
->Parameters
.DeviceIoControl
.IoControlCode
)
241 case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
:
243 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
247 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
248 offset
= inb_p (CRTC_DATA
);
249 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
250 offset
+= (inb_p (CRTC_DATA
) << 8);
253 pcsbi
->dwCursorPosition
.X
= (SHORT
)(offset
% NR_COLUMNS
);
254 pcsbi
->dwCursorPosition
.Y
= (SHORT
)(offset
/ NR_COLUMNS
);
256 pcsbi
->dwSize
.X
= NR_ROWS
;
257 pcsbi
->dwSize
.Y
= NR_COLUMNS
;
259 Irp
->IoStatus
.Information
= sizeof (CONSOLE_SCREEN_BUFFER_INFO
);
260 Status
= STATUS_SUCCESS
;
264 case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
:
266 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
269 DeviceExtension
->CursorX
= pcsbi
->dwCursorPosition
.X
;
270 DeviceExtension
->CursorY
= pcsbi
->dwCursorPosition
.Y
;
272 offset
= (pcsbi
->dwCursorPosition
.Y
* NR_COLUMNS
) +
273 pcsbi
->dwCursorPosition
.X
;
276 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
277 outb_p (CRTC_DATA
, offset
);
278 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
279 outb_p (CRTC_DATA
, offset
>>8);
282 Irp
->IoStatus
.Information
= 0;
283 Status
= STATUS_SUCCESS
;
287 case IOCTL_CONSOLE_GET_CURSOR_INFO
:
289 // PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
291 // DPRINT("GetConsoleCursorInfo: pcci=%p\n", pcci);
292 // DPRINT("GetConsoleCursorInfo\n");
293 // pcci->dwSize = 10;
294 // pcci->bVisible = FALSE;
296 Irp
->IoStatus
.Information
= 0;
297 Status
= STATUS_SUCCESS
;
301 case IOCTL_CONSOLE_SET_CURSOR_INFO
:
303 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
307 DeviceExtension
->CursorSize
= pcci
->dwSize
;
308 DeviceExtension
->CursorVisible
= pcci
->bVisible
;
309 height
= DeviceExtension
->ScanLines
;
310 data
= (pcci
->bVisible
) ? 0x40 : 0x20;
312 size
= (pcci
->dwSize
* height
) / 100;
316 data
|= (BYTE
)(height
- size
);
319 outb_p (CRTC_COMMAND
, CRTC_CURSORSTART
);
320 outb_p (CRTC_DATA
, data
);
321 outb_p (CRTC_COMMAND
, CRTC_CURSOREND
);
322 outb_p (CRTC_DATA
, height
- 1);
325 Irp
->IoStatus
.Information
= 0;
326 Status
= STATUS_SUCCESS
;
332 case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE
:
334 PFILL_OUTPUT_ATTRIBUTE Buf
= (PFILL_OUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
339 vidmem
= DeviceExtension
->VideoMemory
;
340 offset
= (DeviceExtension
->CursorY
* NR_COLUMNS
* 2) +
341 (DeviceExtension
->CursorX
* 2) + 1;
345 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
347 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->wAttribute
;
350 Irp
->IoStatus
.Information
= 0;
351 Status
= STATUS_SUCCESS
;
356 case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE
:
357 case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE
:
361 case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
:
362 DeviceExtension
->CharAttribute
= (WORD
)Irp
->AssociatedIrp
.SystemBuffer
;
363 Irp
->IoStatus
.Information
= 0;
364 Status
= STATUS_SUCCESS
;
368 case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER
:
370 PFILL_OUTPUT_CHARACTER Buf
= (PFILL_OUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
375 vidmem
= DeviceExtension
->VideoMemory
;
376 offset
= (DeviceExtension
->CursorY
* NR_COLUMNS
* 2) +
377 (DeviceExtension
->CursorX
* 2);
381 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
383 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->cCharacter
;
386 Irp
->IoStatus
.Information
= 0;
387 Status
= STATUS_SUCCESS
;
394 Status
= STATUS_NOT_IMPLEMENTED
;
397 Irp
->IoStatus
.Status
= Status
;
398 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
408 VOID
ScrStartIo(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
410 // PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
415 NTSTATUS
ScrDispatch (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
417 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation(Irp
);
420 switch (stk
->MajorFunction
)
423 Status
= STATUS_SUCCESS
;
427 Status
= STATUS_NOT_IMPLEMENTED
;
432 Irp
->IoStatus
.Status
= Status
;
433 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
443 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
445 PDEVICE_OBJECT DeviceObject
;
446 ANSI_STRING adevice_name
;
447 UNICODE_STRING device_name
;
448 ANSI_STRING asymlink_name
;
449 UNICODE_STRING symlink_name
;
451 DbgPrint ("Screen Driver 0.0.5\n");
453 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = ScrCreate
;
454 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = ScrDispatch
;
455 DriverObject
->MajorFunction
[IRP_MJ_READ
] = ScrDispatch
;
456 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = ScrWrite
;
457 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ScrIoControl
;
458 DriverObject
->DriverStartIo
= ScrStartIo
;
460 RtlInitAnsiString (&adevice_name
, "\\Device\\BlueScreen");
461 RtlAnsiStringToUnicodeString (&device_name
, &adevice_name
, TRUE
);
462 IoCreateDevice (DriverObject
,
463 sizeof(DEVICE_EXTENSION
),
470 RtlInitAnsiString (&asymlink_name
, "\\??\\BlueScreen");
471 RtlAnsiStringToUnicodeString (&symlink_name
, &asymlink_name
, TRUE
);
472 IoCreateSymbolicLink (&symlink_name
, &device_name
);
474 return (STATUS_SUCCESS
);