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

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