| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /*	video.S | 
|  | 2 | * | 
|  | 3 | *	Display adapter & video mode setup, version 2.13 (14-May-99) | 
|  | 4 | * | 
|  | 5 | *	Copyright (C) 1995 -- 1998 Martin Mares <mj@ucw.cz> | 
|  | 6 | *	Based on the original setup.S code (C) Linus Torvalds and Mats Anderson | 
|  | 7 | * | 
|  | 8 | *	Rewritten to use GNU 'as' by Chris Noe <stiker@northlink.com> May 1999 | 
|  | 9 | * | 
|  | 10 | *	For further information, look at Documentation/svga.txt. | 
|  | 11 | * | 
|  | 12 | */ | 
|  | 13 |  | 
|  | 14 | #include <linux/config.h> /* for CONFIG_VIDEO_* */ | 
|  | 15 |  | 
|  | 16 | /* Enable autodetection of SVGA adapters and modes. */ | 
|  | 17 | #undef CONFIG_VIDEO_SVGA | 
|  | 18 |  | 
|  | 19 | /* Enable autodetection of VESA modes */ | 
|  | 20 | #define CONFIG_VIDEO_VESA | 
|  | 21 |  | 
|  | 22 | /* Enable compacting of mode table */ | 
|  | 23 | #define CONFIG_VIDEO_COMPACT | 
|  | 24 |  | 
|  | 25 | /* Retain screen contents when switching modes */ | 
|  | 26 | #define CONFIG_VIDEO_RETAIN | 
|  | 27 |  | 
|  | 28 | /* Enable local mode list */ | 
|  | 29 | #undef CONFIG_VIDEO_LOCAL | 
|  | 30 |  | 
|  | 31 | /* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */ | 
|  | 32 | #undef CONFIG_VIDEO_400_HACK | 
|  | 33 |  | 
|  | 34 | /* Hack that lets you force specific BIOS mode ID and specific dimensions */ | 
|  | 35 | #undef CONFIG_VIDEO_GFX_HACK | 
|  | 36 | #define VIDEO_GFX_BIOS_AX 0x4f02	/* 800x600 on ThinkPad */ | 
|  | 37 | #define VIDEO_GFX_BIOS_BX 0x0102 | 
|  | 38 | #define VIDEO_GFX_DUMMY_RESOLUTION 0x6425	/* 100x37 */ | 
|  | 39 |  | 
|  | 40 | /* This code uses an extended set of video mode numbers. These include: | 
|  | 41 | * Aliases for standard modes | 
|  | 42 | *	NORMAL_VGA (-1) | 
|  | 43 | *	EXTENDED_VGA (-2) | 
|  | 44 | *	ASK_VGA (-3) | 
|  | 45 | * Video modes numbered by menu position -- NOT RECOMMENDED because of lack | 
|  | 46 | * of compatibility when extending the table. These are between 0x00 and 0xff. | 
|  | 47 | */ | 
|  | 48 | #define VIDEO_FIRST_MENU 0x0000 | 
|  | 49 |  | 
|  | 50 | /* Standard BIOS video modes (BIOS number + 0x0100) */ | 
|  | 51 | #define VIDEO_FIRST_BIOS 0x0100 | 
|  | 52 |  | 
|  | 53 | /* VESA BIOS video modes (VESA number + 0x0200) */ | 
|  | 54 | #define VIDEO_FIRST_VESA 0x0200 | 
|  | 55 |  | 
|  | 56 | /* Video7 special modes (BIOS number + 0x0900) */ | 
|  | 57 | #define VIDEO_FIRST_V7 0x0900 | 
|  | 58 |  | 
|  | 59 | /* Special video modes */ | 
|  | 60 | #define VIDEO_FIRST_SPECIAL 0x0f00 | 
|  | 61 | #define VIDEO_80x25 0x0f00 | 
|  | 62 | #define VIDEO_8POINT 0x0f01 | 
|  | 63 | #define VIDEO_80x43 0x0f02 | 
|  | 64 | #define VIDEO_80x28 0x0f03 | 
|  | 65 | #define VIDEO_CURRENT_MODE 0x0f04 | 
|  | 66 | #define VIDEO_80x30 0x0f05 | 
|  | 67 | #define VIDEO_80x34 0x0f06 | 
|  | 68 | #define VIDEO_80x60 0x0f07 | 
|  | 69 | #define VIDEO_GFX_HACK 0x0f08 | 
|  | 70 | #define VIDEO_LAST_SPECIAL 0x0f09 | 
|  | 71 |  | 
|  | 72 | /* Video modes given by resolution */ | 
|  | 73 | #define VIDEO_FIRST_RESOLUTION 0x1000 | 
|  | 74 |  | 
|  | 75 | /* The "recalculate timings" flag */ | 
|  | 76 | #define VIDEO_RECALC 0x8000 | 
|  | 77 |  | 
|  | 78 | /* Positions of various video parameters passed to the kernel */ | 
|  | 79 | /* (see also include/linux/tty.h) */ | 
|  | 80 | #define PARAM_CURSOR_POS	0x00 | 
|  | 81 | #define PARAM_VIDEO_PAGE	0x04 | 
|  | 82 | #define PARAM_VIDEO_MODE	0x06 | 
|  | 83 | #define PARAM_VIDEO_COLS	0x07 | 
|  | 84 | #define PARAM_VIDEO_EGA_BX	0x0a | 
|  | 85 | #define PARAM_VIDEO_LINES	0x0e | 
|  | 86 | #define PARAM_HAVE_VGA		0x0f | 
|  | 87 | #define PARAM_FONT_POINTS	0x10 | 
|  | 88 |  | 
|  | 89 | #define PARAM_LFB_WIDTH		0x12 | 
|  | 90 | #define PARAM_LFB_HEIGHT	0x14 | 
|  | 91 | #define PARAM_LFB_DEPTH		0x16 | 
|  | 92 | #define PARAM_LFB_BASE		0x18 | 
|  | 93 | #define PARAM_LFB_SIZE		0x1c | 
|  | 94 | #define PARAM_LFB_LINELENGTH	0x24 | 
|  | 95 | #define PARAM_LFB_COLORS	0x26 | 
|  | 96 | #define PARAM_VESAPM_SEG	0x2e | 
|  | 97 | #define PARAM_VESAPM_OFF	0x30 | 
|  | 98 | #define PARAM_LFB_PAGES		0x32 | 
|  | 99 | #define PARAM_VESA_ATTRIB	0x34 | 
|  | 100 |  | 
|  | 101 | /* Define DO_STORE according to CONFIG_VIDEO_RETAIN */ | 
|  | 102 | #ifdef CONFIG_VIDEO_RETAIN | 
|  | 103 | #define DO_STORE call store_screen | 
|  | 104 | #else | 
|  | 105 | #define DO_STORE | 
|  | 106 | #endif /* CONFIG_VIDEO_RETAIN */ | 
|  | 107 |  | 
|  | 108 | # This is the main entry point called by setup.S | 
|  | 109 | # %ds *must* be pointing to the bootsector | 
|  | 110 | video:	pushw	%ds		# We use different segments | 
|  | 111 | pushw	%ds		# FS contains original DS | 
|  | 112 | popw	%fs | 
|  | 113 | pushw	%cs		# DS is equal to CS | 
|  | 114 | popw	%ds | 
|  | 115 | pushw	%cs		# ES is equal to CS | 
|  | 116 | popw	%es | 
|  | 117 | xorw	%ax, %ax | 
|  | 118 | movw	%ax, %gs	# GS is zero | 
|  | 119 | cld | 
|  | 120 | call	basic_detect	# Basic adapter type testing (EGA/VGA/MDA/CGA) | 
|  | 121 | #ifdef CONFIG_VIDEO_SELECT | 
|  | 122 | movw	%fs:(0x01fa), %ax		# User selected video mode | 
|  | 123 | cmpw	$ASK_VGA, %ax			# Bring up the menu | 
|  | 124 | jz	vid2 | 
|  | 125 |  | 
|  | 126 | call	mode_set			# Set the mode | 
|  | 127 | jc	vid1 | 
|  | 128 |  | 
|  | 129 | leaw	badmdt, %si			# Invalid mode ID | 
|  | 130 | call	prtstr | 
|  | 131 | vid2:	call	mode_menu | 
|  | 132 | vid1: | 
|  | 133 | #ifdef CONFIG_VIDEO_RETAIN | 
|  | 134 | call	restore_screen			# Restore screen contents | 
|  | 135 | #endif /* CONFIG_VIDEO_RETAIN */ | 
|  | 136 | call	store_edid | 
|  | 137 | #endif /* CONFIG_VIDEO_SELECT */ | 
|  | 138 | call	mode_params			# Store mode parameters | 
|  | 139 | popw	%ds				# Restore original DS | 
|  | 140 | ret | 
|  | 141 |  | 
|  | 142 | # Detect if we have CGA, MDA, EGA or VGA and pass it to the kernel. | 
|  | 143 | basic_detect: | 
|  | 144 | movb	$0, %fs:(PARAM_HAVE_VGA) | 
|  | 145 | movb	$0x12, %ah	# Check EGA/VGA | 
|  | 146 | movb	$0x10, %bl | 
|  | 147 | int	$0x10 | 
|  | 148 | movw	%bx, %fs:(PARAM_VIDEO_EGA_BX)	# Identifies EGA to the kernel | 
|  | 149 | cmpb	$0x10, %bl			# No, it's a CGA/MDA/HGA card. | 
|  | 150 | je	basret | 
|  | 151 |  | 
|  | 152 | incb	adapter | 
|  | 153 | movw	$0x1a00, %ax			# Check EGA or VGA? | 
|  | 154 | int	$0x10 | 
|  | 155 | cmpb	$0x1a, %al			# 1a means VGA... | 
|  | 156 | jne	basret				# anything else is EGA. | 
|  | 157 |  | 
|  | 158 | incb	%fs:(PARAM_HAVE_VGA)		# We've detected a VGA | 
|  | 159 | incb	adapter | 
|  | 160 | basret:	ret | 
|  | 161 |  | 
|  | 162 | # Store the video mode parameters for later usage by the kernel. | 
|  | 163 | # This is done by asking the BIOS except for the rows/columns | 
|  | 164 | # parameters in the default 80x25 mode -- these are set directly, | 
|  | 165 | # because some very obscure BIOSes supply insane values. | 
|  | 166 | mode_params: | 
|  | 167 | #ifdef CONFIG_VIDEO_SELECT | 
|  | 168 | cmpb	$0, graphic_mode | 
|  | 169 | jnz	mopar_gr | 
|  | 170 | #endif | 
|  | 171 | movb	$0x03, %ah			# Read cursor position | 
|  | 172 | xorb	%bh, %bh | 
|  | 173 | int	$0x10 | 
|  | 174 | movw	%dx, %fs:(PARAM_CURSOR_POS) | 
|  | 175 | movb	$0x0f, %ah			# Read page/mode/width | 
|  | 176 | int	$0x10 | 
|  | 177 | movw	%bx, %fs:(PARAM_VIDEO_PAGE) | 
|  | 178 | movw	%ax, %fs:(PARAM_VIDEO_MODE)	# Video mode and screen width | 
|  | 179 | cmpb	$0x7, %al			# MDA/HGA => segment differs | 
|  | 180 | jnz	mopar0 | 
|  | 181 |  | 
|  | 182 | movw	$0xb000, video_segment | 
|  | 183 | mopar0: movw	%gs:(0x485), %ax		# Font size | 
|  | 184 | movw	%ax, %fs:(PARAM_FONT_POINTS)	# (valid only on EGA/VGA) | 
|  | 185 | movw	force_size, %ax			# Forced size? | 
|  | 186 | orw	%ax, %ax | 
|  | 187 | jz	mopar1 | 
|  | 188 |  | 
|  | 189 | movb	%ah, %fs:(PARAM_VIDEO_COLS) | 
|  | 190 | movb	%al, %fs:(PARAM_VIDEO_LINES) | 
|  | 191 | ret | 
|  | 192 |  | 
|  | 193 | mopar1:	movb	$25, %al | 
|  | 194 | cmpb	$0, adapter			# If we are on CGA/MDA/HGA, the | 
|  | 195 | jz	mopar2				# screen must have 25 lines. | 
|  | 196 |  | 
|  | 197 | movb	%gs:(0x484), %al		# On EGA/VGA, use the EGA+ BIOS | 
|  | 198 | incb	%al				# location of max lines. | 
|  | 199 | mopar2: movb	%al, %fs:(PARAM_VIDEO_LINES) | 
|  | 200 | ret | 
|  | 201 |  | 
|  | 202 | #ifdef CONFIG_VIDEO_SELECT | 
|  | 203 | # Fetching of VESA frame buffer parameters | 
|  | 204 | mopar_gr: | 
|  | 205 | leaw	modelist+1024, %di | 
|  | 206 | movb	$0x23, %fs:(PARAM_HAVE_VGA) | 
|  | 207 | movw	16(%di), %ax | 
|  | 208 | movw	%ax, %fs:(PARAM_LFB_LINELENGTH) | 
|  | 209 | movw	18(%di), %ax | 
|  | 210 | movw	%ax, %fs:(PARAM_LFB_WIDTH) | 
|  | 211 | movw	20(%di), %ax | 
|  | 212 | movw	%ax, %fs:(PARAM_LFB_HEIGHT) | 
|  | 213 | movb	25(%di), %al | 
|  | 214 | movb	$0, %ah | 
|  | 215 | movw	%ax, %fs:(PARAM_LFB_DEPTH) | 
|  | 216 | movb	29(%di), %al | 
|  | 217 | movb	$0, %ah | 
|  | 218 | movw	%ax, %fs:(PARAM_LFB_PAGES) | 
|  | 219 | movl	40(%di), %eax | 
|  | 220 | movl	%eax, %fs:(PARAM_LFB_BASE) | 
|  | 221 | movl	31(%di), %eax | 
|  | 222 | movl	%eax, %fs:(PARAM_LFB_COLORS) | 
|  | 223 | movl	35(%di), %eax | 
|  | 224 | movl	%eax, %fs:(PARAM_LFB_COLORS+4) | 
|  | 225 | movw	0(%di), %ax | 
|  | 226 | movw	%ax, %fs:(PARAM_VESA_ATTRIB) | 
|  | 227 |  | 
|  | 228 | # get video mem size | 
|  | 229 | leaw	modelist+1024, %di | 
|  | 230 | movw	$0x4f00, %ax | 
|  | 231 | int	$0x10 | 
|  | 232 | xorl	%eax, %eax | 
|  | 233 | movw	18(%di), %ax | 
|  | 234 | movl	%eax, %fs:(PARAM_LFB_SIZE) | 
|  | 235 |  | 
|  | 236 | # switching the DAC to 8-bit is for <= 8 bpp only | 
|  | 237 | movw	%fs:(PARAM_LFB_DEPTH), %ax | 
|  | 238 | cmpw	$8, %ax | 
|  | 239 | jg	dac_done | 
|  | 240 |  | 
|  | 241 | # get DAC switching capability | 
|  | 242 | xorl	%eax, %eax | 
|  | 243 | movb	10(%di), %al | 
|  | 244 | testb	$1, %al | 
|  | 245 | jz	dac_set | 
|  | 246 |  | 
|  | 247 | # attempt to switch DAC to 8-bit | 
|  | 248 | movw	$0x4f08, %ax | 
|  | 249 | movw	$0x0800, %bx | 
|  | 250 | int	$0x10 | 
|  | 251 | cmpw	$0x004f, %ax | 
|  | 252 | jne     dac_set | 
|  | 253 | movb    %bh, dac_size		# store actual DAC size | 
|  | 254 |  | 
|  | 255 | dac_set: | 
|  | 256 | # set color size to DAC size | 
|  | 257 | movb	dac_size, %al | 
|  | 258 | movb	%al, %fs:(PARAM_LFB_COLORS+0) | 
|  | 259 | movb	%al, %fs:(PARAM_LFB_COLORS+2) | 
|  | 260 | movb	%al, %fs:(PARAM_LFB_COLORS+4) | 
|  | 261 | movb	%al, %fs:(PARAM_LFB_COLORS+6) | 
|  | 262 |  | 
|  | 263 | # set color offsets to 0 | 
|  | 264 | movb	$0, %fs:(PARAM_LFB_COLORS+1) | 
|  | 265 | movb	$0, %fs:(PARAM_LFB_COLORS+3) | 
|  | 266 | movb	$0, %fs:(PARAM_LFB_COLORS+5) | 
|  | 267 | movb	$0, %fs:(PARAM_LFB_COLORS+7) | 
|  | 268 |  | 
|  | 269 | dac_done: | 
|  | 270 | # get protected mode interface informations | 
|  | 271 | movw	$0x4f0a, %ax | 
|  | 272 | xorw	%bx, %bx | 
|  | 273 | xorw	%di, %di | 
|  | 274 | int	$0x10 | 
|  | 275 | cmp	$0x004f, %ax | 
|  | 276 | jnz	no_pm | 
|  | 277 |  | 
|  | 278 | movw	%es, %fs:(PARAM_VESAPM_SEG) | 
|  | 279 | movw	%di, %fs:(PARAM_VESAPM_OFF) | 
|  | 280 | no_pm:	ret | 
|  | 281 |  | 
|  | 282 | # The video mode menu | 
|  | 283 | mode_menu: | 
|  | 284 | leaw	keymsg, %si			# "Return/Space/Timeout" message | 
|  | 285 | call	prtstr | 
|  | 286 | call	flush | 
|  | 287 | nokey:	call	getkt | 
|  | 288 |  | 
|  | 289 | cmpb	$0x0d, %al			# ENTER ? | 
|  | 290 | je	listm				# yes - manual mode selection | 
|  | 291 |  | 
|  | 292 | cmpb	$0x20, %al			# SPACE ? | 
|  | 293 | je	defmd1				# no - repeat | 
|  | 294 |  | 
|  | 295 | call 	beep | 
|  | 296 | jmp	nokey | 
|  | 297 |  | 
|  | 298 | defmd1:	ret					# No mode chosen? Default 80x25 | 
|  | 299 |  | 
|  | 300 | listm:	call	mode_table			# List mode table | 
|  | 301 | listm0:	leaw	name_bann, %si			# Print adapter name | 
|  | 302 | call	prtstr | 
|  | 303 | movw	card_name, %si | 
|  | 304 | orw	%si, %si | 
|  | 305 | jnz	an2 | 
|  | 306 |  | 
|  | 307 | movb	adapter, %al | 
|  | 308 | leaw	old_name, %si | 
|  | 309 | orb	%al, %al | 
|  | 310 | jz	an1 | 
|  | 311 |  | 
|  | 312 | leaw	ega_name, %si | 
|  | 313 | decb	%al | 
|  | 314 | jz	an1 | 
|  | 315 |  | 
|  | 316 | leaw	vga_name, %si | 
|  | 317 | jmp	an1 | 
|  | 318 |  | 
|  | 319 | an2:	call	prtstr | 
|  | 320 | leaw	svga_name, %si | 
|  | 321 | an1:	call	prtstr | 
|  | 322 | leaw	listhdr, %si			# Table header | 
|  | 323 | call	prtstr | 
|  | 324 | movb	$0x30, %dl			# DL holds mode number | 
|  | 325 | leaw	modelist, %si | 
|  | 326 | lm1:	cmpw	$ASK_VGA, (%si)			# End? | 
|  | 327 | jz	lm2 | 
|  | 328 |  | 
|  | 329 | movb	%dl, %al			# Menu selection number | 
|  | 330 | call	prtchr | 
|  | 331 | call	prtsp2 | 
|  | 332 | lodsw | 
|  | 333 | call	prthw				# Mode ID | 
|  | 334 | call	prtsp2 | 
|  | 335 | movb	0x1(%si), %al | 
|  | 336 | call	prtdec				# Rows | 
|  | 337 | movb	$0x78, %al			# the letter 'x' | 
|  | 338 | call	prtchr | 
|  | 339 | lodsw | 
|  | 340 | call	prtdec				# Columns | 
|  | 341 | movb	$0x0d, %al			# New line | 
|  | 342 | call	prtchr | 
|  | 343 | movb	$0x0a, %al | 
|  | 344 | call	prtchr | 
|  | 345 | incb	%dl				# Next character | 
|  | 346 | cmpb	$0x3a, %dl | 
|  | 347 | jnz	lm1 | 
|  | 348 |  | 
|  | 349 | movb	$0x61, %dl | 
|  | 350 | jmp	lm1 | 
|  | 351 |  | 
|  | 352 | lm2:	leaw	prompt, %si			# Mode prompt | 
|  | 353 | call	prtstr | 
|  | 354 | leaw	edit_buf, %di			# Editor buffer | 
|  | 355 | lm3:	call	getkey | 
|  | 356 | cmpb	$0x0d, %al			# Enter? | 
|  | 357 | jz	lment | 
|  | 358 |  | 
|  | 359 | cmpb	$0x08, %al			# Backspace? | 
|  | 360 | jz	lmbs | 
|  | 361 |  | 
|  | 362 | cmpb	$0x20, %al			# Printable? | 
|  | 363 | jc	lm3 | 
|  | 364 |  | 
|  | 365 | cmpw	$edit_buf+4, %di		# Enough space? | 
|  | 366 | jz	lm3 | 
|  | 367 |  | 
|  | 368 | stosb | 
|  | 369 | call	prtchr | 
|  | 370 | jmp	lm3 | 
|  | 371 |  | 
|  | 372 | lmbs:	cmpw	$edit_buf, %di			# Backspace | 
|  | 373 | jz	lm3 | 
|  | 374 |  | 
|  | 375 | decw	%di | 
|  | 376 | movb	$0x08, %al | 
|  | 377 | call	prtchr | 
|  | 378 | call	prtspc | 
|  | 379 | movb	$0x08, %al | 
|  | 380 | call	prtchr | 
|  | 381 | jmp	lm3 | 
|  | 382 |  | 
|  | 383 | lment:	movb	$0, (%di) | 
|  | 384 | leaw	crlft, %si | 
|  | 385 | call	prtstr | 
|  | 386 | leaw	edit_buf, %si | 
|  | 387 | cmpb	$0, (%si)			# Empty string = default mode | 
|  | 388 | jz	lmdef | 
|  | 389 |  | 
|  | 390 | cmpb	$0, 1(%si)			# One character = menu selection | 
|  | 391 | jz	mnusel | 
|  | 392 |  | 
|  | 393 | cmpw	$0x6373, (%si)			# "scan" => mode scanning | 
|  | 394 | jnz	lmhx | 
|  | 395 |  | 
|  | 396 | cmpw	$0x6e61, 2(%si) | 
|  | 397 | jz	lmscan | 
|  | 398 |  | 
|  | 399 | lmhx:	xorw	%bx, %bx			# Else => mode ID in hex | 
|  | 400 | lmhex:	lodsb | 
|  | 401 | orb	%al, %al | 
|  | 402 | jz	lmuse1 | 
|  | 403 |  | 
|  | 404 | subb	$0x30, %al | 
|  | 405 | jc	lmbad | 
|  | 406 |  | 
|  | 407 | cmpb	$10, %al | 
|  | 408 | jc	lmhx1 | 
|  | 409 |  | 
|  | 410 | subb	$7, %al | 
|  | 411 | andb	$0xdf, %al | 
|  | 412 | cmpb	$10, %al | 
|  | 413 | jc	lmbad | 
|  | 414 |  | 
|  | 415 | cmpb	$16, %al | 
|  | 416 | jnc	lmbad | 
|  | 417 |  | 
|  | 418 | lmhx1:	shlw	$4, %bx | 
|  | 419 | orb	%al, %bl | 
|  | 420 | jmp	lmhex | 
|  | 421 |  | 
|  | 422 | lmuse1:	movw	%bx, %ax | 
|  | 423 | jmp	lmuse | 
|  | 424 |  | 
|  | 425 | mnusel:	lodsb					# Menu selection | 
|  | 426 | xorb	%ah, %ah | 
|  | 427 | subb	$0x30, %al | 
|  | 428 | jc	lmbad | 
|  | 429 |  | 
|  | 430 | cmpb	$10, %al | 
|  | 431 | jc	lmuse | 
|  | 432 |  | 
|  | 433 | cmpb	$0x61-0x30, %al | 
|  | 434 | jc	lmbad | 
|  | 435 |  | 
|  | 436 | subb	$0x61-0x30-10, %al | 
|  | 437 | cmpb	$36, %al | 
|  | 438 | jnc	lmbad | 
|  | 439 |  | 
|  | 440 | lmuse:	call	mode_set | 
|  | 441 | jc	lmdef | 
|  | 442 |  | 
|  | 443 | lmbad:	leaw	unknt, %si | 
|  | 444 | call	prtstr | 
|  | 445 | jmp	lm2 | 
|  | 446 | lmscan:	cmpb	$0, adapter			# Scanning only on EGA/VGA | 
|  | 447 | jz	lmbad | 
|  | 448 |  | 
|  | 449 | movw	$0, mt_end			# Scanning of modes is | 
|  | 450 | movb	$1, scanning			# done as new autodetection. | 
|  | 451 | call	mode_table | 
|  | 452 | jmp	listm0 | 
|  | 453 | lmdef:	ret | 
|  | 454 |  | 
|  | 455 | # Additional parts of mode_set... (relative jumps, you know) | 
|  | 456 | setv7:						# Video7 extended modes | 
|  | 457 | DO_STORE | 
|  | 458 | subb	$VIDEO_FIRST_V7>>8, %bh | 
|  | 459 | movw	$0x6f05, %ax | 
|  | 460 | int	$0x10 | 
|  | 461 | stc | 
|  | 462 | ret | 
|  | 463 |  | 
|  | 464 | _setrec:	jmp	setrec			# Ugly... | 
|  | 465 | _set_80x25:	jmp	set_80x25 | 
|  | 466 |  | 
|  | 467 | # Aliases for backward compatibility. | 
|  | 468 | setalias: | 
|  | 469 | movw	$VIDEO_80x25, %ax | 
|  | 470 | incw	%bx | 
|  | 471 | jz	mode_set | 
|  | 472 |  | 
|  | 473 | movb	$VIDEO_8POINT-VIDEO_FIRST_SPECIAL, %al | 
|  | 474 | incw	%bx | 
|  | 475 | jnz	setbad				# Fall-through! | 
|  | 476 |  | 
|  | 477 | # Setting of user mode (AX=mode ID) => CF=success | 
|  | 478 | mode_set: | 
|  | 479 | movw	%ax, %fs:(0x01fa)		# Store mode for use in acpi_wakeup.S | 
|  | 480 | movw	%ax, %bx | 
|  | 481 | cmpb	$0xff, %ah | 
|  | 482 | jz	setalias | 
|  | 483 |  | 
|  | 484 | testb	$VIDEO_RECALC>>8, %ah | 
|  | 485 | jnz	_setrec | 
|  | 486 |  | 
|  | 487 | cmpb	$VIDEO_FIRST_RESOLUTION>>8, %ah | 
|  | 488 | jnc	setres | 
|  | 489 |  | 
|  | 490 | cmpb	$VIDEO_FIRST_SPECIAL>>8, %ah | 
|  | 491 | jz	setspc | 
|  | 492 |  | 
|  | 493 | cmpb	$VIDEO_FIRST_V7>>8, %ah | 
|  | 494 | jz	setv7 | 
|  | 495 |  | 
|  | 496 | cmpb	$VIDEO_FIRST_VESA>>8, %ah | 
|  | 497 | jnc	check_vesa | 
|  | 498 |  | 
|  | 499 | orb	%ah, %ah | 
|  | 500 | jz	setmenu | 
|  | 501 |  | 
|  | 502 | decb	%ah | 
|  | 503 | jz	setbios | 
|  | 504 |  | 
|  | 505 | setbad:	clc | 
|  | 506 | movb	$0, do_restore			# The screen needn't be restored | 
|  | 507 | ret | 
|  | 508 |  | 
|  | 509 | setvesa: | 
|  | 510 | DO_STORE | 
|  | 511 | subb	$VIDEO_FIRST_VESA>>8, %bh | 
|  | 512 | movw	$0x4f02, %ax			# VESA BIOS mode set call | 
|  | 513 | int	$0x10 | 
|  | 514 | cmpw	$0x004f, %ax			# AL=4f if implemented | 
|  | 515 | jnz	setbad				# AH=0 if OK | 
|  | 516 |  | 
|  | 517 | stc | 
|  | 518 | ret | 
|  | 519 |  | 
|  | 520 | setbios: | 
|  | 521 | DO_STORE | 
|  | 522 | int	$0x10				# Standard BIOS mode set call | 
|  | 523 | pushw	%bx | 
|  | 524 | movb	$0x0f, %ah			# Check if really set | 
|  | 525 | int	$0x10 | 
|  | 526 | popw	%bx | 
|  | 527 | cmpb	%bl, %al | 
|  | 528 | jnz	setbad | 
|  | 529 |  | 
|  | 530 | stc | 
|  | 531 | ret | 
|  | 532 |  | 
|  | 533 | setspc:	xorb	%bh, %bh			# Set special mode | 
|  | 534 | cmpb	$VIDEO_LAST_SPECIAL-VIDEO_FIRST_SPECIAL, %bl | 
|  | 535 | jnc	setbad | 
|  | 536 |  | 
|  | 537 | addw	%bx, %bx | 
|  | 538 | jmp	*spec_inits(%bx) | 
|  | 539 |  | 
|  | 540 | setmenu: | 
|  | 541 | orb	%al, %al			# 80x25 is an exception | 
|  | 542 | jz	_set_80x25 | 
|  | 543 |  | 
|  | 544 | pushw	%bx				# Set mode chosen from menu | 
|  | 545 | call	mode_table			# Build the mode table | 
|  | 546 | popw	%ax | 
|  | 547 | shlw	$2, %ax | 
|  | 548 | addw	%ax, %si | 
|  | 549 | cmpw	%di, %si | 
|  | 550 | jnc	setbad | 
|  | 551 |  | 
|  | 552 | movw	(%si), %ax			# Fetch mode ID | 
|  | 553 | _m_s:	jmp	mode_set | 
|  | 554 |  | 
|  | 555 | setres:	pushw	%bx				# Set mode chosen by resolution | 
|  | 556 | call	mode_table | 
|  | 557 | popw	%bx | 
|  | 558 | xchgb	%bl, %bh | 
|  | 559 | setr1:	lodsw | 
|  | 560 | cmpw	$ASK_VGA, %ax			# End of the list? | 
|  | 561 | jz	setbad | 
|  | 562 |  | 
|  | 563 | lodsw | 
|  | 564 | cmpw	%bx, %ax | 
|  | 565 | jnz	setr1 | 
|  | 566 |  | 
|  | 567 | movw	-4(%si), %ax			# Fetch mode ID | 
|  | 568 | jmp	_m_s | 
|  | 569 |  | 
|  | 570 | check_vesa: | 
|  | 571 | leaw	modelist+1024, %di | 
|  | 572 | subb	$VIDEO_FIRST_VESA>>8, %bh | 
|  | 573 | movw	%bx, %cx			# Get mode information structure | 
|  | 574 | movw	$0x4f01, %ax | 
|  | 575 | int	$0x10 | 
|  | 576 | addb	$VIDEO_FIRST_VESA>>8, %bh | 
|  | 577 | cmpw	$0x004f, %ax | 
|  | 578 | jnz	setbad | 
|  | 579 |  | 
|  | 580 | movb	(%di), %al			# Check capabilities. | 
|  | 581 | andb	$0x19, %al | 
|  | 582 | cmpb	$0x09, %al | 
|  | 583 | jz	setvesa				# This is a text mode | 
|  | 584 |  | 
|  | 585 | movb	(%di), %al			# Check capabilities. | 
|  | 586 | andb	$0x99, %al | 
|  | 587 | cmpb	$0x99, %al | 
|  | 588 | jnz	_setbad				# Doh! No linear frame buffer. | 
|  | 589 |  | 
|  | 590 | subb	$VIDEO_FIRST_VESA>>8, %bh | 
|  | 591 | orw	$0x4000, %bx			# Use linear frame buffer | 
|  | 592 | movw	$0x4f02, %ax			# VESA BIOS mode set call | 
|  | 593 | int	$0x10 | 
|  | 594 | cmpw	$0x004f, %ax			# AL=4f if implemented | 
|  | 595 | jnz	_setbad				# AH=0 if OK | 
|  | 596 |  | 
|  | 597 | movb	$1, graphic_mode		# flag graphic mode | 
|  | 598 | movb	$0, do_restore			# no screen restore | 
|  | 599 | stc | 
|  | 600 | ret | 
|  | 601 |  | 
|  | 602 | _setbad:	jmp	setbad          	# Ugly... | 
|  | 603 |  | 
|  | 604 | # Recalculate vertical display end registers -- this fixes various | 
|  | 605 | # inconsistencies of extended modes on many adapters. Called when | 
|  | 606 | # the VIDEO_RECALC flag is set in the mode ID. | 
|  | 607 |  | 
|  | 608 | setrec:	subb	$VIDEO_RECALC>>8, %ah		# Set the base mode | 
|  | 609 | call	mode_set | 
|  | 610 | jnc	rct3 | 
|  | 611 |  | 
|  | 612 | movw	%gs:(0x485), %ax		# Font size in pixels | 
|  | 613 | movb	%gs:(0x484), %bl		# Number of rows | 
|  | 614 | incb	%bl | 
|  | 615 | mulb	%bl				# Number of visible | 
|  | 616 | decw	%ax				# scan lines - 1 | 
|  | 617 | movw	$0x3d4, %dx | 
|  | 618 | movw	%ax, %bx | 
|  | 619 | movb	$0x12, %al			# Lower 8 bits | 
|  | 620 | movb	%bl, %ah | 
|  | 621 | outw	%ax, %dx | 
|  | 622 | movb	$0x07, %al		# Bits 8 and 9 in the overflow register | 
|  | 623 | call	inidx | 
|  | 624 | xchgb	%al, %ah | 
|  | 625 | andb	$0xbd, %ah | 
|  | 626 | shrb	%bh | 
|  | 627 | jnc	rct1 | 
|  | 628 | orb	$0x02, %ah | 
|  | 629 | rct1:	shrb	%bh | 
|  | 630 | jnc	rct2 | 
|  | 631 | orb	$0x40, %ah | 
|  | 632 | rct2:	movb	$0x07, %al | 
|  | 633 | outw	%ax, %dx | 
|  | 634 | stc | 
|  | 635 | rct3:	ret | 
|  | 636 |  | 
|  | 637 | # Table of routines for setting of the special modes. | 
|  | 638 | spec_inits: | 
|  | 639 | .word	set_80x25 | 
|  | 640 | .word	set_8pixel | 
|  | 641 | .word	set_80x43 | 
|  | 642 | .word	set_80x28 | 
|  | 643 | .word	set_current | 
|  | 644 | .word	set_80x30 | 
|  | 645 | .word	set_80x34 | 
|  | 646 | .word	set_80x60 | 
|  | 647 | .word	set_gfx | 
|  | 648 |  | 
|  | 649 | # Set the 80x25 mode. If already set, do nothing. | 
|  | 650 | set_80x25: | 
|  | 651 | movw	$0x5019, force_size		# Override possibly broken BIOS | 
|  | 652 | use_80x25: | 
|  | 653 | #ifdef CONFIG_VIDEO_400_HACK | 
|  | 654 | movw	$0x1202, %ax			# Force 400 scan lines | 
|  | 655 | movb	$0x30, %bl | 
|  | 656 | int	$0x10 | 
|  | 657 | #else | 
|  | 658 | movb	$0x0f, %ah			# Get current mode ID | 
|  | 659 | int	$0x10 | 
|  | 660 | cmpw	$0x5007, %ax	# Mode 7 (80x25 mono) is the only one available | 
|  | 661 | jz	st80		# on CGA/MDA/HGA and is also available on EGAM | 
|  | 662 |  | 
|  | 663 | cmpw	$0x5003, %ax	# Unknown mode, force 80x25 color | 
|  | 664 | jnz	force3 | 
|  | 665 |  | 
|  | 666 | st80:	cmpb	$0, adapter	# CGA/MDA/HGA => mode 3/7 is always 80x25 | 
|  | 667 | jz	set80 | 
|  | 668 |  | 
|  | 669 | movb	%gs:(0x0484), %al	# This is EGA+ -- beware of 80x50 etc. | 
|  | 670 | orb	%al, %al		# Some buggy BIOS'es set 0 rows | 
|  | 671 | jz	set80 | 
|  | 672 |  | 
|  | 673 | cmpb	$24, %al		# It's hopefully correct | 
|  | 674 | jz	set80 | 
|  | 675 | #endif /* CONFIG_VIDEO_400_HACK */ | 
|  | 676 | force3:	DO_STORE | 
|  | 677 | movw	$0x0003, %ax			# Forced set | 
|  | 678 | int	$0x10 | 
|  | 679 | set80:	stc | 
|  | 680 | ret | 
|  | 681 |  | 
|  | 682 | # Set the 80x50/80x43 8-pixel mode. Simple BIOS calls. | 
|  | 683 | set_8pixel: | 
|  | 684 | DO_STORE | 
|  | 685 | call	use_80x25			# The base is 80x25 | 
|  | 686 | set_8pt: | 
|  | 687 | movw	$0x1112, %ax			# Use 8x8 font | 
|  | 688 | xorb	%bl, %bl | 
|  | 689 | int	$0x10 | 
|  | 690 | movw	$0x1200, %ax			# Use alternate print screen | 
|  | 691 | movb	$0x20, %bl | 
|  | 692 | int	$0x10 | 
|  | 693 | movw	$0x1201, %ax			# Turn off cursor emulation | 
|  | 694 | movb	$0x34, %bl | 
|  | 695 | int	$0x10 | 
|  | 696 | movb	$0x01, %ah			# Define cursor scan lines 6-7 | 
|  | 697 | movw	$0x0607, %cx | 
|  | 698 | int	$0x10 | 
|  | 699 | set_current: | 
|  | 700 | stc | 
|  | 701 | ret | 
|  | 702 |  | 
|  | 703 | # Set the 80x28 mode. This mode works on all VGA's, because it's a standard | 
|  | 704 | # 80x25 mode with 14-point fonts instead of 16-point. | 
|  | 705 | set_80x28: | 
|  | 706 | DO_STORE | 
|  | 707 | call	use_80x25			# The base is 80x25 | 
|  | 708 | set14:	movw	$0x1111, %ax			# Use 9x14 font | 
|  | 709 | xorb	%bl, %bl | 
|  | 710 | int	$0x10 | 
|  | 711 | movb	$0x01, %ah			# Define cursor scan lines 11-12 | 
|  | 712 | movw	$0x0b0c, %cx | 
|  | 713 | int	$0x10 | 
|  | 714 | stc | 
|  | 715 | ret | 
|  | 716 |  | 
|  | 717 | # Set the 80x43 mode. This mode is works on all VGA's. | 
|  | 718 | # It's a 350-scanline mode with 8-pixel font. | 
|  | 719 | set_80x43: | 
|  | 720 | DO_STORE | 
|  | 721 | movw	$0x1201, %ax			# Set 350 scans | 
|  | 722 | movb	$0x30, %bl | 
|  | 723 | int	$0x10 | 
|  | 724 | movw	$0x0003, %ax			# Reset video mode | 
|  | 725 | int	$0x10 | 
|  | 726 | jmp	set_8pt				# Use 8-pixel font | 
|  | 727 |  | 
|  | 728 | # Set the 80x30 mode (all VGA's). 480 scanlines, 16-pixel font. | 
|  | 729 | set_80x30: | 
|  | 730 | call	use_80x25			# Start with real 80x25 | 
|  | 731 | DO_STORE | 
|  | 732 | movw	$0x3cc, %dx			# Get CRTC port | 
|  | 733 | inb	%dx, %al | 
|  | 734 | movb	$0xd4, %dl | 
|  | 735 | rorb	%al				# Mono or color? | 
|  | 736 | jc	set48a | 
|  | 737 |  | 
|  | 738 | movb	$0xb4, %dl | 
|  | 739 | set48a:	movw	$0x0c11, %ax		# Vertical sync end (also unlocks CR0-7) | 
|  | 740 | call	outidx | 
|  | 741 | movw	$0x0b06, %ax			# Vertical total | 
|  | 742 | call	outidx | 
|  | 743 | movw	$0x3e07, %ax			# (Vertical) overflow | 
|  | 744 | call	outidx | 
|  | 745 | movw	$0xea10, %ax			# Vertical sync start | 
|  | 746 | call	outidx | 
|  | 747 | movw	$0xdf12, %ax			# Vertical display end | 
|  | 748 | call	outidx | 
|  | 749 | movw	$0xe715, %ax			# Vertical blank start | 
|  | 750 | call	outidx | 
|  | 751 | movw	$0x0416, %ax			# Vertical blank end | 
|  | 752 | call	outidx | 
|  | 753 | pushw	%dx | 
|  | 754 | movb	$0xcc, %dl			# Misc output register (read) | 
|  | 755 | inb	%dx, %al | 
|  | 756 | movb	$0xc2, %dl			# (write) | 
|  | 757 | andb	$0x0d, %al	# Preserve clock select bits and color bit | 
|  | 758 | orb	$0xe2, %al			# Set correct sync polarity | 
|  | 759 | outb	%al, %dx | 
|  | 760 | popw	%dx | 
|  | 761 | movw	$0x501e, force_size | 
|  | 762 | stc					# That's all. | 
|  | 763 | ret | 
|  | 764 |  | 
|  | 765 | # Set the 80x34 mode (all VGA's). 480 scans, 14-pixel font. | 
|  | 766 | set_80x34: | 
|  | 767 | call	set_80x30			# Set 480 scans | 
|  | 768 | call	set14				# And 14-pt font | 
|  | 769 | movw	$0xdb12, %ax			# VGA vertical display end | 
|  | 770 | movw	$0x5022, force_size | 
|  | 771 | setvde:	call	outidx | 
|  | 772 | stc | 
|  | 773 | ret | 
|  | 774 |  | 
|  | 775 | # Set the 80x60 mode (all VGA's). 480 scans, 8-pixel font. | 
|  | 776 | set_80x60: | 
|  | 777 | call	set_80x30			# Set 480 scans | 
|  | 778 | call	set_8pt				# And 8-pt font | 
|  | 779 | movw	$0xdf12, %ax			# VGA vertical display end | 
|  | 780 | movw	$0x503c, force_size | 
|  | 781 | jmp	setvde | 
|  | 782 |  | 
|  | 783 | # Special hack for ThinkPad graphics | 
|  | 784 | set_gfx: | 
|  | 785 | #ifdef CONFIG_VIDEO_GFX_HACK | 
|  | 786 | movw	$VIDEO_GFX_BIOS_AX, %ax | 
|  | 787 | movw	$VIDEO_GFX_BIOS_BX, %bx | 
|  | 788 | int	$0x10 | 
|  | 789 | movw	$VIDEO_GFX_DUMMY_RESOLUTION, force_size | 
|  | 790 | stc | 
|  | 791 | #endif | 
|  | 792 | ret | 
|  | 793 |  | 
|  | 794 | #ifdef CONFIG_VIDEO_RETAIN | 
|  | 795 |  | 
|  | 796 | # Store screen contents to temporary buffer. | 
|  | 797 | store_screen: | 
|  | 798 | cmpb	$0, do_restore			# Already stored? | 
|  | 799 | jnz	stsr | 
|  | 800 |  | 
|  | 801 | testb	$CAN_USE_HEAP, loadflags	# Have we space for storing? | 
|  | 802 | jz	stsr | 
|  | 803 |  | 
|  | 804 | pushw	%ax | 
|  | 805 | pushw	%bx | 
|  | 806 | pushw	force_size			# Don't force specific size | 
|  | 807 | movw	$0, force_size | 
|  | 808 | call	mode_params			# Obtain params of current mode | 
|  | 809 | popw	force_size | 
|  | 810 | movb	%fs:(PARAM_VIDEO_LINES), %ah | 
|  | 811 | movb	%fs:(PARAM_VIDEO_COLS), %al | 
|  | 812 | movw	%ax, %bx			# BX=dimensions | 
|  | 813 | mulb	%ah | 
|  | 814 | movw	%ax, %cx			# CX=number of characters | 
|  | 815 | addw	%ax, %ax			# Calculate image size | 
|  | 816 | addw	$modelist+1024+4, %ax | 
|  | 817 | cmpw	heap_end_ptr, %ax | 
|  | 818 | jnc	sts1				# Unfortunately, out of memory | 
|  | 819 |  | 
|  | 820 | movw	%fs:(PARAM_CURSOR_POS), %ax	# Store mode params | 
|  | 821 | leaw	modelist+1024, %di | 
|  | 822 | stosw | 
|  | 823 | movw	%bx, %ax | 
|  | 824 | stosw | 
|  | 825 | pushw	%ds				# Store the screen | 
|  | 826 | movw	video_segment, %ds | 
|  | 827 | xorw	%si, %si | 
|  | 828 | rep | 
|  | 829 | movsw | 
|  | 830 | popw	%ds | 
|  | 831 | incb	do_restore			# Screen will be restored later | 
|  | 832 | sts1:	popw	%bx | 
|  | 833 | popw	%ax | 
|  | 834 | stsr:	ret | 
|  | 835 |  | 
|  | 836 | # Restore screen contents from temporary buffer. | 
|  | 837 | restore_screen: | 
|  | 838 | cmpb	$0, do_restore			# Has the screen been stored? | 
|  | 839 | jz	res1 | 
|  | 840 |  | 
|  | 841 | call	mode_params			# Get parameters of current mode | 
|  | 842 | movb	%fs:(PARAM_VIDEO_LINES), %cl | 
|  | 843 | movb	%fs:(PARAM_VIDEO_COLS), %ch | 
|  | 844 | leaw	modelist+1024, %si		# Screen buffer | 
|  | 845 | lodsw					# Set cursor position | 
|  | 846 | movw	%ax, %dx | 
|  | 847 | cmpb	%cl, %dh | 
|  | 848 | jc	res2 | 
|  | 849 |  | 
|  | 850 | movb	%cl, %dh | 
|  | 851 | decb	%dh | 
|  | 852 | res2:	cmpb	%ch, %dl | 
|  | 853 | jc	res3 | 
|  | 854 |  | 
|  | 855 | movb	%ch, %dl | 
|  | 856 | decb	%dl | 
|  | 857 | res3:	movb	$0x02, %ah | 
|  | 858 | movb	$0x00, %bh | 
|  | 859 | int	$0x10 | 
|  | 860 | lodsw					# Display size | 
|  | 861 | movb	%ah, %dl			# DL=number of lines | 
|  | 862 | movb	$0, %ah				# BX=phys. length of orig. line | 
|  | 863 | movw	%ax, %bx | 
|  | 864 | cmpb	%cl, %dl			# Too many? | 
|  | 865 | jc	res4 | 
|  | 866 |  | 
|  | 867 | pushw	%ax | 
|  | 868 | movb	%dl, %al | 
|  | 869 | subb	%cl, %al | 
|  | 870 | mulb	%bl | 
|  | 871 | addw	%ax, %si | 
|  | 872 | addw	%ax, %si | 
|  | 873 | popw	%ax | 
|  | 874 | movb	%cl, %dl | 
|  | 875 | res4:	cmpb	%ch, %al			# Too wide? | 
|  | 876 | jc	res5 | 
|  | 877 |  | 
|  | 878 | movb	%ch, %al			# AX=width of src. line | 
|  | 879 | res5:	movb	$0, %cl | 
|  | 880 | xchgb	%ch, %cl | 
|  | 881 | movw	%cx, %bp			# BP=width of dest. line | 
|  | 882 | pushw	%es | 
|  | 883 | movw	video_segment, %es | 
|  | 884 | xorw	%di, %di			# Move the data | 
|  | 885 | addw	%bx, %bx			# Convert BX and BP to _bytes_ | 
|  | 886 | addw	%bp, %bp | 
|  | 887 | res6:	pushw	%si | 
|  | 888 | pushw	%di | 
|  | 889 | movw	%ax, %cx | 
|  | 890 | rep | 
|  | 891 | movsw | 
|  | 892 | popw	%di | 
|  | 893 | popw	%si | 
|  | 894 | addw	%bp, %di | 
|  | 895 | addw	%bx, %si | 
|  | 896 | decb	%dl | 
|  | 897 | jnz	res6 | 
|  | 898 |  | 
|  | 899 | popw	%es				# Done | 
|  | 900 | res1:	ret | 
|  | 901 | #endif /* CONFIG_VIDEO_RETAIN */ | 
|  | 902 |  | 
|  | 903 | # Write to indexed VGA register (AL=index, AH=data, DX=index reg. port) | 
|  | 904 | outidx:	outb	%al, %dx | 
|  | 905 | pushw	%ax | 
|  | 906 | movb	%ah, %al | 
|  | 907 | incw	%dx | 
|  | 908 | outb	%al, %dx | 
|  | 909 | decw	%dx | 
|  | 910 | popw	%ax | 
|  | 911 | ret | 
|  | 912 |  | 
|  | 913 | # Build the table of video modes (stored after the setup.S code at the | 
|  | 914 | # `modelist' label. Each video mode record looks like: | 
|  | 915 | #	.word	MODE-ID		(our special mode ID (see above)) | 
|  | 916 | #	.byte	rows		(number of rows) | 
|  | 917 | #	.byte	columns		(number of columns) | 
|  | 918 | # Returns address of the end of the table in DI, the end is marked | 
|  | 919 | # with a ASK_VGA ID. | 
|  | 920 | mode_table: | 
|  | 921 | movw	mt_end, %di			# Already filled? | 
|  | 922 | orw	%di, %di | 
|  | 923 | jnz	mtab1x | 
|  | 924 |  | 
|  | 925 | leaw	modelist, %di			# Store standard modes: | 
|  | 926 | movl	$VIDEO_80x25 + 0x50190000, %eax	# The 80x25 mode (ALL) | 
|  | 927 | stosl | 
|  | 928 | movb	adapter, %al			# CGA/MDA/HGA -- no more modes | 
|  | 929 | orb	%al, %al | 
|  | 930 | jz	mtabe | 
|  | 931 |  | 
|  | 932 | decb	%al | 
|  | 933 | jnz	mtabv | 
|  | 934 |  | 
|  | 935 | movl	$VIDEO_8POINT + 0x502b0000, %eax	# The 80x43 EGA mode | 
|  | 936 | stosl | 
|  | 937 | jmp	mtabe | 
|  | 938 |  | 
|  | 939 | mtab1x:	jmp	mtab1 | 
|  | 940 |  | 
|  | 941 | mtabv:	leaw	vga_modes, %si			# All modes for std VGA | 
|  | 942 | movw	$vga_modes_end-vga_modes, %cx | 
|  | 943 | rep	# I'm unable to use movsw as I don't know how to store a half | 
|  | 944 | movsb	# of the expression above to cx without using explicit shr. | 
|  | 945 |  | 
|  | 946 | cmpb	$0, scanning			# Mode scan requested? | 
|  | 947 | jz	mscan1 | 
|  | 948 |  | 
|  | 949 | call	mode_scan | 
|  | 950 | mscan1: | 
|  | 951 |  | 
|  | 952 | #ifdef CONFIG_VIDEO_LOCAL | 
|  | 953 | call	local_modes | 
|  | 954 | #endif /* CONFIG_VIDEO_LOCAL */ | 
|  | 955 |  | 
|  | 956 | #ifdef CONFIG_VIDEO_VESA | 
|  | 957 | call	vesa_modes			# Detect VESA VGA modes | 
|  | 958 | #endif /* CONFIG_VIDEO_VESA */ | 
|  | 959 |  | 
|  | 960 | #ifdef CONFIG_VIDEO_SVGA | 
|  | 961 | cmpb	$0, scanning			# Bypass when scanning | 
|  | 962 | jnz	mscan2 | 
|  | 963 |  | 
|  | 964 | call	svga_modes			# Detect SVGA cards & modes | 
|  | 965 | mscan2: | 
|  | 966 | #endif /* CONFIG_VIDEO_SVGA */ | 
|  | 967 |  | 
|  | 968 | mtabe: | 
|  | 969 |  | 
|  | 970 | #ifdef CONFIG_VIDEO_COMPACT | 
|  | 971 | leaw	modelist, %si | 
|  | 972 | movw	%di, %dx | 
|  | 973 | movw	%si, %di | 
|  | 974 | cmt1:	cmpw	%dx, %si			# Scan all modes | 
|  | 975 | jz	cmt2 | 
|  | 976 |  | 
|  | 977 | leaw	modelist, %bx			# Find in previous entries | 
|  | 978 | movw	2(%si), %cx | 
|  | 979 | cmt3:	cmpw	%bx, %si | 
|  | 980 | jz	cmt4 | 
|  | 981 |  | 
|  | 982 | cmpw	2(%bx), %cx			# Found => don't copy this entry | 
|  | 983 | jz	cmt5 | 
|  | 984 |  | 
|  | 985 | addw	$4, %bx | 
|  | 986 | jmp	cmt3 | 
|  | 987 |  | 
|  | 988 | cmt4:	movsl					# Copy entry | 
|  | 989 | jmp	cmt1 | 
|  | 990 |  | 
|  | 991 | cmt5:	addw	$4, %si				# Skip entry | 
|  | 992 | jmp	cmt1 | 
|  | 993 |  | 
|  | 994 | cmt2: | 
|  | 995 | #endif	/* CONFIG_VIDEO_COMPACT */ | 
|  | 996 |  | 
|  | 997 | movw	$ASK_VGA, (%di)			# End marker | 
|  | 998 | movw	%di, mt_end | 
|  | 999 | mtab1:	leaw	modelist, %si			# SI=mode list, DI=list end | 
|  | 1000 | ret0:	ret | 
|  | 1001 |  | 
|  | 1002 | # Modes usable on all standard VGAs | 
|  | 1003 | vga_modes: | 
|  | 1004 | .word	VIDEO_8POINT | 
|  | 1005 | .word	0x5032				# 80x50 | 
|  | 1006 | .word	VIDEO_80x43 | 
|  | 1007 | .word	0x502b				# 80x43 | 
|  | 1008 | .word	VIDEO_80x28 | 
|  | 1009 | .word	0x501c				# 80x28 | 
|  | 1010 | .word	VIDEO_80x30 | 
|  | 1011 | .word	0x501e				# 80x30 | 
|  | 1012 | .word	VIDEO_80x34 | 
|  | 1013 | .word	0x5022				# 80x34 | 
|  | 1014 | .word	VIDEO_80x60 | 
|  | 1015 | .word	0x503c				# 80x60 | 
|  | 1016 | #ifdef CONFIG_VIDEO_GFX_HACK | 
|  | 1017 | .word	VIDEO_GFX_HACK | 
|  | 1018 | .word	VIDEO_GFX_DUMMY_RESOLUTION | 
|  | 1019 | #endif | 
|  | 1020 |  | 
|  | 1021 | vga_modes_end: | 
|  | 1022 | # Detect VESA modes. | 
|  | 1023 |  | 
|  | 1024 | #ifdef CONFIG_VIDEO_VESA | 
|  | 1025 | vesa_modes: | 
|  | 1026 | cmpb	$2, adapter			# VGA only | 
|  | 1027 | jnz	ret0 | 
|  | 1028 |  | 
|  | 1029 | movw	%di, %bp			# BP=original mode table end | 
|  | 1030 | addw	$0x200, %di			# Buffer space | 
|  | 1031 | movw	$0x4f00, %ax			# VESA Get card info call | 
|  | 1032 | int	$0x10 | 
|  | 1033 | movw	%bp, %di | 
|  | 1034 | cmpw	$0x004f, %ax			# Successful? | 
|  | 1035 | jnz	ret0 | 
|  | 1036 |  | 
|  | 1037 | cmpw	$0x4556, 0x200(%di) | 
|  | 1038 | jnz	ret0 | 
|  | 1039 |  | 
|  | 1040 | cmpw	$0x4153, 0x202(%di) | 
|  | 1041 | jnz	ret0 | 
|  | 1042 |  | 
|  | 1043 | movw	$vesa_name, card_name		# Set name to "VESA VGA" | 
|  | 1044 | pushw	%gs | 
|  | 1045 | lgsw	0x20e(%di), %si			# GS:SI=mode list | 
|  | 1046 | movw	$128, %cx			# Iteration limit | 
|  | 1047 | vesa1: | 
|  | 1048 | # gas version 2.9.1, using BFD version 2.9.1.0.23 buggers the next inst. | 
|  | 1049 | # XXX:	lodsw	%gs:(%si), %ax			# Get next mode in the list | 
|  | 1050 | gs; lodsw | 
|  | 1051 | cmpw	$0xffff, %ax			# End of the table? | 
|  | 1052 | jz	vesar | 
|  | 1053 |  | 
|  | 1054 | cmpw	$0x0080, %ax			# Check validity of mode ID | 
|  | 1055 | jc	vesa2 | 
|  | 1056 |  | 
|  | 1057 | orb	%ah, %ah		# Valid IDs: 0x0000-0x007f/0x0100-0x07ff | 
|  | 1058 | jz	vesan			# Certain BIOSes report 0x80-0xff! | 
|  | 1059 |  | 
|  | 1060 | cmpw	$0x0800, %ax | 
|  | 1061 | jnc	vesae | 
|  | 1062 |  | 
|  | 1063 | vesa2:	pushw	%cx | 
|  | 1064 | movw	%ax, %cx			# Get mode information structure | 
|  | 1065 | movw	$0x4f01, %ax | 
|  | 1066 | int	$0x10 | 
|  | 1067 | movw	%cx, %bx			# BX=mode number | 
|  | 1068 | addb	$VIDEO_FIRST_VESA>>8, %bh | 
|  | 1069 | popw	%cx | 
|  | 1070 | cmpw	$0x004f, %ax | 
|  | 1071 | jnz	vesan			# Don't report errors (buggy BIOSES) | 
|  | 1072 |  | 
|  | 1073 | movb	(%di), %al			# Check capabilities. We require | 
|  | 1074 | andb	$0x19, %al			# a color text mode. | 
|  | 1075 | cmpb	$0x09, %al | 
|  | 1076 | jnz	vesan | 
|  | 1077 |  | 
|  | 1078 | cmpw	$0xb800, 8(%di)		# Standard video memory address required | 
|  | 1079 | jnz	vesan | 
|  | 1080 |  | 
|  | 1081 | testb	$2, (%di)			# Mode characteristics supplied? | 
|  | 1082 | movw	%bx, (%di)			# Store mode number | 
|  | 1083 | jz	vesa3 | 
|  | 1084 |  | 
|  | 1085 | xorw	%dx, %dx | 
|  | 1086 | movw	0x12(%di), %bx			# Width | 
|  | 1087 | orb	%bh, %bh | 
|  | 1088 | jnz	vesan | 
|  | 1089 |  | 
|  | 1090 | movb	%bl, 0x3(%di) | 
|  | 1091 | movw	0x14(%di), %ax			# Height | 
|  | 1092 | orb	%ah, %ah | 
|  | 1093 | jnz	vesan | 
|  | 1094 |  | 
|  | 1095 | movb	%al, 2(%di) | 
|  | 1096 | mulb	%bl | 
|  | 1097 | cmpw	$8193, %ax		# Small enough for Linux console driver? | 
|  | 1098 | jnc	vesan | 
|  | 1099 |  | 
|  | 1100 | jmp	vesaok | 
|  | 1101 |  | 
|  | 1102 | vesa3:	subw	$0x8108, %bx	# This mode has no detailed info specified, | 
|  | 1103 | jc	vesan		# so it must be a standard VESA mode. | 
|  | 1104 |  | 
|  | 1105 | cmpw	$5, %bx | 
|  | 1106 | jnc	vesan | 
|  | 1107 |  | 
|  | 1108 | movw	vesa_text_mode_table(%bx), %ax | 
|  | 1109 | movw	%ax, 2(%di) | 
|  | 1110 | vesaok:	addw	$4, %di				# The mode is valid. Store it. | 
|  | 1111 | vesan:	loop	vesa1			# Next mode. Limit exceeded => error | 
|  | 1112 | vesae:	leaw	vesaer, %si | 
|  | 1113 | call	prtstr | 
|  | 1114 | movw	%bp, %di			# Discard already found modes. | 
|  | 1115 | vesar:	popw	%gs | 
|  | 1116 | ret | 
|  | 1117 |  | 
|  | 1118 | # Dimensions of standard VESA text modes | 
|  | 1119 | vesa_text_mode_table: | 
|  | 1120 | .byte	60, 80				# 0108 | 
|  | 1121 | .byte	25, 132				# 0109 | 
|  | 1122 | .byte	43, 132				# 010A | 
|  | 1123 | .byte	50, 132				# 010B | 
|  | 1124 | .byte	60, 132				# 010C | 
|  | 1125 | #endif	/* CONFIG_VIDEO_VESA */ | 
|  | 1126 |  | 
|  | 1127 | # Scan for video modes. A bit dirty, but should work. | 
|  | 1128 | mode_scan: | 
|  | 1129 | movw	$0x0100, %cx			# Start with mode 0 | 
|  | 1130 | scm1:	movb	$0, %ah				# Test the mode | 
|  | 1131 | movb	%cl, %al | 
|  | 1132 | int	$0x10 | 
|  | 1133 | movb	$0x0f, %ah | 
|  | 1134 | int	$0x10 | 
|  | 1135 | cmpb	%cl, %al | 
|  | 1136 | jnz	scm2				# Mode not set | 
|  | 1137 |  | 
|  | 1138 | movw	$0x3c0, %dx			# Test if it's a text mode | 
|  | 1139 | movb	$0x10, %al			# Mode bits | 
|  | 1140 | call	inidx | 
|  | 1141 | andb	$0x03, %al | 
|  | 1142 | jnz	scm2 | 
|  | 1143 |  | 
|  | 1144 | movb	$0xce, %dl			# Another set of mode bits | 
|  | 1145 | movb	$0x06, %al | 
|  | 1146 | call	inidx | 
|  | 1147 | shrb	%al | 
|  | 1148 | jc	scm2 | 
|  | 1149 |  | 
|  | 1150 | movb	$0xd4, %dl			# Cursor location | 
|  | 1151 | movb	$0x0f, %al | 
|  | 1152 | call	inidx | 
|  | 1153 | orb	%al, %al | 
|  | 1154 | jnz	scm2 | 
|  | 1155 |  | 
|  | 1156 | movw	%cx, %ax			# Ok, store the mode | 
|  | 1157 | stosw | 
|  | 1158 | movb	%gs:(0x484), %al		# Number of rows | 
|  | 1159 | incb	%al | 
|  | 1160 | stosb | 
|  | 1161 | movw	%gs:(0x44a), %ax		# Number of columns | 
|  | 1162 | stosb | 
|  | 1163 | scm2:	incb	%cl | 
|  | 1164 | jns	scm1 | 
|  | 1165 |  | 
|  | 1166 | movw	$0x0003, %ax			# Return back to mode 3 | 
|  | 1167 | int	$0x10 | 
|  | 1168 | ret | 
|  | 1169 |  | 
|  | 1170 | tstidx:	outw	%ax, %dx			# OUT DX,AX and inidx | 
|  | 1171 | inidx:	outb	%al, %dx			# Read from indexed VGA register | 
|  | 1172 | incw	%dx			# AL=index, DX=index reg port -> AL=data | 
|  | 1173 | inb	%dx, %al | 
|  | 1174 | decw	%dx | 
|  | 1175 | ret | 
|  | 1176 |  | 
|  | 1177 | # Try to detect type of SVGA card and supply (usually approximate) video | 
|  | 1178 | # mode table for it. | 
|  | 1179 |  | 
|  | 1180 | #ifdef CONFIG_VIDEO_SVGA | 
|  | 1181 | svga_modes: | 
|  | 1182 | leaw	svga_table, %si			# Test all known SVGA adapters | 
|  | 1183 | dosvga:	lodsw | 
|  | 1184 | movw	%ax, %bp			# Default mode table | 
|  | 1185 | orw	%ax, %ax | 
|  | 1186 | jz	didsv1 | 
|  | 1187 |  | 
|  | 1188 | lodsw					# Pointer to test routine | 
|  | 1189 | pushw	%si | 
|  | 1190 | pushw	%di | 
|  | 1191 | pushw	%es | 
|  | 1192 | movw	$0xc000, %bx | 
|  | 1193 | movw	%bx, %es | 
|  | 1194 | call	*%ax				# Call test routine | 
|  | 1195 | popw	%es | 
|  | 1196 | popw	%di | 
|  | 1197 | popw	%si | 
|  | 1198 | orw	%bp, %bp | 
|  | 1199 | jz	dosvga | 
|  | 1200 |  | 
|  | 1201 | movw	%bp, %si			# Found, copy the modes | 
|  | 1202 | movb	svga_prefix, %ah | 
|  | 1203 | cpsvga:	lodsb | 
|  | 1204 | orb	%al, %al | 
|  | 1205 | jz	didsv | 
|  | 1206 |  | 
|  | 1207 | stosw | 
|  | 1208 | movsw | 
|  | 1209 | jmp	cpsvga | 
|  | 1210 |  | 
|  | 1211 | didsv:	movw	%si, card_name			# Store pointer to card name | 
|  | 1212 | didsv1:	ret | 
|  | 1213 |  | 
|  | 1214 | # Table of all known SVGA cards. For each card, we store a pointer to | 
|  | 1215 | # a table of video modes supported by the card and a pointer to a routine | 
|  | 1216 | # used for testing of presence of the card. The video mode table is always | 
|  | 1217 | # followed by the name of the card or the chipset. | 
|  | 1218 | svga_table: | 
|  | 1219 | .word	ati_md, ati_test | 
|  | 1220 | .word	oak_md, oak_test | 
|  | 1221 | .word	paradise_md, paradise_test | 
|  | 1222 | .word	realtek_md, realtek_test | 
|  | 1223 | .word	s3_md, s3_test | 
|  | 1224 | .word	chips_md, chips_test | 
|  | 1225 | .word	video7_md, video7_test | 
|  | 1226 | .word	cirrus5_md, cirrus5_test | 
|  | 1227 | .word	cirrus6_md, cirrus6_test | 
|  | 1228 | .word	cirrus1_md, cirrus1_test | 
|  | 1229 | .word	ahead_md, ahead_test | 
|  | 1230 | .word	everex_md, everex_test | 
|  | 1231 | .word	genoa_md, genoa_test | 
|  | 1232 | .word	trident_md, trident_test | 
|  | 1233 | .word	tseng_md, tseng_test | 
|  | 1234 | .word	0 | 
|  | 1235 |  | 
|  | 1236 | # Test routines and mode tables: | 
|  | 1237 |  | 
|  | 1238 | # S3 - The test algorithm was taken from the SuperProbe package | 
|  | 1239 | # for XFree86 1.2.1. Report bugs to Christoph.Niemann@linux.org | 
|  | 1240 | s3_test: | 
|  | 1241 | movw	$0x0f35, %cx	# we store some constants in cl/ch | 
|  | 1242 | movw	$0x03d4, %dx | 
|  | 1243 | movb	$0x38, %al | 
|  | 1244 | call	inidx | 
|  | 1245 | movb	%al, %bh	# store current CRT-register 0x38 | 
|  | 1246 | movw	$0x0038, %ax | 
|  | 1247 | call	outidx		# disable writing to special regs | 
|  | 1248 | movb	%cl, %al	# check whether we can write special reg 0x35 | 
|  | 1249 | call	inidx | 
|  | 1250 | movb	%al, %bl	# save the current value of CRT reg 0x35 | 
|  | 1251 | andb	$0xf0, %al	# clear bits 0-3 | 
|  | 1252 | movb	%al, %ah | 
|  | 1253 | movb	%cl, %al	# and write it to CRT reg 0x35 | 
|  | 1254 | call	outidx | 
|  | 1255 | call	inidx		# now read it back | 
|  | 1256 | andb	%ch, %al	# clear the upper 4 bits | 
|  | 1257 | jz	s3_2		# the first test failed. But we have a | 
|  | 1258 |  | 
|  | 1259 | movb	%bl, %ah	# second chance | 
|  | 1260 | movb	%cl, %al | 
|  | 1261 | call	outidx | 
|  | 1262 | jmp	s3_1		# do the other tests | 
|  | 1263 |  | 
|  | 1264 | s3_2:	movw	%cx, %ax	# load ah with 0xf and al with 0x35 | 
|  | 1265 | orb	%bl, %ah	# set the upper 4 bits of ah with the orig value | 
|  | 1266 | call	outidx		# write ... | 
|  | 1267 | call	inidx		# ... and reread | 
|  | 1268 | andb	%cl, %al	# turn off the upper 4 bits | 
|  | 1269 | pushw	%ax | 
|  | 1270 | movb	%bl, %ah	# restore old value in register 0x35 | 
|  | 1271 | movb	%cl, %al | 
|  | 1272 | call	outidx | 
|  | 1273 | popw	%ax | 
|  | 1274 | cmpb	%ch, %al	# setting lower 4 bits was successful => bad | 
|  | 1275 | je	no_s3		# writing is allowed => this is not an S3 | 
|  | 1276 |  | 
|  | 1277 | s3_1:	movw	$0x4838, %ax	# allow writing to special regs by putting | 
|  | 1278 | call	outidx		# magic number into CRT-register 0x38 | 
|  | 1279 | movb	%cl, %al	# check whether we can write special reg 0x35 | 
|  | 1280 | call	inidx | 
|  | 1281 | movb	%al, %bl | 
|  | 1282 | andb	$0xf0, %al | 
|  | 1283 | movb	%al, %ah | 
|  | 1284 | movb	%cl, %al | 
|  | 1285 | call	outidx | 
|  | 1286 | call	inidx | 
|  | 1287 | andb	%ch, %al | 
|  | 1288 | jnz	no_s3		# no, we can't write => no S3 | 
|  | 1289 |  | 
|  | 1290 | movw	%cx, %ax | 
|  | 1291 | orb	%bl, %ah | 
|  | 1292 | call	outidx | 
|  | 1293 | call	inidx | 
|  | 1294 | andb	%ch, %al | 
|  | 1295 | pushw	%ax | 
|  | 1296 | movb	%bl, %ah	# restore old value in register 0x35 | 
|  | 1297 | movb	%cl, %al | 
|  | 1298 | call	outidx | 
|  | 1299 | popw	%ax | 
|  | 1300 | cmpb	%ch, %al | 
|  | 1301 | jne	no_s31		# writing not possible => no S3 | 
|  | 1302 | movb	$0x30, %al | 
|  | 1303 | call	inidx		# now get the S3 id ... | 
|  | 1304 | leaw	idS3, %di | 
|  | 1305 | movw	$0x10, %cx | 
|  | 1306 | repne | 
|  | 1307 | scasb | 
|  | 1308 | je	no_s31 | 
|  | 1309 |  | 
|  | 1310 | movb	%bh, %ah | 
|  | 1311 | movb	$0x38, %al | 
|  | 1312 | jmp	s3rest | 
|  | 1313 |  | 
|  | 1314 | no_s3:	movb	$0x35, %al	# restore CRT register 0x35 | 
|  | 1315 | movb	%bl, %ah | 
|  | 1316 | call	outidx | 
|  | 1317 | no_s31:	xorw	%bp, %bp	# Detection failed | 
|  | 1318 | s3rest:	movb	%bh, %ah | 
|  | 1319 | movb	$0x38, %al	# restore old value of CRT register 0x38 | 
|  | 1320 | jmp	outidx | 
|  | 1321 |  | 
|  | 1322 | idS3:	.byte	0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95 | 
|  | 1323 | .byte	0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0 | 
|  | 1324 |  | 
|  | 1325 | s3_md:	.byte	0x54, 0x2b, 0x84 | 
|  | 1326 | .byte	0x55, 0x19, 0x84 | 
|  | 1327 | .byte	0 | 
|  | 1328 | .ascii	"S3" | 
|  | 1329 | .byte	0 | 
|  | 1330 |  | 
|  | 1331 | # ATI cards. | 
|  | 1332 | ati_test: | 
|  | 1333 | leaw 	idati, %si | 
|  | 1334 | movw	$0x31, %di | 
|  | 1335 | movw	$0x09, %cx | 
|  | 1336 | repe | 
|  | 1337 | cmpsb | 
|  | 1338 | je	atiok | 
|  | 1339 |  | 
|  | 1340 | xorw	%bp, %bp | 
|  | 1341 | atiok:	ret | 
|  | 1342 |  | 
|  | 1343 | idati:	.ascii	"761295520" | 
|  | 1344 |  | 
|  | 1345 | ati_md:	.byte	0x23, 0x19, 0x84 | 
|  | 1346 | .byte	0x33, 0x2c, 0x84 | 
|  | 1347 | .byte	0x22, 0x1e, 0x64 | 
|  | 1348 | .byte	0x21, 0x19, 0x64 | 
|  | 1349 | .byte	0x58, 0x21, 0x50 | 
|  | 1350 | .byte	0x5b, 0x1e, 0x50 | 
|  | 1351 | .byte	0 | 
|  | 1352 | .ascii	"ATI" | 
|  | 1353 | .byte	0 | 
|  | 1354 |  | 
|  | 1355 | # AHEAD | 
|  | 1356 | ahead_test: | 
|  | 1357 | movw	$0x200f, %ax | 
|  | 1358 | movw	$0x3ce, %dx | 
|  | 1359 | outw	%ax, %dx | 
|  | 1360 | incw	%dx | 
|  | 1361 | inb	%dx, %al | 
|  | 1362 | cmpb	$0x20, %al | 
|  | 1363 | je	isahed | 
|  | 1364 |  | 
|  | 1365 | cmpb	$0x21, %al | 
|  | 1366 | je	isahed | 
|  | 1367 |  | 
|  | 1368 | xorw	%bp, %bp | 
|  | 1369 | isahed:	ret | 
|  | 1370 |  | 
|  | 1371 | ahead_md: | 
|  | 1372 | .byte	0x22, 0x2c, 0x84 | 
|  | 1373 | .byte	0x23, 0x19, 0x84 | 
|  | 1374 | .byte	0x24, 0x1c, 0x84 | 
|  | 1375 | .byte	0x2f, 0x32, 0xa0 | 
|  | 1376 | .byte	0x32, 0x22, 0x50 | 
|  | 1377 | .byte	0x34, 0x42, 0x50 | 
|  | 1378 | .byte	0 | 
|  | 1379 | .ascii	"Ahead" | 
|  | 1380 | .byte	0 | 
|  | 1381 |  | 
|  | 1382 | # Chips & Tech. | 
|  | 1383 | chips_test: | 
|  | 1384 | movw	$0x3c3, %dx | 
|  | 1385 | inb	%dx, %al | 
|  | 1386 | orb	$0x10, %al | 
|  | 1387 | outb	%al, %dx | 
|  | 1388 | movw	$0x104, %dx | 
|  | 1389 | inb	%dx, %al | 
|  | 1390 | movb	%al, %bl | 
|  | 1391 | movw	$0x3c3, %dx | 
|  | 1392 | inb	%dx, %al | 
|  | 1393 | andb	$0xef, %al | 
|  | 1394 | outb	%al, %dx | 
|  | 1395 | cmpb	$0xa5, %bl | 
|  | 1396 | je	cantok | 
|  | 1397 |  | 
|  | 1398 | xorw	%bp, %bp | 
|  | 1399 | cantok:	ret | 
|  | 1400 |  | 
|  | 1401 | chips_md: | 
|  | 1402 | .byte	0x60, 0x19, 0x84 | 
|  | 1403 | .byte	0x61, 0x32, 0x84 | 
|  | 1404 | .byte	0 | 
|  | 1405 | .ascii	"Chips & Technologies" | 
|  | 1406 | .byte	0 | 
|  | 1407 |  | 
|  | 1408 | # Cirrus Logic 5X0 | 
|  | 1409 | cirrus1_test: | 
|  | 1410 | movw	$0x3d4, %dx | 
|  | 1411 | movb	$0x0c, %al | 
|  | 1412 | outb	%al, %dx | 
|  | 1413 | incw	%dx | 
|  | 1414 | inb	%dx, %al | 
|  | 1415 | movb	%al, %bl | 
|  | 1416 | xorb	%al, %al | 
|  | 1417 | outb	%al, %dx | 
|  | 1418 | decw	%dx | 
|  | 1419 | movb	$0x1f, %al | 
|  | 1420 | outb	%al, %dx | 
|  | 1421 | incw	%dx | 
|  | 1422 | inb	%dx, %al | 
|  | 1423 | movb	%al, %bh | 
|  | 1424 | xorb	%ah, %ah | 
|  | 1425 | shlb	$4, %al | 
|  | 1426 | movw	%ax, %cx | 
|  | 1427 | movb	%bh, %al | 
|  | 1428 | shrb	$4, %al | 
|  | 1429 | addw	%ax, %cx | 
|  | 1430 | shlw	$8, %cx | 
|  | 1431 | addw	$6, %cx | 
|  | 1432 | movw	%cx, %ax | 
|  | 1433 | movw	$0x3c4, %dx | 
|  | 1434 | outw	%ax, %dx | 
|  | 1435 | incw	%dx | 
|  | 1436 | inb	%dx, %al | 
|  | 1437 | andb	%al, %al | 
|  | 1438 | jnz	nocirr | 
|  | 1439 |  | 
|  | 1440 | movb	%bh, %al | 
|  | 1441 | outb	%al, %dx | 
|  | 1442 | inb	%dx, %al | 
|  | 1443 | cmpb	$0x01, %al | 
|  | 1444 | je	iscirr | 
|  | 1445 |  | 
|  | 1446 | nocirr:	xorw	%bp, %bp | 
|  | 1447 | iscirr: movw	$0x3d4, %dx | 
|  | 1448 | movb	%bl, %al | 
|  | 1449 | xorb	%ah, %ah | 
|  | 1450 | shlw	$8, %ax | 
|  | 1451 | addw	$0x0c, %ax | 
|  | 1452 | outw	%ax, %dx | 
|  | 1453 | ret | 
|  | 1454 |  | 
|  | 1455 | cirrus1_md: | 
|  | 1456 | .byte	0x1f, 0x19, 0x84 | 
|  | 1457 | .byte	0x20, 0x2c, 0x84 | 
|  | 1458 | .byte	0x22, 0x1e, 0x84 | 
|  | 1459 | .byte	0x31, 0x25, 0x64 | 
|  | 1460 | .byte	0 | 
|  | 1461 | .ascii	"Cirrus Logic 5X0" | 
|  | 1462 | .byte	0 | 
|  | 1463 |  | 
|  | 1464 | # Cirrus Logic 54XX | 
|  | 1465 | cirrus5_test: | 
|  | 1466 | movw	$0x3c4, %dx | 
|  | 1467 | movb	$6, %al | 
|  | 1468 | call	inidx | 
|  | 1469 | movb	%al, %bl			# BL=backup | 
|  | 1470 | movw	$6, %ax | 
|  | 1471 | call	tstidx | 
|  | 1472 | cmpb	$0x0f, %al | 
|  | 1473 | jne	c5fail | 
|  | 1474 |  | 
|  | 1475 | movw	$0x1206, %ax | 
|  | 1476 | call	tstidx | 
|  | 1477 | cmpb	$0x12, %al | 
|  | 1478 | jne	c5fail | 
|  | 1479 |  | 
|  | 1480 | movb	$0x1e, %al | 
|  | 1481 | call	inidx | 
|  | 1482 | movb	%al, %bh | 
|  | 1483 | movb	%bh, %ah | 
|  | 1484 | andb	$0xc0, %ah | 
|  | 1485 | movb	$0x1e, %al | 
|  | 1486 | call	tstidx | 
|  | 1487 | andb	$0x3f, %al | 
|  | 1488 | jne	c5xx | 
|  | 1489 |  | 
|  | 1490 | movb	$0x1e, %al | 
|  | 1491 | movb	%bh, %ah | 
|  | 1492 | orb	$0x3f, %ah | 
|  | 1493 | call	tstidx | 
|  | 1494 | xorb	$0x3f, %al | 
|  | 1495 | andb	$0x3f, %al | 
|  | 1496 | c5xx:	pushf | 
|  | 1497 | movb	$0x1e, %al | 
|  | 1498 | movb	%bh, %ah | 
|  | 1499 | outw	%ax, %dx | 
|  | 1500 | popf | 
|  | 1501 | je	c5done | 
|  | 1502 |  | 
|  | 1503 | c5fail:	xorw	%bp, %bp | 
|  | 1504 | c5done:	movb	$6, %al | 
|  | 1505 | movb	%bl, %ah | 
|  | 1506 | outw	%ax, %dx | 
|  | 1507 | ret | 
|  | 1508 |  | 
|  | 1509 | cirrus5_md: | 
|  | 1510 | .byte	0x14, 0x19, 0x84 | 
|  | 1511 | .byte	0x54, 0x2b, 0x84 | 
|  | 1512 | .byte	0 | 
|  | 1513 | .ascii	"Cirrus Logic 54XX" | 
|  | 1514 | .byte	0 | 
|  | 1515 |  | 
|  | 1516 | # Cirrus Logic 64XX -- no known extra modes, but must be identified, because | 
|  | 1517 | # it's misidentified by the Ahead test. | 
|  | 1518 | cirrus6_test: | 
|  | 1519 | movw	$0x3ce, %dx | 
|  | 1520 | movb	$0x0a, %al | 
|  | 1521 | call	inidx | 
|  | 1522 | movb	%al, %bl	# BL=backup | 
|  | 1523 | movw	$0xce0a, %ax | 
|  | 1524 | call	tstidx | 
|  | 1525 | orb	%al, %al | 
|  | 1526 | jne	c2fail | 
|  | 1527 |  | 
|  | 1528 | movw	$0xec0a, %ax | 
|  | 1529 | call	tstidx | 
|  | 1530 | cmpb	$0x01, %al | 
|  | 1531 | jne	c2fail | 
|  | 1532 |  | 
|  | 1533 | movb	$0xaa, %al | 
|  | 1534 | call	inidx		# 4X, 5X, 7X and 8X are valid 64XX chip ID's. | 
|  | 1535 | shrb	$4, %al | 
|  | 1536 | subb	$4, %al | 
|  | 1537 | jz	c6done | 
|  | 1538 |  | 
|  | 1539 | decb	%al | 
|  | 1540 | jz	c6done | 
|  | 1541 |  | 
|  | 1542 | subb	$2, %al | 
|  | 1543 | jz	c6done | 
|  | 1544 |  | 
|  | 1545 | decb	%al | 
|  | 1546 | jz	c6done | 
|  | 1547 |  | 
|  | 1548 | c2fail:	xorw	%bp, %bp | 
|  | 1549 | c6done:	movb	$0x0a, %al | 
|  | 1550 | movb	%bl, %ah | 
|  | 1551 | outw	%ax, %dx | 
|  | 1552 | ret | 
|  | 1553 |  | 
|  | 1554 | cirrus6_md: | 
|  | 1555 | .byte	0 | 
|  | 1556 | .ascii	"Cirrus Logic 64XX" | 
|  | 1557 | .byte	0 | 
|  | 1558 |  | 
|  | 1559 | # Everex / Trident | 
|  | 1560 | everex_test: | 
|  | 1561 | movw	$0x7000, %ax | 
|  | 1562 | xorw	%bx, %bx | 
|  | 1563 | int	$0x10 | 
|  | 1564 | cmpb	$0x70, %al | 
|  | 1565 | jne	noevrx | 
|  | 1566 |  | 
|  | 1567 | shrw	$4, %dx | 
|  | 1568 | cmpw	$0x678, %dx | 
|  | 1569 | je	evtrid | 
|  | 1570 |  | 
|  | 1571 | cmpw	$0x236, %dx | 
|  | 1572 | jne	evrxok | 
|  | 1573 |  | 
|  | 1574 | evtrid:	leaw	trident_md, %bp | 
|  | 1575 | evrxok:	ret | 
|  | 1576 |  | 
|  | 1577 | noevrx:	xorw	%bp, %bp | 
|  | 1578 | ret | 
|  | 1579 |  | 
|  | 1580 | everex_md: | 
|  | 1581 | .byte	0x03, 0x22, 0x50 | 
|  | 1582 | .byte	0x04, 0x3c, 0x50 | 
|  | 1583 | .byte	0x07, 0x2b, 0x64 | 
|  | 1584 | .byte	0x08, 0x4b, 0x64 | 
|  | 1585 | .byte	0x0a, 0x19, 0x84 | 
|  | 1586 | .byte	0x0b, 0x2c, 0x84 | 
|  | 1587 | .byte	0x16, 0x1e, 0x50 | 
|  | 1588 | .byte	0x18, 0x1b, 0x64 | 
|  | 1589 | .byte	0x21, 0x40, 0xa0 | 
|  | 1590 | .byte	0x40, 0x1e, 0x84 | 
|  | 1591 | .byte	0 | 
|  | 1592 | .ascii	"Everex/Trident" | 
|  | 1593 | .byte	0 | 
|  | 1594 |  | 
|  | 1595 | # Genoa. | 
|  | 1596 | genoa_test: | 
|  | 1597 | leaw	idgenoa, %si			# Check Genoa 'clues' | 
|  | 1598 | xorw	%ax, %ax | 
|  | 1599 | movb	%es:(0x37), %al | 
|  | 1600 | movw	%ax, %di | 
|  | 1601 | movw	$0x04, %cx | 
|  | 1602 | decw	%si | 
|  | 1603 | decw	%di | 
|  | 1604 | l1:	incw	%si | 
|  | 1605 | incw	%di | 
|  | 1606 | movb	(%si), %al | 
|  | 1607 | testb	%al, %al | 
|  | 1608 | jz	l2 | 
|  | 1609 |  | 
|  | 1610 | cmpb	%es:(%di), %al | 
|  | 1611 | l2:	loope 	l1 | 
|  | 1612 | orw	%cx, %cx | 
|  | 1613 | je	isgen | 
|  | 1614 |  | 
|  | 1615 | xorw	%bp, %bp | 
|  | 1616 | isgen:	ret | 
|  | 1617 |  | 
|  | 1618 | idgenoa: .byte	0x77, 0x00, 0x99, 0x66 | 
|  | 1619 |  | 
|  | 1620 | genoa_md: | 
|  | 1621 | .byte	0x58, 0x20, 0x50 | 
|  | 1622 | .byte	0x5a, 0x2a, 0x64 | 
|  | 1623 | .byte	0x60, 0x19, 0x84 | 
|  | 1624 | .byte	0x61, 0x1d, 0x84 | 
|  | 1625 | .byte	0x62, 0x20, 0x84 | 
|  | 1626 | .byte	0x63, 0x2c, 0x84 | 
|  | 1627 | .byte	0x64, 0x3c, 0x84 | 
|  | 1628 | .byte	0x6b, 0x4f, 0x64 | 
|  | 1629 | .byte	0x72, 0x3c, 0x50 | 
|  | 1630 | .byte	0x74, 0x42, 0x50 | 
|  | 1631 | .byte	0x78, 0x4b, 0x64 | 
|  | 1632 | .byte	0 | 
|  | 1633 | .ascii	"Genoa" | 
|  | 1634 | .byte	0 | 
|  | 1635 |  | 
|  | 1636 | # OAK | 
|  | 1637 | oak_test: | 
|  | 1638 | leaw	idoakvga, %si | 
|  | 1639 | movw	$0x08, %di | 
|  | 1640 | movw	$0x08, %cx | 
|  | 1641 | repe | 
|  | 1642 | cmpsb | 
|  | 1643 | je	isoak | 
|  | 1644 |  | 
|  | 1645 | xorw	%bp, %bp | 
|  | 1646 | isoak:	ret | 
|  | 1647 |  | 
|  | 1648 | idoakvga: .ascii  "OAK VGA " | 
|  | 1649 |  | 
|  | 1650 | oak_md: .byte	0x4e, 0x3c, 0x50 | 
|  | 1651 | .byte	0x4f, 0x3c, 0x84 | 
|  | 1652 | .byte	0x50, 0x19, 0x84 | 
|  | 1653 | .byte	0x51, 0x2b, 0x84 | 
|  | 1654 | .byte	0 | 
|  | 1655 | .ascii	"OAK" | 
|  | 1656 | .byte	0 | 
|  | 1657 |  | 
|  | 1658 | # WD Paradise. | 
|  | 1659 | paradise_test: | 
|  | 1660 | leaw	idparadise, %si | 
|  | 1661 | movw	$0x7d, %di | 
|  | 1662 | movw	$0x04, %cx | 
|  | 1663 | repe | 
|  | 1664 | cmpsb | 
|  | 1665 | je	ispara | 
|  | 1666 |  | 
|  | 1667 | xorw	%bp, %bp | 
|  | 1668 | ispara:	ret | 
|  | 1669 |  | 
|  | 1670 | idparadise:	.ascii	"VGA=" | 
|  | 1671 |  | 
|  | 1672 | paradise_md: | 
|  | 1673 | .byte	0x41, 0x22, 0x50 | 
|  | 1674 | .byte	0x47, 0x1c, 0x84 | 
|  | 1675 | .byte	0x55, 0x19, 0x84 | 
|  | 1676 | .byte	0x54, 0x2c, 0x84 | 
|  | 1677 | .byte	0 | 
|  | 1678 | .ascii	"Paradise" | 
|  | 1679 | .byte	0 | 
|  | 1680 |  | 
|  | 1681 | # Trident. | 
|  | 1682 | trident_test: | 
|  | 1683 | movw	$0x3c4, %dx | 
|  | 1684 | movb	$0x0e, %al | 
|  | 1685 | outb	%al, %dx | 
|  | 1686 | incw	%dx | 
|  | 1687 | inb	%dx, %al | 
|  | 1688 | xchgb	%al, %ah | 
|  | 1689 | xorb	%al, %al | 
|  | 1690 | outb	%al, %dx | 
|  | 1691 | inb	%dx, %al | 
|  | 1692 | xchgb	%ah, %al | 
|  | 1693 | movb	%al, %bl	# Strange thing ... in the book this wasn't | 
|  | 1694 | andb	$0x02, %bl	# necessary but it worked on my card which | 
|  | 1695 | jz	setb2		# is a trident. Without it the screen goes | 
|  | 1696 | # blurred ... | 
|  | 1697 | andb	$0xfd, %al | 
|  | 1698 | jmp	clrb2 | 
|  | 1699 |  | 
|  | 1700 | setb2:	orb	$0x02, %al | 
|  | 1701 | clrb2:	outb	%al, %dx | 
|  | 1702 | andb	$0x0f, %ah | 
|  | 1703 | cmpb	$0x02, %ah | 
|  | 1704 | je	istrid | 
|  | 1705 |  | 
|  | 1706 | xorw	%bp, %bp | 
|  | 1707 | istrid:	ret | 
|  | 1708 |  | 
|  | 1709 | trident_md: | 
|  | 1710 | .byte	0x50, 0x1e, 0x50 | 
|  | 1711 | .byte	0x51, 0x2b, 0x50 | 
|  | 1712 | .byte	0x52, 0x3c, 0x50 | 
|  | 1713 | .byte	0x57, 0x19, 0x84 | 
|  | 1714 | .byte	0x58, 0x1e, 0x84 | 
|  | 1715 | .byte	0x59, 0x2b, 0x84 | 
|  | 1716 | .byte	0x5a, 0x3c, 0x84 | 
|  | 1717 | .byte	0 | 
|  | 1718 | .ascii	"Trident" | 
|  | 1719 | .byte	0 | 
|  | 1720 |  | 
|  | 1721 | # Tseng. | 
|  | 1722 | tseng_test: | 
|  | 1723 | movw	$0x3cd, %dx | 
|  | 1724 | inb	%dx, %al	# Could things be this simple ! :-) | 
|  | 1725 | movb	%al, %bl | 
|  | 1726 | movb	$0x55, %al | 
|  | 1727 | outb	%al, %dx | 
|  | 1728 | inb	%dx, %al | 
|  | 1729 | movb	%al, %ah | 
|  | 1730 | movb	%bl, %al | 
|  | 1731 | outb	%al, %dx | 
|  | 1732 | cmpb	$0x55, %ah | 
|  | 1733 | je	istsen | 
|  | 1734 |  | 
|  | 1735 | isnot:	xorw	%bp, %bp | 
|  | 1736 | istsen:	ret | 
|  | 1737 |  | 
|  | 1738 | tseng_md: | 
|  | 1739 | .byte	0x26, 0x3c, 0x50 | 
|  | 1740 | .byte	0x2a, 0x28, 0x64 | 
|  | 1741 | .byte	0x23, 0x19, 0x84 | 
|  | 1742 | .byte	0x24, 0x1c, 0x84 | 
|  | 1743 | .byte	0x22, 0x2c, 0x84 | 
|  | 1744 | .byte	0x21, 0x3c, 0x84 | 
|  | 1745 | .byte	0 | 
|  | 1746 | .ascii	"Tseng" | 
|  | 1747 | .byte	0 | 
|  | 1748 |  | 
|  | 1749 | # Video7. | 
|  | 1750 | video7_test: | 
|  | 1751 | movw	$0x3cc, %dx | 
|  | 1752 | inb	%dx, %al | 
|  | 1753 | movw	$0x3b4, %dx | 
|  | 1754 | andb	$0x01, %al | 
|  | 1755 | jz	even7 | 
|  | 1756 |  | 
|  | 1757 | movw	$0x3d4, %dx | 
|  | 1758 | even7:	movb	$0x0c, %al | 
|  | 1759 | outb	%al, %dx | 
|  | 1760 | incw	%dx | 
|  | 1761 | inb	%dx, %al | 
|  | 1762 | movb	%al, %bl | 
|  | 1763 | movb	$0x55, %al | 
|  | 1764 | outb	%al, %dx | 
|  | 1765 | inb	%dx, %al | 
|  | 1766 | decw	%dx | 
|  | 1767 | movb	$0x1f, %al | 
|  | 1768 | outb	%al, %dx | 
|  | 1769 | incw	%dx | 
|  | 1770 | inb	%dx, %al | 
|  | 1771 | movb	%al, %bh | 
|  | 1772 | decw	%dx | 
|  | 1773 | movb	$0x0c, %al | 
|  | 1774 | outb	%al, %dx | 
|  | 1775 | incw	%dx | 
|  | 1776 | movb	%bl, %al | 
|  | 1777 | outb	%al, %dx | 
|  | 1778 | movb	$0x55, %al | 
|  | 1779 | xorb	$0xea, %al | 
|  | 1780 | cmpb	%bh, %al | 
|  | 1781 | jne	isnot | 
|  | 1782 |  | 
|  | 1783 | movb	$VIDEO_FIRST_V7>>8, svga_prefix # Use special mode switching | 
|  | 1784 | ret | 
|  | 1785 |  | 
|  | 1786 | video7_md: | 
|  | 1787 | .byte	0x40, 0x2b, 0x50 | 
|  | 1788 | .byte	0x43, 0x3c, 0x50 | 
|  | 1789 | .byte	0x44, 0x3c, 0x64 | 
|  | 1790 | .byte	0x41, 0x19, 0x84 | 
|  | 1791 | .byte	0x42, 0x2c, 0x84 | 
|  | 1792 | .byte	0x45, 0x1c, 0x84 | 
|  | 1793 | .byte	0 | 
|  | 1794 | .ascii	"Video 7" | 
|  | 1795 | .byte	0 | 
|  | 1796 |  | 
|  | 1797 | # Realtek VGA | 
|  | 1798 | realtek_test: | 
|  | 1799 | leaw	idrtvga, %si | 
|  | 1800 | movw	$0x45, %di | 
|  | 1801 | movw	$0x0b, %cx | 
|  | 1802 | repe | 
|  | 1803 | cmpsb | 
|  | 1804 | je	isrt | 
|  | 1805 |  | 
|  | 1806 | xorw	%bp, %bp | 
|  | 1807 | isrt:	ret | 
|  | 1808 |  | 
|  | 1809 | idrtvga:	.ascii	"REALTEK VGA" | 
|  | 1810 |  | 
|  | 1811 | realtek_md: | 
|  | 1812 | .byte	0x1a, 0x3c, 0x50 | 
|  | 1813 | .byte	0x1b, 0x19, 0x84 | 
|  | 1814 | .byte	0x1c, 0x1e, 0x84 | 
|  | 1815 | .byte	0x1d, 0x2b, 0x84 | 
|  | 1816 | .byte	0x1e, 0x3c, 0x84 | 
|  | 1817 | .byte	0 | 
|  | 1818 | .ascii	"REALTEK" | 
|  | 1819 | .byte	0 | 
|  | 1820 |  | 
|  | 1821 | #endif	/* CONFIG_VIDEO_SVGA */ | 
|  | 1822 |  | 
|  | 1823 | # User-defined local mode table (VGA only) | 
|  | 1824 | #ifdef CONFIG_VIDEO_LOCAL | 
|  | 1825 | local_modes: | 
|  | 1826 | leaw	local_mode_table, %si | 
|  | 1827 | locm1:	lodsw | 
|  | 1828 | orw	%ax, %ax | 
|  | 1829 | jz	locm2 | 
|  | 1830 |  | 
|  | 1831 | stosw | 
|  | 1832 | movsw | 
|  | 1833 | jmp	locm1 | 
|  | 1834 |  | 
|  | 1835 | locm2:	ret | 
|  | 1836 |  | 
|  | 1837 | # This is the table of local video modes which can be supplied manually | 
|  | 1838 | # by the user. Each entry consists of mode ID (word) and dimensions | 
|  | 1839 | # (byte for column count and another byte for row count). These modes | 
|  | 1840 | # are placed before all SVGA and VESA modes and override them if table | 
|  | 1841 | # compacting is enabled. The table must end with a zero word followed | 
|  | 1842 | # by NUL-terminated video adapter name. | 
|  | 1843 | local_mode_table: | 
|  | 1844 | .word	0x0100				# Example: 40x25 | 
|  | 1845 | .byte	25,40 | 
|  | 1846 | .word	0 | 
|  | 1847 | .ascii	"Local" | 
|  | 1848 | .byte	0 | 
|  | 1849 | #endif	/* CONFIG_VIDEO_LOCAL */ | 
|  | 1850 |  | 
|  | 1851 | # Read a key and return the ASCII code in al, scan code in ah | 
|  | 1852 | getkey:	xorb	%ah, %ah | 
|  | 1853 | int	$0x16 | 
|  | 1854 | ret | 
|  | 1855 |  | 
|  | 1856 | # Read a key with a timeout of 30 seconds. | 
|  | 1857 | # The hardware clock is used to get the time. | 
|  | 1858 | getkt:	call	gettime | 
|  | 1859 | addb	$30, %al			# Wait 30 seconds | 
|  | 1860 | cmpb	$60, %al | 
|  | 1861 | jl	lminute | 
|  | 1862 |  | 
|  | 1863 | subb	$60, %al | 
|  | 1864 | lminute: | 
|  | 1865 | movb	%al, %cl | 
|  | 1866 | again:	movb	$0x01, %ah | 
|  | 1867 | int	$0x16 | 
|  | 1868 | jnz	getkey				# key pressed, so get it | 
|  | 1869 |  | 
|  | 1870 | call	gettime | 
|  | 1871 | cmpb	%cl, %al | 
|  | 1872 | jne	again | 
|  | 1873 |  | 
|  | 1874 | movb	$0x20, %al			# timeout, return `space' | 
|  | 1875 | ret | 
|  | 1876 |  | 
|  | 1877 | # Flush the keyboard buffer | 
|  | 1878 | flush:	movb	$0x01, %ah | 
|  | 1879 | int	$0x16 | 
|  | 1880 | jz	empty | 
|  | 1881 |  | 
|  | 1882 | xorb	%ah, %ah | 
|  | 1883 | int	$0x16 | 
|  | 1884 | jmp	flush | 
|  | 1885 |  | 
|  | 1886 | empty:	ret | 
|  | 1887 |  | 
|  | 1888 | # Print hexadecimal number. | 
|  | 1889 | prthw:	pushw	%ax | 
|  | 1890 | movb	%ah, %al | 
|  | 1891 | call	prthb | 
|  | 1892 | popw	%ax | 
|  | 1893 | prthb:	pushw	%ax | 
|  | 1894 | shrb	$4, %al | 
|  | 1895 | call	prthn | 
|  | 1896 | popw	%ax | 
|  | 1897 | andb	$0x0f, %al | 
|  | 1898 | prthn:	cmpb	$0x0a, %al | 
|  | 1899 | jc	prth1 | 
|  | 1900 |  | 
|  | 1901 | addb	$0x07, %al | 
|  | 1902 | prth1:	addb	$0x30, %al | 
|  | 1903 | jmp	prtchr | 
|  | 1904 |  | 
|  | 1905 | # Print decimal number in al | 
|  | 1906 | prtdec:	pushw	%ax | 
|  | 1907 | pushw	%cx | 
|  | 1908 | xorb	%ah, %ah | 
|  | 1909 | movb	$0x0a, %cl | 
|  | 1910 | idivb	%cl | 
|  | 1911 | cmpb	$0x09, %al | 
|  | 1912 | jbe	lt100 | 
|  | 1913 |  | 
|  | 1914 | call	prtdec | 
|  | 1915 | jmp	skip10 | 
|  | 1916 |  | 
|  | 1917 | lt100:	addb	$0x30, %al | 
|  | 1918 | call	prtchr | 
|  | 1919 | skip10:	movb	%ah, %al | 
|  | 1920 | addb	$0x30, %al | 
|  | 1921 | call	prtchr | 
|  | 1922 | popw	%cx | 
|  | 1923 | popw	%ax | 
|  | 1924 | ret | 
|  | 1925 |  | 
|  | 1926 | store_edid: | 
| Domen Puncer | 125947f | 2005-05-05 16:16:15 -0700 | [diff] [blame] | 1927 | pushw	%es				# just save all registers | 
|  | 1928 | pushw	%ax | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1929 | pushw	%bx | 
|  | 1930 | pushw   %cx | 
|  | 1931 | pushw	%dx | 
|  | 1932 | pushw   %di | 
|  | 1933 |  | 
| Domen Puncer | 125947f | 2005-05-05 16:16:15 -0700 | [diff] [blame] | 1934 | pushw	%fs | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1935 | popw    %es | 
|  | 1936 |  | 
|  | 1937 | movl	$0x13131313, %eax		# memset block with 0x13 | 
|  | 1938 | movw    $32, %cx | 
|  | 1939 | movw	$0x140, %di | 
|  | 1940 | cld | 
| Domen Puncer | 125947f | 2005-05-05 16:16:15 -0700 | [diff] [blame] | 1941 | rep | 
|  | 1942 | stosl | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1943 |  | 
| Domen Puncer | 125947f | 2005-05-05 16:16:15 -0700 | [diff] [blame] | 1944 | movw	$0x4f15, %ax                    # do VBE/DDC | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1945 | movw	$0x01, %bx | 
|  | 1946 | movw	$0x00, %cx | 
|  | 1947 | movw    $0x01, %dx | 
|  | 1948 | movw	$0x140, %di | 
| Domen Puncer | 125947f | 2005-05-05 16:16:15 -0700 | [diff] [blame] | 1949 | int	$0x10 | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1950 |  | 
| Domen Puncer | 125947f | 2005-05-05 16:16:15 -0700 | [diff] [blame] | 1951 | popw	%di				# restore all registers | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1952 | popw	%dx | 
|  | 1953 | popw	%cx | 
|  | 1954 | popw	%bx | 
|  | 1955 | popw	%ax | 
| Domen Puncer | 125947f | 2005-05-05 16:16:15 -0700 | [diff] [blame] | 1956 | popw	%es | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1957 | ret | 
|  | 1958 |  | 
|  | 1959 | # VIDEO_SELECT-only variables | 
|  | 1960 | mt_end:		.word	0	# End of video mode table if built | 
|  | 1961 | edit_buf:	.space	6	# Line editor buffer | 
|  | 1962 | card_name:	.word	0	# Pointer to adapter name | 
|  | 1963 | scanning:	.byte	0	# Performing mode scan | 
|  | 1964 | do_restore:	.byte	0	# Screen contents altered during mode change | 
|  | 1965 | svga_prefix:	.byte	VIDEO_FIRST_BIOS>>8	# Default prefix for BIOS modes | 
|  | 1966 | graphic_mode:	.byte	0	# Graphic mode with a linear frame buffer | 
|  | 1967 | dac_size:	.byte	6	# DAC bit depth | 
|  | 1968 |  | 
|  | 1969 | # Status messages | 
|  | 1970 | keymsg:		.ascii	"Press <RETURN> to see video modes available, " | 
|  | 1971 | .ascii	"<SPACE> to continue or wait 30 secs" | 
|  | 1972 | .byte	0x0d, 0x0a, 0 | 
|  | 1973 |  | 
|  | 1974 | listhdr:	.byte	0x0d, 0x0a | 
|  | 1975 | .ascii	"Mode:    COLSxROWS:" | 
|  | 1976 |  | 
|  | 1977 | crlft:		.byte	0x0d, 0x0a, 0 | 
|  | 1978 |  | 
|  | 1979 | prompt:		.byte	0x0d, 0x0a | 
|  | 1980 | .asciz	"Enter mode number or `scan': " | 
|  | 1981 |  | 
|  | 1982 | unknt:		.asciz	"Unknown mode ID. Try again." | 
|  | 1983 |  | 
|  | 1984 | badmdt:		.ascii	"You passed an undefined mode number." | 
|  | 1985 | .byte	0x0d, 0x0a, 0 | 
|  | 1986 |  | 
|  | 1987 | vesaer:		.ascii	"Error: Scanning of VESA modes failed. Please " | 
|  | 1988 | .ascii	"report to <mj@ucw.cz>." | 
|  | 1989 | .byte	0x0d, 0x0a, 0 | 
|  | 1990 |  | 
|  | 1991 | old_name:	.asciz	"CGA/MDA/HGA" | 
|  | 1992 |  | 
|  | 1993 | ega_name:	.asciz	"EGA" | 
|  | 1994 |  | 
|  | 1995 | svga_name:	.ascii	" " | 
|  | 1996 |  | 
|  | 1997 | vga_name:	.asciz	"VGA" | 
|  | 1998 |  | 
|  | 1999 | vesa_name:	.asciz	"VESA" | 
|  | 2000 |  | 
|  | 2001 | name_bann:	.asciz	"Video adapter: " | 
|  | 2002 | #endif /* CONFIG_VIDEO_SELECT */ | 
|  | 2003 |  | 
|  | 2004 | # Other variables: | 
|  | 2005 | adapter:	.byte	0	# Video adapter: 0=CGA/MDA/HGA,1=EGA,2=VGA | 
|  | 2006 | video_segment:	.word	0xb800	# Video memory segment | 
|  | 2007 | force_size:	.word	0	# Use this size instead of the one in BIOS vars |