patch-1.3.75 linux/arch/i386/boot/video.S

Next file: linux/arch/i386/defconfig
Previous file: linux/arch/i386/boot/setup.S
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.74/linux/arch/i386/boot/video.S linux/arch/i386/boot/video.S
@@ -0,0 +1,1632 @@
+!
+!	Display adapter & video mode setup, version 2.3 (15-Mar-96)
+!
+!	Copyright (C) 1995, 1996 Martin Mares <mj@k332.feld.cvut.cz>
+!	Based on the original setup.S code (C) Linus Torvalds
+!
+
+! Enable autodetection of SVGA adapters and modes
+#define CONFIG_VIDEO_SVGA
+
+! Enable autodetection of VESA modes
+#define CONFIG_VIDEO_VESA
+
+! Enable compacting of mode table
+#define CONFIG_VIDEO_COMPACT
+
+! Retain screen contents when switching modes
+#define CONFIG_VIDEO_RETAIN
+
+! Enable local mode list
+#undef CONFIG_VIDEO_LOCAL
+
+! This code uses an extended set of video mode numbers. These include:
+! Aliases for standard modes
+!	NORMAL_VGA (-1)
+!	EXTENDED_VGA (-2)
+!	ASK_VGA (-3)
+! Video modes numbered by menu position -- NOT RECOMMENDED because of lack
+! of compatibility when extending the table. These are between 0x00 and 0xff.
+#define VIDEO_FIRST_MENU 0x0000
+! Standard BIOS video modes (BIOS number + 0x0100)
+#define VIDEO_FIRST_BIOS 0x0100
+! VESA BIOS video modes (VESA number + 0x0200)
+#define VIDEO_FIRST_VESA 0x0200
+! Special video modes
+#define VIDEO_FIRST_SPECIAL 0x0f00
+#define VIDEO_80x25 0x0f00
+#define VIDEO_8POINT 0x0f01
+#define VIDEO_80x43 0x0f02
+#define VIDEO_80x28 0x0f03
+#define VIDEO_CURRENT_MODE 0x0f04
+#define VIDEO_LAST_SPECIAL 0x0f05
+! Video modes given by resolution
+#define VIDEO_FIRST_RESOLUTION 0x1000
+
+! The "recalculate timings" flag
+#define VIDEO_RECALC 0x8000
+
+! Positions of various video parameters passed to the kernel
+#define PARAM_CURSOR_POS	0
+#define PARAM_VIDEO_PAGE	4
+#define PARAM_VIDEO_MODE	6
+#define PARAM_VIDEO_COLS	7
+#define PARAM_VIDEO_EGA_BX	10
+#define PARAM_VIDEO_LINES	14
+#define PARAM_HAVE_VGA		15
+#define PARAM_FONT_POINTS	16
+
+! Define DO_STORE according to CONFIG_VIDEO_RETAIN
+#ifdef CONFIG_VIDEO_RETAIN
+#define DO_STORE call store_screen
+#else
+#define DO_STORE
+#endif
+
+!
+! This is the main entry point called by setup.S
+!
+
+video:	push	ds		! We use different segments
+	push	ds		! FS contains original DS
+	pop	fs
+	push	cs		! DS is equal to CS
+	pop	ds
+	push	cs		! ES is equal to CS
+	pop	es
+	xor	ax,ax
+	mov	gs,ax		! GS is zero
+	cld
+	call	basic_detect	! Basic adapter type testing (EGA/VGA/MDA/CGA)
+	seg	fs		! User-selected video mode
+	mov	ax,[0x01fa]
+	cmp	ax,#ASK_VGA	! Bring up the menu
+	jz	vid2
+	call	mode_set	! Set the mode
+	jc	vid1
+	lea	si,badmdt	! Invalid mode ID
+	call	prtstr
+vid2:	call	mode_menu
+vid1:
+#ifdef CONFIG_VIDEO_RETAIN
+	call	restore_screen	! Restore screen contents
+#endif
+	call	mode_params	! Store mode parameters
+	pop	ds		! Restore original DS
+	ret
+
+!
+! Detect if we have CGA, MDA, EGA or VGA and pass it to the kernel.
+!
+
+basic_detect:
+	seg	fs		! Default is no VGA
+	movb	[PARAM_HAVE_VGA],#0
+
+	mov	ah,#0x12	! Check EGA/VGA
+	mov	bl,#0x10
+	int	0x10
+	seg	fs
+	mov	[PARAM_VIDEO_EGA_BX],bx	! Used for identification of EGA in the kernel
+	cmp	bl,#0x10	! No, this is a CGA/MDA/HGA card.
+	je	basret
+	incb	[adapter]
+
+	mov	ax,#0x1a00	! Check for EGA/VGA discrimination
+	int	0x10
+	cmp	al,#0x1a	! 1a means VGA, anything else EGA
+	jne	basret
+	seg	fs
+	incb	[PARAM_HAVE_VGA]	! We've detected a VGA
+	incb	[adapter]
+
+basret:	ret
+
+!
+! Store the video mode parameters for later usage by the kernel.
+! This is done by asking the BIOS except for the rows/columns
+! parameters in the default 80x25 mode -- these are set directly,
+! because some very obscure BIOSes supply insane values.
+!
+
+mode_params:
+	mov	ah,#0x03	! Read cursor position
+	xor	bh,bh
+	int	0x10
+	seg	fs
+	mov	[PARAM_CURSOR_POS],dx
+
+	mov	ah,#0x0f	! Read page/mode/width
+	int	0x10
+	seg	fs
+	mov	[PARAM_VIDEO_PAGE],bx
+	seg	fs
+	mov	[PARAM_VIDEO_MODE],ax	! Video mode and screen width
+	cmp	al,#7			! MDA/HGA => segment differs
+	jnz	mopar0
+	mov	[video_segment],#0xb000
+mopar0:	seg	gs			! Font size
+	mov	ax,[0x485]
+	seg	fs
+	mov	[PARAM_FONT_POINTS],ax	! (valid only on EGA/VGA)
+
+	cmpb	[def_mode],#0	! Default mode -- force sane values
+	jz	mopar1
+	seg	fs
+	movb	[PARAM_VIDEO_COLS],#80
+mopar2:	seg	fs
+	movb	[PARAM_VIDEO_LINES],#25
+	ret
+
+mopar1:	cmpb	[adapter],#0	! If we are on CGA/MDA/HGA, the screen must
+	jz	mopar2		! have 25 lines.
+	seg	gs		! On EGA/VGA, use the EGA+ BIOS variable
+	mov	al,[0x484]	! containing maximal line number.
+	inc	al
+	seg	fs
+	movb	[PARAM_VIDEO_LINES],al
+	ret
+
+!
+! The video mode menu
+!
+
+mode_menu:
+	lea	si,keymsg	! "Return/Space/Timeout" message
+	call	prtstr
+	call	flush
+nokey:	call	getkt
+	cmp	al,#0x0d	! ENTER ?
+	je	listm		! yes - manual mode selection
+	cmp	al,#0x20	! SPACE ?
+	je	defmd1		! no - repeat
+	call 	beep
+	jmp	nokey
+defmd1:	ret			! No mode selected => use the 80x25 default
+
+listm:	call	mode_table	! We need a mode table to be listed
+listm0:	lea	si,name_bann	! Print adapter name
+	call	prtstr
+	mov	si,[card_name]
+	or	si,si
+	jnz	an2
+	mov	al,[adapter]
+	lea	si,old_name
+	or	al,al
+	jz	an1
+	lea	si,ega_name
+	dec	al
+	jz	an1
+	lea	si,vga_name
+	jmp	an1
+an2:	call	prtstr
+	lea	si,svga_name
+an1:	call	prtstr
+	lea	si,listhdr	! Table header
+	call	prtstr
+	mov	dl,#0x30	! DL holds mode number
+	lea	si,modelist
+lm1:	cmp	(si),#ASK_VGA	! End?
+	jz	lm2
+	mov	al,dl		! Menu selection number
+	call	prtchr
+	call	prtsp2
+	lodsw
+	call	prthw		! Mode ID
+	call	prtsp2
+	mov	al,(si+1)
+	call	prtdec		! Rows
+	mov	al,#0x78	! 'x'
+	call	prtchr
+	lodsw
+	call	prtdec		! Columns
+	mov	al,#0x0d	! New line
+	call	prtchr
+	mov	al,#0x0a
+	call	prtchr
+	inc	dl		! Next character
+	cmp	dl,#0x3a
+	jnz	lm1
+	mov	dl,#0x61
+	jmp	lm1
+
+lm2:	lea	si,prompt	! Mode prompt
+	call	prtstr
+	lea	di,edit_buf	! Editor buffer
+lm3:	call	getkey
+	cmp	al,#0x0d	! Enter?
+	jz	lment
+	cmp	al,#0x08	! Backspace?
+	jz	lmbs
+	cmp	al,#0x20	! Printable?
+	jc	lm3
+	cmp	di,#edit_buf+4	! Enough space?
+	jz	lm3
+	stosb
+	call	prtchr
+	jmp	lm3
+
+lmbs:	cmp	di,#edit_buf	! Backspace
+	jz	lm3
+	dec	di
+	mov	al,#0x08
+	call	prtchr
+	call	prtspc
+	mov	al,#0x08
+	call	prtchr
+	jmp	lm3
+
+lment:	movb	(di),#0
+	lea	si,crlft
+	call	prtstr
+	lea	si,edit_buf
+	cmpb	(si),#0		! Empty string => use default mode
+	jz	lmdef
+	cmpb	(si+1),#0	! One character => menu selection
+	jz	mnusel
+	cmp	(si),#0x6373	! "scan" => mode scanning
+	jnz	lmhx
+	cmp	(si+2),#0x6e61
+	jz	lmscan
+lmhx:	xor	bx,bx		! Else => mode ID in hex
+lmhex:	lodsb
+	or	al,al
+	jz	lmuse1
+	sub	al,#0x30
+	jc	lmbad
+	cmp	al,#10
+	jc	lmhx1
+	sub	al,#7
+	and	al,#0xdf
+	cmp	al,#10
+	jc	lmbad
+	cmp	al,#16
+	jnc	lmbad
+lmhx1:	shl	bx,#4
+	or	bl,al
+	jmp	lmhex
+lmuse1:	mov	ax,bx
+	jmp	lmuse
+
+mnusel:	lodsb			! Menu selection
+	xor	ah,ah
+	sub	al,#0x30
+	jc	lmbad
+	cmp	al,#10
+	jc	lmuse
+	cmp	al,#0x61-0x30
+	jc	lmbad
+	sub	al,#0x61-0x30-10
+	cmp	al,#36
+	jnc	lmbad
+lmuse:	call	mode_set
+	jc	lmdef
+lmbad:	lea	si,unknt
+	call	prtstr
+	br	lm2
+
+lmscan:	cmpb	[adapter],#0	! Scanning supported only on EGA/VGA
+	jz	lmbad
+	mov	[mt_end],#0	! Scanning of modes: done as new autodetection
+	movb	[scanning],#1
+	call	mode_table
+	br	listm0
+
+lmdef:	ret
+
+!
+! Aliases for backward compatibility.
+!
+
+setalias:
+	mov	ax,#VIDEO_80x25
+	inc	bx
+	jz	mode_set
+	mov	al,#VIDEO_8POINT-VIDEO_FIRST_SPECIAL
+	inc	bx
+	jnz	setbad
+
+	! Fall-thru !
+
+!
+! Setting of user mode (AX=mode ID) => CF=success
+!
+
+mode_set:
+	mov	bx,ax
+	cmp	ah,#0xff
+	jz	setalias
+	test	ah,#VIDEO_RECALC>>8
+	jnz	setrec
+	cmp	ah,#VIDEO_FIRST_RESOLUTION>>8
+	jnc	setres
+	cmp	ah,#VIDEO_FIRST_SPECIAL>>8
+	jz	setspc
+	cmp	ah,#VIDEO_FIRST_VESA>>8
+	jnc	setvesa
+	or	ah,ah
+	jz	setmenu
+	dec	ah
+	jz	setbios
+setbad:	clc
+	movb	[do_restore],#0	! The screen needn't be restored
+	ret
+
+setvesa:
+	DO_STORE
+	sub	bh,#VIDEO_FIRST_VESA>>8
+	mov	ax,#0x4f02	! VESA BIOS mode set call
+	int	0x10
+	cmp	ax,#0x004f	! AL=4f if implemented, AH=0 if OK
+	jnz	setbad
+	stc
+	ret
+
+setbios:
+	DO_STORE
+	int	0x10		! Standard BIOS mode set call
+	push	bx
+	mov	ah,#0x0f	! Check if really set
+	int	0x10
+	pop	bx
+	cmp	al,bl
+	jnz	setbad
+	stc
+	ret
+
+setspc:	xor	bh,bh		! Set special mode
+	cmp	bl,#VIDEO_LAST_SPECIAL-VIDEO_FIRST_SPECIAL
+	jnc	setbad
+	add	bx,bx
+	.word	0xa7ff, spec_inits	! JMP [BX+spec_inits]
+
+setmenu:
+	push	bx		! Set mode chosen from menu
+	call	mode_table	! Build the mode table
+	pop	ax
+	shl	ax,#2
+	add	si,ax
+	cmp	si,di
+	jnc	setbad
+	mov	ax,(si)		! Fetch mode ID
+_m_s:	jmp	mode_set
+
+setres:
+	push	bx		! Set mode chosen by its resolution
+	call	mode_table
+	pop	bx
+	xchg	bh,bl
+setr1:	lodsw
+	cmp	ax,#ASK_VGA	! End of the list?
+	jz	setbad
+	lodsw
+	cmp	ax,bx
+	jnz	setr1
+	mov	ax,(si-4)	! Fetch mode ID
+	jmp	_m_s
+
+!
+! Recalculate vertical display end registers -- this fixes various
+! inconsistencies of extended modes on many adapters. Called when
+! the VIDEO_RECALC flag is set in the mode ID.
+!
+
+setrec:	sub	ah,#VIDEO_RECALC>>8	! Set the base mode
+	call	mode_set
+	jnc	rct3
+	seg	gs			! Font size in pixels
+	mov	ax,[0x485]
+	seg	gs			! Number of rows
+	mov	bl,[0x484]
+	inc	bl
+	mul	bl			! Number of visible
+	dec	ax			! scan lines - 1
+	mov	dx,#0x3d4
+	mov	bx,ax
+	mov	al,#0x12		! Lower 8 bits
+	mov	ah,bl
+	out	dx,ax
+	mov	al,#0x07		! Bits 8 and 9 in the overflow register
+	call	inidx
+	xchg	ah,al
+	and	ah,#0xbd
+	shr	bh,#1
+	jnc	rct1
+	or	ah,#0x02
+rct1:	shr	bh,#1
+	jnc	rct2
+	or	ah,#0x40
+rct2:	mov	al,#0x07
+	out	dx,ax
+	stc
+rct3:	ret
+
+!
+! Table of routines for setting of the special modes.
+!
+
+spec_inits:
+	.word	set_80x25
+	.word	set_8pixel
+	.word	set_80x43
+	.word	set_80x28
+	.word	set_current
+
+!
+! Set the 80x25 mode. If already set, do nothing.
+!
+
+set_80x25:
+	incb	[def_mode]	! Signal "we use default mode"
+use_80x25:
+	mov	ah,#0x0f	! Get current mode ID
+	int	0x10
+	cmp	ax,#0x5007	! Mode 7 (80x25 mono) is the only one available
+	jz	st80		! on CGA/MDA/HGA and is also available on EGAM
+	cmp	ax,#0x5003	! Unknown mode => force 80x25 color
+	jnz	force3
+st80:	cmpb	[adapter],#0	! CGA/MDA/HGA => mode 3/7 is always 80x25
+	jz	set80
+	seg	gs		! This is EGA+ -- beware of 80x50 etc.
+	mov	al,[0x0484]
+	or	al,al		! Some buggy BIOS'es set 0 rows
+	jz	set80
+	cmp	al,#24		! It's hopefully correct
+	jz	set80
+force3:	DO_STORE
+	mov	ax,#0x0003	! Forced set
+	int	0x10
+set80:	stc
+	ret
+
+!
+! Set the 80x50/80x43 8-pixel mode. Simple BIOS calls.
+!
+
+set_8pixel:
+	DO_STORE
+	call	use_80x25	! The base is 80x25
+set_8pt:
+	mov	ax,#0x1112	! Use 8x8 font
+	xor	bl,bl
+	int	0x10
+	mov	ax,#0x1200	! Use alternate print screen
+	mov	bl,#0x20
+	int	0x10
+	mov	ax,#0x1201	! Turn off cursor emulation
+	mov	bl,#0x34
+	int	0x10
+	mov	ah,#0x01	! Define cursor (scan lines 6 to 7)
+	mov	cx,#0x0607
+	int	0x10
+set_current:
+	stc
+	ret
+
+!
+! Set the 80x28 mode. This mode works on all VGA's, because it's a standard
+! 80x25 mode with 14-point fonts instead of 16-point.
+!
+
+set_80x28:
+	DO_STORE
+	call	use_80x25	! The base is 80x25
+	mov	ax,#0x1111	! Use 9x14 font
+	xor	bl,bl
+	int	0x10
+	mov	ah,#0x01	! Define cursor (scan lines 11 to 12)
+	mov	cx,#0x0b0c
+	int	0x10
+	stc
+	ret
+
+!
+! Set the 80x43 mode. This mode is works on all VGA's.
+! It's a 350-scanline mode with 8-pixel font.
+!
+
+set_80x43:
+	DO_STORE
+	mov	ax,#0x1201	! Set 350 scans
+	mov	bl,#0x30
+	int	0x10
+	mov	ax,#0x0003	! Reset video mode
+	int	0x10
+	jmp	set_8pt		! Use 8-pixel font
+
+#ifdef CONFIG_VIDEO_RETAIN
+
+!
+! Store screen contents to temporary buffer.
+!
+
+store_screen:
+	cmpb	[do_restore],#0		! Already stored?
+	jnz	stsr
+	push	ax
+	push	bx
+	incb	[do_restore]		! Screen will be restored later
+	mov	al,[def_mode]		! "Default mode" flag overriden
+	push	ax
+	movb	[def_mode],#0
+	call	mode_params		! Obtain and store basic parameters
+	pop	ax
+	mov	[def_mode],al
+	seg	fs			! of the current mode.
+	mov	ax,[PARAM_CURSOR_POS]
+	lea	di,modelist+8192
+	stosw
+	seg	fs
+	mov	ah,[PARAM_VIDEO_LINES]
+	seg	fs
+	mov	al,[PARAM_VIDEO_COLS]
+	stosw
+	mul	ah
+	mov	cx,ax			! CX=number of characters to store
+
+	push	ds			! Store the screen
+	mov	ds,[video_segment]
+	xor	si,si
+	rep
+	movsw
+	pop	ds
+	pop	bx
+	pop	ax
+stsr:	ret
+
+!
+! Restore screen contents from temporary buffer.
+!
+
+restore_screen:
+	cmpb	[do_restore],#0		! Has the screen been stored?
+	jz	res1
+	call	mode_params		! Get parameters of current mode
+	seg	fs
+	mov	cl,[PARAM_VIDEO_LINES]
+	seg	fs
+	mov	ch,[PARAM_VIDEO_COLS]
+	lea	si,modelist+8192	! Screen buffer
+	lodsw				! Set cursor position
+	mov	dx,ax
+	cmp	dh,cl
+	jc	res2
+	mov	dh,cl
+	dec	dh
+res2:	cmp	dl,ch
+	jc	res3
+	mov	dl,ch
+	dec	dl
+res3:	mov	ah,#0x02
+	mov	bh,#0x00
+	int	0x10
+	lodsw				! Display size
+	mov	dl,ah			! DL=number of lines
+	mov	ah,#0			! BX=physical length of orig. line
+	mov	bx,ax
+	cmp	dl,cl			! Too many?
+	jc	res4
+	push	ax
+	mov	al,dl
+	sub	al,cl
+	mul	bl
+	add	si,ax
+	add	si,ax
+	pop	ax
+	mov	dl,cl
+res4:	cmp	al,ch			! Too wide?
+	jc	res5
+	mov	al,ch			! AX=width of src. line
+res5:	mov	cl,#0
+	xchg	cl,ch
+	mov	bp,cx			! BP=width of dest. line
+	push	es
+	mov	es,[video_segment]
+	xor	di,di			! Move the data
+	add	bx,bx			! Convert BX and BP to _bytes_
+	add	bp,bp
+res6:	push	si
+	push	di
+	mov	cx,ax
+	rep
+	movsw
+	pop	di
+	pop	si
+	add	di,bp
+	add	si,bx
+	dec	dl
+	jnz	res6
+	pop	es			! Done
+res1:	ret
+
+#endif /* CONFIG_VIDEO_RETAIN */
+
+!
+! Build the table of video modes (stored after the setup.S code at the
+! `modelist' label. Each video mode record looks like:
+!	.word	MODE-ID		(our special mode ID (see above))
+!	.byte	rows		(number of rows)
+!	.byte	columns		(number of columns)
+! Returns address of the end of the table in DI, the end is marked
+! with a ASK_VGA ID.
+!
+
+mode_table:
+	mov	di,[mt_end]	! Already filled?
+	or	di,di
+	jnz	mtab1x
+	lea	di,modelist	! Store standard modes:
+
+	mov	eax,#VIDEO_80x25 + 0x50190000	! The 80x25 mode (ALL)
+	stosd
+	mov	al,[adapter]	! CGA/MDA/HGA -- no more modes
+	or	al,al
+	jz	mtabe
+	dec	al
+	jnz	mtabv
+	mov	eax,#VIDEO_8POINT + 0x502b0000	! The 80x43 EGA mode
+	stosd
+	jmp	mtabe
+mtab1x:	jmp	mtab1
+
+mtabv:	mov	eax,#VIDEO_8POINT + 0x50320000	! The 80x50 mode (VGA only)
+	stosd
+	mov	eax,#VIDEO_80x43 + 0x502b0000	! The 80x43 mode (VGA only)
+	stosd
+	mov	eax,#VIDEO_80x28 + 0x501c0000	! The 80x28 mode (VGA only)
+	stosd
+
+	cmpb	[scanning],#0			! Mode scan requested?
+	jz	mscan1
+	call	mode_scan
+mscan1:
+
+#ifdef CONFIG_VIDEO_LOCAL
+	call	local_modes
+#endif
+#ifdef CONFIG_VIDEO_VESA
+	call	vesa_modes			! Detect VESA VGA modes
+#endif
+#ifdef CONFIG_VIDEO_SVGA
+	cmpb	[scanning],#0			! Bypass when scanning
+	jnz	mscan2
+	call	svga_modes			! Detect SVGA cards & modes
+mscan2:
+#endif
+
+mtabe:
+
+#ifdef CONFIG_VIDEO_COMPACT
+	lea	si,modelist	! Compact video mode list if requested.
+	mov	dx,di
+	mov	di,si
+cmt1:	cmp	si,dx		! Scan all modes
+	jz	cmt2
+	lea	bx,modelist	! Find in previous entries
+	mov	cx,(si+2)
+cmt3:	cmp	si,bx
+	jz	cmt4
+	cmp	cx,(bx+2)	! Found => don't copy this entry
+	jz	cmt5
+	add	bx,#4
+	jmp	cmt3
+
+cmt4:	movsd			! Copy entry
+	jmp	cmt1
+
+cmt5:	add	si,#4		! Skip entry
+	jmp	cmt1
+
+cmt2:
+#endif	/* CONFIG_VIDEO_COMPACT */
+
+	mov	(di),#ASK_VGA	! End marker
+	mov	[mt_end],di
+mtab1:	lea	si,modelist	! Returning: SI=mode list, DI=list end
+ret0:	ret
+
+!
+! Detect VESA modes.
+!
+
+#ifdef CONFIG_VIDEO_VESA
+
+vesa_modes:
+	cmpb	[adapter],#2	! VGA only
+	jnz	ret0
+	mov	bp,di		! BP=original mode table end
+	add	di,#0x400	! Buffer space
+	mov	ax,#0x4f00	! VESA Get card info call
+	int	#0x10
+	mov	di,bp
+	cmp	ax,#0x004f	! Successful?
+	jnz	ret0
+	cmp	(di+0x400),#0x4556
+	jnz	ret0
+	cmp	(di+0x402),#0x4153
+	jnz	ret0
+	mov	[card_name],#vesa_name	! Set name to "VESA VGA"
+	push	gs
+	lgs	si,(di+0x40e)	! GS:SI=mode list
+	mov	cx,#128		! Iteration limit
+vesa1:	seg	gs		! Get next mode in the list
+	lodsw
+	cmp	ax,#0xffff	! End of the table?
+	jz	vesar
+	cmp	ax,#0x0080	! Check validity of mode ID
+	jc	vesa2
+	or	ah,ah		! Valid ID's are 0x0000-0x007f
+	jz	vesae		! and 0x0100-0x02ff.
+	cmp	ax,#0x0300
+	jnc	vesae
+vesa2:	push	cx
+	mov	cx,ax		! Get mode information structure
+	mov	ax,#0x4f01
+	int	0x10
+	mov	bx,cx		! BX=mode number
+	add	bh,#VIDEO_FIRST_VESA>>8
+	pop	cx
+	cmp	ax,#0x004f
+	jnz	vesae
+	mov	al,(di)		! Check capabilities. We require
+	and	al,#0x19	! a color text mode.
+	cmp	al,#0x09
+	jnz	vesan
+	cmp	(di+8),#0xb800	! Standard video memory address required
+	jnz	vesan
+	testb	(di),#2		! Mode characteristics supplied?
+	mov	(di),bx		! Store mode number
+	jz	vesa3
+	xor	dx,dx
+	mov	bx,(di+0x12)	! Width
+	or	bh,bh
+	jnz	vesan
+	mov	(di+3),bl
+	mov	ax,(di+0x14)	! Height
+	or	ah,ah
+	jnz	vesan
+	mov	(di+2),al
+	mul	bl
+	cmp	ax,#8193	! Small enough for Linux console driver?
+	jnc	vesan
+	jmp	vesaok
+
+vesa3:	sub	bx,#0x8108	! This mode has no detailed info specified,
+	jc	vesan		! so it must be a standard VESA mode.
+	cmp	bx,#5
+	jnc	vesan
+	mov	ax,(bx+vesa_text_mode_table)
+	mov	(di+2),ax
+vesaok:	add	di,#4		! The mode is valid. Store it.
+vesan:	loop	vesa1		! Next mode. Limit exceeded => error
+vesae:	lea	si,vesaer
+	call	prtstr
+	mov	di,bp		! Discard already found modes.
+vesar:	pop	gs
+	ret
+
+!
+! Dimensions of standard VESA text modes
+!
+
+vesa_text_mode_table:
+	db	60, 80		! 0108
+	db	25, 132		! 0109
+	db	43, 132		! 010A
+	db	50, 132		! 010B
+	db	60, 132		! 010C
+
+#endif	/* CONFIG_VIDEO_VESA */
+
+!
+! Scan for video modes. A bit dirty, but should work.
+!
+
+mode_scan:
+	mov	cx,#0x0100	! Start with mode 0
+scm1:	mov	ah,#0		! Test the mode
+	mov	al,cl
+	int	0x10
+	mov	ah,#0x0f
+	int	0x10
+	cmp	al,cl
+	jnz	scm2		! Mode not set
+	mov	dx,#0x3c0	! Test if it's a text mode
+	mov	al,#0x10		! Mode bits
+	call	inidx
+	and	al,#0x03
+	jnz	scm2
+	mov	dx,#0x3d4		! Cursor location
+	mov	al,#0x0f
+	call	inidx
+	or	al,al
+	jnz	scm2
+	mov	ax,cx		! OK, store the mode
+	stosw
+	seg	gs		! Number of rows
+	mov	al,[0x484]
+	inc	al
+	stosb
+	seg	gs		! Number of columns
+	mov	ax,[0x44a]
+	stosb
+scm2:	inc	cl
+	jns	scm1
+	mov	ax,#0x0003	! Return back to mode 3
+	int	0x10
+	ret
+
+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
+
+!
+! Try to detect type of SVGA card and supply (usually approximate) video
+! mode table for it.
+!
+
+#ifdef CONFIG_VIDEO_SVGA
+
+svga_modes:
+	lea	si,svga_table	! Test all known SVGA adapters
+dosvga:	lodsw
+	mov	bp,ax		! Default mode table
+	or	ax,ax
+	jz	didsv1
+	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,#0x01
+cpsvga:	lodsb
+	or	al,al
+	jz	didsv
+	stosw
+	movsw
+	jmp	cpsvga
+
+didsv:	mov	[card_name],si	! Store pointer to card name
+didsv1:	ret
+
+!
+! 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. The video mode table is always
+! followed by the name of the card or the chipset.
+!
+
+svga_table:
+	.word	s3_md, s3_test
+	.word	ati_md, ati_test
+	.word	chips_md, chips_test
+	.word	cirrus5_md, cirrus5_test
+	.word	cirrus6_md, cirrus6_test
+	.word	cirrus1_md, cirrus1_test
+	.word	ahead_md, ahead_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
+	call	inidx
+	mov	bh,al		! store current value of CRT-register 0x38
+	mov	ax,#0x0038
+	call	outidx		! disable writing to special regs
+	movb	al,cl		! check whether we can write special reg 0x35
+	call	inidx
+	movb	bl,al		! save the current value of CRT reg 0x35
+	andb	al,#0xf0	! clear bits 0-3
+	movb	ah,al
+	movb	al,cl		! and write it to CRT reg 0x35
+	call	outidx
+	call	inidx		! now read it back
+	andb	al,ch		! clear the upper 4 bits
+	jz	s3_2		! the first test failed. But we have a
+	movb	ah,bl		! second chance
+	mov	al,cl
+	call	outidx
+	jmp	s3_1		! do the other tests
+s3_2:	mov	ax,cx		! load ah with 0xf and al with 0x35
+	orb	ah,bl		! set the upper 4 bits of ah with the orig value
+	call	outidx		! write ...
+	call	inidx		! ... and reread 
+	andb	al,cl		! turn off the upper 4 bits
+	push	ax
+	movb	ah,bl		! restore old value in register 0x35
+	movb	al,cl
+	call	outidx
+	pop	ax
+	cmp	al,ch		! setting lower 4 bits was successful => bad
+	je	no_s3		! writing is allowed => this is not an S3
+s3_1:	mov	ax,#0x4838	! allow writing to special regs by putting
+	call	outidx		! magic number into CRT-register 0x38
+	movb	al,cl		! check whether we can write special reg 0x35
+	call	inidx
+	movb	bl,al
+	andb	al,#0xf0
+	movb	ah,al
+	movb	al,cl
+	call	outidx
+	call	inidx
+	andb	al,ch
+	jnz	no_s3		! no, we can't write => no S3
+	mov	ax,cx
+	orb	ah,bl
+	call	outidx
+	call	inidx
+	andb	al,ch
+	push	ax
+	movb	ah,bl		! restore old value in register 0x35
+	movb	al,cl
+	call	outidx
+	pop	ax
+	cmp	al,ch
+	jne	no_s31		! writing not possible => no S3
+	movb	al,#0x30
+	call	inidx		! now get the S3 id ...
+	lea	di,idS3
+	mov	cx,#0x10
+	repne
+	scasb
+	je	no_s31
+	movb	ah,bh
+	movb	al,#0x38
+	jmp	s3rest
+no_s3:	movb	al,#0x35	! restore CRT register 0x35
+	movb	ah,bl
+	call	outidx
+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
+
+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
+	.ascii	"S3"
+	.byte	0
+
+! ATI cards.
+
+ati_test:
+	lea 	si,idati
+	mov	di,#0x31
+	mov 	cx,#0x09
+	repe
+	cmpsb
+	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
+	.ascii	"ATI"
+	.byte	0
+
+! AHEAD
+
+ahead_test:
+	mov	ax,#0x200f
+	mov	dx,#0x3ce
+	out	dx,ax
+	inc	dx
+	in	al,dx
+	cmp	al,#0x20
+	je	isahed
+	cmp	al,#0x21
+	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
+	.ascii	"Ahead"
+	.byte	0
+
+! Chips & Tech.
+
+chips_test:
+	mov	dx,#0x3c3
+	in	al,dx
+	or	al,#0x10
+	out	dx,al
+	mov	dx,#0x104		
+	in	al,dx
+	mov	bl,al
+	mov	dx,#0x3c3
+	in	al,dx
+	and	al,#0xef
+	out	dx,al
+	cmp	bl,#0xa5
+	je	cantok
+	xor	bp,bp
+cantok:	ret
+
+chips_md:
+	.byte	0x60, 0x19, 0x84
+	.byte	0x61, 0x32, 0x84
+	.byte	0
+	.ascii	"Chips & Technologies"
+	.byte	0
+
+! Cirrus Logic 5X0
+
+cirrus1_test:
+	mov	dx,#0x3d4
+	mov	al,#0x0c
+	out	dx,al
+	inc	dx
+	in	al,dx
+	mov	bl,al
+	xor	al,al
+	out	dx,al
+	dec	dx
+	mov	al,#0x1f
+	out	dx,al
+	inc	dx
+	in	al,dx
+	mov	bh,al
+	xor	ah,ah
+	shl	al,#4
+	mov	cx,ax
+	mov	al,bh
+	shr	al,#4
+	add	cx,ax
+	shl	cx,#8
+	add	cx,#6
+	mov	ax,cx
+	mov	dx,#0x3c4
+	out	dx,ax
+	inc	dx
+	in	al,dx
+	and	al,al
+	jnz	nocirr
+	mov	al,bh
+	out	dx,al
+	in	al,dx
+	cmp	al,#0x01
+	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
+
+cirrus1_md:
+	.byte	0x1f, 0x19, 0x84
+	.byte	0x20, 0x2c, 0x84
+	.byte	0x22, 0x1e, 0x84
+	.byte	0x31, 0x25, 0x64
+	.byte	0
+	.ascii	"Cirrus Logic 5X0"
+	.byte	0
+
+! Cirrus Logic 54XX
+
+cirrus5_test:
+	mov	dx,#0x3c4
+	mov	al,#6
+	call	inidx
+	mov	bl,al			! BL=backup
+	mov	ax,#6
+	call	tstidx
+	cmp	al,#0x0f
+	jne	c5fail
+	mov	ax,#0x1206
+	call	tstidx
+	cmp	al,#0x12
+	jne	c5fail
+	mov	al,#0x1e
+	call	inidx
+	mov	bh,al
+	mov	ah,bh
+	and	ah,#0xc0
+	mov	al,#0x1e
+	call	tstidx
+	and	al,#0x3f
+	jne	c5xx
+	mov	al,#0x1e
+	mov	ah,bh
+	or	ah,#0x3f
+	call	tstidx
+	xor	al,#0x3f
+	and	al,#0x3f
+c5xx:	pushf
+	mov	al,#0x1e
+	mov	ah,bh
+	out	dx,ax
+	popf
+	je	c5done
+c5fail:	xor	bp,bp
+c5done:	mov	al,#6
+	mov	ah,bl
+	out	dx,ax
+	ret
+
+cirrus5_md:
+	.byte	0x14, 0x19, 0x84
+	.byte	0x54, 0x2b, 0x84
+	.byte	0
+	.ascii	"Cirrus Logic 54XX"
+	.byte	0
+
+! Cirrus Logic 64XX -- no known extra modes, but must be identified, because
+! it's misidentified by the Ahead test.
+
+cirrus6_test:
+	mov	dx,#0x3ce
+	mov	al,#0x0a
+	call	inidx
+	mov	bl,al			! BL=backup
+	mov	ax,#0xce0a
+	call	tstidx
+	or	al,al
+	jne	c2fail
+	mov	ax,#0xec0a
+	call	tstidx
+	cmp	al,#0x01
+	jne	c2fail
+	mov	al,#0xaa
+	call	inidx	! 4X, 5X, 7X and 8X are valid 64XX chip ID's
+	shr	al,#4
+	sub	al,#4
+	jz	c6done
+	dec	al
+	jz	c6done
+	sub	al,#2
+	jz	c6done
+	dec	al
+	jz	c6done
+c2fail:	xor	bp,bp
+c6done:	mov	al,#0x0a
+	mov	ah,bl
+	out	dx,ax
+	ret
+
+cirrus6_md:
+	.byte	0
+	.ascii	"Cirrus Logic 64XX"
+	.byte	0
+
+! Everex / Trident
+
+everex_test:
+	mov	ax,#0x7000
+	xor	bx,bx
+	int	0x10
+	cmp	al,#0x70
+	jne	noevrx
+	shr	dx,#4
+	cmp	dx,#0x678
+	je	evtrid
+	cmp	dx,#0x236
+	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
+	.ascii	"Everex/Trident"
+	.byte	0
+
+! Genoa.
+
+genoa_test:
+	lea	si,idgenoa		! Check Genoa 'clues'
+	xor 	ax,ax
+	seg es
+	mov	al,[0x37]
+	mov	di,ax
+	mov	cx,#0x04
+	dec	si
+	dec	di
+l1:	inc	si
+	inc	di
+	mov	al,(si)
+	test	al,al
+	jz	l2
+	seg es
+	cmp	al,(di)
+l2:	loope 	l1
+	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
+	.ascii	"Genoa"
+	.byte	0
+
+! OAK
+
+oak_test:
+	lea	si,idoakvga
+	mov	di,#0x08
+	mov	cx,#0x08
+	repe
+	cmpsb
+	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
+	.ascii	"OAK"
+	.byte	0
+
+! WD Paradise.
+
+paradise_test:
+	lea	si,idparadise
+	mov	di,#0x7d
+	mov	cx,#0x04
+	repe
+	cmpsb
+	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
+	.ascii	"Paradise"
+	.byte	0
+
+! Trident.
+
+trident_test:
+	mov	dx,#0x3c4
+	mov	al,#0x0e
+	out	dx,al
+	inc	dx
+	in	al,dx
+	xchg	ah,al
+	xor	al,al
+	out	dx,al
+	in	al,dx
+	xchg	al,ah
+	mov	bl,al		! Strange thing ... in the book this wasn't
+	and	bl,#0x02	! necessary but it worked on my card which
+	jz	setb2		! is a trident. Without it the screen goes
+	and	al,#0xfd	! blurred ...
+	jmp	clrb2		!
+setb2:	or	al,#0x02	!
+clrb2:	out	dx,al
+	and	ah,#0x0f
+	cmp	ah,#0x02
+	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
+	.ascii	"Trident"
+	.byte	0
+
+! Tseng.
+
+tseng_test:
+	mov	dx,#0x3cd
+	in	al,dx			! Could things be this simple ! :-)
+	mov	bl,al
+	mov	al,#0x55
+	out	dx,al
+	in	al,dx
+	mov	ah,al
+	mov	al,bl
+	out	dx,al
+	cmp	ah,#0x55
+ 	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
+	.ascii	"Tseng"
+	.byte	0
+
+! Video7.
+
+video7_test:
+	mov	dx,#0x3cc
+	in	al,dx
+	mov	dx,#0x3b4
+	and	al,#0x01
+	jz	even7
+	mov	dx,#0x3d4
+even7:	mov	al,#0x0c
+	out	dx,al
+	inc	dx
+	in	al,dx
+	mov	bl,al
+	mov	al,#0x55
+	out	dx,al
+	in	al,dx
+	dec	dx
+	mov	al,#0x1f
+	out	dx,al
+	inc	dx
+	in	al,dx
+	mov	bh,al
+	dec	dx
+	mov	al,#0x0c
+	out	dx,al
+	inc	dx
+	mov	al,bl
+	out	dx,al
+	mov	al,#0x55
+	xor	al,#0xea
+	cmp	al,bh
+	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
+	.ascii	"Video 7"
+	.byte	0
+
+#endif	/* CONFIG_VIDEO_SVGA */
+
+!
+! User-defined local mode table (VGA only)
+!
+
+#ifdef CONFIG_VIDEO_LOCAL
+
+local_modes:
+	lea	si,local_mode_table
+locm1:	lodsw
+	or	ax,ax
+	jz	locm2
+	stosw
+	movsw
+	jmp	locm1
+locm2:	ret
+
+! This is the table of local video modes which can be supplied manually
+! by the user. Each entry consists of mode ID (word) and dimensions
+! (byte for column count and another byte for row count). These modes
+! are placed before all SVGA and VESA modes and override them if table
+! compacting is enabled. The table must end with a zero word followed
+! by NUL-terminated video adapter name.
+
+local_mode_table:
+	.word	0x0100		! Example: 40x25
+	.byte	25,40
+	.word	0
+	.ascii	"Local"
+	.byte	0
+
+#endif	/* CONFIG_VIDEO_LOCAL */
+
+!
+! Read a key and return the 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 hardware 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
+
+!
+! Print hexadecimal number.
+!
+
+prthw:	push	ax
+	mov	al,ah
+	call	prthb
+	pop	ax
+prthb:	push	ax
+	shr	al,#4
+	call	prthn
+	pop	ax
+	and	al,#0x0f
+prthn:	cmp	al,#0x0a
+	jc	prth1
+	add	al,#0x07
+prth1:	add	al,#0x30
+	br	prtchr
+
+!
+! Print decimal number (AL).
+!
+
+prtdec:	push	ax
+	push	cx
+	xor	ah,ah		! Clear ah
+	mov	cl,#0x0a
+	idiv	cl
+	cmp	al,#0x09
+	jbe	lt100
+	call	prtdec
+	jmp	skip10
+lt100:	add	al,#0x30
+	call	prtchr
+skip10:	mov	al,ah
+	add	al,#0x30
+	call	prtchr	
+	pop	cx
+	pop	ax
+	ret
+
+! Variables:
+
+adapter:	.byte	0	! Video adapter: 0=CGA/MDA/HGA,1=EGA,2=VGA
+def_mode:	.byte	0	! "Default mode selected" flag
+mt_end:		.word	0	! End of video mode table if built
+edit_buf:	.space	6	! Line editor buffer
+card_name:	.word	0	! Pointer to adapter name
+scanning:	.byte	0	! Performing mode scan
+do_restore:	.byte	0	! Screen contents altered during mode change
+video_segment:	.word	0xb800	! Video memory segment
+
+! Messages:
+
+keymsg:		.ascii	"Press <RETURN> to see video modes available, "
+		.ascii	"<SPACE> to continue or wait 30 secs"
+		db	0x0d, 0x0a, 0
+listhdr:	db	0x0d, 0x0a
+		.ascii	"Mode:    COLSxROWS:"
+crlft:		db	0x0d, 0x0a, 0
+prompt:		db	0x0d, 0x0a
+		.ascii	"Enter mode number: "
+		db	0
+unknt:		.ascii	"Unknown mode ID. Try again."
+		db	0
+badmdt:		.ascii	"You passed an undefined mode number to setup."
+		db	0x0d, 0x0a, 0
+vesaer:		.ascii	"Error: Scanning of VESA modes failed. Please "
+		.ascii	"report to <mj@k332.feld.cvut.cz>."
+		db	0x0d, 0x0a, 0
+old_name:	.ascii	"CGA/MDA/HGA"
+		db	0
+ega_name:	.ascii	"EGA"
+		db	0
+svga_name:	.ascii	" "
+vga_name:	.ascii	"VGA"
+		db	0
+vesa_name:	.ascii	"VESA"
+		db	0
+name_bann:	.ascii	"Video adapter: "
+		db	0

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