root/arch/i386/boot/video.S

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

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