2 ! Display adapter & video mode setup, version 2.13 (14-May-99)
4 ! Copyright (C) 1995 -- 1999 Martin Mares <mj@ucw.cz>
5 ! Based on the original setup.S code (C) Linus Torvalds and Mats Anderson
7 ! For further information, look at Documentation/svga.txt.
10 #include <linux/config.h> /* for CONFIG_VIDEO_* */
12 ! Enable autodetection of SVGA adapters and modes. If you really need this
13 ! feature, drop me a mail as I think of removing it some day. You can
14 ! always enter `scan' to get the video mode table and then use the real
15 ! video mode numbers (those 4-digit hexadecimal numbers, NOT the menu
16 ! item numbers) which don't rely on any autodetection.
17 #undef CONFIG_VIDEO_SVGA
19 ! Enable autodetection of VESA modes
20 #define CONFIG_VIDEO_VESA
22 ! Enable compacting of mode table
23 #define CONFIG_VIDEO_COMPACT
25 ! Retain screen contents when switching modes
26 #define CONFIG_VIDEO_RETAIN
28 ! Enable local mode list
29 #undef CONFIG_VIDEO_LOCAL
31 ! Force 400 scan lines for standard modes (hack to fix bad behaviour
32 ! of certain broken BIOSes -- don't use unless needed)
33 #undef CONFIG_VIDEO_400_HACK
35 ! A special hack allowing to force specific BIOS mode ID along with specific
36 ! dimensions. Especially useful for certain X-Window graphics mode hacks
37 ! (e.g., 800x600 modes on IBM ThinkPad).
38 #undef CONFIG_VIDEO_GFX_HACK
39 #define VIDEO_GFX_BIOS_AX 0x4f02 /* 800x600 on ThinkPad */
40 #define VIDEO_GFX_BIOS_BX 0x0102
41 #define VIDEO_GFX_DUMMY_RESOLUTION 0x6425 /* 100x37 */
43 ! This code uses an extended set of video mode numbers. These include:
44 ! Aliases for standard modes
48 ! Video modes numbered by menu position -- NOT RECOMMENDED because of lack
49 ! of compatibility when extending the table. These are between 0x00 and 0xff.
50 #define VIDEO_FIRST_MENU 0x0000
51 ! Standard BIOS video modes (BIOS number + 0x0100)
52 #define VIDEO_FIRST_BIOS 0x0100
53 ! VESA BIOS video modes (VESA number + 0x0200)
54 #define VIDEO_FIRST_VESA 0x0200
55 ! Video7 special modes (BIOS number + 0x0900)
56 #define VIDEO_FIRST_V7 0x0900
58 #define VIDEO_FIRST_SPECIAL 0x0f00
59 #define VIDEO_80x25 0x0f00
60 #define VIDEO_8POINT 0x0f01
61 #define VIDEO_80x43 0x0f02
62 #define VIDEO_80x28 0x0f03
63 #define VIDEO_CURRENT_MODE 0x0f04
64 #define VIDEO_80x30 0x0f05
65 #define VIDEO_80x34 0x0f06
66 #define VIDEO_80x60 0x0f07
67 #define VIDEO_GFX_HACK 0x0f08
68 #define VIDEO_LAST_SPECIAL 0x0f09
69 ! Video modes given by resolution
70 #define VIDEO_FIRST_RESOLUTION 0x1000
72 ! The "recalculate timings" flag
73 #define VIDEO_RECALC 0x8000
75 ! Positions of various video parameters passed to the kernel
76 ! (see also include/linux/tty.h)
77 #define PARAM_CURSOR_POS 0x00
78 #define PARAM_VIDEO_PAGE 0x04
79 #define PARAM_VIDEO_MODE 0x06
80 #define PARAM_VIDEO_COLS 0x07
81 #define PARAM_VIDEO_EGA_BX 0x0a
82 #define PARAM_VIDEO_LINES 0x0e
83 #define PARAM_HAVE_VGA 0x0f
84 #define PARAM_FONT_POINTS 0x10
86 #define PARAM_LFB_WIDTH 0x12
87 #define PARAM_LFB_HEIGHT 0x14
88 #define PARAM_LFB_DEPTH 0x16
89 #define PARAM_LFB_BASE 0x18
90 #define PARAM_LFB_SIZE 0x1c
91 #define PARAM_LFB_LINELENGTH 0x24
92 #define PARAM_LFB_COLORS 0x26
93 #define PARAM_VESAPM_SEG 0x2e
94 #define PARAM_VESAPM_OFF 0x30
95 #define PARAM_LFB_PAGES 0x32
97 ! Define DO_STORE according to CONFIG_VIDEO_RETAIN
98 #ifdef CONFIG_VIDEO_RETAIN
99 #define DO_STORE call store_screen
102 #endif /* CONFIG_VIDEO_RETAIN */
105 ! This is the main entry point called by setup.S
108 ! DS pointing to the boot sector
110 video: push ds ! We use different segments
111 push ds ! FS contains original DS
113 push cs ! DS is equal to CS
115 push cs ! ES is equal to CS
118 mov gs,ax ! GS is zero
120 call basic_detect ! Basic adapter type testing (EGA/VGA/MDA/CGA)
121 #ifdef CONFIG_VIDEO_SELECT
122 seg fs ! User-selected video mode
124 cmp ax,#ASK_VGA ! Bring up the menu
126 call mode_set ! Set the mode
128 lea si,badmdt ! Invalid mode ID
132 #ifdef CONFIG_VIDEO_RETAIN
133 call restore_screen ! Restore screen contents
134 #endif /* CONFIG_VIDEO_RETAIN */
135 #endif /* CONFIG_VIDEO_SELECT */
136 call mode_params ! Store mode parameters
137 pop ds ! Restore original DS
141 ! Detect if we have CGA, MDA, EGA or VGA and pass it to the kernel.
145 seg fs ! Default is no VGA
146 movb [PARAM_HAVE_VGA],#0
148 mov ah,#0x12 ! Check EGA/VGA
152 mov [PARAM_VIDEO_EGA_BX],bx ! Used for identification of EGA in the kernel
153 cmp bl,#0x10 ! No, this is a CGA/MDA/HGA card.
157 mov ax,#0x1a00 ! Check for EGA/VGA discrimination
159 cmp al,#0x1a ! 1a means VGA, anything else EGA
162 incb [PARAM_HAVE_VGA] ! We've detected a VGA
168 ! Store the video mode parameters for later usage by the kernel.
169 ! This is done by asking the BIOS except for the rows/columns
170 ! parameters in the default 80x25 mode -- these are set directly,
171 ! because some very obscure BIOSes supply insane values.
175 #ifdef CONFIG_VIDEO_SELECT
176 cmpb [graphic_mode],#0
180 mov ah,#0x03 ! Read cursor position
184 mov [PARAM_CURSOR_POS],dx
186 mov ah,#0x0f ! Read page/mode/width
189 mov [PARAM_VIDEO_PAGE],bx
191 mov [PARAM_VIDEO_MODE],ax ! Video mode and screen width
192 cmp al,#7 ! MDA/HGA => segment differs
194 mov [video_segment],#0xb000
195 mopar0: seg gs ! Font size
198 mov [PARAM_FONT_POINTS],ax ! (valid only on EGA/VGA)
200 mov ax,[force_size] ! Forced size?
204 mov [PARAM_VIDEO_COLS],ah
206 mov [PARAM_VIDEO_LINES],al
210 cmpb [adapter],#0 ! If we are on CGA/MDA/HGA, the screen must
211 jz mopar2 ! have 25 lines.
212 seg gs ! On EGA/VGA, use the EGA+ BIOS variable
213 mov al,[0x484] ! containing maximal line number.
216 movb [PARAM_VIDEO_LINES],al
219 #ifdef CONFIG_VIDEO_SELECT
222 ! Fetching of VESA frame buffer parameters
228 movb [PARAM_HAVE_VGA],#0x23
232 mov [PARAM_LFB_LINELENGTH],ax
236 mov [PARAM_LFB_WIDTH],ax
240 mov [PARAM_LFB_HEIGHT],ax
245 mov [PARAM_LFB_DEPTH],ax
250 mov [PARAM_LFB_PAGES],ax
254 mov [PARAM_LFB_BASE],eax
258 mov [PARAM_LFB_COLORS],eax
262 mov [PARAM_LFB_COLORS+4],eax
272 mov [PARAM_LFB_SIZE],eax
274 ! get protected mode interface informations
282 mov [PARAM_VESAPM_SEG],es
284 mov [PARAM_VESAPM_OFF],di
290 ! The video mode menu
294 lea si,keymsg ! "Return/Space/Timeout" message
298 cmp al,#0x0d ! ENTER ?
299 je listm ! yes - manual mode selection
300 cmp al,#0x20 ! SPACE ?
301 je defmd1 ! no - repeat
304 defmd1: ret ! No mode selected => use the 80x25 default
306 listm: call mode_table ! We need a mode table to be listed
307 listm0: lea si,name_bann ! Print adapter name
324 lea si,listhdr ! Table header
326 mov dl,#0x30 ! DL holds mode number
328 lm1: cmp (si),#ASK_VGA ! End?
330 mov al,dl ! Menu selection number
341 call prtdec ! Columns
342 mov al,#0x0d ! New line
346 inc dl ! Next character
352 lm2: lea si,prompt ! Mode prompt
354 lea di,edit_buf ! Editor buffer
356 cmp al,#0x0d ! Enter?
358 cmp al,#0x08 ! Backspace?
360 cmp al,#0x20 ! Printable?
362 cmp di,#edit_buf+4 ! Enough space?
368 lmbs: cmp di,#edit_buf ! Backspace
382 cmpb (si),#0 ! Empty string => use default mode
384 cmpb (si+1),#0 ! One character => menu selection
386 cmp (si),#0x6373 ! "scan" => mode scanning
390 lmhx: xor bx,bx ! Else => mode ID in hex
410 mnusel: lodsb ! Menu selection
427 lmscan: cmpb [adapter],#0 ! Scanning supported only on EGA/VGA
429 mov [mt_end],#0 ! Scanning of modes: done as new autodetection
437 ! Additional parts of mode_set... (relative jumps, you know)
440 setv7: ! Video7 extended modes
442 sub bh,#VIDEO_FIRST_V7>>8
448 _setrec: br setrec ! Ugly...
449 _set_80x25: br set_80x25
452 ! Aliases for backward compatibility.
459 mov al,#VIDEO_8POINT-VIDEO_FIRST_SPECIAL
466 ! Setting of user mode (AX=mode ID) => CF=success
473 test ah,#VIDEO_RECALC>>8
475 cmp ah,#VIDEO_FIRST_RESOLUTION>>8
477 cmp ah,#VIDEO_FIRST_SPECIAL>>8
479 cmp ah,#VIDEO_FIRST_V7>>8
481 cmp ah,#VIDEO_FIRST_VESA>>8
488 movb [do_restore],#0 ! The screen needn't be restored
493 sub bh,#VIDEO_FIRST_VESA>>8
494 mov ax,#0x4f02 ! VESA BIOS mode set call
496 cmp ax,#0x004f ! AL=4f if implemented, AH=0 if OK
503 int 0x10 ! Standard BIOS mode set call
505 mov ah,#0x0f ! Check if really set
513 setspc: xor bh,bh ! Set special mode
514 cmp bl,#VIDEO_LAST_SPECIAL-VIDEO_FIRST_SPECIAL
517 .word 0xa7ff, spec_inits ! JMP [BX+spec_inits]
520 or al,al ! 80x25 is an exception
522 push bx ! Set mode chosen from menu
523 call mode_table ! Build the mode table
529 mov ax,(si) ! Fetch mode ID
533 push bx ! Set mode chosen by its resolution
538 cmp ax,#ASK_VGA ! End of the list?
543 mov ax,(si-4) ! Fetch mode ID
549 sub bh,#VIDEO_FIRST_VESA>>8
550 mov cx,bx ! Get mode information structure
553 add bh,#VIDEO_FIRST_VESA>>8
557 mov al,(di) ! Check capabilities.
560 jz setvesa ! this is a text mode
562 mov al,(di) ! Check capabilities.
565 jnz _setbad ! to bad, no linear frame buffer
567 sub bh,#VIDEO_FIRST_VESA>>8
568 or bx,#0x4000 ! want use linear frame buffer
569 mov ax,#0x4f02 ! VESA BIOS mode set call
571 cmp ax,#0x004f ! AL=4f if implemented, AH=0 if OK
574 movb [graphic_mode],#1 ! flag graphic mode
575 movb [do_restore],#0 ! no screen restore
579 _setbad: br setbad ! Ugly...
582 ! Recalculate vertical display end registers -- this fixes various
583 ! inconsistencies of extended modes on many adapters. Called when
584 ! the VIDEO_RECALC flag is set in the mode ID.
587 setrec: sub ah,#VIDEO_RECALC>>8 ! Set the base mode
590 seg gs ! Font size in pixels
592 seg gs ! Number of rows
595 mul bl ! Number of visible
596 dec ax ! scan lines - 1
599 mov al,#0x12 ! Lower 8 bits
602 mov al,#0x07 ! Bits 8 and 9 in the overflow register
618 ! Table of routines for setting of the special modes.
633 ! Set the 80x25 mode. If already set, do nothing.
637 mov [force_size],#0x5019 ! Override possibly broken BIOS vars
639 #ifdef CONFIG_VIDEO_400_HACK
640 mov ax,#0x1202 ! Force 400 scan lines
644 mov ah,#0x0f ! Get current mode ID
646 cmp ax,#0x5007 ! Mode 7 (80x25 mono) is the only one available
647 jz st80 ! on CGA/MDA/HGA and is also available on EGAM
648 cmp ax,#0x5003 ! Unknown mode => force 80x25 color
650 st80: cmpb [adapter],#0 ! CGA/MDA/HGA => mode 3/7 is always 80x25
652 seg gs ! This is EGA+ -- beware of 80x50 etc.
654 or al,al ! Some buggy BIOSes set 0 rows
656 cmp al,#24 ! Let's hope this is correct
658 #endif /* CONFIG_VIDEO_400_HACK */
660 mov ax,#0x0003 ! Forced set
666 ! Set the 80x50/80x43 8-pixel mode. Simple BIOS calls.
671 call use_80x25 ! The base is 80x25
673 mov ax,#0x1112 ! Use 8x8 font
676 mov ax,#0x1200 ! Use alternate print screen
679 mov ax,#0x1201 ! Turn off cursor emulation
682 mov ah,#0x01 ! Define cursor (scan lines 6 to 7)
690 ! Set the 80x28 mode. This mode works on all VGA's, because it's a standard
691 ! 80x25 mode with 14-point fonts instead of 16-point.
696 call use_80x25 ! The base is 80x25
697 set14: mov ax,#0x1111 ! Use 9x14 font
700 mov ah,#0x01 ! Define cursor (scan lines 11 to 12)
707 ! Set the 80x43 mode. This mode is works on all VGA's.
708 ! It's a 350-scanline mode with 8-pixel font.
713 mov ax,#0x1201 ! Set 350 scans
716 mov ax,#0x0003 ! Reset video mode
718 jmp set_8pt ! Use 8-pixel font
721 ! Set the 80x30 mode (all VGA's). 480 scanlines, 16-pixel font.
725 call use_80x25 ! Start with real 80x25
727 mov dx,#0x3cc ! Get CRTC port
730 ror al,#1 ! Mono or color?
733 set48a: mov ax,#0x0c11 ! Vertical sync end (also unlocks CR0-7)
735 mov ax,#0x0b06 ! Vertical total
737 mov ax,#0x3e07 ! (Vertical) overflow
739 mov ax,#0xea10 ! Vertical sync start
741 mov ax,#0xdf12 ! Vertical display end
743 mov ax,#0xe715 ! Vertical blank start
745 mov ax,#0x0416 ! Vertical blank end
748 mov dl,#0xcc ! Misc output register (read)
750 mov dl,#0xc2 ! (write)
751 and al,#0x0d ! Preserve clock select bits and color bit
752 or al,#0xe2 ! Set correct sync polarity
755 mov [force_size],#0x501e
760 ! Set the 80x34 mode (all VGA's). 480 scans, 14-pixel font.
764 call set_80x30 ! Set 480 scans
765 call set14 ! And 14-pt font
766 mov ax,#0xdb12 ! VGA vertical display end
767 mov [force_size],#0x5022
773 ! Set the 80x60 mode (all VGA's). 480 scans, 8-pixel font.
777 call set_80x30 ! Set 480 scans
778 call set_8pt ! And 8-pt font
779 mov ax,#0xdf12 ! VGA vertical display end
780 mov [force_size],#0x503c
784 ! Special hack for ThinkPad graphics
788 #ifdef CONFIG_VIDEO_GFX_HACK
789 mov ax,# VIDEO_GFX_BIOS_AX
790 mov bx,# VIDEO_GFX_BIOS_BX
792 mov [force_size],# VIDEO_GFX_DUMMY_RESOLUTION
797 #ifdef CONFIG_VIDEO_RETAIN
800 ! Store screen contents to temporary buffer.
804 cmpb [do_restore],#0 ! Already stored?
806 testb [loadflags],#CAN_USE_HEAP ! Have we space for storing?
810 push [force_size] ! Don't force specific size
812 call mode_params ! Obtain params of current mode
816 mov ah,[PARAM_VIDEO_LINES]
818 mov al,[PARAM_VIDEO_COLS]
819 mov bx,ax ! BX=dimensions
821 mov cx,ax ! CX=number of characters to store
822 add ax,ax ! Calculate image size
823 add ax,#modelist+1024+4
824 cmp ax,[heap_end_ptr]
825 jnc sts1 ! Unfortunately, out of memory
827 seg fs ! Store mode params
828 mov ax,[PARAM_CURSOR_POS]
834 push ds ! Store the screen
835 mov ds,[video_segment]
840 incb [do_restore] ! Screen will be restored later
846 ! Restore screen contents from temporary buffer.
850 cmpb [do_restore],#0 ! Has the screen been stored?
852 call mode_params ! Get parameters of current mode
854 mov cl,[PARAM_VIDEO_LINES]
856 mov ch,[PARAM_VIDEO_COLS]
857 lea si,modelist+1024 ! Screen buffer
858 lodsw ! Set cursor position
872 mov dl,ah ! DL=number of lines
873 mov ah,#0 ! BX=physical length of orig. line
875 cmp dl,cl ! Too many?
885 res4: cmp al,ch ! Too wide?
887 mov al,ch ! AX=width of src. line
890 mov bp,cx ! BP=width of dest. line
892 mov es,[video_segment]
893 xor di,di ! Move the data
894 add bx,bx ! Convert BX and BP to _bytes_
910 #endif /* CONFIG_VIDEO_RETAIN */
913 ! Write to indexed VGA register (AL=index, AH=data, DX=index reg. port)
926 ! Build the table of video modes (stored after the setup.S code at the
927 ! `modelist' label. Each video mode record looks like:
928 ! .word MODE-ID (our special mode ID (see above))
929 ! .byte rows (number of rows)
930 ! .byte columns (number of columns)
931 ! Returns address of the end of the table in DI, the end is marked
936 mov di,[mt_end] ! Already filled?
939 lea di,modelist ! Store standard modes:
941 mov eax,#VIDEO_80x25 + 0x50190000 ! The 80x25 mode (ALL)
943 mov al,[adapter] ! CGA/MDA/HGA -- no more modes
948 mov eax,#VIDEO_8POINT + 0x502b0000 ! The 80x43 EGA mode
953 mtabv: lea si,vga_modes ! All modes for std VGA
954 mov cx,#vga_modes_end-vga_modes
955 rep ! I'm unable to use movsw as I don't know how to store a half
956 movsb ! of the expression above to cx without using explicit shr.
958 cmpb [scanning],#0 ! Mode scan requested?
963 #ifdef CONFIG_VIDEO_LOCAL
965 #endif /* CONFIG_VIDEO_LOCAL */
966 #ifdef CONFIG_VIDEO_VESA
967 call vesa_modes ! Detect VESA VGA modes
968 #endif /* CONFIG_VIDEO_VESA */
969 #ifdef CONFIG_VIDEO_SVGA
970 cmpb [scanning],#0 ! Bypass when scanning
972 call svga_modes ! Detect SVGA cards & modes
974 #endif /* CONFIG_VIDEO_SVGA */
978 #ifdef CONFIG_VIDEO_COMPACT
979 lea si,modelist ! Compact video mode list if requested.
982 cmt1: cmp si,dx ! Scan all modes
984 lea bx,modelist ! Find in previous entries
988 cmp cx,(bx+2) ! Found => don't copy this entry
993 cmt4: movsd ! Copy entry
996 cmt5: add si,#4 ! Skip entry
1000 #endif /* CONFIG_VIDEO_COMPACT */
1002 mov (di),#ASK_VGA ! End marker
1004 mtab1: lea si,modelist ! Returning: SI=mode list, DI=list end
1007 ! Modes usable on all standard VGAs
1011 .word 0x5032 ! 80x50
1013 .word 0x502b ! 80x43
1015 .word 0x501c ! 80x28
1017 .word 0x501e ! 80x30
1019 .word 0x5022 ! 80x34
1021 .word 0x503c ! 80x60
1022 #ifdef CONFIG_VIDEO_GFX_HACK
1023 .word VIDEO_GFX_HACK
1024 .word VIDEO_GFX_DUMMY_RESOLUTION
1029 ! Detect VESA modes.
1032 #ifdef CONFIG_VIDEO_VESA
1035 cmpb [adapter],#2 ! VGA only
1037 mov bp,di ! BP=original mode table end
1038 add di,#0x200 ! Buffer space
1039 mov ax,#0x4f00 ! VESA Get card info call
1042 cmp ax,#0x004f ! Successful?
1044 cmp (di+0x200),#0x4556
1046 cmp (di+0x202),#0x4153
1048 mov [card_name],#vesa_name ! Set name to "VESA VGA"
1050 lgs si,(di+0x20e) ! GS:SI=mode list
1051 mov cx,#128 ! Iteration limit
1052 vesa1: seg gs ! Get next mode in the list
1054 cmp ax,#0xffff ! End of the table?
1056 cmp ax,#0x0080 ! Check validity of mode ID
1058 or ah,ah ! Valid IDs are 0x0000-0x007f and 0x0100-0x07ff
1059 jz vesan ! [Certain BIOSes erroneously report 0x80-0xff]
1063 mov cx,ax ! Get mode information structure
1066 mov bx,cx ! BX=mode number
1067 add bh,#VIDEO_FIRST_VESA>>8
1070 jnz vesan ! Don't report errors (buggy BIOSES :-[ )
1071 mov al,(di) ! Check capabilities. We require
1072 and al,#0x19 ! a color text mode.
1075 cmp (di+8),#0xb800 ! Standard video memory address required
1077 testb (di),#2 ! Mode characteristics supplied?
1078 mov (di),bx ! Store mode number
1081 mov bx,(di+0x12) ! Width
1085 mov ax,(di+0x14) ! Height
1090 cmp ax,#8193 ! Small enough for Linux console driver?
1094 vesa3: sub bx,#0x8108 ! This mode has no detailed info specified,
1095 jc vesan ! so it must be a standard VESA mode.
1098 mov ax,(bx+vesa_text_mode_table)
1100 vesaok: add di,#4 ! The mode is valid. Store it.
1101 vesan: loop vesa1 ! Next mode. Limit exceeded => error
1102 vesae: lea si,vesaer
1104 mov di,bp ! Discard already found modes.
1109 ! Dimensions of standard VESA text modes
1112 vesa_text_mode_table:
1119 #endif /* CONFIG_VIDEO_VESA */
1122 ! Scan for video modes. A bit dirty, but should work.
1126 mov cx,#0x0100 ! Start with mode 0
1127 scm1: mov ah,#0 ! Test the mode
1133 jnz scm2 ! Mode not set
1134 mov dx,#0x3c0 ! Test if it's a text mode
1135 mov al,#0x10 ! Mode bits
1139 mov dl,#0xce ! Another set of mode bits
1144 mov dl,#0xd4 ! Cursor location
1149 mov ax,cx ! OK, store the mode
1151 seg gs ! Number of rows
1155 seg gs ! Number of columns
1160 mov ax,#0x0003 ! Return back to mode 3
1164 tstidx: out dx,ax ! OUT DX,AX and inidx
1165 inidx: out dx,al ! Read from indexed VGA register
1166 inc dx ! AL=index, DX=index reg port -> AL=data
1172 ! Try to detect type of SVGA card and supply (usually approximate) video
1173 ! mode table for it.
1176 #ifdef CONFIG_VIDEO_SVGA
1179 lea si,svga_table ! Test all known SVGA adapters
1181 mov bp,ax ! Default mode table
1184 lodsw ! Pointer to test routine
1190 call ax ! Call test routine
1196 mov si,bp ! Found, copy the modes
1197 mov ah,[svga_prefix]
1205 didsv: mov [card_name],si ! Store pointer to card name
1209 ! Table of all known SVGA cards. For each card, we store a pointer to
1210 ! a table of video modes supported by the card and a pointer to a routine
1211 ! used for testing of presence of the card. The video mode table is always
1212 ! followed by the name of the card or the chipset.
1216 .word ati_md, ati_test
1217 .word oak_md, oak_test
1218 .word paradise_md, paradise_test
1219 .word realtek_md, realtek_test
1220 .word s3_md, s3_test
1221 .word chips_md, chips_test
1222 .word video7_md, video7_test
1223 .word cirrus5_md, cirrus5_test
1224 .word cirrus6_md, cirrus6_test
1225 .word cirrus1_md, cirrus1_test
1226 .word ahead_md, ahead_test
1227 .word everex_md, everex_test
1228 .word genoa_md, genoa_test
1229 .word trident_md, trident_test
1230 .word tseng_md, tseng_test
1234 ! Test routines and mode tables:
1237 ! S3 - The test algorithm was taken from the SuperProbe package
1238 ! for XFree86 1.2.1. Report bugs to Christoph.Niemann@linux.org
1241 mov cx,#0x0f35 ! we store some constants in cl/ch
1245 mov bh,al ! store current value of CRT-register 0x38
1247 call outidx ! disable writing to special regs
1248 movb al,cl ! check whether we can write special reg 0x35
1250 movb bl,al ! save the current value of CRT reg 0x35
1251 andb al,#0xf0 ! clear bits 0-3
1253 movb al,cl ! and write it to CRT reg 0x35
1255 call inidx ! now read it back
1256 andb al,ch ! clear the upper 4 bits
1257 jz s3_2 ! the first test failed. But we have a
1258 movb ah,bl ! second chance
1261 jmp s3_1 ! do the other tests
1262 s3_2: mov ax,cx ! load ah with 0xf and al with 0x35
1263 orb ah,bl ! set the upper 4 bits of ah with the orig value
1264 call outidx ! write ...
1265 call inidx ! ... and reread
1266 andb al,cl ! turn off the upper 4 bits
1268 movb ah,bl ! restore old value in register 0x35
1272 cmp al,ch ! setting lower 4 bits was successful => bad
1273 je no_s3 ! writing is allowed => this is not an S3
1274 s3_1: mov ax,#0x4838 ! allow writing to special regs by putting
1275 call outidx ! magic number into CRT-register 0x38
1276 movb al,cl ! check whether we can write special reg 0x35
1285 jnz no_s3 ! no, we can't write => no S3
1292 movb ah,bl ! restore old value in register 0x35
1297 jne no_s31 ! writing not possible => no S3
1299 call inidx ! now get the S3 id ...
1308 no_s3: movb al,#0x35 ! restore CRT register 0x35
1311 no_s31: xor bp,bp ! Detection failed
1313 movb al,#0x38 ! restore old value of CRT register 0x38
1316 idS3: .byte 0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
1317 .byte 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
1319 s3_md: .byte 0x54, 0x2b, 0x84
1320 .byte 0x55, 0x19, 0x84
1337 idati: .ascii "761295520"
1339 ati_md: .byte 0x23, 0x19, 0x84
1340 .byte 0x33, 0x2c, 0x84
1341 .byte 0x22, 0x1e, 0x64
1342 .byte 0x21, 0x19, 0x64
1343 .byte 0x58, 0x21, 0x50
1344 .byte 0x5b, 0x1e, 0x50
1365 .byte 0x22, 0x2c, 0x84
1366 .byte 0x23, 0x19, 0x84
1367 .byte 0x24, 0x1c, 0x84
1368 .byte 0x2f, 0x32, 0xa0
1369 .byte 0x32, 0x22, 0x50
1370 .byte 0x34, 0x42, 0x50
1395 .byte 0x60, 0x19, 0x84
1396 .byte 0x61, 0x32, 0x84
1398 .ascii "Chips & Technologies"
1439 iscirr: mov dx,#0x3d4
1448 .byte 0x1f, 0x19, 0x84
1449 .byte 0x20, 0x2c, 0x84
1450 .byte 0x22, 0x1e, 0x84
1451 .byte 0x31, 0x25, 0x64
1453 .ascii "Cirrus Logic 5X0"
1462 mov bl,al ! BL=backup
1499 .byte 0x14, 0x19, 0x84
1500 .byte 0x54, 0x2b, 0x84
1502 .ascii "Cirrus Logic 54XX"
1505 ! Cirrus Logic 64XX -- no known extra modes, but must be identified, because
1506 ! it's misidentified by the Ahead test.
1512 mov bl,al ! BL=backup
1522 call inidx ! 4X, 5X, 7X and 8X are valid 64XX chip IDs
1533 c6done: mov al,#0x0a
1540 .ascii "Cirrus Logic 64XX"
1556 evtrid: lea bp,trident_md
1563 .byte 0x03, 0x22, 0x50
1564 .byte 0x04, 0x3c, 0x50
1565 .byte 0x07, 0x2b, 0x64
1566 .byte 0x08, 0x4b, 0x64
1567 .byte 0x0a, 0x19, 0x84
1568 .byte 0x0b, 0x2c, 0x84
1569 .byte 0x16, 0x1e, 0x50
1570 .byte 0x18, 0x1b, 0x64
1571 .byte 0x21, 0x40, 0xa0
1572 .byte 0x40, 0x1e, 0x84
1574 .ascii "Everex/Trident"
1580 lea si,idgenoa ! Check Genoa 'clues'
1601 idgenoa: .byte 0x77, 0x00, 0x99, 0x66
1604 .byte 0x58, 0x20, 0x50
1605 .byte 0x5a, 0x2a, 0x64
1606 .byte 0x60, 0x19, 0x84
1607 .byte 0x61, 0x1d, 0x84
1608 .byte 0x62, 0x20, 0x84
1609 .byte 0x63, 0x2c, 0x84
1610 .byte 0x64, 0x3c, 0x84
1611 .byte 0x6b, 0x4f, 0x64
1612 .byte 0x72, 0x3c, 0x50
1613 .byte 0x74, 0x42, 0x50
1614 .byte 0x78, 0x4b, 0x64
1631 idoakvga: .ascii "OAK VGA "
1633 oak_md: .byte 0x4e, 0x3c, 0x50
1634 .byte 0x4f, 0x3c, 0x84
1635 .byte 0x50, 0x19, 0x84
1636 .byte 0x51, 0x2b, 0x84
1653 idparadise: .ascii "VGA="
1656 .byte 0x41, 0x22, 0x50
1657 .byte 0x47, 0x1c, 0x84
1658 .byte 0x55, 0x19, 0x84
1659 .byte 0x54, 0x2c, 0x84
1677 mov bl,al ! Strange thing ... in the book this wasn't
1678 and bl,#0x02 ! necessary but it worked on my card which
1679 jz setb2 ! is a trident. Without it the screen goes
1680 and al,#0xfd ! blurred ...
1682 setb2: or al,#0x02 !
1691 .byte 0x50, 0x1e, 0x50
1692 .byte 0x51, 0x2b, 0x50
1693 .byte 0x52, 0x3c, 0x50
1694 .byte 0x57, 0x19, 0x84
1695 .byte 0x58, 0x1e, 0x84
1696 .byte 0x59, 0x2b, 0x84
1697 .byte 0x5a, 0x3c, 0x84
1706 in al,dx ! Could things be this simple? :-)
1720 .byte 0x26, 0x3c, 0x50
1721 .byte 0x2a, 0x28, 0x64
1722 .byte 0x23, 0x19, 0x84
1723 .byte 0x24, 0x1c, 0x84
1724 .byte 0x22, 0x2c, 0x84
1725 .byte 0x21, 0x3c, 0x84
1763 movb [svga_prefix],#VIDEO_FIRST_V7>>8 ! Use special mode switching
1767 .byte 0x40, 0x2b, 0x50
1768 .byte 0x43, 0x3c, 0x50
1769 .byte 0x44, 0x3c, 0x64
1770 .byte 0x41, 0x19, 0x84
1771 .byte 0x42, 0x2c, 0x84
1772 .byte 0x45, 0x1c, 0x84
1789 idrtvga: .ascii "REALTEK VGA"
1792 .byte 0x1a, 0x3c, 0x50
1793 .byte 0x1b, 0x19, 0x84
1794 .byte 0x1c, 0x1e, 0x84
1795 .byte 0x1d, 0x2b, 0x84
1796 .byte 0x1e, 0x3c, 0x84
1801 #endif /* CONFIG_VIDEO_SVGA */
1804 ! User-defined local mode table (VGA only)
1807 #ifdef CONFIG_VIDEO_LOCAL
1810 lea si,local_mode_table
1819 ! This is the table of local video modes which can be supplied manually
1820 ! by the user. Each entry consists of mode ID (word) and dimensions
1821 ! (byte for column count and another byte for row count). These modes
1822 ! are placed before all SVGA and VESA modes and override them if table
1823 ! compacting is enabled. The table must end with a zero word followed
1824 ! by NUL-terminated video adapter name.
1827 .word 0x0100 ! Example: 40x25
1833 #endif /* CONFIG_VIDEO_LOCAL */
1836 ! Read a key and return the ASCII code in al, scan code in ah
1844 ! Read a key with a timeout of 30 seconds. The hardware clock is used to get
1849 add al,#30 ! Wait 30 seconds
1857 jnz getkey ! key pressed, so get it
1861 mov al,#0x20 ! timeout, return default char `space'
1865 ! Flush the keyboard buffer
1877 ! Print hexadecimal number.
1896 ! Print decimal number (AL).
1901 xor ah,ah ! Clear ah
1918 ! VIDEO_SELECT-only variables
1921 mt_end: .word 0 ! End of video mode table if built
1922 edit_buf: .space 6 ! Line editor buffer
1923 card_name: .word 0 ! Pointer to adapter name
1924 scanning: .byte 0 ! Performing mode scan
1925 do_restore: .byte 0 ! Screen contents altered during mode change
1926 svga_prefix: .byte VIDEO_FIRST_BIOS>>8 ! Default prefix for BIOS modes
1927 graphic_mode: .byte 0 ! Graphic mode with a linear frame buffer
1933 keymsg: .ascii "Press <RETURN> to see video modes available, "
1934 .ascii "<SPACE> to continue or wait 30 secs"
1936 listhdr: db 0x0d, 0x0a
1937 .ascii "Mode: COLSxROWS:"
1938 crlft: db 0x0d, 0x0a, 0
1939 prompt: db 0x0d, 0x0a
1940 .ascii "Enter mode number or `scan': "
1942 unknt: .ascii "Unknown mode ID. Try again."
1944 badmdt: .ascii "You passed an undefined mode number."
1946 vesaer: .ascii "Error: Scanning of VESA modes failed. Please "
1947 .ascii "report to <mj@ucw.cz>."
1949 old_name: .ascii "CGA/MDA/HGA"
1951 ega_name: .ascii "EGA"
1953 svga_name: .ascii " "
1954 vga_name: .ascii "VGA"
1956 vesa_name: .ascii "VESA"
1958 name_bann: .ascii "Video adapter: "
1961 #endif /* CONFIG_VIDEO_SELECT */
1967 adapter: .byte 0 ! Video adapter: 0=CGA/MDA/HGA,1=EGA,2=VGA
1968 video_segment: .word 0xb800 ! Video memory segment
1969 force_size: .word 0 ! Use this size instead of the one in BIOS vars