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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [i386/] [boot/] [video.S] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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