patch-1.3.42 linux/arch/i386/boot/setup.S
Next file: linux/arch/i386/defconfig
Previous file: linux/arch/i386/boot/compressed/Makefile
Back to the patch index
Back to the overall index
- Lines: 1262
- Date:
Tue Nov 14 15:56:35 1995
- Orig file:
v1.3.41/linux/arch/i386/boot/setup.S
- Orig date:
Wed Oct 4 14:14:28 1995
diff -u --recursive --new-file v1.3.41/linux/arch/i386/boot/setup.S linux/arch/i386/boot/setup.S
@@ -1,31 +1,32 @@
!
! setup.S Copyright (C) 1991, 1992 Linus Torvalds
!
-! setup.s is responsible for getting the system data from the BIOS,
-! and putting them into the appropriate places in system memory.
-! both setup.s and system has been loaded by the bootblock.
-!
-! This code asks the bios for memory/disk/other parameters, and
-! puts them in a "safe" place: 0x90000-0x901FF, ie where the
-! boot-block used to be. It is then up to the protected mode
+! This code performs all initialization procedures that should be done
+! before entering the protected mode. It's responsible for getting of all
+! system data offered by BIOS and for detection / selection of video
+! mode. All information is put in a "safe" place: 0x90000-0x901FF, i. e.
+! where the boot-block used to be. It is then up to the protected mode
! system to read them from there before the area is overwritten
! for buffer-blocks.
!
! Move PS/2 aux init code to psaux.c
! (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
!
-! some changes and additional features by Christoph Niemann,
+! Some changes and additional features by Christoph Niemann,
! March 1993/June 1994 (Christoph.Niemann@linux.org)
!
+! Completely new video-mode handling code, VESA mode detection, support
+! for new Cirrus Logic cards and some additional changes
+! by Martin Mares <mj@k332.feld.cvut.cz>, October 1995.
+!
-! NOTE! These had better be the same as in bootsect.s!
+! NOTE! These had better be the same as in bootsect.S!
#define __ASSEMBLY__
#include <linux/config.h>
#include <asm/segment.h>
-#ifndef SVGA_MODE
-#define SVGA_MODE ASK_VGA
-#endif
+! Uncomment this if you want the BIOS mode numbers to be listed
+!#define SHOW_BIOS_MODES
! Signature words to ensure LILO loaded us right
#define SIG1 0xAA55
@@ -46,6 +47,7 @@
entry start
start:
+
! Bootlin depends on this being done early
mov ax,#0x01500
mov dl,#0x81
@@ -72,12 +74,14 @@
! Part of above routine, this one just prints ascii al
prnt1: push ax
+ push bx
push cx
xor bh,bh
mov cx,#0x01
mov ah,#0x0e
int 0x10
pop cx
+ pop bx
pop ax
ret
@@ -145,43 +149,10 @@
xor bx,bx ! clear bx
int 0x16
-! check for EGA/VGA and some config parameters
+! Check for video adapter and its parameters
+! Video mode selection is also handled here
- mov ah,#0x12
- mov bl,#0x10
- int 0x10
- mov [8],ax
- mov [10],bx
- mov [12],cx
- mov ax,#0x5019
- cmp bl,#0x10
- je novga
- mov ax,#0x1a00 ! Added check for EGA/VGA discrimination
- int 0x10
- mov bx,ax
- mov ax,#0x5019
- movb [15],#0 ! by default, no VGA
- cmp bl,#0x1a ! 1a means VGA, anything else EGA or lower
- jne novga
- movb [15],#1 ! we've detected a VGA
- call chsvga
-novga: mov [14],al
- mov ah,#0x03 ! read cursor pos
- xor bh,bh ! clear bh
- int 0x10 ! save it in known place, con_init fetches
- mov [0],dx ! it from 0x90000.
-
-! Get video-card data:
-
- mov ah,#0x0f
- int 0x10
- mov [4],bx ! bh = display page
- mov [6],ax ! al = video mode, ah = window width
- xor ax,ax
- mov es,ax ! Access low memory
- seg es
- mov ax,[0x485] ! POINTS - Height of character matrix
- mov [16],ax
+ call video
! Get hd0 data
@@ -334,17 +305,16 @@
! Well, now's the time to actually move into protected mode. To make
! things as simple as possible, we do no register set-up or anything,
! we let the gnu-compiled 32-bit programs do that. We just jump to
-! absolute address 0x00000, in 32-bit protected mode.
+! absolute address 0x10000, in 32-bit protected mode.
!
! Note that the short jump isn't strictly needed, although there are
! reasons why it might be a good idea. It won't hurt in any case.
!
- xor ax,ax
- inc ax ! protected mode (PE) bit
+ mov ax,#1 ! protected mode (PE) bit
lmsw ax ! This is it!
jmp flush_instr
flush_instr:
- mov bx,#0 ! Flag to indicate a boot
+ xor bx,bx ! Flag to indicate a boot
jmpi 0x1000,KERNEL_CS ! jmp offset 1000 of segment 0x10 (cs)
! This routine checks that the keyboard command queue is empty
@@ -364,61 +334,6 @@
test al,#2 ! is input buffer full?
jnz empty_8042 ! yes - loop
ret
-!
-! Read a key and return the (US-)ascii code in al, scan code in ah
-!
-getkey:
- xor ah,ah
- int 0x16
- ret
-
-!
-! Read a key with a timeout of 30 seconds. The cmos clock is used to get
-! the time.
-!
-getkt:
- call gettime
- add al,#30 ! wait 30 seconds
- cmp al,#60
- jl lminute
- sub al,#60
-lminute:
- mov cl,al
-again: mov ah,#0x01
- int 0x16
- jnz getkey ! key pressed, so get it
- call gettime
- cmp al,cl
- jne again
- mov al,#0x20 ! timeout, return default char `space'
- ret
-
-!
-! Flush the keyboard buffer
-!
-flush: mov ah,#0x01
- int 0x16
- jz empty
- xor ah,ah
- int 0x16
- jmp flush
-empty: ret
-
-!
-! Read the cmos clock. Return the seconds in al
-!
-gettime:
- push cx
- mov ah,#0x02
- int 0x1a
- mov al,dh ! dh contains the seconds
- and al,#0x0f
- mov ah,dh
- mov cl,#0x04
- shr ah,cl
- aad
- pop cx
- ret
!
! Delay is needed after doing i/o
@@ -427,43 +342,199 @@
.word 0x00eb ! jmp $+2
ret
-! Routine trying to recognize type of SVGA-board present (if any)
-! and if it recognize one gives the choices of resolution it offers.
-! If one is found the resolution chosen is given by al,ah (rows,cols).
+!
+! Video card / mode detection. We do some hardware testing and build
+! a video mode list (placed directly after our code and data). Then we
+! choose the right mode given in the configuration or ask the user if
+! we are requested to do so. After all, all video parameters are stored
+! for later perusal by the kernel.
+!
-chsvga: cld
+video: movb [15],#0 ! Default is no VGA
+ mov ax,[0x01fa]
+ push ds
push ds
+ pop fs ! In this routine: FS=orig. DS
push cs
- mov ax,[0x01fa]
- pop ds
+ pop ds ! ES=DS=CS
+ push cs
+ pop es
mov modesave,ax
- mov ax,#0xc000
- mov es,ax
- mov ax,modesave
- cmp ax,#NORMAL_VGA
- je defvga
- cmp ax,#EXTENDED_VGA
- je vga50
+ lea di,modelist ! ES:DI points to current item in our mode list
+ mov eax,#0x50190000 ! Store current mode: 80x25
+ cld
+ stosd
+
+ mov ah,#0x12 ! Check EGA/VGA
+ mov bl,#0x10
+ int 0x10
+ seg fs
+ mov [10],bx ! Used for identification of VGA in the kernel
+ cmp bl,#0x10 ! Not EGA nor VGA -> 80x25 only
+ je selmd1
+
+ mov eax,#0x5032FFFF ! EGA or VGA: 80x50 supported
+ stosd
+
+ mov ax,#0x1a00 ! Added check for EGA/VGA discrimination
+ int 0x10
+ cmp al,#0x1a ! 1a means VGA, anything else EGA
+ jne selmd1
+ seg fs
+ movb [15],#1 ! We've detected a VGA
+
+ mov eax,#0x501cFFFE ! VGA: 80x28 supported
+ stosd
+
+ lea si,vgatable ! Test all known SVGA adapters
+dosvga: lodsw
+ mov bp,ax ! Default mode table
+ or ax,ax
+ jz didsv
+ lodsw ! Pointer to test routine
+ push si
+ push di
+ push es
+ mov bx,#0xc000
+ mov es,bx
+ call ax ! Call test routine
+ pop es
+ pop di
+ pop si
+ or bp,bp
+ jz dosvga
+ mov si,bp ! Found, copy the modes
+ mov ah,#0
+cpsvga: lodsb
+ or al,al
+ jz didsv
+ stosw
+ movsw
+ jmp cpsvga
+
+selmd1: jmp selmd
+
+didsv: mov ax,#0x4f00 ! Fetch VESA information to ES:DI+0x400
+ add di,#0x400
+ int 0x10
+ sub di,#0x400
+ cmp al,#0x4f
+ jne selmd
+ lgs bx,(di+0x40e)
+ cmp (di+0x400),#0x4556
+ jne selmd
+ cmp (di+0x402),#0x4153
+ jne selmd
+
+vesa1: seg gs
+ mov cx,(bx)
+ add bx,#2
+ cmp cx,#0xffff
+ je selmd
+ mov ax,#0x4f01
+ add di,#0xc00
+ int 0x10
+ sub di,#0xc00
+ cmp al,#0x4f
+ jne selmd
+ testb (di+0xc00),#0x10 ! Is it a text mode?
+ jne vesa1
+ testb (di+0xc00),#0x08 ! Has it colors?
+ je vesa1
+ mov dh,(di+0xc12) ! DX=dimensions, CX=mode
+ mov dl,(di+0xc14)
+
+ lea si,modelist ! Check if it's already on the list
+vesa2: lodsw
+ lodsw
+ cmp ax,dx
+ je vesa1
+ cmp si,di
+ jc vesa2
+
+ mov ax,cx ! New mode, store it
+ stosw
+ mov ax,dx
+ stosw
+ jmp vesa1
+
+!
+! Video mode table built. Determine the mode we should use and set it.
+!
+selmd: mov ax,modesave
+ cmp ax,#NORMAL_VGA ! Current mode (80x25)
+ je defmd1
+ cmp ax,#EXTENDED_VGA ! 80x50 mode
+ je try50
cmp ax,#ASK_VGA
- jne svga
- lea si,msg1
+ jne usemd
+banner: lea si,keymsg
call prtstr
call flush
nokey: call getkt
- cmp al,#0x0d ! enter ?
- je svga ! yes - svga selection
- cmp al,#0x20 ! space ?
- je defvga ! no - repeat
+ cmp al,#0x0d ! ENTER ?
+ je listm ! yes - manual mode selection
+ cmp al,#0x20 ! SPACE ?
+ je defmd1 ! no - repeat
call beep
jmp nokey
-defvga: mov ax,#0x5019
- pop ds
- ret
-/* extended vga mode: 80x50 */
-vga50:
- mov ax,#0x1112
+
+defmd1: br defmd
+
+listm: call listmodes ! List all available modes
+keymd: call getkey ! Get key representing mode ID
+ xor ah,ah
+ sub al,#0x30
+ jc keymd
+ cmp al,#10
+ jc usemd
+ sub al,#39
+ cmp al,#10
+ jc keymd
+ cmp al,#26
+ jnc keymd
+ jmp usemd
+
+try50: mov ax,#1 ! 80x50 is mode #1
+usemd: shl ax,#2 ! We're requested to set mode in AX
+ lea si,modelist
+ add si,ax
+ cmp si,di
+ jc mdok
+ cmp modesave,#ASK_VGA
+ je keymd
+ lea si,undefd
+ call prtstr
+ jmp banner
+
+mdok: lodsw ! AX=mode number
+ cmp ah,#0xff
+ jz mdspec
+ or ax,ax
+ jz mdsetd
+ or ah,ah
+ jz mdset
+ mov bx,ax
+ mov ax,#0x4f02
+mdset: int 0x10
+mdsetd: lodsb ! AL=number of lines
+ jmp getpar
+
+mdspec: inc ax ! Special modes
+ jz m80x50
+
+m80x28: mov ax,#0x1111 ! Setting 80x28 (VGA with EGA font)
+ xor bl,bl
+ int 0x10 ! use 9x14 fontset (28 lines on VGA)
+ mov ah,#0x01
+ mov cx,#0x0b0c
+ int 0x10 ! turn on cursor (scan lines 11 to 12)
+ mov al,#28
+ jmp getpar
+
+m80x50: mov ax,#0x1112 ! Setting 80x50 (EGA/VGA)
xor bl,bl
- int 0x10 ! use 8x8 font set (50 lines on VGA)
+ int 0x10 ! use 8x8 font set
mov ax,#0x1200
mov bl,#0x20
int 0x10 ! use alternate print screen
@@ -473,28 +544,65 @@
mov ah,#0x01
mov cx,#0x0607
int 0x10 ! turn on cursor (scan lines 6 to 7)
- pop ds
- mov ax,#0x5032 ! return 80x50
- ret
-/* extended vga mode: 80x28 */
-vga28:
- pop ax ! clean the stack
- mov ax,#0x1111
- xor bl,bl
- int 0x10 ! use 9x14 fontset (28 lines on VGA)
- mov ah, #0x01
- mov cx,#0x0b0c
- int 0x10 ! turn on cursor (scan lines 11 to 12)
- pop ds
- mov ax,#0x501c ! return 80x28
- ret
-/* svga modes */
+ mov al,#50
+ jmp getpar
+
+defmd: mov al,#25 ! Default is 25 lines
+
+!
+! Correct video mode set. Determine the remaining parameters.
+!
+
+getpar: pop ds ! Restore original DS
+ mov [14],al ! Number of lines
+
+ mov ah,#0x03 ! read cursor pos
+ xor bh,bh ! clear bh
+ int 0x10 ! save it in known place, con_init fetches
+ mov [0],dx ! it from 0x90000.
+
+ mov ah,#0x0f
+ int 0x10
+ mov [4],bx ! bh = display page
+ mov [6],ax ! al = video mode, ah = window width
+ xor ax,ax
+ mov es,ax ! Access low memory
+ seg es
+ mov ax,[0x485] ! POINTS - Height of character matrix
+ mov [16],ax
+
+ ret ! Well done...
+
!
-! test for presence of an S3 VGA chip. The algorithm was taken
-! from the SuperProbe package of XFree86 1.2.1
-! report bugs to Christoph.Niemann@linux.org
+! Table of all known SVGA cards. For each card, we store a pointer to
+! a table of video modes supported by the card and a pointer to a routine
+! used for testing of presence of the card.
!
-svga: cld
+
+vgatable:
+ .word s3_md, s3_test
+ .word ati_md, ati_test
+ .word ahead_md, ahead_test
+ .word chips_md, chips_test
+ .word cirrus2_md, cirrus2_test
+ .word cirrus1_md, cirrus1_test
+ .word everex_md, everex_test
+ .word genoa_md, genoa_test
+ .word oak_md, oak_test
+ .word paradise_md, paradise_test
+ .word trident_md, trident_test
+ .word tseng_md, tseng_test
+ .word video7_md, video7_test
+ .word 0
+
+!
+! Test routines and mode tables:
+!
+
+! S3 - The test algorithm was taken from the SuperProbe package
+! for XFree86 1.2.1. Report bugs to Christoph.Niemann@linux.org
+
+s3_test:
mov cx,#0x0f35 ! we store some constants in cl/ch
mov dx,#0x03d4
movb al,#0x38
@@ -559,29 +667,64 @@
repne
scasb
je no_s31
- lea si,dsc_S3 ! table of descriptions of video modes for BIOS
- lea di,mo_S3 ! table of sizes of video modes for my BIOS
movb ah,bh
movb al,#0x38
- call outidx ! restore old value of CRT register 0x38
- br selmod ! go ask for video mode
+ jmp s3rest
no_s3: movb al,#0x35 ! restore CRT register 0x35
movb ah,bl
call outidx
-no_s31: movb ah,bh
- movb al,#0x38
- call outidx ! restore old value of CRT register 0x38
+no_s31: xor bp,bp ! Detection failed
+s3rest: movb ah,bh
+ movb al,#0x38 ! restore old value of CRT register 0x38
+outidx: out dx,al ! Write to indexed VGA register
+ push ax ! AL=index, AH=data, DX=index reg port
+ mov al,ah
+ inc dx
+ out dx,al
+ dec dx
+ pop ax
+ ret
- lea si,idati ! Check ATI 'clues'
+tstidx: out dx,ax ! OUT DX,AX and inidx
+inidx: out dx,al ! Read from indexed VGA register
+ inc dx ! AL=index, DX=index reg port -> AL=data
+ in al,dx
+ dec dx
+ ret
+
+idS3: .byte 0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
+ .byte 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
+
+s3_md: .byte 0x54, 0x2b, 0x84
+ .byte 0x55, 0x19, 0x84
+ .byte 0
+
+! ATI cards.
+
+ati_test:
+ lea si,idati
mov di,#0x31
mov cx,#0x09
repe
cmpsb
- jne noati
- lea si,dscati
- lea di,moati
- br selmod
-noati: mov ax,#0x200f ! Check Ahead 'clues'
+ je atiok
+ xor bp,bp
+atiok: ret
+
+idati: .ascii "761295520"
+
+ati_md: .byte 0x23, 0x19, 0x84
+ .byte 0x33, 0x2c, 0x84
+ .byte 0x22, 0x1e, 0x64
+ .byte 0x21, 0x19, 0x64
+ .byte 0x58, 0x21, 0x50
+ .byte 0x5b, 0x1e, 0x50
+ .byte 0
+
+! AHEAD
+
+ahead_test:
+ mov ax,#0x200f
mov dx,#0x3ce
out dx,ax
inc dx
@@ -589,11 +732,23 @@
cmp al,#0x20
je isahed
cmp al,#0x21
- jne noahed
-isahed: lea si,dscahead
- lea di,moahead
- br selmod
-noahed: mov dx,#0x3c3 ! Check Chips & Tech. 'clues'
+ je isahed
+ xor bp,bp
+isahed: ret
+
+ahead_md:
+ .byte 0x22, 0x2c, 0x84
+ .byte 0x23, 0x19, 0x84
+ .byte 0x24, 0x1c, 0x84
+ .byte 0x2f, 0x32, 0xa0
+ .byte 0x32, 0x22, 0x50
+ .byte 0x34, 0x42, 0x50
+ .byte 0
+
+! Chips & Tech.
+
+chips_test:
+ mov dx,#0x3c3
in al,dx
or al,#0x10
out dx,al
@@ -604,12 +759,20 @@
in al,dx
and al,#0xef
out dx,al
- cmp bl,[idcandt]
- jne nocant
- lea si,dsccandt
- lea di,mocandt
- br selmod
-nocant: mov dx,#0x3d4 ! Check Cirrus 'clues'
+ cmp bl,#0xa5
+ je cantok
+ xor bp,bp
+cantok: ret
+
+chips_md:
+ .byte 0x60, 0x19, 0x84
+ .byte 0x61, 0x32, 0x84
+ .byte 0
+
+! Cirrus Logic 5X0
+
+cirrus1_test:
+ mov dx,#0x3d4
mov al,#0x0c
out dx,al
inc dx
@@ -642,19 +805,76 @@
out dx,al
in al,dx
cmp al,#0x01
- jne nocirr
- call rst3d4
- lea si,dsccirrus
- lea di,mocirrus
- br selmod
-rst3d4: mov dx,#0x3d4
+ je iscirr
+nocirr: xor bp,bp
+iscirr: mov dx,#0x3d4
mov al,bl
xor ah,ah
shl ax,#8
add ax,#0x0c
out dx,ax
- ret
-nocirr: call rst3d4 ! Check Everex 'clues'
+ ret
+
+cirrus1_md:
+ .byte 0x1f, 0x19, 0x84
+ .byte 0x20, 0x2c, 0x84
+ .byte 0x22, 0x1e, 0x84
+ .byte 0x31, 0x25, 0x64
+ .byte 0
+
+! Cirrus Logic 54XX
+
+cirrus2_test:
+ mov dx,#0x3c4
+ mov al,#6
+ call inidx
+ mov bl,al ! BL=backup
+ mov al,#6
+ xor ah,ah
+ call tstidx
+ cmp al,#0x0f
+ jne c2fail
+ mov ax,#0x1206
+ call tstidx
+ cmp al,#0x12
+ jne c2fail
+ mov al,#0x1e
+ call inidx
+ mov bh,al
+ and bh,#0xc0
+ mov ah,bh
+ mov al,#0x1e
+ call tstidx
+ xor al,bh
+ and al,#0x3f
+ jne c2xx
+ mov al,#0x1e
+ mov ah,bh
+ or ah,#0x3f
+ call tstidx
+ xor al,bh
+ xor al,#0x3f
+ and al,#0x3f
+c2xx: pushf
+ mov al,#0x1e
+ mov ah,bh
+ out dx,ax
+ popf
+ je c2done
+c2fail: xor bp,bp
+c2done: mov al,#6
+ mov ah,bl
+ out dx,ax
+ ret
+
+cirrus2_md:
+ .byte 0x14, 0x19, 0x84
+ .byte 0x54, 0x2b, 0x84
+ .byte 0
+
+! Everex / Trident
+
+everex_test:
mov ax,#0x7000
xor bx,bx
int 0x10
@@ -662,15 +882,32 @@
jne noevrx
shr dx,#4
cmp dx,#0x678
- je istrid
+ je evtrid
cmp dx,#0x236
- je istrid
- lea si,dsceverex
- lea di,moeverex
- br selmod
-istrid: lea cx,ev2tri
- jmp cx
-noevrx: lea si,idgenoa ! Check Genoa 'clues'
+ jne evrxok
+evtrid: lea bp,trident_md
+evrxok: ret
+
+noevrx: xor bp,bp
+ ret
+
+everex_md:
+ .byte 0x03, 0x22, 0x50
+ .byte 0x04, 0x3c, 0x50
+ .byte 0x07, 0x2b, 0x64
+ .byte 0x08, 0x4b, 0x64
+ .byte 0x0a, 0x19, 0x84
+ .byte 0x0b, 0x2c, 0x84
+ .byte 0x16, 0x1e, 0x50
+ .byte 0x18, 0x1b, 0x64
+ .byte 0x21, 0x40, 0xa0
+ .byte 0x40, 0x1e, 0x84
+ .byte 0
+
+! Genoa.
+
+genoa_test:
+ lea si,idgenoa ! Check Genoa 'clues'
xor ax,ax
seg es
mov al,[0x37]
@@ -686,32 +923,72 @@
seg es
cmp al,(di)
l2: loope l1
- cmp cx,#0x00
- jne nogen
- lea si,dscgenoa
- lea di,mogenoa
- br selmod
-nogen: cld
+ or cx,cx
+ je isgen
+ xor bp,bp
+isgen: ret
+
+idgenoa: .byte 0x77, 0x00, 0x99, 0x66
+
+genoa_md:
+ .byte 0x58, 0x20, 0x50
+ .byte 0x5a, 0x2a, 0x64
+ .byte 0x60, 0x19, 0x84
+ .byte 0x61, 0x1d, 0x84
+ .byte 0x62, 0x20, 0x84
+ .byte 0x63, 0x2c, 0x84
+ .byte 0x64, 0x3c, 0x84
+ .byte 0x6b, 0x4f, 0x64
+ .byte 0x72, 0x3c, 0x50
+ .byte 0x74, 0x42, 0x50
+ .byte 0x78, 0x4b, 0x64
+ .byte 0
+
+! OAK
+
+oak_test:
lea si,idoakvga
mov di,#0x08
mov cx,#0x08
repe
cmpsb
- jne nooak
- lea si,dscoakvga
- lea di,mooakvga
- br selmod
-nooak: cld
- lea si,idparadise ! Check Paradise 'clues'
+ je isoak
+ xor bp,bp
+isoak: ret
+
+idoakvga: .ascii "OAK VGA "
+
+oak_md: .byte 0x4e, 0x3c, 0x50
+ .byte 0x4f, 0x3c, 0x84
+ .byte 0x50, 0x19, 0x84
+ .byte 0x51, 0x2b, 0x84
+ .byte 0
+
+! WD Paradise.
+
+paradise_test:
+ lea si,idparadise
mov di,#0x7d
mov cx,#0x04
repe
cmpsb
- jne nopara
- lea si,dscparadise
- lea di,moparadise
- br selmod
-nopara: mov dx,#0x3c4 ! Check Trident 'clues'
+ je ispara
+ xor bp,bp
+ispara: ret
+
+idparadise: .ascii "VGA="
+
+paradise_md:
+ .byte 0x41, 0x22, 0x50
+ .byte 0x47, 0x1c, 0x84
+ .byte 0x55, 0x19, 0x84
+ .byte 0x54, 0x2c, 0x84
+ .byte 0
+
+! Trident.
+
+trident_test:
+ mov dx,#0x3c4
mov al,#0x0e
out dx,al
inc dx
@@ -730,11 +1007,24 @@
clrb2: out dx,al
and ah,#0x0f
cmp ah,#0x02
- jne notrid
-ev2tri: lea si,dsctrident
- lea di,motrident
- jmp selmod
-notrid: mov dx,#0x3cd ! Check Tseng 'clues'
+ je istrid
+ xor bp,bp
+istrid: ret
+
+trident_md:
+ .byte 0x50, 0x1e, 0x50
+ .byte 0x51, 0x2b, 0x50
+ .byte 0x52, 0x3c, 0x50
+ .byte 0x57, 0x19, 0x84
+ .byte 0x58, 0x1e, 0x84
+ .byte 0x59, 0x2b, 0x84
+ .byte 0x5a, 0x3c, 0x84
+ .byte 0
+
+! Tseng.
+
+tseng_test:
+ mov dx,#0x3cd
in al,dx ! Could things be this simple ! :-)
mov bl,al
mov al,#0x55
@@ -744,11 +1034,22 @@
mov al,bl
out dx,al
cmp ah,#0x55
- jne notsen
- lea si,dsctseng
- lea di,motseng
- jmp selmod
-notsen: mov dx,#0x3cc ! Check Video7 'clues'
+ je istsen
+ xor bp,bp
+istsen: ret
+
+tseng_md:
+ .byte 0x26, 0x3c, 0x50
+ .byte 0x2a, 0x28, 0x64
+ .byte 0x23, 0x19, 0x84
+ .byte 0x24, 0x1c, 0x84
+ .byte 0x22, 0x2c, 0x84
+ .byte 0
+
+! Video7.
+
+video7_test:
+ mov dx,#0x3cc
in al,dx
mov dx,#0x3b4
and al,#0x01
@@ -777,115 +1078,78 @@
mov al,#0x55
xor al,#0xea
cmp al,bh
- jne novid7
- lea si,dscvideo7
- lea di,movideo7
- jmp selmod
-novid7: lea si,dsunknown
- lea di,mounknown
-selmod: xor cx,cx
- mov cl,(di)
- mov ax,modesave
- cmp ax,#ASK_VGA
- je askmod
- cmp ax,#NORMAL_VGA
- je askmod
- cmp al,cl
- jl gotmode
- push si
- lea si,msg4
+ je isvid7
+ xor bp,bp
+isvid7: ret
+
+video7_md:
+ .byte 0x40, 0x2b, 0x50
+ .byte 0x43, 0x3c, 0x50
+ .byte 0x44, 0x3c, 0x64
+ .byte 0x41, 0x19, 0x84
+ .byte 0x42, 0x2c, 0x84
+ .byte 0x45, 0x1c, 0x84
+ .byte 0
+
+!
+! Displaying of the mode list.
+!
+
+listmodes:
+ lea si,listhdr
call prtstr
- pop si
-askmod: push si
- lea si,msg2
+ lea bx,modelist
+ mov cl,#0x30
+listm1: mov modenr,cl
+ lea si,modestring
call prtstr
- pop si
- push si
- push cx
-tbl: pop bx
- push bx
- mov al,bl
- sub al,cl
- call modepr
- lodsw
- xchg al,ah
+ mov al,(bx+3)
call dprnt
- xchg ah,al
- push ax
mov al,#0x78
call prnt1
- pop ax
+ mov al,(bx+2)
call dprnt
- push si
- lea si,crlf ! print CR+LF
- call prtstr
- pop si
- loop tbl
- pop cx
- lea si,msg3
+#ifdef SHOW_BIOS_MODES
+ mov al,#0x20
+ call prnt1
+ mov al,#0x28
+ call prnt1
+ mov al,(bx+1)
+ call prthex
+ mov al,(bx)
+ call prthex
+ mov al,#0x29
+ call prnt1
+#endif
+ lea si,crlf
call prtstr
- pop si
- add cl,#0x30
- jmp nonum
-nonumb: call beep
-nonum: call getkey
- cmp al,#0x30 ! ascii `0'
- jb nonumb
- cmp al,#0x3a ! ascii `9'
- jbe number
- cmp al,#0x61 ! ascii `a'
- jb nonumb
- cmp al,#0x7a ! ascii `z'
- ja nonumb
- sub al,#0x27
- cmp al,cl
- jae nonumb
- sub al,#0x30
- jmp gotmode
-number: cmp al,cl
- jae nonumb
- sub al,#0x30
-gotmode: xor ah,ah
- or al,al
- beq vga50
- push ax
- dec ax
- beq vga28
- add di,ax
- mov al,(di)
- int 0x10
- pop ax
- shl ax,#1
- add si,ax
- lodsw
- pop ds
- ret
+ add bx,#4
+ inc cl
+ cmp cl,#0x3a
+ jnz listm2
+ mov cl,#0x61
+listm2: cmp bx,di
+ jc listm1
+ lea si,prompt
+ br prtstr
-! Routine to write al into a VGA-register that is
-! accessed via an index register
-!
-! dx contains the address of the index register
-! al contains the index
-! ah contains the value to write to the data register (dx + 1)
-!
-! no registers are changed
+! Routine to print a hexadecimal byte (AL) on screen.
-outidx: out dx,al
- push ax
- mov al,ah
- inc dx
- out dx,al
- dec dx
+#ifdef SHOW_BIOS_MODES
+prthex: push ax
+ shr al,#4
+ call prth1
pop ax
- ret
-inidx: out dx,al
- inc dx
- in al,dx
- dec dx
- ret
+prth1: and al,#15
+ cmp al,#10
+ jc prth2
+ add al,#7
+prth2: add al,#0x30
+ br prnt1
+#endif
! Routine to print a decimal value on screen, the value to be
-! printed is put in al (i.e 0-255).
+! printed is put in AL (i.e 0-255).
dprnt: push ax
push cx
@@ -906,25 +1170,65 @@
ret
!
-! Routine to print the mode number key on screen. Mode numbers
-! 0-9 print the ascii values `0' to '9', 10-35 are represented by
-! the letters `a' to `z'. This routine prints some spaces around the
-! mode no.
+! Read a key and return the (US-)ascii code in al, scan code in ah
!
+getkey:
+ xor ah,ah
+ int 0x16
+ ret
-modepr: push ax
- cmp al,#0x0a
- jb digit ! Here is no check for number > 35
- add al,#0x27
-digit: add al,#0x30
- mov modenr, al
- push si
- lea si, modestring
- call prtstr
- pop si
- pop ax
+!
+! Read a key with a timeout of 30 seconds. The cmos clock is used to get
+! the time.
+!
+getkt:
+ call gettime
+ add al,#30 ! wait 30 seconds
+ cmp al,#60
+ jl lminute
+ sub al,#60
+lminute:
+ mov cl,al
+again: mov ah,#0x01
+ int 0x16
+ jnz getkey ! key pressed, so get it
+ call gettime
+ cmp al,cl
+ jne again
+ mov al,#0x20 ! timeout, return default char `space'
ret
+!
+! Flush the keyboard buffer
+!
+flush: mov ah,#0x01
+ int 0x16
+ jz empty
+ xor ah,ah
+ int 0x16
+ jmp flush
+empty: ret
+
+!
+! Read the cmos clock. Return the seconds in al
+!
+gettime:
+ push cx
+ mov ah,#0x02
+ int 0x1a
+ mov al,dh ! dh contains the seconds
+ and al,#0x0f
+ mov ah,dh
+ mov cl,#0x04
+ shr ah,cl
+ aad
+ pop cx
+ ret
+
+!
+! Descriptor table for our protected mode transition.
+!
+
gdt:
.word 0,0,0,0 ! dummy
@@ -948,68 +1252,36 @@
.word 0x800 ! gdt limit=2048, 256 GDT entries
.word 512+gdt,0x9 ! gdt base = 0X9xxxx
-msg1: .ascii "Press <RETURN> to see SVGA-modes available, <SPACE> to continue or wait 30 secs."
- db 0x0d, 0x0a, 0x0a, 0x00
-msg2: .ascii "Mode: COLSxROWS:"
+!
+! Assorted messages.
+!
+
+keymsg: .ascii "Press <RETURN> to see video modes available, <SPACE> to continue or wait 30 secs"
+ db 0x0d, 0x0a, 0x00
+listhdr: .ascii "Mode: COLSxROWS:"
db 0x0d, 0x0a, 0x0a, 0x00
-msg3: db 0x0d, 0x0a
+prompt: db 0x0d, 0x0a
.ascii "Choose mode by pressing the corresponding number or letter."
crlf: db 0x0d, 0x0a, 0x00
-msg4: .ascii "You passed an undefined mode number to setup. Please choose a new mode."
+undefd: .ascii "You passed an undefined mode number to setup. Please choose a new mode."
db 0x0d, 0x0a, 0x0a, 0x07, 0x00
modestring: .ascii " "
modenr: db 0x00 ! mode number
.ascii ": "
db 0x00
-
-idati: .ascii "761295520"
-idcandt: .byte 0xa5
-idgenoa: .byte 0x77, 0x00, 0x99, 0x66
-idparadise: .ascii "VGA="
-idoakvga: .ascii "OAK VGA "
-idS3: .byte 0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
- .byte 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
-
-! Manufacturer: Numofmodes+2: Mode:
-! Number of modes is the number of chip-specific svga modes plus the extended
-! modes available on any vga (currently 2)
-
-moati: .byte 0x06, 0x23, 0x33, 0x22, 0x21
-moahead: .byte 0x07, 0x22, 0x23, 0x24, 0x2f, 0x34
-mocandt: .byte 0x04, 0x60, 0x61
-mocirrus: .byte 0x06, 0x1f, 0x20, 0x22, 0x31
-moeverex: .byte 0x0c, 0x03, 0x04, 0x07, 0x08, 0x0a, 0x0b, 0x16, 0x18, 0x21, 0x40
-mogenoa: .byte 0x0c, 0x58, 0x5a, 0x60, 0x61, 0x62, 0x63, 0x64, 0x72, 0x74, 0x78
-moparadise: .byte 0x04, 0x55, 0x54
-motrident: .byte 0x09, 0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a
-motseng: .byte 0x07, 0x26, 0x2a, 0x23, 0x24, 0x22
-movideo7: .byte 0x08, 0x40, 0x43, 0x44, 0x41, 0x42, 0x45
-mooakvga: .byte 0x08, 0x00, 0x07, 0x4e, 0x4f, 0x50, 0x51
-mo_S3: .byte 0x04, 0x54, 0x55
-mounknown: .byte 0x02
-
-! msb = Cols lsb = Rows:
-! The first two modes are standard vga modes available on any vga.
-! mode 0 is 80x50 and mode 1 is 80x28
-
-dscati: .word 0x5032, 0x501c, 0x8419, 0x842c, 0x641e, 0x6419
-dscahead: .word 0x5032, 0x501c, 0x842c, 0x8419, 0x841c, 0xa032, 0x5042
-dsccandt: .word 0x5032, 0x501c, 0x8419, 0x8432
-dsccirrus: .word 0x5032, 0x501c, 0x8419, 0x842c, 0x841e, 0x6425
-dsceverex: .word 0x5032, 0x501c, 0x5022, 0x503c, 0x642b, 0x644b, 0x8419, 0x842c, 0x501e, 0x641b, 0xa040, 0x841e
-dscgenoa: .word 0x5032, 0x501c, 0x5020, 0x642a, 0x8419, 0x841d, 0x8420, 0x842c, 0x843c, 0x503c, 0x5042, 0x644b
-dscparadise: .word 0x5032, 0x501c, 0x8419, 0x842c
-dsctrident: .word 0x5032, 0x501c, 0x501e, 0x502b, 0x503c, 0x8419, 0x841e, 0x842b, 0x843c
-dsctseng: .word 0x5032, 0x501c, 0x503c, 0x6428, 0x8419, 0x841c, 0x842c
-dscvideo7: .word 0x5032, 0x501c, 0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c
-dscoakvga: .word 0x5032, 0x501c, 0x2819, 0x5019, 0x503c, 0x843c, 0x8419, 0x842b
-dsc_S3: .word 0x5032, 0x501c, 0x842b, 0x8419
-dsunknown: .word 0x5032, 0x501c
-modesave: .word SVGA_MODE
+
+modesave: .word 0 ! Requsted mode ID.
! This must be last
setup_sig1: .word SIG1
setup_sig2: .word SIG2
+
+! After our code and data, we'll store the mode list.
+! Mode record: .word modenr
+! .byte lines
+! .byte columns
+! Mode numbers used: 0=current, >=0x100=VESA, -1=80x50, -2=80x28
+modelist:
.text
endtext:
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this