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

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