root/arch/i386/boot/video.S

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

/* [previous][next][first][last][top][bottom][index][help] */