root/boot/setup.S

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

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