OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [x86_64/] [boot/] [video.S] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*      video.S
2
 *
3
 *      Display adapter & video mode setup, version 2.13 (14-May-99)
4
 *
5
 *      Copyright (C) 1995 -- 1998 Martin Mares 
6
 *      Based on the original setup.S code (C) Linus Torvalds and Mats Anderson
7
 *
8
 *      Rewritten to use GNU 'as' by Chris Noe  May 1999
9
 *
10
 *      For further information, look at Documentation/svga.txt.
11
 *
12
 */
13
 
14
#include  /* for CONFIG_VIDEO_* */
15
 
16
/* Enable autodetection of SVGA adapters and modes. */
17
#undef CONFIG_VIDEO_SVGA
18
 
19
/* Enable autodetection of VESA modes */
20
#define CONFIG_VIDEO_VESA
21
 
22
/* Enable compacting of mode table */
23
#define CONFIG_VIDEO_COMPACT
24
 
25
/* Retain screen contents when switching modes */
26
#define CONFIG_VIDEO_RETAIN
27
 
28
/* Enable local mode list */
29
#undef CONFIG_VIDEO_LOCAL
30
 
31
/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
32
#undef CONFIG_VIDEO_400_HACK
33
 
34
/* Hack that lets you force specific BIOS mode ID and specific dimensions */
35
#undef CONFIG_VIDEO_GFX_HACK
36
#define VIDEO_GFX_BIOS_AX 0x4f02        /* 800x600 on ThinkPad */
37
#define VIDEO_GFX_BIOS_BX 0x0102
38
#define VIDEO_GFX_DUMMY_RESOLUTION 0x6425       /* 100x37 */
39
 
40
/* This code uses an extended set of video mode numbers. These include:
41
 * Aliases for standard modes
42
 *      NORMAL_VGA (-1)
43
 *      EXTENDED_VGA (-2)
44
 *      ASK_VGA (-3)
45
 * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
46
 * of compatibility when extending the table. These are between 0x00 and 0xff.
47
 */
48
#define VIDEO_FIRST_MENU 0x0000
49
 
50
/* Standard BIOS video modes (BIOS number + 0x0100) */
51
#define VIDEO_FIRST_BIOS 0x0100
52
 
53
/* VESA BIOS video modes (VESA number + 0x0200) */
54
#define VIDEO_FIRST_VESA 0x0200
55
 
56
/* Video7 special modes (BIOS number + 0x0900) */
57
#define VIDEO_FIRST_V7 0x0900
58
 
59
/* Special video modes */
60
#define VIDEO_FIRST_SPECIAL 0x0f00
61
#define VIDEO_80x25 0x0f00
62
#define VIDEO_8POINT 0x0f01
63
#define VIDEO_80x43 0x0f02
64
#define VIDEO_80x28 0x0f03
65
#define VIDEO_CURRENT_MODE 0x0f04
66
#define VIDEO_80x30 0x0f05
67
#define VIDEO_80x34 0x0f06
68
#define VIDEO_80x60 0x0f07
69
#define VIDEO_LAST_SPECIAL 0x0f09
70
 
71
/* Video modes given by resolution */
72
#define VIDEO_FIRST_RESOLUTION 0x1000
73
 
74
/* The "recalculate timings" flag */
75
#define VIDEO_RECALC 0x8000
76
 
77
/* Positions of various video parameters passed to the kernel */
78
/* (see also include/linux/tty.h) */
79
#define PARAM_CURSOR_POS        0x00
80
#define PARAM_VIDEO_PAGE        0x04
81
#define PARAM_VIDEO_MODE        0x06
82
#define PARAM_VIDEO_COLS        0x07
83
#define PARAM_VIDEO_EGA_BX      0x0a
84
#define PARAM_VIDEO_LINES       0x0e
85
#define PARAM_HAVE_VGA          0x0f
86
#define PARAM_FONT_POINTS       0x10
87
 
88
#define PARAM_LFB_WIDTH         0x12
89
#define PARAM_LFB_HEIGHT        0x14
90
#define PARAM_LFB_DEPTH         0x16
91
#define PARAM_LFB_BASE          0x18
92
#define PARAM_LFB_SIZE          0x1c
93
#define PARAM_LFB_LINELENGTH    0x24
94
#define PARAM_LFB_COLORS        0x26
95
#define PARAM_VESAPM_SEG        0x2e
96
#define PARAM_VESAPM_OFF        0x30
97
#define PARAM_LFB_PAGES         0x32
98
 
99
 
100
/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
101
#ifdef CONFIG_VIDEO_RETAIN
102
#define DO_STORE call store_screen
103
#else
104
#define DO_STORE
105
#endif /* CONFIG_VIDEO_RETAIN */
106
 
107
# This is the main entry point called by setup.S
108
# %ds *must* be pointing to the bootsector
109
video:  pushw   %ds             # We use different segments
110
        pushw   %ds             # FS contains original DS
111
        popw    %fs
112
        pushw   %cs             # DS is equal to CS
113
        popw    %ds
114
        pushw   %cs             # ES is equal to CS
115
        popw    %es
116
        xorw    %ax, %ax
117
        movw    %ax, %gs        # GS is zero
118
        cld
119
        call    basic_detect    # Basic adapter type testing (EGA/VGA/MDA/CGA)
120
#ifdef CONFIG_VIDEO_SELECT
121
        movw    %fs:(0x01fa), %ax               # User selected video mode
122
        cmpw    $ASK_VGA, %ax                   # Bring up the menu
123
        jz      vid2
124
 
125
        call    mode_set                        # Set the mode
126
        jc      vid1
127
 
128
        leaw    badmdt, %si                     # Invalid mode ID
129
        call    prtstr
130
vid2:   call    mode_menu
131
vid1:
132
#ifdef CONFIG_VIDEO_RETAIN
133
        call    restore_screen                  # Restore screen contents
134
#endif /* CONFIG_VIDEO_RETAIN */
135
#endif /* CONFIG_VIDEO_SELECT */
136
        call    mode_params                     # Store mode parameters
137
        popw    %ds                             # Restore original DS
138
        ret
139
 
140
# Detect if we have CGA, MDA, EGA or VGA and pass it to the kernel.
141
basic_detect:
142
        movb    $0, %fs:(PARAM_HAVE_VGA)
143
        movb    $0x12, %ah      # Check EGA/VGA
144
        movb    $0x10, %bl
145
        int     $0x10
146
        movw    %bx, %fs:(PARAM_VIDEO_EGA_BX)   # Identifies EGA to the kernel
147
        cmpb    $0x10, %bl                      # No, it's a CGA/MDA/HGA card.
148
        je      basret
149
 
150
        incb    adapter
151
        movw    $0x1a00, %ax                    # Check EGA or VGA?
152
        int     $0x10
153
        cmpb    $0x1a, %al                      # 1a means VGA...
154
        jne     basret                          # anything else is EGA.
155
 
156
        incb    %fs:(PARAM_HAVE_VGA)            # We've detected a VGA
157
        incb    adapter
158
basret: ret
159
 
160
# Store the video mode parameters for later usage by the kernel.
161
# This is done by asking the BIOS except for the rows/columns
162
# parameters in the default 80x25 mode -- these are set directly,
163
# because some very obscure BIOSes supply insane values.
164
mode_params:
165
#ifdef CONFIG_VIDEO_SELECT
166
        cmpb    $0, graphic_mode
167
        jnz     mopar_gr
168
#endif
169
        movb    $0x03, %ah                      # Read cursor position
170
        xorb    %bh, %bh
171
        int     $0x10
172
        movw    %dx, %fs:(PARAM_CURSOR_POS)
173
        movb    $0x0f, %ah                      # Read page/mode/width
174
        int     $0x10
175
        movw    %bx, %fs:(PARAM_VIDEO_PAGE)
176
        movw    %ax, %fs:(PARAM_VIDEO_MODE)     # Video mode and screen width
177
        cmpb    $0x7, %al                       # MDA/HGA => segment differs
178
        jnz     mopar0
179
 
180
        movw    $0xb000, video_segment
181
mopar0: movw    %gs:(0x485), %ax                # Font size
182
        movw    %ax, %fs:(PARAM_FONT_POINTS)    # (valid only on EGA/VGA)
183
        movw    force_size, %ax                 # Forced size?
184
        orw     %ax, %ax
185
        jz      mopar1
186
 
187
        movb    %ah, %fs:(PARAM_VIDEO_COLS)
188
        movb    %al, %fs:(PARAM_VIDEO_LINES)
189
        ret
190
 
191
mopar1: movb    $25, %al
192
        cmpb    $0, adapter                     # If we are on CGA/MDA/HGA, the
193
        jz      mopar2                          # screen must have 25 lines.
194
 
195
        movb    %gs:(0x484), %al                # On EGA/VGA, use the EGA+ BIOS
196
        incb    %al                             # location of max lines.
197
mopar2: movb    %al, %fs:(PARAM_VIDEO_LINES)
198
        ret
199
 
200
#ifdef CONFIG_VIDEO_SELECT
201
# Fetching of VESA frame buffer parameters
202
mopar_gr:
203
        leaw    modelist+1024, %di
204
        movb    $0x23, %fs:(PARAM_HAVE_VGA)
205
        movw    16(%di), %ax
206
        movw    %ax, %fs:(PARAM_LFB_LINELENGTH)
207
        movw    18(%di), %ax
208
        movw    %ax, %fs:(PARAM_LFB_WIDTH)
209
        movw    20(%di), %ax
210
        movw    %ax, %fs:(PARAM_LFB_HEIGHT)
211
        movb    25(%di), %al
212
        movb    $0, %ah
213
        movw    %ax, %fs:(PARAM_LFB_DEPTH)
214
        movb    29(%di), %al
215
        movb    $0, %ah
216
        movw    %ax, %fs:(PARAM_LFB_PAGES)
217
        movl    40(%di), %eax
218
        movl    %eax, %fs:(PARAM_LFB_BASE)
219
        movl    31(%di), %eax
220
        movl    %eax, %fs:(PARAM_LFB_COLORS)
221
        movl    35(%di), %eax
222
        movl    %eax, %fs:(PARAM_LFB_COLORS+4)
223
 
224
# get video mem size
225
        leaw    modelist+1024, %di
226
        movw    $0x4f00, %ax
227
        int     $0x10
228
        xorl    %eax, %eax
229
        movw    18(%di), %ax
230
        movl    %eax, %fs:(PARAM_LFB_SIZE)
231
# get protected mode interface informations
232
        movw    $0x4f0a, %ax
233
        xorw    %bx, %bx
234
        xorw    %di, %di
235
        int     $0x10
236
        cmp     $0x004f, %ax
237
        jnz     no_pm
238
 
239
        movw    %es, %fs:(PARAM_VESAPM_SEG)
240
        movw    %di, %fs:(PARAM_VESAPM_OFF)
241
no_pm:  ret
242
 
243
# The video mode menu
244
mode_menu:
245
        leaw    keymsg, %si                     # "Return/Space/Timeout" message
246
        call    prtstr
247
        call    flush
248
nokey:  call    getkt
249
 
250
        cmpb    $0x0d, %al                      # ENTER ?
251
        je      listm                           # yes - manual mode selection
252
 
253
        cmpb    $0x20, %al                      # SPACE ?
254
        je      defmd1                          # no - repeat
255
 
256
        call    beep
257
        jmp     nokey
258
 
259
defmd1: ret                                     # No mode chosen? Default 80x25
260
 
261
listm:  call    mode_table                      # List mode table
262
listm0: leaw    name_bann, %si                  # Print adapter name
263
        call    prtstr
264
        movw    card_name, %si
265
        orw     %si, %si
266
        jnz     an2
267
 
268
        movb    adapter, %al
269
        leaw    old_name, %si
270
        orb     %al, %al
271
        jz      an1
272
 
273
        leaw    ega_name, %si
274
        decb    %al
275
        jz      an1
276
 
277
        leaw    vga_name, %si
278
        jmp     an1
279
 
280
an2:    call    prtstr
281
        leaw    svga_name, %si
282
an1:    call    prtstr
283
        leaw    listhdr, %si                    # Table header
284
        call    prtstr
285
        movb    $0x30, %dl                      # DL holds mode number
286
        leaw    modelist, %si
287
lm1:    cmpw    $ASK_VGA, (%si)                 # End?
288
        jz      lm2
289
 
290
        movb    %dl, %al                        # Menu selection number
291
        call    prtchr
292
        call    prtsp2
293
        lodsw
294
        call    prthw                           # Mode ID
295
        call    prtsp2
296
        movb    0x1(%si), %al
297
        call    prtdec                          # Rows
298
        movb    $0x78, %al                      # the letter 'x'
299
        call    prtchr
300
        lodsw
301
        call    prtdec                          # Columns
302
        movb    $0x0d, %al                      # New line
303
        call    prtchr
304
        movb    $0x0a, %al
305
        call    prtchr
306
        incb    %dl                             # Next character
307
        cmpb    $0x3a, %dl
308
        jnz     lm1
309
 
310
        movb    $0x61, %dl
311
        jmp     lm1
312
 
313
lm2:    leaw    prompt, %si                     # Mode prompt
314
        call    prtstr
315
        leaw    edit_buf, %di                   # Editor buffer
316
lm3:    call    getkey
317
        cmpb    $0x0d, %al                      # Enter?
318
        jz      lment
319
 
320
        cmpb    $0x08, %al                      # Backspace?
321
        jz      lmbs
322
 
323
        cmpb    $0x20, %al                      # Printable?
324
        jc      lm3
325
 
326
        cmpw    $edit_buf+4, %di                # Enough space?
327
        jz      lm3
328
 
329
        stosb
330
        call    prtchr
331
        jmp     lm3
332
 
333
lmbs:   cmpw    $edit_buf, %di                  # Backspace
334
        jz      lm3
335
 
336
        decw    %di
337
        movb    $0x08, %al
338
        call    prtchr
339
        call    prtspc
340
        movb    $0x08, %al
341
        call    prtchr
342
        jmp     lm3
343
 
344
lment:  movb    $0, (%di)
345
        leaw    crlft, %si
346
        call    prtstr
347
        leaw    edit_buf, %si
348
        cmpb    $0, (%si)                       # Empty string = default mode
349
        jz      lmdef
350
 
351
        cmpb    $0, 1(%si)                      # One character = menu selection
352
        jz      mnusel
353
 
354
        cmpw    $0x6373, (%si)                  # "scan" => mode scanning
355
        jnz     lmhx
356
 
357
        cmpw    $0x6e61, 2(%si)
358
        jz      lmscan
359
 
360
lmhx:   xorw    %bx, %bx                        # Else => mode ID in hex
361
lmhex:  lodsb
362
        orb     %al, %al
363
        jz      lmuse1
364
 
365
        subb    $0x30, %al
366
        jc      lmbad
367
 
368
        cmpb    $10, %al
369
        jc      lmhx1
370
 
371
        subb    $7, %al
372
        andb    $0xdf, %al
373
        cmpb    $10, %al
374
        jc      lmbad
375
 
376
        cmpb    $16, %al
377
        jnc     lmbad
378
 
379
lmhx1:  shlw    $4, %bx
380
        orb     %al, %bl
381
        jmp     lmhex
382
 
383
lmuse1: movw    %bx, %ax
384
        jmp     lmuse
385
 
386
mnusel: lodsb                                   # Menu selection
387
        xorb    %ah, %ah
388
        subb    $0x30, %al
389
        jc      lmbad
390
 
391
        cmpb    $10, %al
392
        jc      lmuse
393
 
394
        cmpb    $0x61-0x30, %al
395
        jc      lmbad
396
 
397
        subb    $0x61-0x30-10, %al
398
        cmpb    $36, %al
399
        jnc     lmbad
400
 
401
lmuse:  call    mode_set
402
        jc      lmdef
403
 
404
lmbad:  leaw    unknt, %si
405
        call    prtstr
406
        jmp     lm2
407
lmscan: cmpb    $0, adapter                     # Scanning only on EGA/VGA
408
        jz      lmbad
409
 
410
        movw    $0, mt_end                      # Scanning of modes is
411
        movb    $1, scanning                    # done as new autodetection.
412
        call    mode_table
413
        jmp     listm0
414
lmdef:  ret
415
 
416
# Additional parts of mode_set... (relative jumps, you know)
417
setv7:                                          # Video7 extended modes
418
        DO_STORE
419
        subb    $VIDEO_FIRST_V7>>8, %bh
420
        movw    $0x6f05, %ax
421
        int     $0x10
422
        stc
423
        ret
424
 
425
_setrec:        jmp     setrec                  # Ugly...
426
_set_80x25:     jmp     set_80x25
427
 
428
# Aliases for backward compatibility.
429
setalias:
430
        movw    $VIDEO_80x25, %ax
431
        incw    %bx
432
        jz      mode_set
433
 
434
        movb    $VIDEO_8POINT-VIDEO_FIRST_SPECIAL, %al
435
        incw    %bx
436
        jnz     setbad                          # Fall-through!
437
 
438
# Setting of user mode (AX=mode ID) => CF=success
439
mode_set:
440
        movw    %ax, %bx
441
        cmpb    $0xff, %ah
442
        jz      setalias
443
 
444
        testb   $VIDEO_RECALC>>8, %ah
445
        jnz     _setrec
446
 
447
        cmpb    $VIDEO_FIRST_RESOLUTION>>8, %ah
448
        jnc     setres
449
 
450
        cmpb    $VIDEO_FIRST_SPECIAL>>8, %ah
451
        jz      setspc
452
 
453
        cmpb    $VIDEO_FIRST_V7>>8, %ah
454
        jz      setv7
455
 
456
        cmpb    $VIDEO_FIRST_VESA>>8, %ah
457
        jnc     check_vesa
458
 
459
        orb     %ah, %ah
460
        jz      setmenu
461
 
462
        decb    %ah
463
        jz      setbios
464
 
465
setbad: clc
466
        movb    $0, do_restore                  # The screen needn't be restored
467
        ret
468
 
469
setvesa:
470
        DO_STORE
471
        subb    $VIDEO_FIRST_VESA>>8, %bh
472
        movw    $0x4f02, %ax                    # VESA BIOS mode set call
473
        int     $0x10
474
        cmpw    $0x004f, %ax                    # AL=4f if implemented
475
        jnz     setbad                          # AH=0 if OK
476
 
477
        stc
478
        ret
479
 
480
setbios:
481
        DO_STORE
482
        int     $0x10                           # Standard BIOS mode set call
483
        pushw   %bx
484
        movb    $0x0f, %ah                      # Check if really set
485
        int     $0x10
486
        popw    %bx
487
        cmpb    %bl, %al
488
        jnz     setbad
489
 
490
        stc
491
        ret
492
 
493
setspc: xorb    %bh, %bh                        # Set special mode
494
        cmpb    $VIDEO_LAST_SPECIAL-VIDEO_FIRST_SPECIAL, %bl
495
        jnc     setbad
496
 
497
        addw    %bx, %bx
498
        jmp     *spec_inits(%bx)
499
 
500
setmenu:
501
        orb     %al, %al                        # 80x25 is an exception
502
        jz      _set_80x25
503
 
504
        pushw   %bx                             # Set mode chosen from menu
505
        call    mode_table                      # Build the mode table
506
        popw    %ax
507
        shlw    $2, %ax
508
        addw    %ax, %si
509
        cmpw    %di, %si
510
        jnc     setbad
511
 
512
        movw    (%si), %ax                      # Fetch mode ID
513
_m_s:   jmp     mode_set
514
 
515
setres: pushw   %bx                             # Set mode chosen by resolution
516
        call    mode_table
517
        popw    %bx
518
        xchgb   %bl, %bh
519
setr1:  lodsw
520
        cmpw    $ASK_VGA, %ax                   # End of the list?
521
        jz      setbad
522
 
523
        lodsw
524
        cmpw    %bx, %ax
525
        jnz     setr1
526
 
527
        movw    -4(%si), %ax                    # Fetch mode ID
528
        jmp     _m_s
529
 
530
check_vesa:
531
        leaw    modelist+1024, %di
532
        subb    $VIDEO_FIRST_VESA>>8, %bh
533
        movw    %bx, %cx                        # Get mode information structure
534
        movw    $0x4f01, %ax
535
        int     $0x10
536
        addb    $VIDEO_FIRST_VESA>>8, %bh
537
        cmpw    $0x004f, %ax
538
        jnz     setbad
539
 
540
        movb    (%di), %al                      # Check capabilities.
541
        andb    $0x19, %al
542
        cmpb    $0x09, %al
543
        jz      setvesa                         # This is a text mode
544
 
545
        movb    (%di), %al                      # Check capabilities.
546
        andb    $0x99, %al
547
        cmpb    $0x99, %al
548
        jnz     _setbad                         # Doh! No linear frame buffer.
549
 
550
        subb    $VIDEO_FIRST_VESA>>8, %bh
551
        orw     $0x4000, %bx                    # Use linear frame buffer
552
        movw    $0x4f02, %ax                    # VESA BIOS mode set call
553
        int     $0x10
554
        cmpw    $0x004f, %ax                    # AL=4f if implemented
555
        jnz     _setbad                         # AH=0 if OK
556
 
557
        movb    $1, graphic_mode                # flag graphic mode
558
        movb    $0, do_restore                  # no screen restore
559
        stc
560
        ret
561
 
562
_setbad:        jmp     setbad                  # Ugly...
563
 
564
# Recalculate vertical display end registers -- this fixes various
565
# inconsistencies of extended modes on many adapters. Called when
566
# the VIDEO_RECALC flag is set in the mode ID.
567
 
568
setrec: subb    $VIDEO_RECALC>>8, %ah           # Set the base mode
569
        call    mode_set
570
        jnc     rct3
571
 
572
        movw    %gs:(0x485), %ax                # Font size in pixels
573
        movb    %gs:(0x484), %bl                # Number of rows
574
        incb    %bl
575
        mulb    %bl                             # Number of visible
576
        decw    %ax                             # scan lines - 1
577
        movw    $0x3d4, %dx
578
        movw    %ax, %bx
579
        movb    $0x12, %al                      # Lower 8 bits
580
        movb    %bl, %ah
581
        outw    %ax, %dx
582
        movb    $0x07, %al              # Bits 8 and 9 in the overflow register
583
        call    inidx
584
        xchgb   %al, %ah
585
        andb    $0xbd, %ah
586
        shrb    %bh
587
        jnc     rct1
588
        orb     $0x02, %ah
589
rct1:   shrb    %bh
590
        jnc     rct2
591
        orb     $0x40, %ah
592
rct2:   movb    $0x07, %al
593
        outw    %ax, %dx
594
        stc
595
rct3:   ret
596
 
597
# Table of routines for setting of the special modes.
598
spec_inits:
599
        .word   set_80x25
600
        .word   set_8pixel
601
        .word   set_80x43
602
        .word   set_80x28
603
        .word   set_current
604
        .word   set_80x30
605
        .word   set_80x34
606
        .word   set_80x60
607
        .word   set_gfx
608
 
609
# Set the 80x25 mode. If already set, do nothing.
610
set_80x25:
611
        movw    $0x5019, force_size             # Override possibly broken BIOS
612
use_80x25:
613
#ifdef CONFIG_VIDEO_400_HACK
614
        movw    $0x1202, %ax                    # Force 400 scan lines
615
        movb    $0x30, %bl
616
        int     $0x10
617
#else
618
        movb    $0x0f, %ah                      # Get current mode ID
619
        int     $0x10
620
        cmpw    $0x5007, %ax    # Mode 7 (80x25 mono) is the only one available
621
        jz      st80            # on CGA/MDA/HGA and is also available on EGAM
622
 
623
        cmpw    $0x5003, %ax    # Unknown mode, force 80x25 color
624
        jnz     force3
625
 
626
st80:   cmpb    $0, adapter     # CGA/MDA/HGA => mode 3/7 is always 80x25
627
        jz      set80
628
 
629
        movb    %gs:(0x0484), %al       # This is EGA+ -- beware of 80x50 etc.
630
        orb     %al, %al                # Some buggy BIOS'es set 0 rows
631
        jz      set80
632
 
633
        cmpb    $24, %al                # It's hopefully correct
634
        jz      set80
635
#endif /* CONFIG_VIDEO_400_HACK */
636
force3: DO_STORE
637
        movw    $0x0003, %ax                    # Forced set
638
        int     $0x10
639
set80:  stc
640
        ret
641
 
642
# Set the 80x50/80x43 8-pixel mode. Simple BIOS calls.
643
set_8pixel:
644
        DO_STORE
645
        call    use_80x25                       # The base is 80x25
646
set_8pt:
647
        movw    $0x1112, %ax                    # Use 8x8 font
648
        xorb    %bl, %bl
649
        int     $0x10
650
        movw    $0x1200, %ax                    # Use alternate print screen
651
        movb    $0x20, %bl
652
        int     $0x10
653
        movw    $0x1201, %ax                    # Turn off cursor emulation
654
        movb    $0x34, %bl
655
        int     $0x10
656
        movb    $0x01, %ah                      # Define cursor scan lines 6-7
657
        movw    $0x0607, %cx
658
        int     $0x10
659
set_current:
660
        stc
661
        ret
662
 
663
# Set the 80x28 mode. This mode works on all VGA's, because it's a standard
664
# 80x25 mode with 14-point fonts instead of 16-point.
665
set_80x28:
666
        DO_STORE
667
        call    use_80x25                       # The base is 80x25
668
set14:  movw    $0x1111, %ax                    # Use 9x14 font
669
        xorb    %bl, %bl
670
        int     $0x10
671
        movb    $0x01, %ah                      # Define cursor scan lines 11-12
672
        movw    $0x0b0c, %cx
673
        int     $0x10
674
        stc
675
        ret
676
 
677
# Set the 80x43 mode. This mode is works on all VGA's.
678
# It's a 350-scanline mode with 8-pixel font.
679
set_80x43:
680
        DO_STORE
681
        movw    $0x1201, %ax                    # Set 350 scans
682
        movb    $0x30, %bl
683
        int     $0x10
684
        movw    $0x0003, %ax                    # Reset video mode
685
        int     $0x10
686
        jmp     set_8pt                         # Use 8-pixel font
687
 
688
# Set the 80x30 mode (all VGA's). 480 scanlines, 16-pixel font.
689
set_80x30:
690
        call    use_80x25                       # Start with real 80x25
691
        DO_STORE
692
        movw    $0x3cc, %dx                     # Get CRTC port
693
        inb     %dx, %al
694
        movb    $0xd4, %dl
695
        rorb    %al                             # Mono or color?
696
        jc      set48a
697
 
698
        movb    $0xb4, %dl
699
set48a: movw    $0x0c11, %ax            # Vertical sync end (also unlocks CR0-7)
700
        call    outidx
701
        movw    $0x0b06, %ax                    # Vertical total
702
        call    outidx
703
        movw    $0x3e07, %ax                    # (Vertical) overflow
704
        call    outidx
705
        movw    $0xea10, %ax                    # Vertical sync start
706
        call    outidx
707
        movw    $0xdf12, %ax                    # Vertical display end
708
        call    outidx
709
        movw    $0xe715, %ax                    # Vertical blank start
710
        call    outidx
711
        movw    $0x0416, %ax                    # Vertical blank end
712
        call    outidx
713
        pushw   %dx
714
        movb    $0xcc, %dl                      # Misc output register (read)
715
        inb     %dx, %al
716
        movb    $0xc2, %dl                      # (write)
717
        andb    $0x0d, %al      # Preserve clock select bits and color bit
718
        orb     $0xe2, %al                      # Set correct sync polarity
719
        outb    %al, %dx
720
        popw    %dx
721
        movw    $0x501e, force_size
722
        stc                                     # That's all.
723
        ret
724
 
725
# Set the 80x34 mode (all VGA's). 480 scans, 14-pixel font.
726
set_80x34:
727
        call    set_80x30                       # Set 480 scans
728
        call    set14                           # And 14-pt font
729
        movw    $0xdb12, %ax                    # VGA vertical display end
730
        movw    $0x5022, force_size
731
setvde: call    outidx
732
        stc
733
        ret
734
 
735
# Set the 80x60 mode (all VGA's). 480 scans, 8-pixel font.
736
set_80x60:
737
        call    set_80x30                       # Set 480 scans
738
        call    set_8pt                         # And 8-pt font
739
        movw    $0xdf12, %ax                    # VGA vertical display end
740
        movw    $0x503c, force_size
741
        jmp     setvde
742
 
743
set_gfx:
744
        ret
745
 
746
#ifdef CONFIG_VIDEO_RETAIN
747
 
748
# Store screen contents to temporary buffer.
749
store_screen:
750
        cmpb    $0, do_restore                  # Already stored?
751
        jnz     stsr
752
 
753
        testb   $CAN_USE_HEAP, loadflags        # Have we space for storing?
754
        jz      stsr
755
 
756
        pushw   %ax
757
        pushw   %bx
758
        pushw   force_size                      # Don't force specific size
759
        movw    $0, force_size
760
        call    mode_params                     # Obtain params of current mode
761
        popw    force_size
762
        movb    %fs:(PARAM_VIDEO_LINES), %ah
763
        movb    %fs:(PARAM_VIDEO_COLS), %al
764
        movw    %ax, %bx                        # BX=dimensions
765
        mulb    %ah
766
        movw    %ax, %cx                        # CX=number of characters
767
        addw    %ax, %ax                        # Calculate image size
768
        addw    $modelist+1024+4, %ax
769
        cmpw    heap_end_ptr, %ax
770
        jnc     sts1                            # Unfortunately, out of memory
771
 
772
        movw    %fs:(PARAM_CURSOR_POS), %ax     # Store mode params
773
        leaw    modelist+1024, %di
774
        stosw
775
        movw    %bx, %ax
776
        stosw
777
        pushw   %ds                             # Store the screen
778
        movw    video_segment, %ds
779
        xorw    %si, %si
780
        rep
781
        movsw
782
        popw    %ds
783
        incb    do_restore                      # Screen will be restored later
784
sts1:   popw    %bx
785
        popw    %ax
786
stsr:   ret
787
 
788
# Restore screen contents from temporary buffer.
789
restore_screen:
790
        cmpb    $0, do_restore                  # Has the screen been stored?
791
        jz      res1
792
 
793
        call    mode_params                     # Get parameters of current mode
794
        movb    %fs:(PARAM_VIDEO_LINES), %cl
795
        movb    %fs:(PARAM_VIDEO_COLS), %ch
796
        leaw    modelist+1024, %si              # Screen buffer
797
        lodsw                                   # Set cursor position
798
        movw    %ax, %dx
799
        cmpb    %cl, %dh
800
        jc      res2
801
 
802
        movb    %cl, %dh
803
        decb    %dh
804
res2:   cmpb    %ch, %dl
805
        jc      res3
806
 
807
        movb    %ch, %dl
808
        decb    %dl
809
res3:   movb    $0x02, %ah
810
        movb    $0x00, %bh
811
        int     $0x10
812
        lodsw                                   # Display size
813
        movb    %ah, %dl                        # DL=number of lines
814
        movb    $0, %ah                         # BX=phys. length of orig. line
815
        movw    %ax, %bx
816
        cmpb    %cl, %dl                        # Too many?
817
        jc      res4
818
 
819
        pushw   %ax
820
        movb    %dl, %al
821
        subb    %cl, %al
822
        mulb    %bl
823
        addw    %ax, %si
824
        addw    %ax, %si
825
        popw    %ax
826
        movb    %cl, %dl
827
res4:   cmpb    %ch, %al                        # Too wide?
828
        jc      res5
829
 
830
        movb    %ch, %al                        # AX=width of src. line
831
res5:   movb    $0, %cl
832
        xchgb   %ch, %cl
833
        movw    %cx, %bp                        # BP=width of dest. line
834
        pushw   %es
835
        movw    video_segment, %es
836
        xorw    %di, %di                        # Move the data
837
        addw    %bx, %bx                        # Convert BX and BP to _bytes_
838
        addw    %bp, %bp
839
res6:   pushw   %si
840
        pushw   %di
841
        movw    %ax, %cx
842
        rep
843
        movsw
844
        popw    %di
845
        popw    %si
846
        addw    %bp, %di
847
        addw    %bx, %si
848
        decb    %dl
849
        jnz     res6
850
 
851
        popw    %es                             # Done
852
res1:   ret
853
#endif /* CONFIG_VIDEO_RETAIN */
854
 
855
# Write to indexed VGA register (AL=index, AH=data, DX=index reg. port)
856
outidx: outb    %al, %dx
857
        pushw   %ax
858
        movb    %ah, %al
859
        incw    %dx
860
        outb    %al, %dx
861
        decw    %dx
862
        popw    %ax
863
        ret
864
 
865
# Build the table of video modes (stored after the setup.S code at the
866
# `modelist' label. Each video mode record looks like:
867
#       .word   MODE-ID         (our special mode ID (see above))
868
#       .byte   rows            (number of rows)
869
#       .byte   columns         (number of columns)
870
# Returns address of the end of the table in DI, the end is marked
871
# with a ASK_VGA ID.
872
mode_table:
873
        movw    mt_end, %di                     # Already filled?
874
        orw     %di, %di
875
        jnz     mtab1x
876
 
877
        leaw    modelist, %di                   # Store standard modes:
878
        movl    $VIDEO_80x25 + 0x50190000, %eax # The 80x25 mode (ALL)
879
        stosl
880
        movb    adapter, %al                    # CGA/MDA/HGA -- no more modes
881
        orb     %al, %al
882
        jz      mtabe
883
 
884
        decb    %al
885
        jnz     mtabv
886
 
887
        movl    $VIDEO_8POINT + 0x502b0000, %eax        # The 80x43 EGA mode
888
        stosl
889
        jmp     mtabe
890
 
891
mtab1x: jmp     mtab1
892
 
893
mtabv:  leaw    vga_modes, %si                  # All modes for std VGA
894
        movw    $vga_modes_end-vga_modes, %cx
895
        rep     # I'm unable to use movsw as I don't know how to store a half
896
        movsb   # of the expression above to cx without using explicit shr.
897
 
898
        cmpb    $0, scanning                    # Mode scan requested?
899
        jz      mscan1
900
 
901
        call    mode_scan
902
mscan1:
903
 
904
#ifdef CONFIG_VIDEO_LOCAL
905
        call    local_modes
906
#endif /* CONFIG_VIDEO_LOCAL */
907
 
908
#ifdef CONFIG_VIDEO_VESA
909
        call    vesa_modes                      # Detect VESA VGA modes
910
#endif /* CONFIG_VIDEO_VESA */
911
 
912
#ifdef CONFIG_VIDEO_SVGA
913
        cmpb    $0, scanning                    # Bypass when scanning
914
        jnz     mscan2
915
 
916
        call    svga_modes                      # Detect SVGA cards & modes
917
mscan2:
918
#endif /* CONFIG_VIDEO_SVGA */
919
 
920
mtabe:
921
 
922
#ifdef CONFIG_VIDEO_COMPACT
923
        leaw    modelist, %si
924
        movw    %di, %dx
925
        movw    %si, %di
926
cmt1:   cmpw    %dx, %si                        # Scan all modes
927
        jz      cmt2
928
 
929
        leaw    modelist, %bx                   # Find in previous entries
930
        movw    2(%si), %cx
931
cmt3:   cmpw    %bx, %si
932
        jz      cmt4
933
 
934
        cmpw    2(%bx), %cx                     # Found => don't copy this entry
935
        jz      cmt5
936
 
937
        addw    $4, %bx
938
        jmp     cmt3
939
 
940
cmt4:   movsl                                   # Copy entry
941
        jmp     cmt1
942
 
943
cmt5:   addw    $4, %si                         # Skip entry
944
        jmp     cmt1
945
 
946
cmt2:
947
#endif  /* CONFIG_VIDEO_COMPACT */
948
 
949
        movw    $ASK_VGA, (%di)                 # End marker
950
        movw    %di, mt_end
951
mtab1:  leaw    modelist, %si                   # SI=mode list, DI=list end
952
ret0:   ret
953
 
954
# Modes usable on all standard VGAs
955
vga_modes:
956
        .word   VIDEO_8POINT
957
        .word   0x5032                          # 80x50
958
        .word   VIDEO_80x43
959
        .word   0x502b                          # 80x43
960
        .word   VIDEO_80x28
961
        .word   0x501c                          # 80x28
962
        .word   VIDEO_80x30
963
        .word   0x501e                          # 80x30
964
        .word   VIDEO_80x34
965
        .word   0x5022                          # 80x34
966
        .word   VIDEO_80x60
967
        .word   0x503c                          # 80x60
968
 
969
vga_modes_end:
970
# Detect VESA modes.
971
 
972
#ifdef CONFIG_VIDEO_VESA
973
vesa_modes:
974
        cmpb    $2, adapter                     # VGA only
975
        jnz     ret0
976
 
977
        movw    %di, %bp                        # BP=original mode table end
978
        addw    $0x200, %di                     # Buffer space
979
        movw    $0x4f00, %ax                    # VESA Get card info call
980
        int     $0x10
981
        movw    %bp, %di
982
        cmpw    $0x004f, %ax                    # Successful?
983
        jnz     ret0
984
 
985
        cmpw    $0x4556, 0x200(%di)
986
        jnz     ret0
987
 
988
        cmpw    $0x4153, 0x202(%di)
989
        jnz     ret0
990
 
991
        movw    $vesa_name, card_name           # Set name to "VESA VGA"
992
        pushw   %gs
993
        lgsw    0x20e(%di), %si                 # GS:SI=mode list
994
        movw    $128, %cx                       # Iteration limit
995
vesa1:
996
# gas version 2.9.1, using BFD version 2.9.1.0.23 buggers the next inst.
997
# XXX:  lodsw   %gs:(%si), %ax                  # Get next mode in the list
998
        gs; lodsw
999
        cmpw    $0xffff, %ax                    # End of the table?
1000
        jz      vesar
1001
 
1002
        cmpw    $0x0080, %ax                    # Check validity of mode ID
1003
        jc      vesa2
1004
 
1005
        orb     %ah, %ah                # Valid IDs: 0x0000-0x007f/0x0100-0x07ff
1006
        jz      vesan                   # Certain BIOSes report 0x80-0xff!
1007
 
1008
        cmpw    $0x0800, %ax
1009
        jnc     vesae
1010
 
1011
vesa2:  pushw   %cx
1012
        movw    %ax, %cx                        # Get mode information structure
1013
        movw    $0x4f01, %ax
1014
        int     $0x10
1015
        movw    %cx, %bx                        # BX=mode number
1016
        addb    $VIDEO_FIRST_VESA>>8, %bh
1017
        popw    %cx
1018
        cmpw    $0x004f, %ax
1019
        jnz     vesan                   # Don't report errors (buggy BIOSES)
1020
 
1021
        movb    (%di), %al                      # Check capabilities. We require
1022
        andb    $0x19, %al                      # a color text mode.
1023
        cmpb    $0x09, %al
1024
        jnz     vesan
1025
 
1026
        cmpw    $0xb800, 8(%di)         # Standard video memory address required
1027
        jnz     vesan
1028
 
1029
        testb   $2, (%di)                       # Mode characteristics supplied?
1030
        movw    %bx, (%di)                      # Store mode number
1031
        jz      vesa3
1032
 
1033
        xorw    %dx, %dx
1034
        movw    0x12(%di), %bx                  # Width
1035
        orb     %bh, %bh
1036
        jnz     vesan
1037
 
1038
        movb    %bl, 0x3(%di)
1039
        movw    0x14(%di), %ax                  # Height
1040
        orb     %ah, %ah
1041
        jnz     vesan
1042
 
1043
        movb    %al, 2(%di)
1044
        mulb    %bl
1045
        cmpw    $8193, %ax              # Small enough for Linux console driver?
1046
        jnc     vesan
1047
 
1048
        jmp     vesaok
1049
 
1050
vesa3:  subw    $0x8108, %bx    # This mode has no detailed info specified,
1051
        jc      vesan           # so it must be a standard VESA mode.
1052
 
1053
        cmpw    $5, %bx
1054
        jnc     vesan
1055
 
1056
        movw    vesa_text_mode_table(%bx), %ax
1057
        movw    %ax, 2(%di)
1058
vesaok: addw    $4, %di                         # The mode is valid. Store it.
1059
vesan:  loop    vesa1                   # Next mode. Limit exceeded => error
1060
vesae:  leaw    vesaer, %si
1061
        call    prtstr
1062
        movw    %bp, %di                        # Discard already found modes.
1063
vesar:  popw    %gs
1064
        ret
1065
 
1066
# Dimensions of standard VESA text modes
1067
vesa_text_mode_table:
1068
        .byte   60, 80                          # 0108
1069
        .byte   25, 132                         # 0109
1070
        .byte   43, 132                         # 010A
1071
        .byte   50, 132                         # 010B
1072
        .byte   60, 132                         # 010C
1073
#endif  /* CONFIG_VIDEO_VESA */
1074
 
1075
# Scan for video modes. A bit dirty, but should work.
1076
mode_scan:
1077
        movw    $0x0100, %cx                    # Start with mode 0
1078
scm1:   movb    $0, %ah                         # Test the mode
1079
        movb    %cl, %al
1080
        int     $0x10
1081
        movb    $0x0f, %ah
1082
        int     $0x10
1083
        cmpb    %cl, %al
1084
        jnz     scm2                            # Mode not set
1085
 
1086
        movw    $0x3c0, %dx                     # Test if it's a text mode
1087
        movb    $0x10, %al                      # Mode bits
1088
        call    inidx
1089
        andb    $0x03, %al
1090
        jnz     scm2
1091
 
1092
        movb    $0xce, %dl                      # Another set of mode bits
1093
        movb    $0x06, %al
1094
        call    inidx
1095
        shrb    %al
1096
        jc      scm2
1097
 
1098
        movb    $0xd4, %dl                      # Cursor location
1099
        movb    $0x0f, %al
1100
        call    inidx
1101
        orb     %al, %al
1102
        jnz     scm2
1103
 
1104
        movw    %cx, %ax                        # Ok, store the mode
1105
        stosw
1106
        movb    %gs:(0x484), %al                # Number of rows
1107
        incb    %al
1108
        stosb
1109
        movw    %gs:(0x44a), %ax                # Number of columns
1110
        stosb
1111
scm2:   incb    %cl
1112
        jns     scm1
1113
 
1114
        movw    $0x0003, %ax                    # Return back to mode 3
1115
        int     $0x10
1116
        ret
1117
 
1118
tstidx: outw    %ax, %dx                        # OUT DX,AX and inidx
1119
inidx:  outb    %al, %dx                        # Read from indexed VGA register
1120
        incw    %dx                     # AL=index, DX=index reg port -> AL=data
1121
        inb     %dx, %al
1122
        decw    %dx
1123
        ret
1124
 
1125
# Try to detect type of SVGA card and supply (usually approximate) video
1126
# mode table for it.
1127
 
1128
#ifdef CONFIG_VIDEO_SVGA
1129
svga_modes:
1130
        leaw    svga_table, %si                 # Test all known SVGA adapters
1131
dosvga: lodsw
1132
        movw    %ax, %bp                        # Default mode table
1133
        orw     %ax, %ax
1134
        jz      didsv1
1135
 
1136
        lodsw                                   # Pointer to test routine
1137
        pushw   %si
1138
        pushw   %di
1139
        pushw   %es
1140
        movw    $0xc000, %bx
1141
        movw    %bx, %es
1142
        call    *%ax                            # Call test routine
1143
        popw    %es
1144
        popw    %di
1145
        popw    %si
1146
        orw     %bp, %bp
1147
        jz      dosvga
1148
 
1149
        movw    %bp, %si                        # Found, copy the modes
1150
        movb    svga_prefix, %ah
1151
cpsvga: lodsb
1152
        orb     %al, %al
1153
        jz      didsv
1154
 
1155
        stosw
1156
        movsw
1157
        jmp     cpsvga
1158
 
1159
didsv:  movw    %si, card_name                  # Store pointer to card name
1160
didsv1: ret
1161
 
1162
# Table of all known SVGA cards. For each card, we store a pointer to
1163
# a table of video modes supported by the card and a pointer to a routine
1164
# used for testing of presence of the card. The video mode table is always
1165
# followed by the name of the card or the chipset.
1166
svga_table:
1167
        .word   ati_md, ati_test
1168
        .word   oak_md, oak_test
1169
        .word   paradise_md, paradise_test
1170
        .word   realtek_md, realtek_test
1171
        .word   s3_md, s3_test
1172
        .word   chips_md, chips_test
1173
        .word   video7_md, video7_test
1174
        .word   cirrus5_md, cirrus5_test
1175
        .word   cirrus6_md, cirrus6_test
1176
        .word   cirrus1_md, cirrus1_test
1177
        .word   ahead_md, ahead_test
1178
        .word   everex_md, everex_test
1179
        .word   genoa_md, genoa_test
1180
        .word   trident_md, trident_test
1181
        .word   tseng_md, tseng_test
1182
        .word   0
1183
 
1184
# Test routines and mode tables:
1185
 
1186
# S3 - The test algorithm was taken from the SuperProbe package
1187
# for XFree86 1.2.1. Report bugs to Christoph.Niemann@linux.org
1188
s3_test:
1189
        movw    $0x0f35, %cx    # we store some constants in cl/ch
1190
        movw    $0x03d4, %dx
1191
        movb    $0x38, %al
1192
        call    inidx
1193
        movb    %al, %bh        # store current CRT-register 0x38
1194
        movw    $0x0038, %ax
1195
        call    outidx          # disable writing to special regs
1196
        movb    %cl, %al        # check whether we can write special reg 0x35
1197
        call    inidx
1198
        movb    %al, %bl        # save the current value of CRT reg 0x35
1199
        andb    $0xf0, %al      # clear bits 0-3
1200
        movb    %al, %ah
1201
        movb    %cl, %al        # and write it to CRT reg 0x35
1202
        call    outidx
1203
        call    inidx           # now read it back
1204
        andb    %ch, %al        # clear the upper 4 bits
1205
        jz      s3_2            # the first test failed. But we have a
1206
 
1207
        movb    %bl, %ah        # second chance
1208
        movb    %cl, %al
1209
        call    outidx
1210
        jmp     s3_1            # do the other tests
1211
 
1212
s3_2:   movw    %cx, %ax        # load ah with 0xf and al with 0x35
1213
        orb     %bl, %ah        # set the upper 4 bits of ah with the orig value
1214
        call    outidx          # write ...
1215
        call    inidx           # ... and reread
1216
        andb    %cl, %al        # turn off the upper 4 bits
1217
        pushw   %ax
1218
        movb    %bl, %ah        # restore old value in register 0x35
1219
        movb    %cl, %al
1220
        call    outidx
1221
        popw    %ax
1222
        cmpb    %ch, %al        # setting lower 4 bits was successful => bad
1223
        je      no_s3           # writing is allowed => this is not an S3
1224
 
1225
s3_1:   movw    $0x4838, %ax    # allow writing to special regs by putting
1226
        call    outidx          # magic number into CRT-register 0x38
1227
        movb    %cl, %al        # check whether we can write special reg 0x35
1228
        call    inidx
1229
        movb    %al, %bl
1230
        andb    $0xf0, %al
1231
        movb    %al, %ah
1232
        movb    %cl, %al
1233
        call    outidx
1234
        call    inidx
1235
        andb    %ch, %al
1236
        jnz     no_s3           # no, we can't write => no S3
1237
 
1238
        movw    %cx, %ax
1239
        orb     %bl, %ah
1240
        call    outidx
1241
        call    inidx
1242
        andb    %ch, %al
1243
        pushw   %ax
1244
        movb    %bl, %ah        # restore old value in register 0x35
1245
        movb    %cl, %al
1246
        call    outidx
1247
        popw    %ax
1248
        cmpb    %ch, %al
1249
        jne     no_s31          # writing not possible => no S3
1250
        movb    $0x30, %al
1251
        call    inidx           # now get the S3 id ...
1252
        leaw    idS3, %di
1253
        movw    $0x10, %cx
1254
        repne
1255
        scasb
1256
        je      no_s31
1257
 
1258
        movb    %bh, %ah
1259
        movb    $0x38, %al
1260
        jmp     s3rest
1261
 
1262
no_s3:  movb    $0x35, %al      # restore CRT register 0x35
1263
        movb    %bl, %ah
1264
        call    outidx
1265
no_s31: xorw    %bp, %bp        # Detection failed
1266
s3rest: movb    %bh, %ah
1267
        movb    $0x38, %al      # restore old value of CRT register 0x38
1268
        jmp     outidx
1269
 
1270
idS3:   .byte   0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
1271
        .byte   0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
1272
 
1273
s3_md:  .byte   0x54, 0x2b, 0x84
1274
        .byte   0x55, 0x19, 0x84
1275
        .byte   0
1276
        .ascii  "S3"
1277
        .byte   0
1278
 
1279
# ATI cards.
1280
ati_test:
1281
        leaw    idati, %si
1282
        movw    $0x31, %di
1283
        movw    $0x09, %cx
1284
        repe
1285
        cmpsb
1286
        je      atiok
1287
 
1288
        xorw    %bp, %bp
1289
atiok:  ret
1290
 
1291
idati:  .ascii  "761295520"
1292
 
1293
ati_md: .byte   0x23, 0x19, 0x84
1294
        .byte   0x33, 0x2c, 0x84
1295
        .byte   0x22, 0x1e, 0x64
1296
        .byte   0x21, 0x19, 0x64
1297
        .byte   0x58, 0x21, 0x50
1298
        .byte   0x5b, 0x1e, 0x50
1299
        .byte   0
1300
        .ascii  "ATI"
1301
        .byte   0
1302
 
1303
# AHEAD
1304
ahead_test:
1305
        movw    $0x200f, %ax
1306
        movw    $0x3ce, %dx
1307
        outw    %ax, %dx
1308
        incw    %dx
1309
        inb     %dx, %al
1310
        cmpb    $0x20, %al
1311
        je      isahed
1312
 
1313
        cmpb    $0x21, %al
1314
        je      isahed
1315
 
1316
        xorw    %bp, %bp
1317
isahed: ret
1318
 
1319
ahead_md:
1320
        .byte   0x22, 0x2c, 0x84
1321
        .byte   0x23, 0x19, 0x84
1322
        .byte   0x24, 0x1c, 0x84
1323
        .byte   0x2f, 0x32, 0xa0
1324
        .byte   0x32, 0x22, 0x50
1325
        .byte   0x34, 0x42, 0x50
1326
        .byte   0
1327
        .ascii  "Ahead"
1328
        .byte   0
1329
 
1330
# Chips & Tech.
1331
chips_test:
1332
        movw    $0x3c3, %dx
1333
        inb     %dx, %al
1334
        orb     $0x10, %al
1335
        outb    %al, %dx
1336
        movw    $0x104, %dx
1337
        inb     %dx, %al
1338
        movb    %al, %bl
1339
        movw    $0x3c3, %dx
1340
        inb     %dx, %al
1341
        andb    $0xef, %al
1342
        outb    %al, %dx
1343
        cmpb    $0xa5, %bl
1344
        je      cantok
1345
 
1346
        xorw    %bp, %bp
1347
cantok: ret
1348
 
1349
chips_md:
1350
        .byte   0x60, 0x19, 0x84
1351
        .byte   0x61, 0x32, 0x84
1352
        .byte   0
1353
        .ascii  "Chips & Technologies"
1354
        .byte   0
1355
 
1356
# Cirrus Logic 5X0
1357
cirrus1_test:
1358
        movw    $0x3d4, %dx
1359
        movb    $0x0c, %al
1360
        outb    %al, %dx
1361
        incw    %dx
1362
        inb     %dx, %al
1363
        movb    %al, %bl
1364
        xorb    %al, %al
1365
        outb    %al, %dx
1366
        decw    %dx
1367
        movb    $0x1f, %al
1368
        outb    %al, %dx
1369
        incw    %dx
1370
        inb     %dx, %al
1371
        movb    %al, %bh
1372
        xorb    %ah, %ah
1373
        shlb    $4, %al
1374
        movw    %ax, %cx
1375
        movb    %bh, %al
1376
        shrb    $4, %al
1377
        addw    %ax, %cx
1378
        shlw    $8, %cx
1379
        addw    $6, %cx
1380
        movw    %cx, %ax
1381
        movw    $0x3c4, %dx
1382
        outw    %ax, %dx
1383
        incw    %dx
1384
        inb     %dx, %al
1385
        andb    %al, %al
1386
        jnz     nocirr
1387
 
1388
        movb    %bh, %al
1389
        outb    %al, %dx
1390
        inb     %dx, %al
1391
        cmpb    $0x01, %al
1392
        je      iscirr
1393
 
1394
nocirr: xorw    %bp, %bp
1395
iscirr: movw    $0x3d4, %dx
1396
        movb    %bl, %al
1397
        xorb    %ah, %ah
1398
        shlw    $8, %ax
1399
        addw    $0x0c, %ax
1400
        outw    %ax, %dx
1401
        ret
1402
 
1403
cirrus1_md:
1404
        .byte   0x1f, 0x19, 0x84
1405
        .byte   0x20, 0x2c, 0x84
1406
        .byte   0x22, 0x1e, 0x84
1407
        .byte   0x31, 0x25, 0x64
1408
        .byte   0
1409
        .ascii  "Cirrus Logic 5X0"
1410
        .byte   0
1411
 
1412
# Cirrus Logic 54XX
1413
cirrus5_test:
1414
        movw    $0x3c4, %dx
1415
        movb    $6, %al
1416
        call    inidx
1417
        movb    %al, %bl                        # BL=backup
1418
        movw    $6, %ax
1419
        call    tstidx
1420
        cmpb    $0x0f, %al
1421
        jne     c5fail
1422
 
1423
        movw    $0x1206, %ax
1424
        call    tstidx
1425
        cmpb    $0x12, %al
1426
        jne     c5fail
1427
 
1428
        movb    $0x1e, %al
1429
        call    inidx
1430
        movb    %al, %bh
1431
        movb    %bh, %ah
1432
        andb    $0xc0, %ah
1433
        movb    $0x1e, %al
1434
        call    tstidx
1435
        andb    $0x3f, %al
1436
        jne     c5xx
1437
 
1438
        movb    $0x1e, %al
1439
        movb    %bh, %ah
1440
        orb     $0x3f, %ah
1441
        call    tstidx
1442
        xorb    $0x3f, %al
1443
        andb    $0x3f, %al
1444
c5xx:   pushf
1445
        movb    $0x1e, %al
1446
        movb    %bh, %ah
1447
        outw    %ax, %dx
1448
        popf
1449
        je      c5done
1450
 
1451
c5fail: xorw    %bp, %bp
1452
c5done: movb    $6, %al
1453
        movb    %bl, %ah
1454
        outw    %ax, %dx
1455
        ret
1456
 
1457
cirrus5_md:
1458
        .byte   0x14, 0x19, 0x84
1459
        .byte   0x54, 0x2b, 0x84
1460
        .byte   0
1461
        .ascii  "Cirrus Logic 54XX"
1462
        .byte   0
1463
 
1464
# Cirrus Logic 64XX -- no known extra modes, but must be identified, because
1465
# it's misidentified by the Ahead test.
1466
cirrus6_test:
1467
        movw    $0x3ce, %dx
1468
        movb    $0x0a, %al
1469
        call    inidx
1470
        movb    %al, %bl        # BL=backup
1471
        movw    $0xce0a, %ax
1472
        call    tstidx
1473
        orb     %al, %al
1474
        jne     c2fail
1475
 
1476
        movw    $0xec0a, %ax
1477
        call    tstidx
1478
        cmpb    $0x01, %al
1479
        jne     c2fail
1480
 
1481
        movb    $0xaa, %al
1482
        call    inidx           # 4X, 5X, 7X and 8X are valid 64XX chip ID's.
1483
        shrb    $4, %al
1484
        subb    $4, %al
1485
        jz      c6done
1486
 
1487
        decb    %al
1488
        jz      c6done
1489
 
1490
        subb    $2, %al
1491
        jz      c6done
1492
 
1493
        decb    %al
1494
        jz      c6done
1495
 
1496
c2fail: xorw    %bp, %bp
1497
c6done: movb    $0x0a, %al
1498
        movb    %bl, %ah
1499
        outw    %ax, %dx
1500
        ret
1501
 
1502
cirrus6_md:
1503
        .byte   0
1504
        .ascii  "Cirrus Logic 64XX"
1505
        .byte   0
1506
 
1507
# Everex / Trident
1508
everex_test:
1509
        movw    $0x7000, %ax
1510
        xorw    %bx, %bx
1511
        int     $0x10
1512
        cmpb    $0x70, %al
1513
        jne     noevrx
1514
 
1515
        shrw    $4, %dx
1516
        cmpw    $0x678, %dx
1517
        je      evtrid
1518
 
1519
        cmpw    $0x236, %dx
1520
        jne     evrxok
1521
 
1522
evtrid: leaw    trident_md, %bp
1523
evrxok: ret
1524
 
1525
noevrx: xorw    %bp, %bp
1526
        ret
1527
 
1528
everex_md:
1529
        .byte   0x03, 0x22, 0x50
1530
        .byte   0x04, 0x3c, 0x50
1531
        .byte   0x07, 0x2b, 0x64
1532
        .byte   0x08, 0x4b, 0x64
1533
        .byte   0x0a, 0x19, 0x84
1534
        .byte   0x0b, 0x2c, 0x84
1535
        .byte   0x16, 0x1e, 0x50
1536
        .byte   0x18, 0x1b, 0x64
1537
        .byte   0x21, 0x40, 0xa0
1538
        .byte   0x40, 0x1e, 0x84
1539
        .byte   0
1540
        .ascii  "Everex/Trident"
1541
        .byte   0
1542
 
1543
# Genoa.
1544
genoa_test:
1545
        leaw    idgenoa, %si                    # Check Genoa 'clues'
1546
        xorw    %ax, %ax
1547
        movb    %es:(0x37), %al
1548
        movw    %ax, %di
1549
        movw    $0x04, %cx
1550
        decw    %si
1551
        decw    %di
1552
l1:     incw    %si
1553
        incw    %di
1554
        movb    (%si), %al
1555
        testb   %al, %al
1556
        jz      l2
1557
 
1558
        cmpb    %es:(%di), %al
1559
l2:     loope   l1
1560
        orw     %cx, %cx
1561
        je      isgen
1562
 
1563
        xorw    %bp, %bp
1564
isgen:  ret
1565
 
1566
idgenoa: .byte  0x77, 0x00, 0x99, 0x66
1567
 
1568
genoa_md:
1569
        .byte   0x58, 0x20, 0x50
1570
        .byte   0x5a, 0x2a, 0x64
1571
        .byte   0x60, 0x19, 0x84
1572
        .byte   0x61, 0x1d, 0x84
1573
        .byte   0x62, 0x20, 0x84
1574
        .byte   0x63, 0x2c, 0x84
1575
        .byte   0x64, 0x3c, 0x84
1576
        .byte   0x6b, 0x4f, 0x64
1577
        .byte   0x72, 0x3c, 0x50
1578
        .byte   0x74, 0x42, 0x50
1579
        .byte   0x78, 0x4b, 0x64
1580
        .byte   0
1581
        .ascii  "Genoa"
1582
        .byte   0
1583
 
1584
# OAK
1585
oak_test:
1586
        leaw    idoakvga, %si
1587
        movw    $0x08, %di
1588
        movw    $0x08, %cx
1589
        repe
1590
        cmpsb
1591
        je      isoak
1592
 
1593
        xorw    %bp, %bp
1594
isoak:  ret
1595
 
1596
idoakvga: .ascii  "OAK VGA "
1597
 
1598
oak_md: .byte   0x4e, 0x3c, 0x50
1599
        .byte   0x4f, 0x3c, 0x84
1600
        .byte   0x50, 0x19, 0x84
1601
        .byte   0x51, 0x2b, 0x84
1602
        .byte   0
1603
        .ascii  "OAK"
1604
        .byte   0
1605
 
1606
# WD Paradise.
1607
paradise_test:
1608
        leaw    idparadise, %si
1609
        movw    $0x7d, %di
1610
        movw    $0x04, %cx
1611
        repe
1612
        cmpsb
1613
        je      ispara
1614
 
1615
        xorw    %bp, %bp
1616
ispara: ret
1617
 
1618
idparadise:     .ascii  "VGA="
1619
 
1620
paradise_md:
1621
        .byte   0x41, 0x22, 0x50
1622
        .byte   0x47, 0x1c, 0x84
1623
        .byte   0x55, 0x19, 0x84
1624
        .byte   0x54, 0x2c, 0x84
1625
        .byte   0
1626
        .ascii  "Paradise"
1627
        .byte   0
1628
 
1629
# Trident.
1630
trident_test:
1631
        movw    $0x3c4, %dx
1632
        movb    $0x0e, %al
1633
        outb    %al, %dx
1634
        incw    %dx
1635
        inb     %dx, %al
1636
        xchgb   %al, %ah
1637
        xorb    %al, %al
1638
        outb    %al, %dx
1639
        inb     %dx, %al
1640
        xchgb   %ah, %al
1641
        movb    %al, %bl        # Strange thing ... in the book this wasn't
1642
        andb    $0x02, %bl      # necessary but it worked on my card which
1643
        jz      setb2           # is a trident. Without it the screen goes
1644
                                # blurred ...
1645
        andb    $0xfd, %al
1646
        jmp     clrb2
1647
 
1648
setb2:  orb     $0x02, %al
1649
clrb2:  outb    %al, %dx
1650
        andb    $0x0f, %ah
1651
        cmpb    $0x02, %ah
1652
        je      istrid
1653
 
1654
        xorw    %bp, %bp
1655
istrid: ret
1656
 
1657
trident_md:
1658
        .byte   0x50, 0x1e, 0x50
1659
        .byte   0x51, 0x2b, 0x50
1660
        .byte   0x52, 0x3c, 0x50
1661
        .byte   0x57, 0x19, 0x84
1662
        .byte   0x58, 0x1e, 0x84
1663
        .byte   0x59, 0x2b, 0x84
1664
        .byte   0x5a, 0x3c, 0x84
1665
        .byte   0
1666
        .ascii  "Trident"
1667
        .byte   0
1668
 
1669
# Tseng.
1670
tseng_test:
1671
        movw    $0x3cd, %dx
1672
        inb     %dx, %al        # Could things be this simple ! :-)
1673
        movb    %al, %bl
1674
        movb    $0x55, %al
1675
        outb    %al, %dx
1676
        inb     %dx, %al
1677
        movb    %al, %ah
1678
        movb    %bl, %al
1679
        outb    %al, %dx
1680
        cmpb    $0x55, %ah
1681
        je      istsen
1682
 
1683
isnot:  xorw    %bp, %bp
1684
istsen: ret
1685
 
1686
tseng_md:
1687
        .byte   0x26, 0x3c, 0x50
1688
        .byte   0x2a, 0x28, 0x64
1689
        .byte   0x23, 0x19, 0x84
1690
        .byte   0x24, 0x1c, 0x84
1691
        .byte   0x22, 0x2c, 0x84
1692
        .byte   0x21, 0x3c, 0x84
1693
        .byte   0
1694
        .ascii  "Tseng"
1695
        .byte   0
1696
 
1697
# Video7.
1698
video7_test:
1699
        movw    $0x3cc, %dx
1700
        inb     %dx, %al
1701
        movw    $0x3b4, %dx
1702
        andb    $0x01, %al
1703
        jz      even7
1704
 
1705
        movw    $0x3d4, %dx
1706
even7:  movb    $0x0c, %al
1707
        outb    %al, %dx
1708
        incw    %dx
1709
        inb     %dx, %al
1710
        movb    %al, %bl
1711
        movb    $0x55, %al
1712
        outb    %al, %dx
1713
        inb     %dx, %al
1714
        decw    %dx
1715
        movb    $0x1f, %al
1716
        outb    %al, %dx
1717
        incw    %dx
1718
        inb     %dx, %al
1719
        movb    %al, %bh
1720
        decw    %dx
1721
        movb    $0x0c, %al
1722
        outb    %al, %dx
1723
        incw    %dx
1724
        movb    %bl, %al
1725
        outb    %al, %dx
1726
        movb    $0x55, %al
1727
        xorb    $0xea, %al
1728
        cmpb    %bh, %al
1729
        jne     isnot
1730
 
1731
        movb    $VIDEO_FIRST_V7>>8, svga_prefix # Use special mode switching
1732
        ret
1733
 
1734
video7_md:
1735
        .byte   0x40, 0x2b, 0x50
1736
        .byte   0x43, 0x3c, 0x50
1737
        .byte   0x44, 0x3c, 0x64
1738
        .byte   0x41, 0x19, 0x84
1739
        .byte   0x42, 0x2c, 0x84
1740
        .byte   0x45, 0x1c, 0x84
1741
        .byte   0
1742
        .ascii  "Video 7"
1743
        .byte   0
1744
 
1745
# Realtek VGA
1746
realtek_test:
1747
        leaw    idrtvga, %si
1748
        movw    $0x45, %di
1749
        movw    $0x0b, %cx
1750
        repe
1751
        cmpsb
1752
        je      isrt
1753
 
1754
        xorw    %bp, %bp
1755
isrt:   ret
1756
 
1757
idrtvga:        .ascii  "REALTEK VGA"
1758
 
1759
realtek_md:
1760
        .byte   0x1a, 0x3c, 0x50
1761
        .byte   0x1b, 0x19, 0x84
1762
        .byte   0x1c, 0x1e, 0x84
1763
        .byte   0x1d, 0x2b, 0x84
1764
        .byte   0x1e, 0x3c, 0x84
1765
        .byte   0
1766
        .ascii  "REALTEK"
1767
        .byte   0
1768
 
1769
#endif  /* CONFIG_VIDEO_SVGA */
1770
 
1771
# User-defined local mode table (VGA only)
1772
#ifdef CONFIG_VIDEO_LOCAL
1773
local_modes:
1774
        leaw    local_mode_table, %si
1775
locm1:  lodsw
1776
        orw     %ax, %ax
1777
        jz      locm2
1778
 
1779
        stosw
1780
        movsw
1781
        jmp     locm1
1782
 
1783
locm2:  ret
1784
 
1785
# This is the table of local video modes which can be supplied manually
1786
# by the user. Each entry consists of mode ID (word) and dimensions
1787
# (byte for column count and another byte for row count). These modes
1788
# are placed before all SVGA and VESA modes and override them if table
1789
# compacting is enabled. The table must end with a zero word followed
1790
# by NUL-terminated video adapter name.
1791
local_mode_table:
1792
        .word   0x0100                          # Example: 40x25
1793
        .byte   25,40
1794
        .word   0
1795
        .ascii  "Local"
1796
        .byte   0
1797
#endif  /* CONFIG_VIDEO_LOCAL */
1798
 
1799
# Read a key and return the ASCII code in al, scan code in ah
1800
getkey: xorb    %ah, %ah
1801
        int     $0x16
1802
        ret
1803
 
1804
# Read a key with a timeout of 30 seconds.
1805
# The hardware clock is used to get the time.
1806
getkt:  call    gettime
1807
        addb    $30, %al                        # Wait 30 seconds
1808
        cmpb    $60, %al
1809
        jl      lminute
1810
 
1811
        subb    $60, %al
1812
lminute:
1813
        movb    %al, %cl
1814
again:  movb    $0x01, %ah
1815
        int     $0x16
1816
        jnz     getkey                          # key pressed, so get it
1817
 
1818
        call    gettime
1819
        cmpb    %cl, %al
1820
        jne     again
1821
 
1822
        movb    $0x20, %al                      # timeout, return `space'
1823
        ret
1824
 
1825
# Flush the keyboard buffer
1826
flush:  movb    $0x01, %ah
1827
        int     $0x16
1828
        jz      empty
1829
 
1830
        xorb    %ah, %ah
1831
        int     $0x16
1832
        jmp     flush
1833
 
1834
empty:  ret
1835
 
1836
# Print hexadecimal number.
1837
prthw:  pushw   %ax
1838
        movb    %ah, %al
1839
        call    prthb
1840
        popw    %ax
1841
prthb:  pushw   %ax
1842
        shrb    $4, %al
1843
        call    prthn
1844
        popw    %ax
1845
        andb    $0x0f, %al
1846
prthn:  cmpb    $0x0a, %al
1847
        jc      prth1
1848
 
1849
        addb    $0x07, %al
1850
prth1:  addb    $0x30, %al
1851
        jmp     prtchr
1852
 
1853
# Print decimal number in al
1854
prtdec: pushw   %ax
1855
        pushw   %cx
1856
        xorb    %ah, %ah
1857
        movb    $0x0a, %cl
1858
        idivb   %cl
1859
        cmpb    $0x09, %al
1860
        jbe     lt100
1861
 
1862
        call    prtdec
1863
        jmp     skip10
1864
 
1865
lt100:  addb    $0x30, %al
1866
        call    prtchr
1867
skip10: movb    %ah, %al
1868
        addb    $0x30, %al
1869
        call    prtchr
1870
        popw    %cx
1871
        popw    %ax
1872
        ret
1873
 
1874
# VIDEO_SELECT-only variables
1875
mt_end:         .word   0        # End of video mode table if built
1876
edit_buf:       .space  6       # Line editor buffer
1877
card_name:      .word   0        # Pointer to adapter name
1878
scanning:       .byte   0        # Performing mode scan
1879
do_restore:     .byte   0        # Screen contents altered during mode change
1880
svga_prefix:    .byte   VIDEO_FIRST_BIOS>>8     # Default prefix for BIOS modes
1881
graphic_mode:   .byte   0        # Graphic mode with a linear frame buffer
1882
 
1883
# Status messages
1884
keymsg:         .ascii  "Press  to see video modes available, "
1885
                .ascii  " to continue or wait 30 secs"
1886
                .byte   0x0d, 0x0a, 0
1887
 
1888
listhdr:        .byte   0x0d, 0x0a
1889
                .ascii  "Mode:    COLSxROWS:"
1890
 
1891
crlft:          .byte   0x0d, 0x0a, 0
1892
 
1893
prompt:         .byte   0x0d, 0x0a
1894
                .asciz  "Enter mode number or `scan': "
1895
 
1896
unknt:          .asciz  "Unknown mode ID. Try again."
1897
 
1898
badmdt:         .ascii  "You passed an undefined mode number."
1899
                .byte   0x0d, 0x0a, 0
1900
 
1901
vesaer:         .ascii  "Error: Scanning of VESA modes failed. Please "
1902
                .ascii  "report to ."
1903
                .byte   0x0d, 0x0a, 0
1904
 
1905
old_name:       .asciz  "CGA/MDA/HGA"
1906
 
1907
ega_name:       .asciz  "EGA"
1908
 
1909
svga_name:      .ascii  " "
1910
 
1911
vga_name:       .asciz  "VGA"
1912
 
1913
vesa_name:      .asciz  "VESA"
1914
 
1915
name_bann:      .asciz  "Video adapter: "
1916
#endif /* CONFIG_VIDEO_SELECT */
1917
 
1918
# Other variables:
1919
adapter:        .byte   0        # Video adapter: 0=CGA/MDA/HGA,1=EGA,2=VGA
1920
video_segment:  .word   0xb800  # Video memory segment
1921
force_size:     .word   0        # Use this size instead of the one in BIOS vars

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.