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>
14 #define IDMAP_BASE (0xd0000000)
15 #define VIDMEM_BASE 0xb8000
18 * Return a linear address which can be used to access the physical memory
21 extern inline unsigned int physical_to_linear(unsigned int x
)
26 extern inline unsigned int linear_to_physical(unsigned int x
)
34 #define CRTC_COMMAND 0x3d4
35 #define CRTC_DATA 0x3d5
37 #define CRTC_CURSORSTART 0x0a
38 #define CRTC_CURSOREND 0x0b
39 #define CRTC_CURSORPOSLO 0x0f
40 #define CRTC_CURSORPOSHI 0x0e
48 /* NOTES ******************************************************************/
50 * [[character][attribute]][[character][attribute]]....
54 /* TYPEDEFS ***************************************************************/
56 typedef struct _DEVICE_EXTENSION
65 BYTE ScanLines
; /* Height of a text line */
67 } DEVICE_EXTENSION
, *PDEVICE_EXTENSION
;
73 /* FUNCTIONS **************************************************************/
76 NTSTATUS
ScrCreate (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
78 // PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
79 PDEVICE_EXTENSION DeviceExtension
;
83 DeviceExtension
= DeviceObject
->DeviceExtension
;
85 /* initialize device extension */
86 /* get pointer to video memory */
87 DeviceExtension
->VideoMemory
= (PBYTE
)physical_to_linear (VIDMEM_BASE
);
89 /* get current output position */
91 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
92 offset
= inb_p (CRTC_DATA
);
93 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
94 offset
+= (inb_p (CRTC_DATA
) << 8);
97 DeviceExtension
->CursorX
= (SHORT
)(offset
% NR_COLUMNS
);
98 DeviceExtension
->CursorY
= (SHORT
)(offset
/ NR_COLUMNS
);
99 DeviceExtension
->CursorSize
= 5; /* FIXME: value correct?? */
100 DeviceExtension
->CursorVisible
= TRUE
;
103 DeviceExtension
->ScanLines
= 8; /* FIXME: read it from CRTC */
106 /* more initialization */
107 DeviceExtension
->CharAttribute
= 0x17; /* light grey on blue */
108 DeviceExtension
->Mode
= ENABLE_PROCESSED_OUTPUT
|
109 ENABLE_WRAP_AT_EOL_OUTPUT
;
111 /* FIXME: more initialization?? */
114 /* show blinking cursor */
115 /* FIXME: calculate cursor size */
117 outb_p (CRTC_COMMAND
, CRTC_CURSORSTART
);
118 outb_p (CRTC_DATA
, 0x47);
119 outb_p (CRTC_COMMAND
, CRTC_CURSOREND
);
120 outb_p (CRTC_DATA
, 0x07);
124 Status
= STATUS_SUCCESS
;
126 Irp
->IoStatus
.Status
= Status
;
127 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
133 NTSTATUS
ScrWrite (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
135 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
136 PDEVICE_EXTENSION DeviceExtension
;
138 char *pch
= Irp
->UserBuffer
;
141 int cursorx
, cursory
;
143 DeviceExtension
= DeviceObject
->DeviceExtension
;
144 vidmem
= DeviceExtension
->VideoMemory
;
145 cursorx
= DeviceExtension
->CursorX
;
146 cursory
= DeviceExtension
->CursorY
;
148 for (i
= 0; i
< stk
->Parameters
.Write
.Length
; i
++, pch
++)
157 else if (cursory
> 0)
159 cursorx
= NR_COLUMNS
- 1;
173 offset
= TAB_WIDTH
- (cursorx
% TAB_WIDTH
);
174 for (j
= 0; j
< offset
; j
++)
176 vidmem
[(cursorx
* 2) + (cursory
* NR_COLUMNS
* 2)] = ' ';
179 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
)
200 if (cursory
>= NR_ROWS
)
202 unsigned short *LinePtr
;
205 &vidmem
[NR_COLUMNS
* 2],
206 NR_COLUMNS
* (NR_ROWS
- 1) * 2);
208 LinePtr
= (unsigned short *) &vidmem
[NR_COLUMNS
* (NR_ROWS
- 1) * 2];
210 for (j
= 0; j
< NR_COLUMNS
; j
++)
212 LinePtr
[j
] = DeviceExtension
->CharAttribute
<< 8;
214 cursory
= NR_ROWS
- 1;
219 /* 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
;
233 Status
= STATUS_SUCCESS
;
235 Irp
->IoStatus
.Status
= Status
;
236 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
244 NTSTATUS
ScrIoControl (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
246 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation (Irp
);
247 PDEVICE_EXTENSION DeviceExtension
;
251 DeviceExtension
= DeviceObject
->DeviceExtension
;
253 switch (stk
->Parameters
.DeviceIoControl
.IoControlCode
)
255 case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
:
257 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
261 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
262 offset
= inb_p (CRTC_DATA
);
263 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
264 offset
+= (inb_p (CRTC_DATA
) << 8);
267 pcsbi
->dwCursorPosition
.X
= (SHORT
)(offset
% NR_COLUMNS
);
268 pcsbi
->dwCursorPosition
.Y
= (SHORT
)(offset
/ NR_COLUMNS
);
270 pcsbi
->dwSize
.X
= NR_ROWS
;
271 pcsbi
->dwSize
.Y
= NR_COLUMNS
;
273 Irp
->IoStatus
.Information
= sizeof (CONSOLE_SCREEN_BUFFER_INFO
);
274 Status
= STATUS_SUCCESS
;
278 case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
:
280 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
283 DeviceExtension
->CursorX
= pcsbi
->dwCursorPosition
.X
;
284 DeviceExtension
->CursorY
= pcsbi
->dwCursorPosition
.Y
;
286 offset
= (pcsbi
->dwCursorPosition
.Y
* NR_COLUMNS
) +
287 pcsbi
->dwCursorPosition
.X
;
290 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSLO
);
291 outb_p (CRTC_DATA
, offset
);
292 outb_p (CRTC_COMMAND
, CRTC_CURSORPOSHI
);
293 outb_p (CRTC_DATA
, offset
>>8);
296 Irp
->IoStatus
.Information
= 0;
297 Status
= STATUS_SUCCESS
;
301 case IOCTL_CONSOLE_GET_CURSOR_INFO
:
303 // PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
305 // DPRINT("GetConsoleCursorInfo: pcci=%p\n", pcci);
306 // DPRINT("GetConsoleCursorInfo\n");
307 // pcci->dwSize = 10;
308 // pcci->bVisible = FALSE;
310 Irp
->IoStatus
.Information
= 0;
311 Status
= STATUS_SUCCESS
;
315 case IOCTL_CONSOLE_SET_CURSOR_INFO
:
317 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
321 DeviceExtension
->CursorSize
= pcci
->dwSize
;
322 DeviceExtension
->CursorVisible
= pcci
->bVisible
;
323 height
= DeviceExtension
->ScanLines
;
324 data
= (pcci
->bVisible
) ? 0x40 : 0x20;
326 size
= (pcci
->dwSize
* height
) / 100;
330 data
|= (BYTE
)(height
- size
);
333 outb_p (CRTC_COMMAND
, CRTC_CURSORSTART
);
334 outb_p (CRTC_DATA
, data
);
335 outb_p (CRTC_COMMAND
, CRTC_CURSOREND
);
336 outb_p (CRTC_DATA
, height
- 1);
339 Irp
->IoStatus
.Information
= 0;
340 Status
= STATUS_SUCCESS
;
346 case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE
:
348 PFILL_OUTPUT_ATTRIBUTE Buf
= (PFILL_OUTPUT_ATTRIBUTE
)Irp
->AssociatedIrp
.SystemBuffer
;
353 vidmem
= DeviceExtension
->VideoMemory
;
354 offset
= (DeviceExtension
->CursorY
* NR_COLUMNS
* 2) +
355 (DeviceExtension
->CursorX
* 2) + 1;
359 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
361 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->wAttribute
;
364 Irp
->IoStatus
.Information
= 0;
365 Status
= STATUS_SUCCESS
;
370 case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE
:
371 case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE
:
375 case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
:
376 DeviceExtension
->CharAttribute
= (WORD
)Irp
->AssociatedIrp
.SystemBuffer
;
377 Irp
->IoStatus
.Information
= 0;
378 Status
= STATUS_SUCCESS
;
382 case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER
:
384 PFILL_OUTPUT_CHARACTER Buf
= (PFILL_OUTPUT_CHARACTER
)Irp
->AssociatedIrp
.SystemBuffer
;
389 vidmem
= DeviceExtension
->VideoMemory
;
390 offset
= (DeviceExtension
->CursorY
* NR_COLUMNS
* 2) +
391 (DeviceExtension
->CursorX
* 2);
395 for (dwCount
= 0; dwCount
< Buf
->nLength
; dwCount
++)
397 vidmem
[offset
+ (dwCount
* 2)] = (char) Buf
->cCharacter
;
400 Irp
->IoStatus
.Information
= 0;
401 Status
= STATUS_SUCCESS
;
408 Status
= STATUS_NOT_IMPLEMENTED
;
411 Irp
->IoStatus
.Status
= Status
;
412 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
422 VOID
ScrStartIo(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
424 // PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
429 NTSTATUS
ScrDispatch (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
431 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation(Irp
);
434 switch (stk
->MajorFunction
)
437 Status
= STATUS_SUCCESS
;
441 Status
= STATUS_NOT_IMPLEMENTED
;
446 Irp
->IoStatus
.Status
= Status
;
447 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
457 DriverEntry (PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
459 PDEVICE_OBJECT DeviceObject
;
460 ANSI_STRING adevice_name
;
461 UNICODE_STRING device_name
;
462 ANSI_STRING asymlink_name
;
463 UNICODE_STRING symlink_name
;
465 DbgPrint ("Screen Driver 0.0.5\n");
467 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = ScrCreate
;
468 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = ScrDispatch
;
469 DriverObject
->MajorFunction
[IRP_MJ_READ
] = ScrDispatch
;
470 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = ScrWrite
;
471 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ScrIoControl
;
472 DriverObject
->DriverStartIo
= ScrStartIo
;
474 RtlInitAnsiString (&adevice_name
, "\\Device\\BlueScreen");
475 RtlAnsiStringToUnicodeString (&device_name
, &adevice_name
, TRUE
);
476 IoCreateDevice (DriverObject
,
477 sizeof(DEVICE_EXTENSION
),
484 RtlInitAnsiString (&asymlink_name
, "\\??\\BlueScreen");
485 RtlAnsiStringToUnicodeString (&symlink_name
, &asymlink_name
, TRUE
);
486 IoCreateSymbolicLink (&symlink_name
, &device_name
);
488 return (STATUS_SUCCESS
);