⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video.s

📁 linux-2.6.15.6
💻 S
📖 第 1 页 / 共 3 页
字号:
/*	video.S * *	Display adapter & video mode setup, version 2.13 (14-May-99) * *	Copyright (C) 1995 -- 1998 Martin Mares <mj@ucw.cz> *	Based on the original setup.S code (C) Linus Torvalds and Mats Anderson * *	Rewritten to use GNU 'as' by Chris Noe <stiker@northlink.com> May 1999 * *	For further information, look at Documentation/svga.txt. * */#include <linux/config.h> /* for CONFIG_VIDEO_* *//* Enable autodetection of SVGA adapters and modes. */#undef 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/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */#undef CONFIG_VIDEO_400_HACK/* Hack that lets you force specific BIOS mode ID and specific dimensions */#undef CONFIG_VIDEO_GFX_HACK#define VIDEO_GFX_BIOS_AX 0x4f02	/* 800x600 on ThinkPad */#define VIDEO_GFX_BIOS_BX 0x0102#define VIDEO_GFX_DUMMY_RESOLUTION 0x6425	/* 100x37 *//* 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/* Video7 special modes (BIOS number + 0x0900) */#define VIDEO_FIRST_V7 0x0900/* 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_80x30 0x0f05#define VIDEO_80x34 0x0f06#define VIDEO_80x60 0x0f07#define VIDEO_GFX_HACK 0x0f08#define VIDEO_LAST_SPECIAL 0x0f09/* 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 *//* (see also include/linux/tty.h) */#define PARAM_CURSOR_POS	0x00#define PARAM_VIDEO_PAGE	0x04#define PARAM_VIDEO_MODE	0x06#define PARAM_VIDEO_COLS	0x07#define PARAM_VIDEO_EGA_BX	0x0a#define PARAM_VIDEO_LINES	0x0e#define PARAM_HAVE_VGA		0x0f#define PARAM_FONT_POINTS	0x10#define PARAM_LFB_WIDTH		0x12#define PARAM_LFB_HEIGHT	0x14#define PARAM_LFB_DEPTH		0x16#define PARAM_LFB_BASE		0x18#define PARAM_LFB_SIZE		0x1c#define PARAM_LFB_LINELENGTH	0x24#define PARAM_LFB_COLORS	0x26#define PARAM_VESAPM_SEG	0x2e#define PARAM_VESAPM_OFF	0x30#define PARAM_LFB_PAGES		0x32#define PARAM_VESA_ATTRIB	0x34/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */#ifdef CONFIG_VIDEO_RETAIN#define DO_STORE call store_screen#else#define DO_STORE#endif /* CONFIG_VIDEO_RETAIN */# This is the main entry point called by setup.S# %ds *must* be pointing to the bootsectorvideo:	pushw	%ds		# We use different segments	pushw	%ds		# FS contains original DS	popw	%fs	pushw	%cs		# DS is equal to CS	popw	%ds	pushw	%cs		# ES is equal to CS	popw	%es	xorw	%ax, %ax	movw	%ax, %gs	# GS is zero	cld	call	basic_detect	# Basic adapter type testing (EGA/VGA/MDA/CGA)#ifdef CONFIG_VIDEO_SELECT	movw	%fs:(0x01fa), %ax		# User selected video mode	cmpw	$ASK_VGA, %ax			# Bring up the menu	jz	vid2	call	mode_set			# Set the mode	jc	vid1	leaw	badmdt, %si			# Invalid mode ID	call	prtstrvid2:	call	mode_menuvid1:#ifdef CONFIG_VIDEO_RETAIN	call	restore_screen			# Restore screen contents#endif /* CONFIG_VIDEO_RETAIN */	call	store_edid#endif /* CONFIG_VIDEO_SELECT */	call	mode_params			# Store mode parameters	popw	%ds				# Restore original DS	ret# Detect if we have CGA, MDA, EGA or VGA and pass it to the kernel.basic_detect:	movb	$0, %fs:(PARAM_HAVE_VGA)	movb	$0x12, %ah	# Check EGA/VGA	movb	$0x10, %bl	int	$0x10	movw	%bx, %fs:(PARAM_VIDEO_EGA_BX)	# Identifies EGA to the kernel	cmpb	$0x10, %bl			# No, it's a CGA/MDA/HGA card.	je	basret	incb	adapter	movw	$0x1a00, %ax			# Check EGA or VGA?	int	$0x10	cmpb	$0x1a, %al			# 1a means VGA...	jne	basret				# anything else is EGA.		incb	%fs:(PARAM_HAVE_VGA)		# We've detected a VGA	incb	adapterbasret:	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:#ifdef CONFIG_VIDEO_SELECT	cmpb	$0, graphic_mode	jnz	mopar_gr#endif	movb	$0x03, %ah			# Read cursor position	xorb	%bh, %bh	int	$0x10	movw	%dx, %fs:(PARAM_CURSOR_POS)	movb	$0x0f, %ah			# Read page/mode/width	int	$0x10	movw	%bx, %fs:(PARAM_VIDEO_PAGE)	movw	%ax, %fs:(PARAM_VIDEO_MODE)	# Video mode and screen width	cmpb	$0x7, %al			# MDA/HGA => segment differs	jnz	mopar0	movw	$0xb000, video_segmentmopar0: movw	%gs:(0x485), %ax		# Font size	movw	%ax, %fs:(PARAM_FONT_POINTS)	# (valid only on EGA/VGA)	movw	force_size, %ax			# Forced size?	orw	%ax, %ax	jz	mopar1	movb	%ah, %fs:(PARAM_VIDEO_COLS)	movb	%al, %fs:(PARAM_VIDEO_LINES)	retmopar1:	movb	$25, %al	cmpb	$0, adapter			# If we are on CGA/MDA/HGA, the	jz	mopar2				# screen must have 25 lines.	movb	%gs:(0x484), %al		# On EGA/VGA, use the EGA+ BIOS	incb	%al				# location of max lines.mopar2: movb	%al, %fs:(PARAM_VIDEO_LINES)	ret#ifdef CONFIG_VIDEO_SELECT# Fetching of VESA frame buffer parametersmopar_gr:	leaw	modelist+1024, %di	movb	$0x23, %fs:(PARAM_HAVE_VGA)	movw	16(%di), %ax	movw	%ax, %fs:(PARAM_LFB_LINELENGTH)	movw	18(%di), %ax	movw	%ax, %fs:(PARAM_LFB_WIDTH)	movw	20(%di), %ax	movw	%ax, %fs:(PARAM_LFB_HEIGHT)	movb	25(%di), %al	movb	$0, %ah	movw	%ax, %fs:(PARAM_LFB_DEPTH)	movb	29(%di), %al		movb	$0, %ah	movw	%ax, %fs:(PARAM_LFB_PAGES)	movl	40(%di), %eax	movl	%eax, %fs:(PARAM_LFB_BASE)	movl	31(%di), %eax	movl	%eax, %fs:(PARAM_LFB_COLORS)	movl	35(%di), %eax	movl	%eax, %fs:(PARAM_LFB_COLORS+4)	movw	0(%di), %ax	movw	%ax, %fs:(PARAM_VESA_ATTRIB)# get video mem size	leaw	modelist+1024, %di	movw	$0x4f00, %ax	int	$0x10	xorl	%eax, %eax	movw	18(%di), %ax	movl	%eax, %fs:(PARAM_LFB_SIZE)# switching the DAC to 8-bit is for <= 8 bpp only	movw	%fs:(PARAM_LFB_DEPTH), %ax	cmpw	$8, %ax	jg	dac_done# get DAC switching capability	xorl	%eax, %eax	movb	10(%di), %al	testb	$1, %al	jz	dac_set# attempt to switch DAC to 8-bit	movw	$0x4f08, %ax	movw	$0x0800, %bx	int	$0x10	cmpw	$0x004f, %ax	jne     dac_set	movb    %bh, dac_size		# store actual DAC sizedac_set:# set color size to DAC size	movb	dac_size, %al	movb	%al, %fs:(PARAM_LFB_COLORS+0)	movb	%al, %fs:(PARAM_LFB_COLORS+2)	movb	%al, %fs:(PARAM_LFB_COLORS+4)	movb	%al, %fs:(PARAM_LFB_COLORS+6)# set color offsets to 0	movb	$0, %fs:(PARAM_LFB_COLORS+1)	movb	$0, %fs:(PARAM_LFB_COLORS+3)	movb	$0, %fs:(PARAM_LFB_COLORS+5)	movb	$0, %fs:(PARAM_LFB_COLORS+7)dac_done:# get protected mode interface informations	movw	$0x4f0a, %ax	xorw	%bx, %bx	xorw	%di, %di	int	$0x10	cmp	$0x004f, %ax	jnz	no_pm	movw	%es, %fs:(PARAM_VESAPM_SEG)	movw	%di, %fs:(PARAM_VESAPM_OFF)no_pm:	ret# The video mode menumode_menu:	leaw	keymsg, %si			# "Return/Space/Timeout" message	call	prtstr	call	flushnokey:	call	getkt	cmpb	$0x0d, %al			# ENTER ?	je	listm				# yes - manual mode selection	cmpb	$0x20, %al			# SPACE ?	je	defmd1				# no - repeat	call 	beep	jmp	nokeydefmd1:	ret					# No mode chosen? Default 80x25listm:	call	mode_table			# List mode tablelistm0:	leaw	name_bann, %si			# Print adapter name	call	prtstr	movw	card_name, %si	orw	%si, %si	jnz	an2	movb	adapter, %al	leaw	old_name, %si	orb	%al, %al	jz	an1	leaw	ega_name, %si	decb	%al	jz	an1	leaw	vga_name, %si	jmp	an1an2:	call	prtstr	leaw	svga_name, %sian1:	call	prtstr	leaw	listhdr, %si			# Table header	call	prtstr	movb	$0x30, %dl			# DL holds mode number	leaw	modelist, %silm1:	cmpw	$ASK_VGA, (%si)			# End?	jz	lm2	movb	%dl, %al			# Menu selection number	call	prtchr	call	prtsp2	lodsw	call	prthw				# Mode ID	call	prtsp2	movb	0x1(%si), %al	call	prtdec				# Rows	movb	$0x78, %al			# the letter 'x'	call	prtchr	lodsw	call	prtdec				# Columns	movb	$0x0d, %al			# New line	call	prtchr	movb	$0x0a, %al	call	prtchr	incb	%dl				# Next character	cmpb	$0x3a, %dl	jnz	lm1	movb	$0x61, %dl	jmp	lm1lm2:	leaw	prompt, %si			# Mode prompt	call	prtstr	leaw	edit_buf, %di			# Editor bufferlm3:	call	getkey	cmpb	$0x0d, %al			# Enter?	jz	lment	cmpb	$0x08, %al			# Backspace?	jz	lmbs	cmpb	$0x20, %al			# Printable?	jc	lm3	cmpw	$edit_buf+4, %di		# Enough space?	jz	lm3	stosb	call	prtchr	jmp	lm3lmbs:	cmpw	$edit_buf, %di			# Backspace	jz	lm3	decw	%di	movb	$0x08, %al	call	prtchr	call	prtspc	movb	$0x08, %al	call	prtchr	jmp	lm3	lment:	movb	$0, (%di)	leaw	crlft, %si	call	prtstr	leaw	edit_buf, %si	cmpb	$0, (%si)			# Empty string = default mode	jz	lmdef	cmpb	$0, 1(%si)			# One character = menu selection	jz	mnusel	cmpw	$0x6373, (%si)			# "scan" => mode scanning	jnz	lmhx	cmpw	$0x6e61, 2(%si)	jz	lmscanlmhx:	xorw	%bx, %bx			# Else => mode ID in hexlmhex:	lodsb	orb	%al, %al	jz	lmuse1	subb	$0x30, %al	jc	lmbad	cmpb	$10, %al	jc	lmhx1	subb	$7, %al	andb	$0xdf, %al	cmpb	$10, %al	jc	lmbad	cmpb	$16, %al	jnc	lmbadlmhx1:	shlw	$4, %bx	orb	%al, %bl	jmp	lmhexlmuse1:	movw	%bx, %ax	jmp	lmusemnusel:	lodsb					# Menu selection	xorb	%ah, %ah	subb	$0x30, %al	jc	lmbad	cmpb	$10, %al	jc	lmuse		cmpb	$0x61-0x30, %al	jc	lmbad		subb	$0x61-0x30-10, %al	cmpb	$36, %al	jnc	lmbadlmuse:	call	mode_set	jc	lmdeflmbad:	leaw	unknt, %si	call	prtstr	jmp	lm2lmscan:	cmpb	$0, adapter			# Scanning only on EGA/VGA	jz	lmbad	movw	$0, mt_end			# Scanning of modes is	movb	$1, scanning			# done as new autodetection.	call	mode_table	jmp	listm0lmdef:	ret# Additional parts of mode_set... (relative jumps, you know)setv7:						# Video7 extended modes	DO_STORE	subb	$VIDEO_FIRST_V7>>8, %bh	movw	$0x6f05, %ax	int	$0x10	stc	ret_setrec:	jmp	setrec			# Ugly..._set_80x25:	jmp	set_80x25# Aliases for backward compatibility.setalias:	movw	$VIDEO_80x25, %ax	incw	%bx	jz	mode_set	movb	$VIDEO_8POINT-VIDEO_FIRST_SPECIAL, %al	incw	%bx	jnz	setbad				# Fall-through!# Setting of user mode (AX=mode ID) => CF=successmode_set:	movw	%ax, %fs:(0x01fa)		# Store mode for use in acpi_wakeup.S	movw	%ax, %bx	cmpb	$0xff, %ah	jz	setalias	testb	$VIDEO_RECALC>>8, %ah	jnz	_setrec	cmpb	$VIDEO_FIRST_RESOLUTION>>8, %ah	jnc	setres		cmpb	$VIDEO_FIRST_SPECIAL>>8, %ah	jz	setspc		cmpb	$VIDEO_FIRST_V7>>8, %ah	jz	setv7		cmpb	$VIDEO_FIRST_VESA>>8, %ah	jnc	check_vesa		orb	%ah, %ah	jz	setmenu		decb	%ah	jz	setbiossetbad:	clc	movb	$0, do_restore			# The screen needn't be restored	retsetvesa:	DO_STORE	subb	$VIDEO_FIRST_VESA>>8, %bh	movw	$0x4f02, %ax			# VESA BIOS mode set call	int	$0x10	cmpw	$0x004f, %ax			# AL=4f if implemented	jnz	setbad				# AH=0 if OK	stc	retsetbios:	DO_STORE	int	$0x10				# Standard BIOS mode set call	pushw	%bx	movb	$0x0f, %ah			# Check if really set	int	$0x10	popw	%bx	cmpb	%bl, %al	jnz	setbad		stc	retsetspc:	xorb	%bh, %bh			# Set special mode	cmpb	$VIDEO_LAST_SPECIAL-VIDEO_FIRST_SPECIAL, %bl	jnc	setbad		addw	%bx, %bx	jmp	*spec_inits(%bx)setmenu:	orb	%al, %al			# 80x25 is an exception	jz	_set_80x25		pushw	%bx				# Set mode chosen from menu	call	mode_table			# Build the mode table	popw	%ax	shlw	$2, %ax	addw	%ax, %si	cmpw	%di, %si	jnc	setbad		movw	(%si), %ax			# Fetch mode ID_m_s:	jmp	mode_setsetres:	pushw	%bx				# Set mode chosen by resolution	call	mode_table	popw	%bx	xchgb	%bl, %bhsetr1:	lodsw	cmpw	$ASK_VGA, %ax			# End of the list?	jz	setbad		lodsw	cmpw	%bx, %ax	jnz	setr1		movw	-4(%si), %ax			# Fetch mode ID	jmp	_m_scheck_vesa:	leaw	modelist+1024, %di	subb	$VIDEO_FIRST_VESA>>8, %bh	movw	%bx, %cx			# Get mode information structure	movw	$0x4f01, %ax	int	$0x10	addb	$VIDEO_FIRST_VESA>>8, %bh	cmpw	$0x004f, %ax	jnz	setbad	movb	(%di), %al			# Check capabilities.	andb	$0x19, %al	cmpb	$0x09, %al	jz	setvesa				# This is a text mode	movb	(%di), %al			# Check capabilities.	andb	$0x99, %al	cmpb	$0x99, %al	jnz	_setbad				# Doh! No linear frame buffer.	subb	$VIDEO_FIRST_VESA>>8, %bh	orw	$0x4000, %bx			# Use linear frame buffer	movw	$0x4f02, %ax			# VESA BIOS mode set call	int	$0x10	cmpw	$0x004f, %ax			# AL=4f if implemented	jnz	_setbad				# AH=0 if OK	movb	$1, graphic_mode		# flag graphic mode	movb	$0, do_restore			# no screen restore	stc	ret_setbad:	jmp	setbad          	# Ugly...# 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:	subb	$VIDEO_RECALC>>8, %ah		# Set the base mode	call	mode_set	jnc	rct3	movw	%gs:(0x485), %ax		# Font size in pixels	movb	%gs:(0x484), %bl		# Number of rows	incb	%bl	mulb	%bl				# Number of visible	decw	%ax				# scan lines - 1	movw	$0x3d4, %dx	movw	%ax, %bx	movb	$0x12, %al			# Lower 8 bits	movb	%bl, %ah	outw	%ax, %dx	movb	$0x07, %al		# Bits 8 and 9 in the overflow register	call	inidx	xchgb	%al, %ah	andb	$0xbd, %ah	shrb	%bh	jnc	rct1	orb	$0x02, %ahrct1:	shrb	%bh	jnc	rct2	orb	$0x40, %ahrct2:	movb	$0x07, %al	outw	%ax, %dx	stcrct3:	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	.word	set_80x30	.word	set_80x34	.word	set_80x60	.word	set_gfx# Set the 80x25 mode. If already set, do nothing.set_80x25:	movw	$0x5019, force_size		# Override possibly broken BIOSuse_80x25:#ifdef CONFIG_VIDEO_400_HACK	movw	$0x1202, %ax			# Force 400 scan lines	movb	$0x30, %bl	int	$0x10#else	movb	$0x0f, %ah			# Get current mode ID	int	$0x10	cmpw	$0x5007, %ax	# Mode 7 (80x25 mono) is the only one available	jz	st80		# on CGA/MDA/HGA and is also available on EGAM	cmpw	$0x5003, %ax	# Unknown mode, force 80x25 color	jnz	force3st80:	cmpb	$0, adapter	# CGA/MDA/HGA => mode 3/7 is always 80x25	jz	set80	movb	%gs:(0x0484), %al	# This is EGA+ -- beware of 80x50 etc.	orb	%al, %al		# Some buggy BIOS'es set 0 rows

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -