summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halalpha/vga.c
blob: c8b10394fb3bed10868bebc059f2f10fdc817d0b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
/*++

Copyright (c) 1992, 1993, 1994  Digital Equipment Corporation

Module Name:

    vga.c

Abstract:

    This module implements device-independent HAL display initialization and
    output routines for Alpha systems.

    It was stolen from a combination of the jxdisp.c routine in the firmware
    directory, written by John DeRosa, and the jxdisp.c routines in the MIPS
    HAL directory.

Author:

    Miche Baker-Harvey (miche) 10-Jun-1992

Environment:

    Kernel mode

Revision History:

    12-July-1994 Eric Rehm
        Support RESET_DISPLAY_PARAMETERS callback registered during
        HalAcquireDisplayOwnership.  This callback is supplied by
        the Video Miniport driver's HwResetHw entry in the HW_INITIALIZATION_DATA
        structure.

    17-Feb-1994 Eric Rehm
        Rewrite ouput routines to be device-independent through callback
        to firmware VenPrint routine.

    30-Dec-1993 Joe Notarangelo
        Eliminate the video initialization code that was compiled only
        when VIDEO_CALLBACK_IMPLEMENTED is not defined.  It is now a
        requirement that the firmware implement the callback.

    04-Mar-1993 Joe Mitchell (DEC)
      Modify HalpScrollDisplay to pause after displaying each screenful of
      information during a bugcheck.
      Modify InitializeVGA to call the firmware to init the video display
      rather than doing the initialization itself.

    10-Aug-1992 Jeff McLeman (DEC)
      Put in debug fixes.

    22-Jul-1992 Jeff McLeman (mcleman)
      Remove inline asm(MB)s , because Hal access routines manage
      read/write ordering.

--*/

//
// Need some include files here
#include "halp.h"
#include "arc.h"
#include "halvga.h"
#include "fwcallbk.h"
#include "stdio.h"

//
// Define forward referenced procedure prototypes.
//

VOID
HalpDisplayCharacter (
    IN UCHAR Character
    );

VOID
HalpSetLoc (
    );

BOOLEAN
InitializeDisplay (
    );

BOOLEAN
HalpInitializeDisplay (
    IN PLOADER_PARAMETER_BLOCK LoaderBlock
    );

VOID
HalpScrollDisplay(
    VOID
    );

VOID
HalpFlushKeyboardBuffer (
    VOID
    );

VOID
HalpWaitForKeyPress (
    VOID
    );
typedef
ULONG
(*PFW_INITIALIZE_VIDEO_CALLBACK) (
    OUT ULONG AlphaVideoType
    );


//
// Define static data.
//

BOOLEAN HalpDisplayInitialized = FALSE;
BOOLEAN HalpDisplayOwnedByHal;
ULONG HalpColumn;
ULONG HalpRow;
PUCHAR HalpDestination;
ULONG HalpForegroundColor;
ULONG HalpBackgroundColor;
ULONG DisplayWidth;
ULONG DisplayHeight;
ULONG MaxRow;
ULONG MaxColumn;

#define CONTROL_SEQUENCE_MAX_PARAMETER 10
ULONG Parameter[CONTROL_SEQUENCE_MAX_PARAMETER];

PHAL_RESET_DISPLAY_PARAMETERS HalpResetDisplayParameters;

//
// Declare externally defined data.
//
// none.


BOOLEAN
HalpInitializeDisplay (
    IN PLOADER_PARAMETER_BLOCK LoaderBlock
    )

/*++

Routine Description:

    This routine initializes and clears the display.

    This is called during phase 0 of the Hal initialization.

Arguments:

    LoaderBlock - Supplies a pointer to the loader parameter block.

Return Value:

    If the initialization is successfully completed, than a value of TRUE
    is returned. Otherwise, a value of FALSE is returned.

--*/

{

    //
    // Initialize static data.
    //

    HalpColumn = 0;
    HalpRow = 0;

    //
    // Initialize the display controller.
    //

    if (InitializeDisplay() == TRUE) {

        //
        // Mark the display as successfully initialized.
        //

        HalpDisplayInitialized = TRUE;

        return TRUE;
    }

    return FALSE;
}

BOOLEAN
InitializeDisplay (
    )

/*++

Routine Description:

    This routine initializes and clears the display.

    It is initialized to: alphanumeric mode, 16 colors fore & background,
    8x16 pixel fonts, 80x25 characters, 640 x 400 display.
    This is not ARC compliant (no underline, no monochrome support)
    but its good enough for now and can be enhanced later.  (For booting,
    the ARC spec is overkill anyway.)


Arguments:

    None.

Return Value:

    If the video was initialized, TRUE is returned, otherwise FALSE

--*/

{
    ULONG UnusedParameter;
    PARC_DISPLAY_STATUS DisplayStatus;
    char String[16];

    //
    // Initialize static data.
    //

    HalpForegroundColor = FW_COLOR_HI_WHITE;
    HalpBackgroundColor = FW_COLOR_BLUE;

    DisplayStatus = ArcGetDisplayStatus(ARC_CONSOLE_OUTPUT);
    DisplayWidth  = DisplayStatus->CursorMaxXPosition;
    DisplayHeight = DisplayStatus->CursorMaxYPosition;

    MaxRow = DisplayHeight -1;
    MaxColumn = DisplayWidth -1;

    //
    // [ecr] Call the video driver to intialize the video display,
    // if it has supplied a reset routine.
    //

    if (HalpResetDisplayParameters) {
        HalpDisplayOwnedByHal = HalpResetDisplayParameters(MaxColumn+1, MaxRow+1);
    }

    //
    // [jrm] Call the firmware to initialize the video display.
    //

    VenVideoDisplayInitialize(&UnusedParameter);

    //
    // Initialize the current display column, row, and ownership values.
    //

    HalpDisplayOwnedByHal = TRUE;

    //
    // Set the video memory to blue.
    //

    sprintf(String, "%c%dm%c%2J", ASCII_CSI, HalpBackgroundColor+40,
                                  ASCII_CSI);
    VenPrint(String);


    return TRUE;
}

VOID
HalAcquireDisplayOwnership (
    IN PHAL_RESET_DISPLAY_PARAMETERS  ResetDisplayParameters
    )

/*++

Routine Description:

    This routine switches ownership of the display away from the HAL to
    the system display driver. It is called when the system has reached
    a point during bootstrap where it is self supporting and can output
    its own messages. Once ownership has passed to the system display
    driver any attempts to output messages using HalDisplayString must
    result in ownership of the display reverting to the HAL and the
    display hardware reinitialized for use by the HAL.

Arguments:

    ResetDisplayParameters - if non-NULL the address of a function
    the hal can call to reset the video card.  The function returns
    TRUE if the display was reset.

Return Value:

    None.

--*/

{

    //
    // Set HAL ownership of the display to false.
    //

    HalpDisplayOwnedByHal = FALSE;
    HalpResetDisplayParameters=ResetDisplayParameters;

    //
    // Reset the display to begin in the upper left corner.
    //

    HalpColumn = 0;
    HalpRow = 0;

    return;
}

VOID
HalpVideoReboot(
     VOID
     )
{

    if (HalpResetDisplayParameters && !HalpDisplayOwnedByHal) {

        //
        // Video work-around.  The video driver has a reset function,
        // call it before resetting the system in case the bios doesn't
        // know how to reset the display's video mode.
        //
#if HALDBG
        DbgPrint("HalpVideoReboot: calling HalpResetDisplayParameters (%x,%x)\n",
                  MaxColumn+1, MaxRow+1);
#endif

        HalpResetDisplayParameters(MaxColumn+1, MaxRow+1);
    }
}

VOID
HalDisplayString (
    PUCHAR String
    )

/*++

Routine Description:

    This routine displays a character string on the display screen.

Arguments:

    String - Supplies a pointer to the characters that are to be displayed.

Return Value:

    None.

--*/

{
    KIRQL OldIrql;

    //
    // Note that the MIPS version of this routine goes through mapping
    // the device into the users space; since we have reserved the top
    // PDE in system space, we dont have to do this - its always mapped.
    //

    //
    // Check if the display has already been successfully initialized.
    // If it has not then we cannot print on the display.
    //

    if( HalpDisplayInitialized != TRUE ){

#if (DBG) || (HALDBG)

        DbgPrint( "HDS: %s\n", String );

#endif //DBG || HALDBG

        return;

    }

    //
    // Raise the IRQL to dispatch level and acquire the display adapter lock.
    //

    KeRaiseIrql(HIGH_LEVEL, &OldIrql);
    KiAcquireSpinLock(&HalpDisplayAdapterLock);

    //
    // If ownership of the display has been switched to the system display
    // driver, then reinitialize the display controller and revert ownership
    // to the HAL.
    //

    if (HalpDisplayOwnedByHal == FALSE) {
        InitializeDisplay();
    }

    while (*String)
    {
        switch (*String)
        {
          case '\n':
            if (HalpRow == MaxRow-1-1) {
                HalpScrollDisplay();
            } else {
                ++HalpRow;
            }
            HalpColumn = 0;
            break;

          case '\b':
            if(HalpColumn != 0) {
                --HalpColumn;
            }
            break;

          case '\r':
            HalpColumn = 0;
            break;

          default:
            if (HalpColumn > MaxColumn)
            {
                if (HalpRow == MaxRow-1-1) {
                    HalpScrollDisplay();
                } else {
                    ++HalpRow;
                }
                HalpColumn = 0;
            }
            HalpDisplayCharacter(*String);
            HalpColumn++;
        }
        ++String;
    }

    //
    // Release the display adapter lock and restore the IRQL.
    //

    KiReleaseSpinLock(&HalpDisplayAdapterLock);
    KeLowerIrql(OldIrql);

    return;
}

VOID
HalQueryDisplayParameters (
    OUT PULONG WidthInCharacters,
    OUT PULONG HeightInLines,
    OUT PULONG CursorColumn,
    OUT PULONG CursorRow
    )

/*++

Routine Description:

    This routine return information about the display area and current
    cursor position.

Arguments:

    WidthInCharacter - Supplies a pointer to a varible that receives
        the width of the display area in characters.

    HeightInLines - Supplies a pointer to a variable that receives the
        height of the display area in lines.

    CursorColumn - Supplies a pointer to a variable that receives the
        current display column position.

    CursorRow - Supplies a pointer to a variable that receives the
        current display row position.

Return Value:

    None.

--*/

{

    //
    // Set the display parameter values and return.
    //

    *WidthInCharacters = DisplayWidth;
    *HeightInLines = DisplayHeight;
    *CursorColumn = HalpColumn;
    *CursorRow = HalpRow;
    return;
}

VOID
HalSetDisplayParameters (
    IN ULONG CursorColumn,
    IN ULONG CursorRow
    )

/*++

Routine Description:

    This routine set the current cursor position on the display area.

Arguments:

    CursorColumn - Supplies the new display column position.

    CursorRow - Supplies a the new display row position.

Return Value:

    None.

--*/

{

    //
    // Set the display parameter values and return.
    //

    if (CursorColumn > DisplayWidth) {
        CursorColumn = DisplayWidth;
    }

    if (CursorRow > DisplayHeight) {
        CursorRow = DisplayHeight;
    }

    HalpColumn = CursorColumn;
    HalpRow = CursorRow;
    return;
}

VOID
HalpDisplayCharacter (
    IN UCHAR Character
    )

/*++

Routine Description:

    This routine displays a character at the current x and y positions in
    the frame buffer.


Arguments:

    Character - Supplies a character to be displayed.

Return Value:

    None.

--*/

{
    char String[16];

    sprintf(String, "%c%d;%dH%c%d;%dm%c",
            ASCII_CSI, HalpRow+1,  HalpColumn+1,
            ASCII_CSI, HalpForegroundColor+30, HalpBackgroundColor+40,
            Character);
    VenPrint(String);

}


VOID
HalpScrollDisplay (
    VOID
    )

/*++

Routine Description:

    This routine scrolls the display up one line.

Arguments:

    None.

Return Value:

    None.

--*/

{

    char String[16];

    //
    // Force a FwScrollDisplay by positioning FwRow off the
    // bottom of the screen and then doing a line feed.
    //

    sprintf(String, "%c%dB%c", ASCII_CSI, 255, ASCII_LF);
    VenPrint(String);

}