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         jmpi    0x1000,KERNEL_CS        ! jmp offset 1000 of segment 0x10 (cs)
 348 
 349 ! This routine checks that the keyboard command queue is empty
 350 ! (after emptying the output buffers)
 351 !
 352 ! No timeout is used - if this hangs there is something wrong with
 353 ! the machine, and we probably couldn't proceed anyway.
 354 empty_8042:
 355         call    delay
 356         in      al,#0x64        ! 8042 status port
 357         test    al,#1           ! output buffer?
 358         jz      no_output
 359         call    delay
 360         in      al,#0x60        ! read it
 361         jmp     empty_8042
 362 no_output:
 363         test    al,#2           ! is input buffer full?
 364         jnz     empty_8042      ! yes - loop
 365         ret
 366 !
 367 ! Read a key and return the (US-)ascii code in al, scan code in ah
 368 !
 369 getkey:
 370         xor     ah,ah
 371         int     0x16
 372         ret
 373 
 374 !
 375 ! Read a key with a timeout of 30 seconds. The cmos clock is used to get
 376 ! the time.
 377 !
 378 getkt:
 379         call    gettime
 380         add     al,#30          ! wait 30 seconds
 381         cmp     al,#60
 382         jl      lminute
 383         sub     al,#60
 384 lminute:
 385         mov     cl,al
 386 again:  mov     ah,#0x01
 387         int     0x16
 388         jnz     getkey          ! key pressed, so get it
 389         call    gettime
 390         cmp     al,cl
 391         jne     again
 392         mov     al,#0x20        ! timeout, return default char `space'
 393         ret
 394 
 395 !
 396 ! Flush the keyboard buffer
 397 !
 398 flush:  mov     ah,#0x01
 399         int     0x16
 400         jz      empty
 401         xor     ah,ah
 402         int     0x16
 403         jmp     flush
 404 empty:  ret
 405 
 406 !
 407 ! Read the cmos clock. Return the seconds in al
 408 !
 409 gettime:
 410         push    cx
 411         mov     ah,#0x02
 412         int     0x1a
 413         mov     al,dh                   ! dh contains the seconds
 414         and     al,#0x0f
 415         mov     ah,dh
 416         mov     cl,#0x04
 417         shr     ah,cl
 418         aad
 419         pop     cx
 420         ret
 421 
 422 !
 423 ! Delay is needed after doing i/o
 424 !
 425 delay:
 426         .word   0x00eb                  ! jmp $+2
 427         ret
 428 
 429 ! Routine trying to recognize type of SVGA-board present (if any)
 430 ! and if it recognize one gives the choices of resolution it offers.
 431 ! If one is found the resolution chosen is given by al,ah (rows,cols).
 432 
 433 chsvga: cld
 434         push    ds
 435         push    cs
 436         mov     ax,[0x01fa]
 437         pop     ds
 438         mov     modesave,ax
 439         mov     ax,#0xc000
 440         mov     es,ax
 441         mov     ax,modesave
 442         cmp     ax,#NORMAL_VGA
 443         je      defvga
 444         cmp     ax,#EXTENDED_VGA
 445         je      vga50
 446         cmp     ax,#ASK_VGA
 447         jne     svga
 448         lea     si,msg1
 449         call    prtstr
 450         call    flush
 451 nokey:  call    getkt
 452         cmp     al,#0x0d                ! enter ?
 453         je      svga                    ! yes - svga selection
 454         cmp     al,#0x20                ! space ?
 455         je      defvga                  ! no - repeat
 456         call    beep
 457         jmp     nokey
 458 defvga: mov     ax,#0x5019
 459         pop     ds
 460         ret
 461 /* extended vga mode: 80x50 */
 462 vga50:
 463         mov     ax,#0x1112
 464         xor     bl,bl
 465         int     0x10            ! use 8x8 font set (50 lines on VGA)
 466         mov     ax,#0x1200
 467         mov     bl,#0x20
 468         int     0x10            ! use alternate print screen
 469         mov     ax,#0x1201
 470         mov     bl,#0x34
 471         int     0x10            ! turn off cursor emulation
 472         mov     ah,#0x01
 473         mov     cx,#0x0607
 474         int     0x10            ! turn on cursor (scan lines 6 to 7)
 475         pop     ds
 476         mov     ax,#0x5032      ! return 80x50
 477         ret
 478 /* extended vga mode: 80x28 */
 479 vga28:
 480         pop     ax              ! clean the stack
 481         mov     ax,#0x1111
 482         xor     bl,bl
 483         int     0x10            ! use 9x14 fontset (28 lines on VGA)
 484         mov     ah, #0x01
 485         mov     cx,#0x0b0c
 486         int     0x10            ! turn on cursor (scan lines 11 to 12)
 487         pop     ds
 488         mov     ax,#0x501c      ! return 80x28
 489         ret
 490 /* svga modes */
 491 !
 492 !       test for presence of an S3 VGA chip. The algorithm was taken
 493 !       from the SuperProbe package of XFree86 1.2.1
 494 !       report bugs to Christoph.Niemann@linux.org
 495 !
 496 svga:   cld
 497         mov     cx,#0x0f35      ! we store some constants in cl/ch
 498         mov     dx,#0x03d4
 499         movb    al,#0x38
 500         call    inidx
 501         mov     bh,al           ! store current value of CRT-register 0x38
 502         mov     ax,#0x0038
 503         call    outidx          ! disable writing to special regs
 504         movb    al,cl           ! check whether we can write special reg 0x35
 505         call    inidx
 506         movb    bl,al           ! save the current value of CRT reg 0x35
 507         andb    al,#0xf0        ! clear bits 0-3
 508         movb    ah,al
 509         movb    al,cl           ! and write it to CRT reg 0x35
 510         call    outidx
 511         call    inidx           ! now read it back
 512         andb    al,ch           ! clear the upper 4 bits
 513         jz      s3_2            ! the first test failed. But we have a
 514         movb    ah,bl           ! second chance
 515         mov     al,cl
 516         call    outidx
 517         jmp     s3_1            ! do the other tests
 518 s3_2:   mov     ax,cx           ! load ah with 0xf and al with 0x35
 519         orb     ah,bl           ! set the upper 4 bits of ah with the orig value
 520         call    outidx          ! write ...
 521         call    inidx           ! ... and reread 
 522         andb    al,cl           ! turn off the upper 4 bits
 523         push    ax
 524         movb    ah,bl           ! restore old value in register 0x35
 525         movb    al,cl
 526         call    outidx
 527         pop     ax
 528         cmp     al,ch           ! setting lower 4 bits was successful => bad
 529         je      no_s3           ! writing is allowed => this is not an S3
 530 s3_1:   mov     ax,#0x4838      ! allow writing to special regs by putting
 531         call    outidx          ! magic number into CRT-register 0x38
 532         movb    al,cl           ! check whether we can write special reg 0x35
 533         call    inidx
 534         movb    bl,al
 535         andb    al,#0xf0
 536         movb    ah,al
 537         movb    al,cl
 538         call    outidx
 539         call    inidx
 540         andb    al,ch
 541         jnz     no_s3           ! no, we can't write => no S3
 542         mov     ax,cx
 543         orb     ah,bl
 544         call    outidx
 545         call    inidx
 546         andb    al,ch
 547         push    ax
 548         movb    ah,bl           ! restore old value in register 0x35
 549         movb    al,cl
 550         call    outidx
 551         pop     ax
 552         cmp     al,ch
 553         jne     no_s31          ! writing not possible => no S3
 554         movb    al,#0x30
 555         call    inidx           ! now get the S3 id ...
 556         lea     di,idS3
 557         mov     cx,#0x10
 558         repne
 559         scasb
 560         je      no_s31
 561         lea     si,dsc_S3       ! table of descriptions of video modes for BIOS
 562         lea     di,mo_S3        ! table of sizes of video modes for my BIOS
 563         movb    ah,bh
 564         movb    al,#0x38
 565         call    outidx          ! restore old value of CRT register 0x38
 566         br      selmod          ! go ask for video mode
 567 no_s3:  movb    al,#0x35        ! restore CRT register 0x35
 568         movb    ah,bl
 569         call    outidx
 570 no_s31: movb    ah,bh
 571         movb    al,#0x38
 572         call    outidx          ! restore old value of CRT register 0x38
 573 
 574         lea     si,idati                ! Check ATI 'clues'
 575         mov     di,#0x31
 576         mov     cx,#0x09
 577         repe
 578         cmpsb
 579         jne     noati
 580         lea     si,dscati
 581         lea     di,moati
 582         br      selmod
 583 noati:  mov     ax,#0x200f              ! Check Ahead 'clues'
 584         mov     dx,#0x3ce
 585         out     dx,ax
 586         inc     dx
 587         in      al,dx
 588         cmp     al,#0x20
 589         je      isahed
 590         cmp     al,#0x21
 591         jne     noahed
 592 isahed: lea     si,dscahead
 593         lea     di,moahead
 594         br      selmod
 595 noahed: mov     dx,#0x3c3               ! Check Chips & Tech. 'clues'
 596         in      al,dx
 597         or      al,#0x10
 598         out     dx,al
 599         mov     dx,#0x104               
 600         in      al,dx
 601         mov     bl,al
 602         mov     dx,#0x3c3
 603         in      al,dx
 604         and     al,#0xef
 605         out     dx,al
 606         cmp     bl,[idcandt]
 607         jne     nocant
 608         lea     si,dsccandt
 609         lea     di,mocandt
 610         br      selmod
 611 nocant: mov     dx,#0x3d4               ! Check Cirrus 'clues'
 612         mov     al,#0x0c
 613         out     dx,al
 614         inc     dx
 615         in      al,dx
 616         mov     bl,al
 617         xor     al,al
 618         out     dx,al
 619         dec     dx
 620         mov     al,#0x1f
 621         out     dx,al
 622         inc     dx
 623         in      al,dx
 624         mov     bh,al
 625         xor     ah,ah
 626         shl     al,#4
 627         mov     cx,ax
 628         mov     al,bh
 629         shr     al,#4
 630         add     cx,ax
 631         shl     cx,#8
 632         add     cx,#6
 633         mov     ax,cx
 634         mov     dx,#0x3c4
 635         out     dx,ax
 636         inc     dx
 637         in      al,dx
 638         and     al,al
 639         jnz     nocirr
 640         mov     al,bh
 641         out     dx,al
 642         in      al,dx
 643         cmp     al,#0x01
 644         jne     nocirr
 645         call    rst3d4  
 646         lea     si,dsccirrus
 647         lea     di,mocirrus
 648         br      selmod
 649 rst3d4: mov     dx,#0x3d4
 650         mov     al,bl
 651         xor     ah,ah
 652         shl     ax,#8
 653         add     ax,#0x0c
 654         out     dx,ax
 655         ret     
 656 nocirr: call    rst3d4                  ! Check Everex 'clues'
 657         mov     ax,#0x7000
 658         xor     bx,bx
 659         int     0x10
 660         cmp     al,#0x70
 661         jne     noevrx
 662         shr     dx,#4
 663         cmp     dx,#0x678
 664         je      istrid
 665         cmp     dx,#0x236
 666         je      istrid
 667         lea     si,dsceverex
 668         lea     di,moeverex
 669         br      selmod
 670 istrid: lea     cx,ev2tri
 671         jmp     cx
 672 noevrx: lea     si,idgenoa              ! Check Genoa 'clues'
 673         xor     ax,ax
 674         seg es
 675         mov     al,[0x37]
 676         mov     di,ax
 677         mov     cx,#0x04
 678         dec     si
 679         dec     di
 680 l1:     inc     si
 681         inc     di
 682         mov     al,(si)
 683         test    al,al
 684         jz      l2
 685         seg es
 686         cmp     al,(di)
 687 l2:     loope   l1
 688         cmp     cx,#0x00
 689         jne     nogen
 690         lea     si,dscgenoa
 691         lea     di,mogenoa
 692         br      selmod
 693 nogen:  cld
 694         lea     si,idoakvga
 695         mov     di,#0x08
 696         mov     cx,#0x08
 697         repe
 698         cmpsb
 699         jne     nooak
 700         lea     si,dscoakvga
 701         lea     di,mooakvga
 702         br      selmod
 703 nooak:  cld
 704         lea     si,idparadise           ! Check Paradise 'clues'
 705         mov     di,#0x7d
 706         mov     cx,#0x04
 707         repe
 708         cmpsb
 709         jne     nopara
 710         lea     si,dscparadise
 711         lea     di,moparadise
 712         br      selmod
 713 nopara: mov     dx,#0x3c4               ! Check Trident 'clues'
 714         mov     al,#0x0e
 715         out     dx,al
 716         inc     dx
 717         in      al,dx
 718         xchg    ah,al
 719         xor     al,al
 720         out     dx,al
 721         in      al,dx
 722         xchg    al,ah
 723         mov     bl,al           ! Strange thing ... in the book this wasn't
 724         and     bl,#0x02        ! necessary but it worked on my card which
 725         jz      setb2           ! is a trident. Without it the screen goes
 726         and     al,#0xfd        ! blurred ...
 727         jmp     clrb2           !
 728 setb2:  or      al,#0x02        !
 729 clrb2:  out     dx,al
 730         and     ah,#0x0f
 731         cmp     ah,#0x02
 732         jne     notrid
 733 ev2tri: lea     si,dsctrident
 734         lea     di,motrident
 735         jmp     selmod
 736 notrid: mov     dx,#0x3cd               ! Check Tseng 'clues'
 737         in      al,dx                   ! Could things be this simple ! :-)
 738         mov     bl,al
 739         mov     al,#0x55
 740         out     dx,al
 741         in      al,dx
 742         mov     ah,al
 743         mov     al,bl
 744         out     dx,al
 745         cmp     ah,#0x55
 746         jne     notsen
 747         lea     si,dsctseng
 748         lea     di,motseng
 749         jmp     selmod
 750 notsen: mov     dx,#0x3cc               ! Check Video7 'clues'
 751         in      al,dx
 752         mov     dx,#0x3b4
 753         and     al,#0x01
 754         jz      even7
 755         mov     dx,#0x3d4
 756 even7:  mov     al,#0x0c
 757         out     dx,al
 758         inc     dx
 759         in      al,dx
 760         mov     bl,al
 761         mov     al,#0x55
 762         out     dx,al
 763         in      al,dx
 764         dec     dx
 765         mov     al,#0x1f
 766         out     dx,al
 767         inc     dx
 768         in      al,dx
 769         mov     bh,al
 770         dec     dx
 771         mov     al,#0x0c
 772         out     dx,al
 773         inc     dx
 774         mov     al,bl
 775         out     dx,al
 776         mov     al,#0x55
 777         xor     al,#0xea
 778         cmp     al,bh
 779         jne     novid7
 780         lea     si,dscvideo7
 781         lea     di,movideo7
 782         jmp     selmod
 783 novid7: lea     si,dsunknown
 784         lea     di,mounknown
 785 selmod: xor     cx,cx
 786         mov     cl,(di)
 787         mov     ax,modesave
 788         cmp     ax,#ASK_VGA
 789         je      askmod
 790         cmp     ax,#NORMAL_VGA
 791         je      askmod
 792         cmp     al,cl
 793         jl      gotmode
 794         push    si
 795         lea     si,msg4
 796         call    prtstr
 797         pop     si
 798 askmod: push    si
 799         lea     si,msg2
 800         call    prtstr
 801         pop     si
 802         push    si
 803         push    cx
 804 tbl:    pop     bx
 805         push    bx
 806         mov     al,bl
 807         sub     al,cl
 808         call    modepr
 809         lodsw
 810         xchg    al,ah
 811         call    dprnt
 812         xchg    ah,al
 813         push    ax
 814         mov     al,#0x78
 815         call    prnt1
 816         pop     ax
 817         call    dprnt
 818         push    si
 819         lea     si,crlf         ! print CR+LF
 820         call    prtstr
 821         pop     si
 822         loop    tbl
 823         pop     cx
 824         lea     si,msg3
 825         call    prtstr
 826         pop     si
 827         add     cl,#0x30
 828         jmp     nonum
 829 nonumb: call    beep
 830 nonum:  call    getkey
 831         cmp     al,#0x30        ! ascii `0'
 832         jb      nonumb
 833         cmp     al,#0x3a        ! ascii `9'
 834         jbe     number
 835         cmp     al,#0x61        ! ascii `a'
 836         jb      nonumb
 837         cmp     al,#0x7a        ! ascii `z'
 838         ja      nonumb
 839         sub     al,#0x27
 840         cmp     al,cl
 841         jae     nonumb
 842         sub     al,#0x30
 843         jmp     gotmode
 844 number: cmp     al,cl
 845         jae     nonumb
 846         sub     al,#0x30
 847 gotmode:        xor     ah,ah
 848         or      al,al
 849         beq     vga50
 850         push    ax
 851         dec     ax
 852         beq     vga28
 853         add     di,ax
 854         mov     al,(di)
 855         int     0x10
 856         pop     ax
 857         shl     ax,#1
 858         add     si,ax
 859         lodsw
 860         pop     ds
 861         ret
 862 
 863 ! Routine to write al into a VGA-register that is
 864 ! accessed via an index register
 865 !
 866 ! dx contains the address of the index register
 867 ! al contains the index
 868 ! ah contains the value to write to the data register (dx + 1)
 869 !
 870 ! no registers are changed
 871 
 872 outidx: out     dx,al
 873         push    ax
 874         mov     al,ah
 875         inc     dx
 876         out     dx,al
 877         dec     dx
 878         pop     ax
 879         ret
 880 inidx:  out     dx,al
 881         inc     dx
 882         in      al,dx
 883         dec     dx
 884         ret
 885 
 886 ! Routine to print a decimal value on screen, the value to be
 887 ! printed is put in al (i.e 0-255). 
 888 
 889 dprnt:  push    ax
 890         push    cx
 891         xor     ah,ah           ! Clear ah
 892         mov     cl,#0x0a
 893         idiv    cl
 894         cmp     al,#0x09
 895         jbe     lt100
 896         call    dprnt
 897         jmp     skip10
 898 lt100:  add     al,#0x30
 899         call    prnt1
 900 skip10: mov     al,ah
 901         add     al,#0x30
 902         call    prnt1   
 903         pop     cx
 904         pop     ax
 905         ret
 906 
 907 !
 908 ! Routine to print the mode number key on screen. Mode numbers
 909 ! 0-9 print the ascii values `0' to '9', 10-35 are represented by
 910 ! the letters `a' to `z'. This routine prints some spaces around the
 911 ! mode no.
 912 !
 913 
 914 modepr: push    ax
 915         cmp     al,#0x0a
 916         jb      digit           ! Here is no check for number > 35
 917         add     al,#0x27
 918 digit:  add     al,#0x30
 919         mov     modenr, al
 920         push    si
 921         lea     si, modestring
 922         call    prtstr
 923         pop     si
 924         pop     ax
 925         ret
 926 
 927 gdt:
 928         .word   0,0,0,0         ! dummy
 929 
 930         .word   0,0,0,0         ! unused
 931 
 932         .word   0x07FF          ! 8Mb - limit=2047 (2048*4096=8Mb)
 933         .word   0x0000          ! base address=0
 934         .word   0x9A00          ! code read/exec
 935         .word   0x00C0          ! granularity=4096, 386
 936 
 937         .word   0x07FF          ! 8Mb - limit=2047 (2048*4096=8Mb)
 938         .word   0x0000          ! base address=0
 939         .word   0x9200          ! data read/write
 940         .word   0x00C0          ! granularity=4096, 386
 941 
 942 idt_48:
 943         .word   0                       ! idt limit=0
 944         .word   0,0                     ! idt base=0L
 945 
 946 gdt_48:
 947         .word   0x800           ! gdt limit=2048, 256 GDT entries
 948         .word   512+gdt,0x9     ! gdt base = 0X9xxxx
 949 
 950 msg1:           .ascii  "Press <RETURN> to see SVGA-modes available, <SPACE> to continue or wait 30 secs."
 951                 db      0x0d, 0x0a, 0x0a, 0x00
 952 msg2:           .ascii  "Mode:  COLSxROWS:"
 953                 db      0x0d, 0x0a, 0x0a, 0x00
 954 msg3:           db      0x0d, 0x0a
 955                 .ascii  "Choose mode by pressing the corresponding number or letter."
 956 crlf:           db      0x0d, 0x0a, 0x00
 957 msg4:           .ascii  "You passed an undefined mode number to setup. Please choose a new mode."
 958                 db      0x0d, 0x0a, 0x0a, 0x07, 0x00
 959 modestring:     .ascii  "   "
 960 modenr:         db      0x00    ! mode number
 961                 .ascii  ":    "
 962                 db      0x00
 963                 
 964 idati:          .ascii  "761295520"
 965 idcandt:        .byte   0xa5
 966 idgenoa:        .byte   0x77, 0x00, 0x99, 0x66
 967 idparadise:     .ascii  "VGA="
 968 idoakvga:       .ascii  "OAK VGA "
 969 idS3:           .byte   0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
 970                 .byte   0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
 971 
 972 ! Manufacturer:   Numofmodes+2: Mode:
 973 ! Number of modes is the number of chip-specific svga modes plus the extended
 974 ! modes available on any vga (currently 2)
 975 
 976 moati:          .byte   0x06,   0x23, 0x33, 0x22, 0x21
 977 moahead:        .byte   0x07,   0x22, 0x23, 0x24, 0x2f, 0x34
 978 mocandt:        .byte   0x04,   0x60, 0x61
 979 mocirrus:       .byte   0x06,   0x1f, 0x20, 0x22, 0x31
 980 moeverex:       .byte   0x0c,   0x03, 0x04, 0x07, 0x08, 0x0a, 0x0b, 0x16, 0x18, 0x21, 0x40
 981 mogenoa:        .byte   0x0c,   0x58, 0x5a, 0x60, 0x61, 0x62, 0x63, 0x64, 0x72, 0x74, 0x78
 982 moparadise:     .byte   0x04,   0x55, 0x54
 983 motrident:      .byte   0x09,   0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a
 984 motseng:        .byte   0x07,   0x26, 0x2a, 0x23, 0x24, 0x22
 985 movideo7:       .byte   0x08,   0x40, 0x43, 0x44, 0x41, 0x42, 0x45
 986 mooakvga:       .byte   0x08,   0x00, 0x07, 0x4e, 0x4f, 0x50, 0x51
 987 mo_S3:          .byte   0x04,   0x54, 0x55
 988 mounknown:      .byte   0x02
 989 
 990 !                       msb = Cols lsb = Rows:
 991 ! The first two modes are standard vga modes available on any vga.
 992 ! mode 0 is 80x50 and mode 1 is 80x28
 993 
 994 dscati:         .word   0x5032, 0x501c, 0x8419, 0x842c, 0x641e, 0x6419
 995 dscahead:       .word   0x5032, 0x501c, 0x842c, 0x8419, 0x841c, 0xa032, 0x5042
 996 dsccandt:       .word   0x5032, 0x501c, 0x8419, 0x8432
 997 dsccirrus:      .word   0x5032, 0x501c, 0x8419, 0x842c, 0x841e, 0x6425
 998 dsceverex:      .word   0x5032, 0x501c, 0x5022, 0x503c, 0x642b, 0x644b, 0x8419, 0x842c, 0x501e, 0x641b, 0xa040, 0x841e
 999 dscgenoa:       .word   0x5032, 0x501c, 0x5020, 0x642a, 0x8419, 0x841d, 0x8420, 0x842c, 0x843c, 0x503c, 0x5042, 0x644b
1000 dscparadise:    .word   0x5032, 0x501c, 0x8419, 0x842c
1001 dsctrident:     .word   0x5032, 0x501c, 0x501e, 0x502b, 0x503c, 0x8419, 0x841e, 0x842b, 0x843c
1002 dsctseng:       .word   0x5032, 0x501c, 0x503c, 0x6428, 0x8419, 0x841c, 0x842c
1003 dscvideo7:      .word   0x5032, 0x501c, 0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c
1004 dscoakvga:      .word   0x5032, 0x501c, 0x2819, 0x5019, 0x503c, 0x843c, 0x8419, 0x842b
1005 dsc_S3:         .word   0x5032, 0x501c, 0x842b, 0x8419
1006 dsunknown:      .word   0x5032, 0x501c
1007 modesave:       .word   SVGA_MODE
1008 
1009 ! This must be last
1010 setup_sig1:     .word   SIG1
1011 setup_sig2:     .word   SIG2
1012 
1013 .text
1014 endtext:
1015 .data
1016 enddata:
1017 .bss
1018 endbss:

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