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

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