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

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