2 #include <internal/mmhal.h>
3 #include <internal/halio.h>
4 #include <internal/hal/page.h>
7 #include <internal/string.h>
9 #include <ddk/ntddblue.h>
12 #include <internal/debug.h>
16 #define VIDMEM_BASE 0xb8000
21 #define CRTC_COMMAND 0x3d4
22 #define CRTC_DATA 0x3d5
24 #define CRTC_CURSORSTART 0x0a
25 #define CRTC_CURSOREND 0x0b
26 #define CRTC_CURSORPOSLO 0x0f
27 #define CRTC_CURSORPOSHI 0x0e
35 /* NOTES ******************************************************************/
37 * [[character][attribute]][[character][attribute]]....
41 /* TYPEDEFS ***************************************************************/
43 typedef struct _DEVICE_EXTENSION
52 BYTE ScanLines
; /* Height of a text line */
54 } DEVICE_EXTENSION
, *PDEVICE_EXTENSION
;
60 /* FUNCTIONS **************************************************************/
63 NTSTATUS
ScrCreate (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
65 // PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
66 PDEVICE_EXTENSION DeviceExtension
;
70 DeviceExtension
= DeviceObject
->DeviceExtension
;
72 /* initialize device extension */
73 /* get pointer to video memory */
74 DeviceExtension
->VideoMemory
= (PBYTE
)physical_to_linear (VIDMEM_BASE
);
76 /* get current output position */
78 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
79 offset
= inb_p (CRTC_DATA
);
80 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
81 offset
+= (inb_p (CRTC_DATA
) << 8);
84 DeviceExtension
->CursorX
= (SHORT
)(offset
% NR_COLUMNS
);
85 DeviceExtension
->CursorY
= (SHORT
)(offset
/ NR_COLUMNS
);
86 DeviceExtension
->CursorSize
= 5; /* FIXME: value correct?? */
87 DeviceExtension
->CursorVisible
= TRUE
;
90 DeviceExtension
->ScanLines
= 8; /* FIXME: read it from CRTC */
93 /* more initialization */
94 DeviceExtension
->CharAttribute
= 0x17; /* light grey on blue */
95 DeviceExtension
->Mode
= ENABLE_PROCESSED_OUTPUT
|
96 ENABLE_WRAP_AT_EOL_OUTPUT
;
98 /* FIXME: more initialization?? */
101 /* show blinking cursor */
102 /* FIXME: calculate cursor size */
104 outb_p (CRTC_COMMAND
, CRTC_CURSORSTART
);
105 outb_p (CRTC_DATA
, 0x47);
106 outb_p (CRTC_COMMAND
, CRTC_CURSOREND
);
107 outb_p (CRTC_DATA
, 0x07);
111 Status
= STATUS_SUCCESS
;
113 Irp
->IoStatus
.Status
= Status
;
114 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
120 NTSTATUS
ScrWrite (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
122 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
123 PDEVICE_EXTENSION DeviceExtension
;
125 char *pch
= Irp
->UserBuffer
;
128 int cursorx
, cursory
;
130 DeviceExtension
= DeviceObject
->DeviceExtension
;
131 vidmem
= DeviceExtension
->VideoMemory
;
132 cursorx
= DeviceExtension
->CursorX
;
133 cursory
= DeviceExtension
->CursorY
;
135 for (i
= 0; i
< stk
->Parameters
.Write
.Length
; i
++, pch
++)
144 else if (cursory
> 0)
146 cursorx
= NR_COLUMNS
- 1;
160 offset
= TAB_WIDTH
- (cursorx
% TAB_WIDTH
);
161 for (j
= 0; j
< offset
; j
++)
163 vidmem
[(cursorx
* 2) + (cursory
* NR_COLUMNS
* 2)] = ' ';
166 if (cursorx >= NR_COLUMNS)
176 vidmem
[(cursorx
* 2) + (cursory
* NR_COLUMNS
* 2)] = *pch
;
177 vidmem
[(cursorx
* 2) + (cursory
* NR_COLUMNS
* 2) + 1] = (char) DeviceExtension
->CharAttribute
;
179 if (cursorx
>= NR_COLUMNS
)
187 if (cursory
>= NR_ROWS
)
189 unsigned short *LinePtr
;
192 &vidmem
[NR_COLUMNS
* 2],
193 NR_COLUMNS
* (NR_ROWS
- 1) * 2);
195 LinePtr
= (unsigned short *) &vidmem
[NR_COLUMNS
* (NR_ROWS
- 1) * 2];
197 for (j
= 0; j
< NR_COLUMNS
; j
++)
199 LinePtr
[j
] = DeviceExtension
->CharAttribute
<< 8;
201 cursory
= NR_ROWS
- 1;
206 /* Set the cursor position */
208 offset
= (cursory
* NR_COLUMNS
) + cursorx
;
210 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
211 outb_p (CRTC_DATA
, offset
);
212 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
214 outb_p (CRTC_DATA
, offset
);
216 DeviceExtension
->CursorX
= cursorx
;
217 DeviceExtension
->CursorY
= cursory
;
220 Status
= STATUS_SUCCESS
;
222 Irp
->IoStatus
.Status
= Status
;
223 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
231 NTSTATUS
ScrIoControl (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
233 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
234 PDEVICE_EXTENSION DeviceExtension
;
238 DeviceExtension
= DeviceObject
->DeviceExtension
;
240 switch (stk
->Parameters
.DeviceIoControl
.IoControlCode
)
242 case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
:
244 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
248 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
249 offset
= inb_p (CRTC_DATA
);
250 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
251 offset
+= (inb_p (CRTC_DATA
) << 8);
254 pcsbi
->dwCursorPosition
.X
= (SHORT
)(offset
% NR_COLUMNS
);
255 pcsbi
->dwCursorPosition
.Y
= (SHORT
)(offset
/ NR_COLUMNS
);
257 pcsbi
->dwSize
.X
= NR_ROWS
;
258 pcsbi
->dwSize
.Y
= NR_COLUMNS
;
260 Irp
->IoStatus
.Information
= sizeof (CONSOLE_SCREEN_BUFFER_INFO
);
261 Status
= STATUS_SUCCESS
;
265 case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
:
267 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
270 DeviceExtension
->CursorX
= pcsbi
->dwCursorPosition
.X
;
271 DeviceExtension
->CursorY
= pcsbi
->dwCursorPosition
.Y
;
273 offset
= (pcsbi
->dwCursorPosition
.Y
* NR_COLUMNS
) +
274 pcsbi
->dwCursorPosition
.X
;
277 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
278 outb_p (CRTC_DATA
, offset
);
279 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
280 outb_p (CRTC_DATA
, offset
>>8);
283 Irp
->IoStatus
.Information
= 0;
284 Status
= STATUS_SUCCESS
;
288 case IOCTL_CONSOLE_GET_CURSOR_INFO
:
290 // PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
292 // DPRINT("GetConsoleCursorInfo: pcci=%p\n", pcci);
293 // DPRINT("GetConsoleCursorInfo\n");
294 // pcci->dwSize = 10;
295 // pcci->bVisible = FALSE;
297 Irp
->IoStatus
.Information
= 0;
298 Status
= STATUS_SUCCESS
;
302 case IOCTL_CONSOLE_SET_CURSOR_INFO
:
304 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
308 DeviceExtension
->CursorSize
= pcci
->dwSize
;
309 DeviceExtension
->CursorVisible
= pcci
->bVisible
;
310 height
= DeviceExtension
->ScanLines
;
311 data
= (pcci
->bVisible
) ? 0x40 : 0x20;
313 size
= (pcci
->dwSize
* height
) / 100;
317 data
|= (BYTE
)(height
- size
);
320 outb_p (CRTC_COMMAND
, CRTC_CURSORSTART
);
321 outb_p (CRTC_DATA
, data
);
322 outb_p (CRTC_COMMAND
, CRTC_CURSOREND
);
323 outb_p (CRTC_DATA
, height
- 1);
326 Irp
->IoStatus
.Information
= 0;
327 Status
= STATUS_SUCCESS
;
333 case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE
:
335 PFILL_OUTPUT_ATTRIBUTE Buf
= (PFILL_OUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
340 vidmem
= DeviceExtension
->VideoMemory
;
341 offset
= (DeviceExtension
->CursorY
* NR_COLUMNS
* 2) +
342 (DeviceExtension
->CursorX
* 2) + 1;
346 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
348 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->wAttribute
;
351 Irp
->IoStatus
.Information
= 0;
352 Status
= STATUS_SUCCESS
;
357 case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE
:
358 case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE
:
362 case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
:
363 DeviceExtension
->CharAttribute
= (WORD
)Irp
->AssociatedIrp
.SystemBuffer
;
364 Irp
->IoStatus
.Information
= 0;
365 Status
= STATUS_SUCCESS
;
369 case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER
:
371 PFILL_OUTPUT_CHARACTER Buf
= (PFILL_OUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
376 vidmem
= DeviceExtension
->VideoMemory
;
377 offset
= (DeviceExtension
->CursorY
* NR_COLUMNS
* 2) +
378 (DeviceExtension
->CursorX
* 2);
382 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
384 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->cCharacter
;
387 Irp
->IoStatus
.Information
= 0;
388 Status
= STATUS_SUCCESS
;
395 Status
= STATUS_NOT_IMPLEMENTED
;
398 Irp
->IoStatus
.Status
= Status
;
399 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
409 VOID
ScrStartIo(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
411 // PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
416 NTSTATUS
ScrDispatch (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
418 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation(Irp
);
421 switch (stk
->MajorFunction
)
424 Status
= STATUS_SUCCESS
;
428 Status
= STATUS_NOT_IMPLEMENTED
;
433 Irp
->IoStatus
.Status
= Status
;
434 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
444 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
446 PDEVICE_OBJECT DeviceObject
;
447 ANSI_STRING adevice_name
;
448 UNICODE_STRING device_name
;
449 ANSI_STRING asymlink_name
;
450 UNICODE_STRING symlink_name
;
452 DbgPrint ("Screen Driver 0.0.5\n");
454 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = ScrCreate
;
455 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = ScrDispatch
;
456 DriverObject
->MajorFunction
[IRP_MJ_READ
] = ScrDispatch
;
457 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = ScrWrite
;
458 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ScrIoControl
;
459 DriverObject
->DriverStartIo
= ScrStartIo
;
461 RtlInitAnsiString (&adevice_name
, "\\Device\\BlueScreen");
462 RtlAnsiStringToUnicodeString (&device_name
, &adevice_name
, TRUE
);
463 IoCreateDevice (DriverObject
,
464 sizeof(DEVICE_EXTENSION
),
471 RtlInitAnsiString (&asymlink_name
, "\\??\\BlueScreen");
472 RtlAnsiStringToUnicodeString (&symlink_name
, &asymlink_name
, TRUE
);
473 IoCreateSymbolicLink (&symlink_name
, &device_name
);
475 return (STATUS_SUCCESS
);