video.S 40 KB

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