root/arch/i386/boot/setup.S

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

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