root/arch/i386/boot/setup.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 !
   2 !       setup.S         Copyright (C) 1991, 1992 Linus Torvalds
   3 !
   4 ! setup.s is responsible for getting the system data from the BIOS,
   5 ! and putting them into the appropriate places in system memory.
   6 ! both setup.s and system has been loaded by the bootblock.
   7 !
   8 ! This code asks the bios for memory/disk/other parameters, and
   9 ! puts them in a "safe" place: 0x90000-0x901FF, ie where the
  10 ! boot-block used to be. It is then up to the protected mode
  11 ! system to read them from there before the area is overwritten
  12 ! for buffer-blocks.
  13 !
  14 ! Move PS/2 aux init code to psaux.c
  15 ! (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
  16 !
  17 ! some changes and additional features by Christoph Niemann,
  18 ! March 1993/June 1994 (Christoph.Niemann@linux.org)
  19 !
  20 
  21 ! NOTE! These had better be the same as in bootsect.s!
  22 #include <linux/config.h>
  23 #include <linux/segment.h>
  24 
  25 #ifndef SVGA_MODE
  26 #define SVGA_MODE ASK_VGA
  27 #endif
  28 
  29 ! Signature words to ensure LILO loaded us right
  30 #define SIG1    0xAA55
  31 #define SIG2    0x5A5A
  32 
  33 INITSEG  = DEF_INITSEG  ! we move boot here - out of the way
  34 SYSSEG   = DEF_SYSSEG   ! system loaded at 0x10000 (65536).
  35 SETUPSEG = DEF_SETUPSEG ! this is the current segment
  36 
  37 .globl begtext, begdata, begbss, endtext, enddata, endbss
  38 .text
  39 begtext:
  40 .data
  41 begdata:
  42 .bss
  43 begbss:
  44 .text
  45 
  46 entry start
  47 start:
  48 ! Check signature at end of setup
  49         mov     ax,#SETUPSEG
  50         mov     ds,ax
  51         cmp     setup_sig1,#SIG1
  52         jne     bad_sig
  53         cmp     setup_sig2,#SIG2
  54         jne     bad_sig
  55         jmp     good_sig1
  56 
  57 ! Routine to print asciiz-string at DS:SI
  58 
  59 prtstr: lodsb
  60         and     al,al
  61         jz      fin
  62         call    prnt1
  63         jmp     prtstr
  64 fin:    ret
  65 
  66 ! Part of above routine, this one just prints ascii al
  67 
  68 prnt1:  push    ax
  69         push    cx
  70         xor     bh,bh
  71         mov     cx,#0x01
  72         mov     ah,#0x0e
  73         int     0x10
  74         pop     cx
  75         pop     ax
  76         ret
  77 
  78 beep:   mov     al,#0x07
  79         jmp     prnt1
  80         
  81 no_sig_mess:    .ascii  "No setup signature found ..."
  82                 db      0x00
  83 start_sys_seg:  .word   SYSSEG
  84 
  85 good_sig1:
  86         jmp     good_sig
  87 
  88 ! We now have to find the rest of the setup code/data
  89 bad_sig:
  90         mov     ax,#INITSEG
  91         mov     ds,ax
  92         xor     bh,bh
  93         mov     bl,[497]        ! get setup sects from boot sector
  94         sub     bx,#4           ! LILO loads 4 sectors of setup
  95         shl     bx,#8           ! convert to words
  96         mov     cx,bx
  97         shr     bx,#3           ! convert to segment
  98         add     bx,#SYSSEG
  99         seg cs
 100         mov     start_sys_seg,bx
 101 
 102 ! Move rest of setup code/data to here
 103         mov     di,#2048        ! four sectors loaded by LILO
 104         sub     si,si
 105         mov     ax,#SETUPSEG
 106         mov     es,ax
 107         mov     ax,#SYSSEG
 108         mov     ds,ax
 109         rep
 110         movsw
 111 
 112         mov     ax,#SETUPSEG
 113         mov     ds,ax
 114         cmp     setup_sig1,#SIG1
 115         jne     no_sig
 116         cmp     setup_sig2,#SIG2
 117         jne     no_sig
 118         jmp     good_sig
 119 
 120 no_sig:
 121         lea     si,no_sig_mess
 122         call    prtstr
 123 no_sig_loop:
 124         jmp     no_sig_loop
 125 
 126 good_sig:
 127         mov     ax,#INITSEG
 128         mov     ds,ax
 129 
 130 ! Get memory size (extended mem, kB)
 131 
 132         mov     ah,#0x88
 133         int     0x15
 134         mov     [2],ax
 135 
 136 ! set the keyboard repeat rate to the max
 137 
 138         mov     ax,#0x0305
 139         xor     bx,bx           ! clear bx
 140         int     0x16
 141 
 142 ! check for EGA/VGA and some config parameters
 143 
 144         mov     ah,#0x12
 145         mov     bl,#0x10
 146         int     0x10
 147         mov     [8],ax
 148         mov     [10],bx
 149         mov     [12],cx
 150         mov     ax,#0x5019
 151         cmp     bl,#0x10
 152         je      novga
 153         mov     ax,#0x1a00      ! Added check for EGA/VGA discrimination
 154         int     0x10
 155         mov     bx,ax
 156         mov     ax,#0x5019
 157         cmp     bl,#0x1a        ! 1a means VGA, anything else EGA or lower
 158         jne     novga   
 159         call    chsvga
 160 novga:  mov     [14],ax
 161         mov     ah,#0x03        ! read cursor pos
 162         xor     bh,bh           ! clear bh
 163         int     0x10            ! save it in known place, con_init fetches
 164         mov     [0],dx          ! it from 0x90000.
 165         
 166 ! Get video-card data:
 167         
 168         mov     ah,#0x0f
 169         int     0x10
 170         mov     [4],bx          ! bh = display page
 171         mov     [6],ax          ! al = video mode, ah = window width
 172 
 173 ! Get hd0 data
 174 
 175         xor     ax,ax           ! clear ax
 176         mov     ds,ax
 177         lds     si,[4*0x41]
 178         mov     ax,#INITSEG
 179         push    ax
 180         mov     es,ax
 181         mov     di,#0x0080
 182         mov     cx,#0x10
 183         push    cx
 184         cld
 185         rep
 186         movsb
 187 
 188 ! Get hd1 data
 189 
 190         xor     ax,ax           ! clear ax
 191         mov     ds,ax
 192         lds     si,[4*0x46]
 193         pop     cx
 194         pop     es
 195         mov     di,#0x0090
 196         rep
 197         movsb
 198 
 199 ! Check that there IS a hd1 :-)
 200 
 201         mov     ax,#0x01500
 202         mov     dl,#0x81
 203         int     0x13
 204         jc      no_disk1
 205         cmp     ah,#3
 206         je      is_disk1
 207 no_disk1:
 208         mov     ax,#INITSEG
 209         mov     es,ax
 210         mov     di,#0x0090
 211         mov     cx,#0x10
 212         xor     ax,ax           ! clear ax
 213         cld
 214         rep
 215         stosb
 216 is_disk1:
 217 
 218 ! check for PS/2 pointing device
 219 
 220         mov     ax,#INITSEG
 221         mov     ds,ax
 222         mov     [0x1ff],#0      ! default is no pointing device
 223         int     0x11            ! int 0x11: equipment determination
 224         test    al,#0x04        ! check if pointing device installed
 225         jz      no_psmouse
 226         mov     [0x1ff],#0xaa   ! device present
 227 no_psmouse:
 228 ! now we want to move to protected mode ...
 229 
 230         cli                     ! no interrupts allowed !
 231         mov     al,#0x80        ! disable NMI for the bootup sequence
 232         out     #0x70,al
 233 
 234 ! first we move the system to its rightful place
 235 
 236         mov     ax,#0x100       ! start of destination segment
 237         seg cs
 238         mov     bx,start_sys_seg        ! start of source segment
 239         cld                     ! 'direction'=0, movs moves forward
 240 do_move:
 241         mov     es,ax           ! destination segment
 242         inc     ah              ! instead of add ax,#0x100
 243         cmp     ax,#0x9000
 244         jz      end_move
 245         mov     ds,bx           ! source segment
 246         add     bx,#0x100
 247         sub     di,di
 248         sub     si,si
 249         mov     cx,#0x800
 250         rep
 251         movsw
 252         jmp     do_move
 253 
 254 ! then we load the segment descriptors
 255 
 256 end_move:
 257         mov     ax,#SETUPSEG    ! right, forgot this at first. didn't work :-)
 258         mov     ds,ax
 259         lidt    idt_48          ! load idt with 0,0
 260         lgdt    gdt_48          ! load gdt with whatever appropriate
 261 
 262 ! that was painless, now we enable A20
 263 
 264         call    empty_8042
 265         mov     al,#0xD1                ! command write
 266         out     #0x64,al
 267         call    empty_8042
 268         mov     al,#0xDF                ! A20 on
 269         out     #0x60,al
 270         call    empty_8042
 271 
 272 ! make sure any possible coprocessor is properly reset..
 273 
 274         xor     ax,ax
 275         out     #0xf0,al
 276         call    delay
 277         out     #0xf1,al
 278         call    delay
 279 
 280 ! well, that went ok, I hope. Now we have to reprogram the interrupts :-(
 281 ! we put them right after the intel-reserved hardware interrupts, at
 282 ! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
 283 ! messed this up with the original PC, and they haven't been able to
 284 ! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
 285 ! which is used for the internal hardware interrupts as well. We just
 286 ! have to reprogram the 8259's, and it isn't fun.
 287 
 288         mov     al,#0x11                ! initialization sequence
 289         out     #0x20,al                ! send it to 8259A-1
 290         call    delay
 291         out     #0xA0,al                ! and to 8259A-2
 292         call    delay
 293         mov     al,#0x20                ! start of hardware int's (0x20)
 294         out     #0x21,al
 295         call    delay
 296         mov     al,#0x28                ! start of hardware int's 2 (0x28)
 297         out     #0xA1,al
 298         call    delay
 299         mov     al,#0x04                ! 8259-1 is master
 300         out     #0x21,al
 301         call    delay
 302         mov     al,#0x02                ! 8259-2 is slave
 303         out     #0xA1,al
 304         call    delay
 305         mov     al,#0x01                ! 8086 mode for both
 306         out     #0x21,al
 307         call    delay
 308         out     #0xA1,al
 309         call    delay
 310         mov     al,#0xFF                ! mask off all interrupts for now
 311         out     #0xA1,al
 312         call    delay
 313         mov     al,#0xFB                ! mask all irq's but irq2 which
 314         out     #0x21,al                ! is cascaded
 315 
 316 ! well, that certainly wasn't fun :-(. Hopefully it works, and we don't
 317 ! need no steenking BIOS anyway (except for the initial loading :-).
 318 ! The BIOS-routine wants lots of unnecessary data, and it's less
 319 ! "interesting" anyway. This is how REAL programmers do it.
 320 !
 321 ! Well, now's the time to actually move into protected mode. To make
 322 ! things as simple as possible, we do no register set-up or anything,
 323 ! we let the gnu-compiled 32-bit programs do that. We just jump to
 324 ! absolute address 0x00000, in 32-bit protected mode.
 325 !
 326 ! Note that the short jump isn't strictly needed, although there are
 327 ! reasons why it might be a good idea. It won't hurt in any case.
 328 !
 329         xor     ax,ax
 330         inc     ax              ! protected mode (PE) bit
 331         lmsw    ax              ! This is it!
 332         jmp     flush_instr
 333 flush_instr:
 334         jmpi    0x1000,KERNEL_CS        ! jmp offset 1000 of segment 0x10 (cs)
 335 
 336 ! This routine checks that the keyboard command queue is empty
 337 ! (after emptying the output buffers)
 338 !
 339 ! No timeout is used - if this hangs there is something wrong with
 340 ! the machine, and we probably couldn't proceed anyway.
 341 empty_8042:
 342         call    delay
 343         in      al,#0x64        ! 8042 status port
 344         test    al,#1           ! output buffer?
 345         jz      no_output
 346         call    delay
 347         in      al,#0x60        ! read it
 348         jmp     empty_8042
 349 no_output:
 350         test    al,#2           ! is input buffer full?
 351         jnz     empty_8042      ! yes - loop
 352         ret
 353 !
 354 ! Read a key and return the (US-)ascii code in al, scan code in ah
 355 !
 356 getkey:
 357         xor     ah,ah
 358         int     0x16
 359         ret
 360 
 361 !
 362 ! Read a key with a timeout of 30 seconds. The cmos clock is used to get
 363 ! the time.
 364 !
 365 getkt:
 366         call    gettime
 367         add     al,#30          ! wait 30 seconds
 368         cmp     al,#60
 369         jl      lminute
 370         sub     al,#60
 371 lminute:
 372         mov     cl,al
 373 again:  mov     ah,#0x01
 374         int     0x16
 375         jnz     getkey          ! key pressed, so get it
 376         call    gettime
 377         cmp     al,cl
 378         jne     again
 379         mov     al,#0x20        ! timeout, return default char `space'
 380         ret
 381 
 382 !
 383 ! Flush the keyboard buffer
 384 !
 385 flush:  mov     ah,#0x01
 386         int     0x16
 387         jz      empty
 388         xor     ah,ah
 389         int     0x16
 390         jmp     flush
 391 empty:  ret
 392 
 393 !
 394 ! Read the cmos clock. Return the seconds in al
 395 !
 396 gettime:
 397         push    cx
 398         mov     ah,#0x02
 399         int     0x1a
 400         mov     al,dh                   ! dh contains the seconds
 401         and     al,#0x0f
 402         mov     ah,dh
 403         mov     cl,#0x04
 404         shr     ah,cl
 405         aad
 406         pop     cx
 407         ret
 408 
 409 !
 410 ! Delay is needed after doing i/o
 411 !
 412 delay:
 413         .word   0x00eb                  ! jmp $+2
 414         ret
 415 
 416 ! Routine trying to recognize type of SVGA-board present (if any)
 417 ! and if it recognize one gives the choices of resolution it offers.
 418 ! If one is found the resolution chosen is given by al,ah (rows,cols).
 419 
 420 chsvga: cld
 421         push    ds
 422         push    cs
 423         mov     ax,[0x01fa]
 424         pop     ds
 425         mov     modesave,ax
 426         mov     ax,#0xc000
 427         mov     es,ax
 428         mov     ax,modesave
 429         cmp     ax,#NORMAL_VGA
 430         je      defvga
 431         cmp     ax,#EXTENDED_VGA
 432         je      vga50
 433         cmp     ax,#ASK_VGA
 434         jne     svga
 435         lea     si,msg1
 436         call    prtstr
 437         call    flush
 438 nokey:  call    getkt
 439         cmp     al,#0x0d                ! enter ?
 440         je      svga                    ! yes - svga selection
 441         cmp     al,#0x20                ! space ?
 442         je      defvga                  ! no - repeat
 443         call    beep
 444         jmp     nokey
 445 defvga: mov     ax,#0x5019
 446         pop     ds
 447         ret
 448 /* extended vga mode: 80x50 */
 449 vga50:
 450         mov     ax,#0x1112
 451         xor     bl,bl
 452         int     0x10            ! use 8x8 font set (50 lines on VGA)
 453         mov     ax,#0x1200
 454         mov     bl,#0x20
 455         int     0x10            ! use alternate print screen
 456         mov     ax,#0x1201
 457         mov     bl,#0x34
 458         int     0x10            ! turn off cursor emulation
 459         mov     ah,#0x01
 460         mov     cx,#0x0607
 461         int     0x10            ! turn on cursor (scan lines 6 to 7)
 462         pop     ds
 463         mov     ax,#0x5032      ! return 80x50
 464         ret
 465 /* extended vga mode: 80x28 */
 466 vga28:
 467         pop     ax              ! clean the stack
 468         mov     ax,#0x1111
 469         xor     bl,bl
 470         int     0x10            ! use 9x14 fontset (28 lines on VGA)
 471         mov     ah, #0x01
 472         mov     cx,#0x0b0c
 473         int     0x10            ! turn on cursor (scan lines 11 to 12)
 474         pop     ds
 475         mov     ax,#0x501c      ! return 80x28
 476         ret
 477 /* svga modes */
 478 !
 479 !       test for presence of an S3 VGA chip. The algorithm was taken
 480 !       from the SuperProbe package of XFree86 1.2.1
 481 !       report bugs to Christoph.Niemann@linux.org
 482 !
 483 svga:   cld
 484         mov     cx,#0x0f35      ! we store some constants in cl/ch
 485         mov     dx,#0x03d4
 486         movb    al,#0x38
 487         call    inidx
 488         mov     bh,al           ! store current value of CRT-register 0x38
 489         mov     ax,#0x0038
 490         call    outidx          ! disable writing to special regs
 491         movb    al,cl           ! check whether we can write special reg 0x35
 492         call    inidx
 493         movb    bl,al           ! save the current value of CRT reg 0x35
 494         andb    al,#0xf0        ! clear bits 0-3
 495         movb    ah,al
 496         movb    al,cl           ! and write it to CRT reg 0x35
 497         call    outidx
 498         call    inidx           ! now read it back
 499         andb    al,ch           ! clear the upper 4 bits
 500         jz      s3_2            ! the first test failed. But we have a
 501         movb    ah,bl           ! second chance
 502         mov     al,cl
 503         call    outidx
 504         jmp     s3_1            ! do the other tests
 505 s3_2:   mov     ax,cx           ! load ah with 0xf and al with 0x35
 506         orb     ah,bl           ! set the upper 4 bits of ah with the orig value
 507         call    outidx          ! write ...
 508         call    inidx           ! ... and reread 
 509         andb    al,cl           ! turn off the upper 4 bits
 510         push    ax
 511         movb    ah,bl           ! restore old value in register 0x35
 512         movb    al,cl
 513         call    outidx
 514         pop     ax
 515         cmp     al,ch           ! setting lower 4 bits was successful => bad
 516         je      no_s3           ! writing is allowed => this is not an S3
 517 s3_1:   mov     ax,#0x4838      ! allow writing to special regs by putting
 518         call    outidx          ! magic number into CRT-register 0x38
 519         movb    al,cl           ! check whether we can write special reg 0x35
 520         call    inidx
 521         movb    bl,al
 522         andb    al,#0xf0
 523         movb    ah,al
 524         movb    al,cl
 525         call    outidx
 526         call    inidx
 527         andb    al,ch
 528         jnz     no_s3           ! no, we can't write => no S3
 529         mov     ax,cx
 530         orb     ah,bl
 531         call    outidx
 532         call    inidx
 533         andb    al,ch
 534         push    ax
 535         movb    ah,bl           ! restore old value in register 0x35
 536         movb    al,cl
 537         call    outidx
 538         pop     ax
 539         cmp     al,ch
 540         jne     no_s31          ! writing not possible => no S3
 541         movb    al,#0x30
 542         call    inidx           ! now get the S3 id ...
 543         lea     di,idS3
 544         mov     cx,#0x10
 545         repne
 546         scasb
 547         je      no_s31
 548         lea     si,dsc_S3       ! table of descriptions of video modes for BIOS
 549         lea     di,mo_S3        ! table of sizes of video modes for my BIOS
 550         movb    ah,bh
 551         movb    al,#0x38
 552         call    outidx          ! restore old value of CRT register 0x38
 553         br      selmod          ! go ask for video mode
 554 no_s3:  movb    al,#0x35        ! restore CRT register 0x35
 555         movb    ah,bl
 556         call    outidx
 557 no_s31: movb    ah,bh
 558         movb    al,#0x38
 559         call    outidx          ! restore old value of CRT register 0x38
 560 
 561         lea     si,idati                ! Check ATI 'clues'
 562         mov     di,#0x31
 563         mov     cx,#0x09
 564         repe
 565         cmpsb
 566         jne     noati
 567         lea     si,dscati
 568         lea     di,moati
 569         br      selmod
 570 noati:  mov     ax,#0x200f              ! Check Ahead 'clues'
 571         mov     dx,#0x3ce
 572         out     dx,ax
 573         inc     dx
 574         in      al,dx
 575         cmp     al,#0x20
 576         je      isahed
 577         cmp     al,#0x21
 578         jne     noahed
 579 isahed: lea     si,dscahead
 580         lea     di,moahead
 581         br      selmod
 582 noahed: mov     dx,#0x3c3               ! Check Chips & Tech. 'clues'
 583         in      al,dx
 584         or      al,#0x10
 585         out     dx,al
 586         mov     dx,#0x104               
 587         in      al,dx
 588         mov     bl,al
 589         mov     dx,#0x3c3
 590         in      al,dx
 591         and     al,#0xef
 592         out     dx,al
 593         cmp     bl,[idcandt]
 594         jne     nocant
 595         lea     si,dsccandt
 596         lea     di,mocandt
 597         br      selmod
 598 nocant: mov     dx,#0x3d4               ! Check Cirrus 'clues'
 599         mov     al,#0x0c
 600         out     dx,al
 601         inc     dx
 602         in      al,dx
 603         mov     bl,al
 604         xor     al,al
 605         out     dx,al
 606         dec     dx
 607         mov     al,#0x1f
 608         out     dx,al
 609         inc     dx
 610         in      al,dx
 611         mov     bh,al
 612         xor     ah,ah
 613         shl     al,#4
 614         mov     cx,ax
 615         mov     al,bh
 616         shr     al,#4
 617         add     cx,ax
 618         shl     cx,#8
 619         add     cx,#6
 620         mov     ax,cx
 621         mov     dx,#0x3c4
 622         out     dx,ax
 623         inc     dx
 624         in      al,dx
 625         and     al,al
 626         jnz     nocirr
 627         mov     al,bh
 628         out     dx,al
 629         in      al,dx
 630         cmp     al,#0x01
 631         jne     nocirr
 632         call    rst3d4  
 633         lea     si,dsccirrus
 634         lea     di,mocirrus
 635         br      selmod
 636 rst3d4: mov     dx,#0x3d4
 637         mov     al,bl
 638         xor     ah,ah
 639         shl     ax,#8
 640         add     ax,#0x0c
 641         out     dx,ax
 642         ret     
 643 nocirr: call    rst3d4                  ! Check Everex 'clues'
 644         mov     ax,#0x7000
 645         xor     bx,bx
 646         int     0x10
 647         cmp     al,#0x70
 648         jne     noevrx
 649         shr     dx,#4
 650         cmp     dx,#0x678
 651         je      istrid
 652         cmp     dx,#0x236
 653         je      istrid
 654         lea     si,dsceverex
 655         lea     di,moeverex
 656         br      selmod
 657 istrid: lea     cx,ev2tri
 658         jmp     cx
 659 noevrx: lea     si,idgenoa              ! Check Genoa 'clues'
 660         xor     ax,ax
 661         seg es
 662         mov     al,[0x37]
 663         mov     di,ax
 664         mov     cx,#0x04
 665         dec     si
 666         dec     di
 667 l1:     inc     si
 668         inc     di
 669         mov     al,(si)
 670         test    al,al
 671         jz      l2
 672         seg es
 673         cmp     al,(di)
 674 l2:     loope   l1
 675         cmp     cx,#0x00
 676         jne     nogen
 677         lea     si,dscgenoa
 678         lea     di,mogenoa
 679         br      selmod
 680 nogen:  cld
 681         lea     si,idoakvga
 682         mov     di,#0x08
 683         mov     cx,#0x08
 684         repe
 685         cmpsb
 686         jne     nooak
 687         lea     si,dscoakvga
 688         lea     di,mooakvga
 689         br      selmod
 690 nooak:  cld
 691         lea     si,idparadise           ! Check Paradise 'clues'
 692         mov     di,#0x7d
 693         mov     cx,#0x04
 694         repe
 695         cmpsb
 696         jne     nopara
 697         lea     si,dscparadise
 698         lea     di,moparadise
 699         br      selmod
 700 nopara: mov     dx,#0x3c4               ! Check Trident 'clues'
 701         mov     al,#0x0e
 702         out     dx,al
 703         inc     dx
 704         in      al,dx
 705         xchg    ah,al
 706         xor     al,al
 707         out     dx,al
 708         in      al,dx
 709         xchg    al,ah
 710         mov     bl,al           ! Strange thing ... in the book this wasn't
 711         and     bl,#0x02        ! necessary but it worked on my card which
 712         jz      setb2           ! is a trident. Without it the screen goes
 713         and     al,#0xfd        ! blurred ...
 714         jmp     clrb2           !
 715 setb2:  or      al,#0x02        !
 716 clrb2:  out     dx,al
 717         and     ah,#0x0f
 718         cmp     ah,#0x02
 719         jne     notrid
 720 ev2tri: lea     si,dsctrident
 721         lea     di,motrident
 722         jmp     selmod
 723 notrid: mov     dx,#0x3cd               ! Check Tseng 'clues'
 724         in      al,dx                   ! Could things be this simple ! :-)
 725         mov     bl,al
 726         mov     al,#0x55
 727         out     dx,al
 728         in      al,dx
 729         mov     ah,al
 730         mov     al,bl
 731         out     dx,al
 732         cmp     ah,#0x55
 733         jne     notsen
 734         lea     si,dsctseng
 735         lea     di,motseng
 736         jmp     selmod
 737 notsen: mov     dx,#0x3cc               ! Check Video7 'clues'
 738         in      al,dx
 739         mov     dx,#0x3b4
 740         and     al,#0x01
 741         jz      even7
 742         mov     dx,#0x3d4
 743 even7:  mov     al,#0x0c
 744         out     dx,al
 745         inc     dx
 746         in      al,dx
 747         mov     bl,al
 748         mov     al,#0x55
 749         out     dx,al
 750         in      al,dx
 751         dec     dx
 752         mov     al,#0x1f
 753         out     dx,al
 754         inc     dx
 755         in      al,dx
 756         mov     bh,al
 757         dec     dx
 758         mov     al,#0x0c
 759         out     dx,al
 760         inc     dx
 761         mov     al,bl
 762         out     dx,al
 763         mov     al,#0x55
 764         xor     al,#0xea
 765         cmp     al,bh
 766         jne     novid7
 767         lea     si,dscvideo7
 768         lea     di,movideo7
 769         jmp     selmod
 770 novid7: lea     si,dsunknown
 771         lea     di,mounknown
 772 selmod: xor     cx,cx
 773         mov     cl,(di)
 774         mov     ax,modesave
 775         cmp     ax,#ASK_VGA
 776         je      askmod
 777         cmp     ax,#NORMAL_VGA
 778         je      askmod
 779         cmp     al,cl
 780         jl      gotmode
 781         push    si
 782         lea     si,msg4
 783         call    prtstr
 784         pop     si
 785 askmod: push    si
 786         lea     si,msg2
 787         call    prtstr
 788         pop     si
 789         push    si
 790         push    cx
 791 tbl:    pop     bx
 792         push    bx
 793         mov     al,bl
 794         sub     al,cl
 795         call    modepr
 796         lodsw
 797         xchg    al,ah
 798         call    dprnt
 799         xchg    ah,al
 800         push    ax
 801         mov     al,#0x78
 802         call    prnt1
 803         pop     ax
 804         call    dprnt
 805         push    si
 806         lea     si,crlf         ! print CR+LF
 807         call    prtstr
 808         pop     si
 809         loop    tbl
 810         pop     cx
 811         lea     si,msg3
 812         call    prtstr
 813         pop     si
 814         add     cl,#0x30
 815         jmp     nonum
 816 nonumb: call    beep
 817 nonum:  call    getkey
 818         cmp     al,#0x30        ! ascii `0'
 819         jb      nonumb
 820         cmp     al,#0x3a        ! ascii `9'
 821         jbe     number
 822         cmp     al,#0x61        ! ascii `a'
 823         jb      nonumb
 824         cmp     al,#0x7a        ! ascii `z'
 825         ja      nonumb
 826         sub     al,#0x27
 827         cmp     al,cl
 828         jae     nonumb
 829         sub     al,#0x30
 830         jmp     gotmode
 831 number: cmp     al,cl
 832         jae     nonumb
 833         sub     al,#0x30
 834 gotmode:        xor     ah,ah
 835         or      al,al
 836         beq     vga50
 837         push    ax
 838         dec     ax
 839         beq     vga28
 840         add     di,ax
 841         mov     al,(di)
 842         int     0x10
 843         pop     ax
 844         shl     ax,#1
 845         add     si,ax
 846         lodsw
 847         pop     ds
 848         ret
 849 
 850 ! Routine to write al into a VGA-register that is
 851 ! accessed via an index register
 852 !
 853 ! dx contains the address of the index register
 854 ! al contains the index
 855 ! ah contains the value to write to the data register (dx + 1)
 856 !
 857 ! no registers are changed
 858 
 859 outidx: out     dx,al
 860         push    ax
 861         mov     al,ah
 862         inc     dx
 863         out     dx,al
 864         dec     dx
 865         pop     ax
 866         ret
 867 inidx:  out     dx,al
 868         inc     dx
 869         in      al,dx
 870         dec     dx
 871         ret
 872 
 873 ! Routine to print a decimal value on screen, the value to be
 874 ! printed is put in al (i.e 0-255). 
 875 
 876 dprnt:  push    ax
 877         push    cx
 878         xor     ah,ah           ! Clear ah
 879         mov     cl,#0x0a
 880         idiv    cl
 881         cmp     al,#0x09
 882         jbe     lt100
 883         call    dprnt
 884         jmp     skip10
 885 lt100:  add     al,#0x30
 886         call    prnt1
 887 skip10: mov     al,ah
 888         add     al,#0x30
 889         call    prnt1   
 890         pop     cx
 891         pop     ax
 892         ret
 893 
 894 !
 895 ! Routine to print the mode number key on screen. Mode numbers
 896 ! 0-9 print the ascii values `0' to '9', 10-35 are represented by
 897 ! the letters `a' to `z'. This routine prints some spaces around the
 898 ! mode no.
 899 !
 900 
 901 modepr: push    ax
 902         cmp     al,#0x0a
 903         jb      digit           ! Here is no check for number > 35
 904         add     al,#0x27
 905 digit:  add     al,#0x30
 906         mov     modenr, al
 907         push    si
 908         lea     si, modestring
 909         call    prtstr
 910         pop     si
 911         pop     ax
 912         ret
 913 
 914 gdt:
 915         .word   0,0,0,0         ! dummy
 916 
 917         .word   0,0,0,0         ! unused
 918 
 919         .word   0x07FF          ! 8Mb - limit=2047 (2048*4096=8Mb)
 920         .word   0x0000          ! base address=0
 921         .word   0x9A00          ! code read/exec
 922         .word   0x00C0          ! granularity=4096, 386
 923 
 924         .word   0x07FF          ! 8Mb - limit=2047 (2048*4096=8Mb)
 925         .word   0x0000          ! base address=0
 926         .word   0x9200          ! data read/write
 927         .word   0x00C0          ! granularity=4096, 386
 928 
 929 idt_48:
 930         .word   0                       ! idt limit=0
 931         .word   0,0                     ! idt base=0L
 932 
 933 gdt_48:
 934         .word   0x800           ! gdt limit=2048, 256 GDT entries
 935         .word   512+gdt,0x9     ! gdt base = 0X9xxxx
 936 
 937 msg1:           .ascii  "Press <RETURN> to see SVGA-modes available, <SPACE> to continue or wait 30 secs."
 938                 db      0x0d, 0x0a, 0x0a, 0x00
 939 msg2:           .ascii  "Mode:  COLSxROWS:"
 940                 db      0x0d, 0x0a, 0x0a, 0x00
 941 msg3:           db      0x0d, 0x0a
 942                 .ascii  "Choose mode by pressing the corresponding number or letter."
 943 crlf:           db      0x0d, 0x0a, 0x00
 944 msg4:           .ascii  "You passed an undefined mode number to setup. Please choose a new mode."
 945                 db      0x0d, 0x0a, 0x0a, 0x07, 0x00
 946 modestring:     .ascii  "   "
 947 modenr:         db      0x00    ! mode number
 948                 .ascii  ":    "
 949                 db      0x00
 950                 
 951 idati:          .ascii  "761295520"
 952 idcandt:        .byte   0xa5
 953 idgenoa:        .byte   0x77, 0x00, 0x99, 0x66
 954 idparadise:     .ascii  "VGA="
 955 idoakvga:       .ascii  "OAK VGA "
 956 idS3:           .byte   0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
 957                 .byte   0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
 958 
 959 ! Manufacturer:   Numofmodes+2: Mode:
 960 ! Number of modes is the number of chip-specific svga modes plus the extended
 961 ! modes available on any vga (currently 2)
 962 
 963 moati:          .byte   0x06,   0x23, 0x33, 0x22, 0x21
 964 moahead:        .byte   0x07,   0x22, 0x23, 0x24, 0x2f, 0x34
 965 mocandt:        .byte   0x04,   0x60, 0x61
 966 mocirrus:       .byte   0x06,   0x1f, 0x20, 0x22, 0x31
 967 moeverex:       .byte   0x0c,   0x03, 0x04, 0x07, 0x08, 0x0a, 0x0b, 0x16, 0x18, 0x21, 0x40
 968 mogenoa:        .byte   0x0c,   0x58, 0x5a, 0x60, 0x61, 0x62, 0x63, 0x64, 0x72, 0x74, 0x78
 969 moparadise:     .byte   0x04,   0x55, 0x54
 970 motrident:      .byte   0x09,   0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a
 971 motseng:        .byte   0x07,   0x26, 0x2a, 0x23, 0x24, 0x22
 972 movideo7:       .byte   0x08,   0x40, 0x43, 0x44, 0x41, 0x42, 0x45
 973 mooakvga:       .byte   0x08,   0x00, 0x07, 0x4e, 0x4f, 0x50, 0x51
 974 mo_S3:          .byte   0x04,   0x54, 0x55
 975 mounknown:      .byte   0x02
 976 
 977 !                       msb = Cols lsb = Rows:
 978 ! The first two modes are standard vga modes available on any vga.
 979 ! mode 0 is 80x50 and mode 1 is 80x28
 980 
 981 dscati:         .word   0x5032, 0x501c, 0x8419, 0x842c, 0x641e, 0x6419
 982 dscahead:       .word   0x5032, 0x501c, 0x842c, 0x8419, 0x841c, 0xa032, 0x5042
 983 dsccandt:       .word   0x5032, 0x501c, 0x8419, 0x8432
 984 dsccirrus:      .word   0x5032, 0x501c, 0x8419, 0x842c, 0x841e, 0x6425
 985 dsceverex:      .word   0x5032, 0x501c, 0x5022, 0x503c, 0x642b, 0x644b, 0x8419, 0x842c, 0x501e, 0x641b, 0xa040, 0x841e
 986 dscgenoa:       .word   0x5032, 0x501c, 0x5020, 0x642a, 0x8419, 0x841d, 0x8420, 0x842c, 0x843c, 0x503c, 0x5042, 0x644b
 987 dscparadise:    .word   0x5032, 0x501c, 0x8419, 0x842c
 988 dsctrident:     .word   0x5032, 0x501c, 0x501e, 0x502b, 0x503c, 0x8419, 0x841e, 0x842b, 0x843c
 989 dsctseng:       .word   0x5032, 0x501c, 0x503c, 0x6428, 0x8419, 0x841c, 0x842c
 990 dscvideo7:      .word   0x5032, 0x501c, 0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c
 991 dscoakvga:      .word   0x5032, 0x501c, 0x2819, 0x5019, 0x503c, 0x843c, 0x8419, 0x842b
 992 dsc_S3:         .word   0x5032, 0x501c, 0x842b, 0x8419
 993 dsunknown:      .word   0x5032, 0x501c
 994 modesave:       .word   SVGA_MODE
 995 
 996 ! This must be last
 997 setup_sig1:     .word   SIG1
 998 setup_sig2:     .word   SIG2
 999 
1000 .text
1001 endtext:
1002 .data
1003 enddata:
1004 .bss
1005 endbss:

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