video.S 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029
  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. leaw modelist+1024, %di
  474. subb $VIDEO_FIRST_VESA>>8, %bh
  475. movw %bx, %cx # Get mode information structure
  476. movw $0x4f01, %ax
  477. int $0x10
  478. addb $VIDEO_FIRST_VESA>>8, %bh
  479. cmpw $0x004f, %ax
  480. jnz setbad
  481. movb (%di), %al # Check capabilities.
  482. andb $0x19, %al
  483. cmpb $0x09, %al
  484. jz setvesa # This is a text mode
  485. movb (%di), %al # Check capabilities.
  486. andb $0x99, %al
  487. cmpb $0x99, %al
  488. jnz _setbad # Doh! No linear frame buffer.
  489. subb $VIDEO_FIRST_VESA>>8, %bh
  490. orw $0x4000, %bx # Use linear frame buffer
  491. movw $0x4f02, %ax # VESA BIOS mode set call
  492. int $0x10
  493. cmpw $0x004f, %ax # AL=4f if implemented
  494. jnz _setbad # AH=0 if OK
  495. movb $1, graphic_mode # flag graphic mode
  496. movb $0, do_restore # no screen restore
  497. stc
  498. ret
  499. _setbad: jmp setbad # Ugly...
  500. # Recalculate vertical display end registers -- this fixes various
  501. # inconsistencies of extended modes on many adapters. Called when
  502. # the VIDEO_RECALC flag is set in the mode ID.
  503. setrec: subb $VIDEO_RECALC>>8, %ah # Set the base mode
  504. call mode_set
  505. jnc rct3
  506. movw %gs:(0x485), %ax # Font size in pixels
  507. movb %gs:(0x484), %bl # Number of rows
  508. incb %bl
  509. mulb %bl # Number of visible
  510. decw %ax # scan lines - 1
  511. movw $0x3d4, %dx
  512. movw %ax, %bx
  513. movb $0x12, %al # Lower 8 bits
  514. movb %bl, %ah
  515. outw %ax, %dx
  516. movb $0x07, %al # Bits 8 and 9 in the overflow register
  517. call inidx
  518. xchgb %al, %ah
  519. andb $0xbd, %ah
  520. shrb %bh
  521. jnc rct1
  522. orb $0x02, %ah
  523. rct1: shrb %bh
  524. jnc rct2
  525. orb $0x40, %ah
  526. rct2: movb $0x07, %al
  527. outw %ax, %dx
  528. stc
  529. rct3: ret
  530. # Table of routines for setting of the special modes.
  531. spec_inits:
  532. .word set_80x25
  533. .word set_8pixel
  534. .word set_80x43
  535. .word set_80x28
  536. .word set_current
  537. .word set_80x30
  538. .word set_80x34
  539. .word set_80x60
  540. .word set_gfx
  541. # Set the 80x25 mode. If already set, do nothing.
  542. set_80x25:
  543. movw $0x5019, force_size # Override possibly broken BIOS
  544. use_80x25:
  545. #ifdef CONFIG_VIDEO_400_HACK
  546. movw $0x1202, %ax # Force 400 scan lines
  547. movb $0x30, %bl
  548. int $0x10
  549. #else
  550. movb $0x0f, %ah # Get current mode ID
  551. int $0x10
  552. cmpw $0x5007, %ax # Mode 7 (80x25 mono) is the only one available
  553. jz st80 # on CGA/MDA/HGA and is also available on EGAM
  554. cmpw $0x5003, %ax # Unknown mode, force 80x25 color
  555. jnz force3
  556. st80: cmpb $0, adapter # CGA/MDA/HGA => mode 3/7 is always 80x25
  557. jz set80
  558. movb %gs:(0x0484), %al # This is EGA+ -- beware of 80x50 etc.
  559. orb %al, %al # Some buggy BIOS'es set 0 rows
  560. jz set80
  561. cmpb $24, %al # It's hopefully correct
  562. jz set80
  563. #endif /* CONFIG_VIDEO_400_HACK */
  564. force3: DO_STORE
  565. movw $0x0003, %ax # Forced set
  566. int $0x10
  567. set80: stc
  568. ret
  569. # Set the 80x50/80x43 8-pixel mode. Simple BIOS calls.
  570. set_8pixel:
  571. DO_STORE
  572. call use_80x25 # The base is 80x25
  573. set_8pt:
  574. movw $0x1112, %ax # Use 8x8 font
  575. xorb %bl, %bl
  576. int $0x10
  577. movw $0x1200, %ax # Use alternate print screen
  578. movb $0x20, %bl
  579. int $0x10
  580. movw $0x1201, %ax # Turn off cursor emulation
  581. movb $0x34, %bl
  582. int $0x10
  583. movb $0x01, %ah # Define cursor scan lines 6-7
  584. movw $0x0607, %cx
  585. int $0x10
  586. set_current:
  587. stc
  588. ret
  589. # Set the 80x28 mode. This mode works on all VGA's, because it's a standard
  590. # 80x25 mode with 14-point fonts instead of 16-point.
  591. set_80x28:
  592. DO_STORE
  593. call use_80x25 # The base is 80x25
  594. set14: movw $0x1111, %ax # Use 9x14 font
  595. xorb %bl, %bl
  596. int $0x10
  597. movb $0x01, %ah # Define cursor scan lines 11-12
  598. movw $0x0b0c, %cx
  599. int $0x10
  600. stc
  601. ret
  602. # Set the 80x43 mode. This mode is works on all VGA's.
  603. # It's a 350-scanline mode with 8-pixel font.
  604. set_80x43:
  605. DO_STORE
  606. movw $0x1201, %ax # Set 350 scans
  607. movb $0x30, %bl
  608. int $0x10
  609. movw $0x0003, %ax # Reset video mode
  610. int $0x10
  611. jmp set_8pt # Use 8-pixel font
  612. # Set the 80x30 mode (all VGA's). 480 scanlines, 16-pixel font.
  613. set_80x30:
  614. call use_80x25 # Start with real 80x25
  615. DO_STORE
  616. movw $0x3cc, %dx # Get CRTC port
  617. inb %dx, %al
  618. movb $0xd4, %dl
  619. rorb %al # Mono or color?
  620. jc set48a
  621. movb $0xb4, %dl
  622. set48a: movw $0x0c11, %ax # Vertical sync end (also unlocks CR0-7)
  623. call outidx
  624. movw $0x0b06, %ax # Vertical total
  625. call outidx
  626. movw $0x3e07, %ax # (Vertical) overflow
  627. call outidx
  628. movw $0xea10, %ax # Vertical sync start
  629. call outidx
  630. movw $0xdf12, %ax # Vertical display end
  631. call outidx
  632. movw $0xe715, %ax # Vertical blank start
  633. call outidx
  634. movw $0x0416, %ax # Vertical blank end
  635. call outidx
  636. pushw %dx
  637. movb $0xcc, %dl # Misc output register (read)
  638. inb %dx, %al
  639. movb $0xc2, %dl # (write)
  640. andb $0x0d, %al # Preserve clock select bits and color bit
  641. orb $0xe2, %al # Set correct sync polarity
  642. outb %al, %dx
  643. popw %dx
  644. movw $0x501e, force_size
  645. stc # That's all.
  646. ret
  647. # Set the 80x34 mode (all VGA's). 480 scans, 14-pixel font.
  648. set_80x34:
  649. call set_80x30 # Set 480 scans
  650. call set14 # And 14-pt font
  651. movw $0xdb12, %ax # VGA vertical display end
  652. movw $0x5022, force_size
  653. setvde: call outidx
  654. stc
  655. ret
  656. # Set the 80x60 mode (all VGA's). 480 scans, 8-pixel font.
  657. set_80x60:
  658. call set_80x30 # Set 480 scans
  659. call set_8pt # And 8-pt font
  660. movw $0xdf12, %ax # VGA vertical display end
  661. movw $0x503c, force_size
  662. jmp setvde
  663. # Special hack for ThinkPad graphics
  664. set_gfx:
  665. #ifdef CONFIG_VIDEO_GFX_HACK
  666. movw $VIDEO_GFX_BIOS_AX, %ax
  667. movw $VIDEO_GFX_BIOS_BX, %bx
  668. int $0x10
  669. movw $VIDEO_GFX_DUMMY_RESOLUTION, force_size
  670. stc
  671. #endif
  672. ret
  673. #ifdef CONFIG_VIDEO_RETAIN
  674. # Store screen contents to temporary buffer.
  675. store_screen:
  676. cmpb $0, do_restore # Already stored?
  677. jnz stsr
  678. testb $CAN_USE_HEAP, loadflags # Have we space for storing?
  679. jz stsr
  680. pushw %ax
  681. pushw %bx
  682. pushw force_size # Don't force specific size
  683. movw $0, force_size
  684. call mode_params # Obtain params of current mode
  685. popw force_size
  686. movb %fs:(PARAM_VIDEO_LINES), %ah
  687. movb %fs:(PARAM_VIDEO_COLS), %al
  688. movw %ax, %bx # BX=dimensions
  689. mulb %ah
  690. movw %ax, %cx # CX=number of characters
  691. addw %ax, %ax # Calculate image size
  692. addw $modelist+1024+4, %ax
  693. cmpw heap_end_ptr, %ax
  694. jnc sts1 # Unfortunately, out of memory
  695. movw %fs:(PARAM_CURSOR_POS), %ax # Store mode params
  696. leaw modelist+1024, %di
  697. stosw
  698. movw %bx, %ax
  699. stosw
  700. pushw %ds # Store the screen
  701. movw video_segment, %ds
  702. xorw %si, %si
  703. rep
  704. movsw
  705. popw %ds
  706. incb do_restore # Screen will be restored later
  707. sts1: popw %bx
  708. popw %ax
  709. stsr: ret
  710. # Restore screen contents from temporary buffer.
  711. restore_screen:
  712. cmpb $0, do_restore # Has the screen been stored?
  713. jz res1
  714. call mode_params # Get parameters of current mode
  715. movb %fs:(PARAM_VIDEO_LINES), %cl
  716. movb %fs:(PARAM_VIDEO_COLS), %ch
  717. leaw modelist+1024, %si # Screen buffer
  718. lodsw # Set cursor position
  719. movw %ax, %dx
  720. cmpb %cl, %dh
  721. jc res2
  722. movb %cl, %dh
  723. decb %dh
  724. res2: cmpb %ch, %dl
  725. jc res3
  726. movb %ch, %dl
  727. decb %dl
  728. res3: movb $0x02, %ah
  729. movb $0x00, %bh
  730. int $0x10
  731. lodsw # Display size
  732. movb %ah, %dl # DL=number of lines
  733. movb $0, %ah # BX=phys. length of orig. line
  734. movw %ax, %bx
  735. cmpb %cl, %dl # Too many?
  736. jc res4
  737. pushw %ax
  738. movb %dl, %al
  739. subb %cl, %al
  740. mulb %bl
  741. addw %ax, %si
  742. addw %ax, %si
  743. popw %ax
  744. movb %cl, %dl
  745. res4: cmpb %ch, %al # Too wide?
  746. jc res5
  747. movb %ch, %al # AX=width of src. line
  748. res5: movb $0, %cl
  749. xchgb %ch, %cl
  750. movw %cx, %bp # BP=width of dest. line
  751. pushw %es
  752. movw video_segment, %es
  753. xorw %di, %di # Move the data
  754. addw %bx, %bx # Convert BX and BP to _bytes_
  755. addw %bp, %bp
  756. res6: pushw %si
  757. pushw %di
  758. movw %ax, %cx
  759. rep
  760. movsw
  761. popw %di
  762. popw %si
  763. addw %bp, %di
  764. addw %bx, %si
  765. decb %dl
  766. jnz res6
  767. popw %es # Done
  768. res1: ret
  769. #endif /* CONFIG_VIDEO_RETAIN */
  770. # Write to indexed VGA register (AL=index, AH=data, DX=index reg. port)
  771. outidx: outb %al, %dx
  772. pushw %ax
  773. movb %ah, %al
  774. incw %dx
  775. outb %al, %dx
  776. decw %dx
  777. popw %ax
  778. ret
  779. # Build the table of video modes (stored after the setup.S code at the
  780. # `modelist' label. Each video mode record looks like:
  781. # .word MODE-ID (our special mode ID (see above))
  782. # .byte rows (number of rows)
  783. # .byte columns (number of columns)
  784. # Returns address of the end of the table in DI, the end is marked
  785. # with a ASK_VGA ID.
  786. mode_table:
  787. movw mt_end, %di # Already filled?
  788. orw %di, %di
  789. jnz mtab1x
  790. leaw modelist, %di # Store standard modes:
  791. movl $VIDEO_80x25 + 0x50190000, %eax # The 80x25 mode (ALL)
  792. stosl
  793. movb adapter, %al # CGA/MDA/HGA -- no more modes
  794. orb %al, %al
  795. jz mtabe
  796. decb %al
  797. jnz mtabv
  798. movl $VIDEO_8POINT + 0x502b0000, %eax # The 80x43 EGA mode
  799. stosl
  800. jmp mtabe
  801. mtab1x: jmp mtab1
  802. mtabv: leaw vga_modes, %si # All modes for std VGA
  803. movw $vga_modes_end-vga_modes, %cx
  804. rep # I'm unable to use movsw as I don't know how to store a half
  805. movsb # of the expression above to cx without using explicit shr.
  806. cmpb $0, scanning # Mode scan requested?
  807. jz mscan1
  808. call mode_scan
  809. mscan1:
  810. #ifdef CONFIG_VIDEO_LOCAL
  811. call local_modes
  812. #endif /* CONFIG_VIDEO_LOCAL */
  813. #ifdef CONFIG_VIDEO_VESA
  814. call vesa_modes # Detect VESA VGA modes
  815. #endif /* CONFIG_VIDEO_VESA */
  816. #ifdef CONFIG_VIDEO_SVGA
  817. cmpb $0, scanning # Bypass when scanning
  818. jnz mscan2
  819. call svga_modes # Detect SVGA cards & modes
  820. mscan2:
  821. #endif /* CONFIG_VIDEO_SVGA */
  822. mtabe:
  823. #ifdef CONFIG_VIDEO_COMPACT
  824. leaw modelist, %si
  825. movw %di, %dx
  826. movw %si, %di
  827. cmt1: cmpw %dx, %si # Scan all modes
  828. jz cmt2
  829. leaw modelist, %bx # Find in previous entries
  830. movw 2(%si), %cx
  831. cmt3: cmpw %bx, %si
  832. jz cmt4
  833. cmpw 2(%bx), %cx # Found => don't copy this entry
  834. jz cmt5
  835. addw $4, %bx
  836. jmp cmt3
  837. cmt4: movsl # Copy entry
  838. jmp cmt1
  839. cmt5: addw $4, %si # Skip entry
  840. jmp cmt1
  841. cmt2:
  842. #endif /* CONFIG_VIDEO_COMPACT */
  843. movw $ASK_VGA, (%di) # End marker
  844. movw %di, mt_end
  845. mtab1: leaw modelist, %si # SI=mode list, DI=list end
  846. ret0: ret
  847. # Modes usable on all standard VGAs
  848. vga_modes:
  849. .word VIDEO_8POINT
  850. .word 0x5032 # 80x50
  851. .word VIDEO_80x43
  852. .word 0x502b # 80x43
  853. .word VIDEO_80x28
  854. .word 0x501c # 80x28
  855. .word VIDEO_80x30
  856. .word 0x501e # 80x30
  857. .word VIDEO_80x34
  858. .word 0x5022 # 80x34
  859. .word VIDEO_80x60
  860. .word 0x503c # 80x60
  861. #ifdef CONFIG_VIDEO_GFX_HACK
  862. .word VIDEO_GFX_HACK
  863. .word VIDEO_GFX_DUMMY_RESOLUTION
  864. #endif
  865. vga_modes_end:
  866. # Detect VESA modes.
  867. #ifdef CONFIG_VIDEO_VESA
  868. vesa_modes:
  869. cmpb $2, adapter # VGA only
  870. jnz ret0
  871. movw %di, %bp # BP=original mode table end
  872. addw $0x200, %di # Buffer space
  873. movw $0x4f00, %ax # VESA Get card info call
  874. int $0x10
  875. movw %bp, %di
  876. cmpw $0x004f, %ax # Successful?
  877. jnz ret0
  878. cmpw $0x4556, 0x200(%di)
  879. jnz ret0
  880. cmpw $0x4153, 0x202(%di)
  881. jnz ret0
  882. movw $vesa_name, card_name # Set name to "VESA VGA"
  883. pushw %gs
  884. lgsw 0x20e(%di), %si # GS:SI=mode list
  885. movw $128, %cx # Iteration limit
  886. vesa1:
  887. # gas version 2.9.1, using BFD version 2.9.1.0.23 buggers the next inst.
  888. # XXX: lodsw %gs:(%si), %ax # Get next mode in the list
  889. gs; lodsw
  890. cmpw $0xffff, %ax # End of the table?
  891. jz vesar
  892. cmpw $0x0080, %ax # Check validity of mode ID
  893. jc vesa2
  894. orb %ah, %ah # Valid IDs: 0x0000-0x007f/0x0100-0x07ff
  895. jz vesan # Certain BIOSes report 0x80-0xff!
  896. cmpw $0x0800, %ax
  897. jnc vesae
  898. vesa2: pushw %cx
  899. movw %ax, %cx # Get mode information structure
  900. movw $0x4f01, %ax
  901. int $0x10
  902. movw %cx, %bx # BX=mode number
  903. addb $VIDEO_FIRST_VESA>>8, %bh
  904. popw %cx
  905. cmpw $0x004f, %ax
  906. jnz vesan # Don't report errors (buggy BIOSES)
  907. movb (%di), %al # Check capabilities. We require
  908. andb $0x19, %al # a color text mode.
  909. cmpb $0x09, %al
  910. jnz vesan
  911. cmpw $0xb800, 8(%di) # Standard video memory address required
  912. jnz vesan
  913. testb $2, (%di) # Mode characteristics supplied?
  914. movw %bx, (%di) # Store mode number
  915. jz vesa3
  916. xorw %dx, %dx
  917. movw 0x12(%di), %bx # Width
  918. orb %bh, %bh
  919. jnz vesan
  920. movb %bl, 0x3(%di)
  921. movw 0x14(%di), %ax # Height
  922. orb %ah, %ah
  923. jnz vesan
  924. movb %al, 2(%di)
  925. mulb %bl
  926. cmpw $8193, %ax # Small enough for Linux console driver?
  927. jnc vesan
  928. jmp vesaok
  929. vesa3: subw $0x8108, %bx # This mode has no detailed info specified,
  930. jc vesan # so it must be a standard VESA mode.
  931. cmpw $5, %bx
  932. jnc vesan
  933. movw vesa_text_mode_table(%bx), %ax
  934. movw %ax, 2(%di)
  935. vesaok: addw $4, %di # The mode is valid. Store it.
  936. vesan: loop vesa1 # Next mode. Limit exceeded => error
  937. vesae: leaw vesaer, %si
  938. call prtstr
  939. movw %bp, %di # Discard already found modes.
  940. vesar: popw %gs
  941. ret
  942. # Dimensions of standard VESA text modes
  943. vesa_text_mode_table:
  944. .byte 60, 80 # 0108
  945. .byte 25, 132 # 0109
  946. .byte 43, 132 # 010A
  947. .byte 50, 132 # 010B
  948. .byte 60, 132 # 010C
  949. #endif /* CONFIG_VIDEO_VESA */
  950. # Scan for video modes. A bit dirty, but should work.
  951. mode_scan:
  952. movw $0x0100, %cx # Start with mode 0
  953. scm1: movb $0, %ah # Test the mode
  954. movb %cl, %al
  955. int $0x10
  956. movb $0x0f, %ah
  957. int $0x10
  958. cmpb %cl, %al
  959. jnz scm2 # Mode not set
  960. movw $0x3c0, %dx # Test if it's a text mode
  961. movb $0x10, %al # Mode bits
  962. call inidx
  963. andb $0x03, %al
  964. jnz scm2
  965. movb $0xce, %dl # Another set of mode bits
  966. movb $0x06, %al
  967. call inidx
  968. shrb %al
  969. jc scm2
  970. movb $0xd4, %dl # Cursor location
  971. movb $0x0f, %al
  972. call inidx
  973. orb %al, %al
  974. jnz scm2
  975. movw %cx, %ax # Ok, store the mode
  976. stosw
  977. movb %gs:(0x484), %al # Number of rows
  978. incb %al
  979. stosb
  980. movw %gs:(0x44a), %ax # Number of columns
  981. stosb
  982. scm2: incb %cl
  983. jns scm1
  984. movw $0x0003, %ax # Return back to mode 3
  985. int $0x10
  986. ret
  987. tstidx: outw %ax, %dx # OUT DX,AX and inidx
  988. inidx: outb %al, %dx # Read from indexed VGA register
  989. incw %dx # AL=index, DX=index reg port -> AL=data
  990. inb %dx, %al
  991. decw %dx
  992. ret
  993. # Try to detect type of SVGA card and supply (usually approximate) video
  994. # mode table for it.
  995. #ifdef CONFIG_VIDEO_SVGA
  996. svga_modes:
  997. leaw svga_table, %si # Test all known SVGA adapters
  998. dosvga: lodsw
  999. movw %ax, %bp # Default mode table
  1000. orw %ax, %ax
  1001. jz didsv1
  1002. lodsw # Pointer to test routine
  1003. pushw %si
  1004. pushw %di
  1005. pushw %es
  1006. movw $0xc000, %bx
  1007. movw %bx, %es
  1008. call *%ax # Call test routine
  1009. popw %es
  1010. popw %di
  1011. popw %si
  1012. orw %bp, %bp
  1013. jz dosvga
  1014. movw %bp, %si # Found, copy the modes
  1015. movb svga_prefix, %ah
  1016. cpsvga: lodsb
  1017. orb %al, %al
  1018. jz didsv
  1019. stosw
  1020. movsw
  1021. jmp cpsvga
  1022. didsv: movw %si, card_name # Store pointer to card name
  1023. didsv1: ret
  1024. # Table of all known SVGA cards. For each card, we store a pointer to
  1025. # a table of video modes supported by the card and a pointer to a routine
  1026. # used for testing of presence of the card. The video mode table is always
  1027. # followed by the name of the card or the chipset.
  1028. svga_table:
  1029. .word ati_md, ati_test
  1030. .word oak_md, oak_test
  1031. .word paradise_md, paradise_test
  1032. .word realtek_md, realtek_test
  1033. .word s3_md, s3_test
  1034. .word chips_md, chips_test
  1035. .word video7_md, video7_test
  1036. .word cirrus5_md, cirrus5_test
  1037. .word cirrus6_md, cirrus6_test
  1038. .word cirrus1_md, cirrus1_test
  1039. .word ahead_md, ahead_test
  1040. .word everex_md, everex_test
  1041. .word genoa_md, genoa_test
  1042. .word trident_md, trident_test
  1043. .word tseng_md, tseng_test
  1044. .word 0
  1045. # Test routines and mode tables:
  1046. # S3 - The test algorithm was taken from the SuperProbe package
  1047. # for XFree86 1.2.1. Report bugs to Christoph.Niemann@linux.org
  1048. s3_test:
  1049. movw $0x0f35, %cx # we store some constants in cl/ch
  1050. movw $0x03d4, %dx
  1051. movb $0x38, %al
  1052. call inidx
  1053. movb %al, %bh # store current CRT-register 0x38
  1054. movw $0x0038, %ax
  1055. call outidx # disable writing to special regs
  1056. movb %cl, %al # check whether we can write special reg 0x35
  1057. call inidx
  1058. movb %al, %bl # save the current value of CRT reg 0x35
  1059. andb $0xf0, %al # clear bits 0-3
  1060. movb %al, %ah
  1061. movb %cl, %al # and write it to CRT reg 0x35
  1062. call outidx
  1063. call inidx # now read it back
  1064. andb %ch, %al # clear the upper 4 bits
  1065. jz s3_2 # the first test failed. But we have a
  1066. movb %bl, %ah # second chance
  1067. movb %cl, %al
  1068. call outidx
  1069. jmp s3_1 # do the other tests
  1070. s3_2: movw %cx, %ax # load ah with 0xf and al with 0x35
  1071. orb %bl, %ah # set the upper 4 bits of ah with the orig value
  1072. call outidx # write ...
  1073. call inidx # ... and reread
  1074. andb %cl, %al # turn off the upper 4 bits
  1075. pushw %ax
  1076. movb %bl, %ah # restore old value in register 0x35
  1077. movb %cl, %al
  1078. call outidx
  1079. popw %ax
  1080. cmpb %ch, %al # setting lower 4 bits was successful => bad
  1081. je no_s3 # writing is allowed => this is not an S3
  1082. s3_1: movw $0x4838, %ax # allow writing to special regs by putting
  1083. call outidx # magic number into CRT-register 0x38
  1084. movb %cl, %al # check whether we can write special reg 0x35
  1085. call inidx
  1086. movb %al, %bl
  1087. andb $0xf0, %al
  1088. movb %al, %ah
  1089. movb %cl, %al
  1090. call outidx
  1091. call inidx
  1092. andb %ch, %al
  1093. jnz no_s3 # no, we can't write => no S3
  1094. movw %cx, %ax
  1095. orb %bl, %ah
  1096. call outidx
  1097. call inidx
  1098. andb %ch, %al
  1099. pushw %ax
  1100. movb %bl, %ah # restore old value in register 0x35
  1101. movb %cl, %al
  1102. call outidx
  1103. popw %ax
  1104. cmpb %ch, %al
  1105. jne no_s31 # writing not possible => no S3
  1106. movb $0x30, %al
  1107. call inidx # now get the S3 id ...
  1108. leaw idS3, %di
  1109. movw $0x10, %cx
  1110. repne
  1111. scasb
  1112. je no_s31
  1113. movb %bh, %ah
  1114. movb $0x38, %al
  1115. jmp s3rest
  1116. no_s3: movb $0x35, %al # restore CRT register 0x35
  1117. movb %bl, %ah
  1118. call outidx
  1119. no_s31: xorw %bp, %bp # Detection failed
  1120. s3rest: movb %bh, %ah
  1121. movb $0x38, %al # restore old value of CRT register 0x38
  1122. jmp outidx
  1123. idS3: .byte 0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
  1124. .byte 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
  1125. s3_md: .byte 0x54, 0x2b, 0x84
  1126. .byte 0x55, 0x19, 0x84
  1127. .byte 0
  1128. .ascii "S3"
  1129. .byte 0
  1130. # ATI cards.
  1131. ati_test:
  1132. leaw idati, %si
  1133. movw $0x31, %di
  1134. movw $0x09, %cx
  1135. repe
  1136. cmpsb
  1137. je atiok
  1138. xorw %bp, %bp
  1139. atiok: ret
  1140. idati: .ascii "761295520"
  1141. ati_md: .byte 0x23, 0x19, 0x84
  1142. .byte 0x33, 0x2c, 0x84
  1143. .byte 0x22, 0x1e, 0x64
  1144. .byte 0x21, 0x19, 0x64
  1145. .byte 0x58, 0x21, 0x50
  1146. .byte 0x5b, 0x1e, 0x50
  1147. .byte 0
  1148. .ascii "ATI"
  1149. .byte 0
  1150. # AHEAD
  1151. ahead_test:
  1152. movw $0x200f, %ax
  1153. movw $0x3ce, %dx
  1154. outw %ax, %dx
  1155. incw %dx
  1156. inb %dx, %al
  1157. cmpb $0x20, %al
  1158. je isahed
  1159. cmpb $0x21, %al
  1160. je isahed
  1161. xorw %bp, %bp
  1162. isahed: ret
  1163. ahead_md:
  1164. .byte 0x22, 0x2c, 0x84
  1165. .byte 0x23, 0x19, 0x84
  1166. .byte 0x24, 0x1c, 0x84
  1167. .byte 0x2f, 0x32, 0xa0
  1168. .byte 0x32, 0x22, 0x50
  1169. .byte 0x34, 0x42, 0x50
  1170. .byte 0
  1171. .ascii "Ahead"
  1172. .byte 0
  1173. # Chips & Tech.
  1174. chips_test:
  1175. movw $0x3c3, %dx
  1176. inb %dx, %al
  1177. orb $0x10, %al
  1178. outb %al, %dx
  1179. movw $0x104, %dx
  1180. inb %dx, %al
  1181. movb %al, %bl
  1182. movw $0x3c3, %dx
  1183. inb %dx, %al
  1184. andb $0xef, %al
  1185. outb %al, %dx
  1186. cmpb $0xa5, %bl
  1187. je cantok
  1188. xorw %bp, %bp
  1189. cantok: ret
  1190. chips_md:
  1191. .byte 0x60, 0x19, 0x84
  1192. .byte 0x61, 0x32, 0x84
  1193. .byte 0
  1194. .ascii "Chips & Technologies"
  1195. .byte 0
  1196. # Cirrus Logic 5X0
  1197. cirrus1_test:
  1198. movw $0x3d4, %dx
  1199. movb $0x0c, %al
  1200. outb %al, %dx
  1201. incw %dx
  1202. inb %dx, %al
  1203. movb %al, %bl
  1204. xorb %al, %al
  1205. outb %al, %dx
  1206. decw %dx
  1207. movb $0x1f, %al
  1208. outb %al, %dx
  1209. incw %dx
  1210. inb %dx, %al
  1211. movb %al, %bh
  1212. xorb %ah, %ah
  1213. shlb $4, %al
  1214. movw %ax, %cx
  1215. movb %bh, %al
  1216. shrb $4, %al
  1217. addw %ax, %cx
  1218. shlw $8, %cx
  1219. addw $6, %cx
  1220. movw %cx, %ax
  1221. movw $0x3c4, %dx
  1222. outw %ax, %dx
  1223. incw %dx
  1224. inb %dx, %al
  1225. andb %al, %al
  1226. jnz nocirr
  1227. movb %bh, %al
  1228. outb %al, %dx
  1229. inb %dx, %al
  1230. cmpb $0x01, %al
  1231. je iscirr
  1232. nocirr: xorw %bp, %bp
  1233. iscirr: movw $0x3d4, %dx
  1234. movb %bl, %al
  1235. xorb %ah, %ah
  1236. shlw $8, %ax
  1237. addw $0x0c, %ax
  1238. outw %ax, %dx
  1239. ret
  1240. cirrus1_md:
  1241. .byte 0x1f, 0x19, 0x84
  1242. .byte 0x20, 0x2c, 0x84
  1243. .byte 0x22, 0x1e, 0x84
  1244. .byte 0x31, 0x25, 0x64
  1245. .byte 0
  1246. .ascii "Cirrus Logic 5X0"
  1247. .byte 0
  1248. # Cirrus Logic 54XX
  1249. cirrus5_test:
  1250. movw $0x3c4, %dx
  1251. movb $6, %al
  1252. call inidx
  1253. movb %al, %bl # BL=backup
  1254. movw $6, %ax
  1255. call tstidx
  1256. cmpb $0x0f, %al
  1257. jne c5fail
  1258. movw $0x1206, %ax
  1259. call tstidx
  1260. cmpb $0x12, %al
  1261. jne c5fail
  1262. movb $0x1e, %al
  1263. call inidx
  1264. movb %al, %bh
  1265. movb %bh, %ah
  1266. andb $0xc0, %ah
  1267. movb $0x1e, %al
  1268. call tstidx
  1269. andb $0x3f, %al
  1270. jne c5xx
  1271. movb $0x1e, %al
  1272. movb %bh, %ah
  1273. orb $0x3f, %ah
  1274. call tstidx
  1275. xorb $0x3f, %al
  1276. andb $0x3f, %al
  1277. c5xx: pushf
  1278. movb $0x1e, %al
  1279. movb %bh, %ah
  1280. outw %ax, %dx
  1281. popf
  1282. je c5done
  1283. c5fail: xorw %bp, %bp
  1284. c5done: movb $6, %al
  1285. movb %bl, %ah
  1286. outw %ax, %dx
  1287. ret
  1288. cirrus5_md:
  1289. .byte 0x14, 0x19, 0x84
  1290. .byte 0x54, 0x2b, 0x84
  1291. .byte 0
  1292. .ascii "Cirrus Logic 54XX"
  1293. .byte 0
  1294. # Cirrus Logic 64XX -- no known extra modes, but must be identified, because
  1295. # it's misidentified by the Ahead test.
  1296. cirrus6_test:
  1297. movw $0x3ce, %dx
  1298. movb $0x0a, %al
  1299. call inidx
  1300. movb %al, %bl # BL=backup
  1301. movw $0xce0a, %ax
  1302. call tstidx
  1303. orb %al, %al
  1304. jne c2fail
  1305. movw $0xec0a, %ax
  1306. call tstidx
  1307. cmpb $0x01, %al
  1308. jne c2fail
  1309. movb $0xaa, %al
  1310. call inidx # 4X, 5X, 7X and 8X are valid 64XX chip ID's.
  1311. shrb $4, %al
  1312. subb $4, %al
  1313. jz c6done
  1314. decb %al
  1315. jz c6done
  1316. subb $2, %al
  1317. jz c6done
  1318. decb %al
  1319. jz c6done
  1320. c2fail: xorw %bp, %bp
  1321. c6done: movb $0x0a, %al
  1322. movb %bl, %ah
  1323. outw %ax, %dx
  1324. ret
  1325. cirrus6_md:
  1326. .byte 0
  1327. .ascii "Cirrus Logic 64XX"
  1328. .byte 0
  1329. # Everex / Trident
  1330. everex_test:
  1331. movw $0x7000, %ax
  1332. xorw %bx, %bx
  1333. int $0x10
  1334. cmpb $0x70, %al
  1335. jne noevrx
  1336. shrw $4, %dx
  1337. cmpw $0x678, %dx
  1338. je evtrid
  1339. cmpw $0x236, %dx
  1340. jne evrxok
  1341. evtrid: leaw trident_md, %bp
  1342. evrxok: ret
  1343. noevrx: xorw %bp, %bp
  1344. ret
  1345. everex_md:
  1346. .byte 0x03, 0x22, 0x50
  1347. .byte 0x04, 0x3c, 0x50
  1348. .byte 0x07, 0x2b, 0x64
  1349. .byte 0x08, 0x4b, 0x64
  1350. .byte 0x0a, 0x19, 0x84
  1351. .byte 0x0b, 0x2c, 0x84
  1352. .byte 0x16, 0x1e, 0x50
  1353. .byte 0x18, 0x1b, 0x64
  1354. .byte 0x21, 0x40, 0xa0
  1355. .byte 0x40, 0x1e, 0x84
  1356. .byte 0
  1357. .ascii "Everex/Trident"
  1358. .byte 0
  1359. # Genoa.
  1360. genoa_test:
  1361. leaw idgenoa, %si # Check Genoa 'clues'
  1362. xorw %ax, %ax
  1363. movb %es:(0x37), %al
  1364. movw %ax, %di
  1365. movw $0x04, %cx
  1366. decw %si
  1367. decw %di
  1368. l1: incw %si
  1369. incw %di
  1370. movb (%si), %al
  1371. testb %al, %al
  1372. jz l2
  1373. cmpb %es:(%di), %al
  1374. l2: loope l1
  1375. orw %cx, %cx
  1376. je isgen
  1377. xorw %bp, %bp
  1378. isgen: ret
  1379. idgenoa: .byte 0x77, 0x00, 0x99, 0x66
  1380. genoa_md:
  1381. .byte 0x58, 0x20, 0x50
  1382. .byte 0x5a, 0x2a, 0x64
  1383. .byte 0x60, 0x19, 0x84
  1384. .byte 0x61, 0x1d, 0x84
  1385. .byte 0x62, 0x20, 0x84
  1386. .byte 0x63, 0x2c, 0x84
  1387. .byte 0x64, 0x3c, 0x84
  1388. .byte 0x6b, 0x4f, 0x64
  1389. .byte 0x72, 0x3c, 0x50
  1390. .byte 0x74, 0x42, 0x50
  1391. .byte 0x78, 0x4b, 0x64
  1392. .byte 0
  1393. .ascii "Genoa"
  1394. .byte 0
  1395. # OAK
  1396. oak_test:
  1397. leaw idoakvga, %si
  1398. movw $0x08, %di
  1399. movw $0x08, %cx
  1400. repe
  1401. cmpsb
  1402. je isoak
  1403. xorw %bp, %bp
  1404. isoak: ret
  1405. idoakvga: .ascii "OAK VGA "
  1406. oak_md: .byte 0x4e, 0x3c, 0x50
  1407. .byte 0x4f, 0x3c, 0x84
  1408. .byte 0x50, 0x19, 0x84
  1409. .byte 0x51, 0x2b, 0x84
  1410. .byte 0
  1411. .ascii "OAK"
  1412. .byte 0
  1413. # WD Paradise.
  1414. paradise_test:
  1415. leaw idparadise, %si
  1416. movw $0x7d, %di
  1417. movw $0x04, %cx
  1418. repe
  1419. cmpsb
  1420. je ispara
  1421. xorw %bp, %bp
  1422. ispara: ret
  1423. idparadise: .ascii "VGA="
  1424. paradise_md:
  1425. .byte 0x41, 0x22, 0x50
  1426. .byte 0x47, 0x1c, 0x84
  1427. .byte 0x55, 0x19, 0x84
  1428. .byte 0x54, 0x2c, 0x84
  1429. .byte 0
  1430. .ascii "Paradise"
  1431. .byte 0
  1432. # Trident.
  1433. trident_test:
  1434. movw $0x3c4, %dx
  1435. movb $0x0e, %al
  1436. outb %al, %dx
  1437. incw %dx
  1438. inb %dx, %al
  1439. xchgb %al, %ah
  1440. xorb %al, %al
  1441. outb %al, %dx
  1442. inb %dx, %al
  1443. xchgb %ah, %al
  1444. movb %al, %bl # Strange thing ... in the book this wasn't
  1445. andb $0x02, %bl # necessary but it worked on my card which
  1446. jz setb2 # is a trident. Without it the screen goes
  1447. # blurred ...
  1448. andb $0xfd, %al
  1449. jmp clrb2
  1450. setb2: orb $0x02, %al
  1451. clrb2: outb %al, %dx
  1452. andb $0x0f, %ah
  1453. cmpb $0x02, %ah
  1454. je istrid
  1455. xorw %bp, %bp
  1456. istrid: ret
  1457. trident_md:
  1458. .byte 0x50, 0x1e, 0x50
  1459. .byte 0x51, 0x2b, 0x50
  1460. .byte 0x52, 0x3c, 0x50
  1461. .byte 0x57, 0x19, 0x84
  1462. .byte 0x58, 0x1e, 0x84
  1463. .byte 0x59, 0x2b, 0x84
  1464. .byte 0x5a, 0x3c, 0x84
  1465. .byte 0
  1466. .ascii "Trident"
  1467. .byte 0
  1468. # Tseng.
  1469. tseng_test:
  1470. movw $0x3cd, %dx
  1471. inb %dx, %al # Could things be this simple ! :-)
  1472. movb %al, %bl
  1473. movb $0x55, %al
  1474. outb %al, %dx
  1475. inb %dx, %al
  1476. movb %al, %ah
  1477. movb %bl, %al
  1478. outb %al, %dx
  1479. cmpb $0x55, %ah
  1480. je istsen
  1481. isnot: xorw %bp, %bp
  1482. istsen: ret
  1483. tseng_md:
  1484. .byte 0x26, 0x3c, 0x50
  1485. .byte 0x2a, 0x28, 0x64
  1486. .byte 0x23, 0x19, 0x84
  1487. .byte 0x24, 0x1c, 0x84
  1488. .byte 0x22, 0x2c, 0x84
  1489. .byte 0x21, 0x3c, 0x84
  1490. .byte 0
  1491. .ascii "Tseng"
  1492. .byte 0
  1493. # Video7.
  1494. video7_test:
  1495. movw $0x3cc, %dx
  1496. inb %dx, %al
  1497. movw $0x3b4, %dx
  1498. andb $0x01, %al
  1499. jz even7
  1500. movw $0x3d4, %dx
  1501. even7: movb $0x0c, %al
  1502. outb %al, %dx
  1503. incw %dx
  1504. inb %dx, %al
  1505. movb %al, %bl
  1506. movb $0x55, %al
  1507. outb %al, %dx
  1508. inb %dx, %al
  1509. decw %dx
  1510. movb $0x1f, %al
  1511. outb %al, %dx
  1512. incw %dx
  1513. inb %dx, %al
  1514. movb %al, %bh
  1515. decw %dx
  1516. movb $0x0c, %al
  1517. outb %al, %dx
  1518. incw %dx
  1519. movb %bl, %al
  1520. outb %al, %dx
  1521. movb $0x55, %al
  1522. xorb $0xea, %al
  1523. cmpb %bh, %al
  1524. jne isnot
  1525. movb $VIDEO_FIRST_V7>>8, svga_prefix # Use special mode switching
  1526. ret
  1527. video7_md:
  1528. .byte 0x40, 0x2b, 0x50
  1529. .byte 0x43, 0x3c, 0x50
  1530. .byte 0x44, 0x3c, 0x64
  1531. .byte 0x41, 0x19, 0x84
  1532. .byte 0x42, 0x2c, 0x84
  1533. .byte 0x45, 0x1c, 0x84
  1534. .byte 0
  1535. .ascii "Video 7"
  1536. .byte 0
  1537. # Realtek VGA
  1538. realtek_test:
  1539. leaw idrtvga, %si
  1540. movw $0x45, %di
  1541. movw $0x0b, %cx
  1542. repe
  1543. cmpsb
  1544. je isrt
  1545. xorw %bp, %bp
  1546. isrt: ret
  1547. idrtvga: .ascii "REALTEK VGA"
  1548. realtek_md:
  1549. .byte 0x1a, 0x3c, 0x50
  1550. .byte 0x1b, 0x19, 0x84
  1551. .byte 0x1c, 0x1e, 0x84
  1552. .byte 0x1d, 0x2b, 0x84
  1553. .byte 0x1e, 0x3c, 0x84
  1554. .byte 0
  1555. .ascii "REALTEK"
  1556. .byte 0
  1557. #endif /* CONFIG_VIDEO_SVGA */
  1558. # User-defined local mode table (VGA only)
  1559. #ifdef CONFIG_VIDEO_LOCAL
  1560. local_modes:
  1561. leaw local_mode_table, %si
  1562. locm1: lodsw
  1563. orw %ax, %ax
  1564. jz locm2
  1565. stosw
  1566. movsw
  1567. jmp locm1
  1568. locm2: ret
  1569. # This is the table of local video modes which can be supplied manually
  1570. # by the user. Each entry consists of mode ID (word) and dimensions
  1571. # (byte for column count and another byte for row count). These modes
  1572. # are placed before all SVGA and VESA modes and override them if table
  1573. # compacting is enabled. The table must end with a zero word followed
  1574. # by NUL-terminated video adapter name.
  1575. local_mode_table:
  1576. .word 0x0100 # Example: 40x25
  1577. .byte 25,40
  1578. .word 0
  1579. .ascii "Local"
  1580. .byte 0
  1581. #endif /* CONFIG_VIDEO_LOCAL */
  1582. # Read a key and return the ASCII code in al, scan code in ah
  1583. getkey: xorb %ah, %ah
  1584. int $0x16
  1585. ret
  1586. # Read a key with a timeout of 30 seconds.
  1587. # The hardware clock is used to get the time.
  1588. getkt: call gettime
  1589. addb $30, %al # Wait 30 seconds
  1590. cmpb $60, %al
  1591. jl lminute
  1592. subb $60, %al
  1593. lminute:
  1594. movb %al, %cl
  1595. again: movb $0x01, %ah
  1596. int $0x16
  1597. jnz getkey # key pressed, so get it
  1598. call gettime
  1599. cmpb %cl, %al
  1600. jne again
  1601. movb $0x20, %al # timeout, return `space'
  1602. ret
  1603. # Flush the keyboard buffer
  1604. flush: movb $0x01, %ah
  1605. int $0x16
  1606. jz empty
  1607. xorb %ah, %ah
  1608. int $0x16
  1609. jmp flush
  1610. empty: ret
  1611. # Print hexadecimal number.
  1612. prthw: pushw %ax
  1613. movb %ah, %al
  1614. call prthb
  1615. popw %ax
  1616. prthb: pushw %ax
  1617. shrb $4, %al
  1618. call prthn
  1619. popw %ax
  1620. andb $0x0f, %al
  1621. prthn: cmpb $0x0a, %al
  1622. jc prth1
  1623. addb $0x07, %al
  1624. prth1: addb $0x30, %al
  1625. jmp prtchr
  1626. # Print decimal number in al
  1627. prtdec: pushw %ax
  1628. pushw %cx
  1629. xorb %ah, %ah
  1630. movb $0x0a, %cl
  1631. idivb %cl
  1632. cmpb $0x09, %al
  1633. jbe lt100
  1634. call prtdec
  1635. jmp skip10
  1636. lt100: addb $0x30, %al
  1637. call prtchr
  1638. skip10: movb %ah, %al
  1639. addb $0x30, %al
  1640. call prtchr
  1641. popw %cx
  1642. popw %ax
  1643. ret
  1644. store_edid:
  1645. #ifdef CONFIG_FIRMWARE_EDID
  1646. pushw %es # just save all registers
  1647. pushw %ax
  1648. pushw %bx
  1649. pushw %cx
  1650. pushw %dx
  1651. pushw %di
  1652. pushw %fs
  1653. popw %es
  1654. movl $0x13131313, %eax # memset block with 0x13
  1655. movw $32, %cx
  1656. movw $0x140, %di
  1657. cld
  1658. rep
  1659. stosl
  1660. pushw %es # save ES
  1661. xorw %di, %di # Report Capability
  1662. pushw %di
  1663. popw %es # ES:DI must be 0:0
  1664. movw $0x4f15, %ax
  1665. xorw %bx, %bx
  1666. xorw %cx, %cx
  1667. int $0x10
  1668. popw %es # restore ES
  1669. cmpb $0x00, %ah # call successful
  1670. jne no_edid
  1671. cmpb $0x4f, %al # function supported
  1672. jne no_edid
  1673. movw $0x4f15, %ax # do VBE/DDC
  1674. movw $0x01, %bx
  1675. movw $0x00, %cx
  1676. movw $0x00, %dx
  1677. movw $0x140, %di
  1678. int $0x10
  1679. no_edid:
  1680. popw %di # restore all registers
  1681. popw %dx
  1682. popw %cx
  1683. popw %bx
  1684. popw %ax
  1685. popw %es
  1686. #endif
  1687. ret
  1688. # VIDEO_SELECT-only variables
  1689. mt_end: .word 0 # End of video mode table if built
  1690. edit_buf: .space 6 # Line editor buffer
  1691. card_name: .word 0 # Pointer to adapter name
  1692. scanning: .byte 0 # Performing mode scan
  1693. do_restore: .byte 0 # Screen contents altered during mode change
  1694. svga_prefix: .byte VIDEO_FIRST_BIOS>>8 # Default prefix for BIOS modes
  1695. graphic_mode: .byte 0 # Graphic mode with a linear frame buffer
  1696. dac_size: .byte 6 # DAC bit depth
  1697. # Status messages
  1698. keymsg: .ascii "Press <RETURN> to see video modes available, "
  1699. .ascii "<SPACE> to continue or wait 30 secs"
  1700. .byte 0x0d, 0x0a, 0
  1701. listhdr: .byte 0x0d, 0x0a
  1702. .ascii "Mode: COLSxROWS:"
  1703. crlft: .byte 0x0d, 0x0a, 0
  1704. prompt: .byte 0x0d, 0x0a
  1705. .asciz "Enter mode number or `scan': "
  1706. unknt: .asciz "Unknown mode ID. Try again."
  1707. badmdt: .ascii "You passed an undefined mode number."
  1708. .byte 0x0d, 0x0a, 0
  1709. vesaer: .ascii "Error: Scanning of VESA modes failed. Please "
  1710. .ascii "report to <mj@ucw.cz>."
  1711. .byte 0x0d, 0x0a, 0
  1712. old_name: .asciz "CGA/MDA/HGA"
  1713. ega_name: .asciz "EGA"
  1714. svga_name: .ascii " "
  1715. vga_name: .asciz "VGA"
  1716. vesa_name: .asciz "VESA"
  1717. name_bann: .asciz "Video adapter: "
  1718. #endif /* CONFIG_VIDEO_SELECT */
  1719. # Other variables:
  1720. adapter: .byte 0 # Video adapter: 0=CGA/MDA/HGA,1=EGA,2=VGA
  1721. video_segment: .word 0xb800 # Video memory segment
  1722. force_size: .word 0 # Use this size instead of the one in BIOS vars