Files
oldlinux-website/Book-Lite/code-list/html/P6-2.html
2024-03-17 13:59:32 +08:00

5877 lines
266 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name=Generator content="Microsoft Word 14 (filtered)">
<style>
<!--
/* Font Definitions */
@font-face
{font-family:Helvetica;
panose-1:2 11 6 4 2 2 2 2 2 4;}
@font-face
{font-family:Courier;
panose-1:2 7 4 9 2 2 5 2 4 4;}
@font-face
{font-family:"Tms Rmn";
panose-1:2 2 6 3 4 5 5 2 3 4;}
@font-face
{font-family:Helv;
panose-1:2 11 6 4 2 2 2 3 2 4;}
@font-face
{font-family:"New York";
panose-1:2 4 5 3 6 5 6 2 3 4;}
@font-face
{font-family:System;
panose-1:0 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:"MS Mincho";
panose-1:2 2 6 9 4 2 5 8 3 4;}
@font-face
{font-family:Batang;
panose-1:2 3 6 0 0 1 1 1 1 1;}
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:PMingLiU;
panose-1:2 2 5 0 0 0 0 0 0 0;}
@font-face
{font-family:"MS Gothic";
panose-1:2 11 6 9 7 2 5 8 2 4;}
@font-face
{font-family:Dotum;
panose-1:2 11 6 0 0 1 1 1 1 1;}
@font-face
{font-family:黑体;
panose-1:2 1 6 9 6 1 1 1 1 1;}
@font-face
{font-family:MingLiU;
panose-1:2 2 5 9 0 0 0 0 0 0;}
@font-face
{font-family:Mincho;
panose-1:2 2 6 9 4 3 5 8 3 5;}
@font-face
{font-family:Gulim;
panose-1:2 11 6 0 0 1 1 1 1 1;}
@font-face
{font-family:Century;
panose-1:2 4 6 4 5 5 5 2 3 4;}
@font-face
{font-family:"Angsana New";
panose-1:2 2 6 3 5 4 5 2 3 4;}
@font-face
{font-family:"Cordia New";
panose-1:2 11 3 4 2 2 2 2 2 4;}
@font-face
{font-family:Mangal;
panose-1:2 4 5 3 5 2 3 3 2 2;}
@font-face
{font-family:Latha;
panose-1:2 11 6 4 2 2 2 2 2 4;}
@font-face
{font-family:Sylfaen;
panose-1:1 10 5 2 5 3 6 3 3 3;}
@font-face
{font-family:Vrinda;
panose-1:2 11 5 2 4 2 4 2 2 3;}
@font-face
{font-family:Raavi;
panose-1:2 11 5 2 4 2 4 2 2 3;}
@font-face
{font-family:Shruti;
panose-1:2 11 5 2 4 2 4 2 2 3;}
@font-face
{font-family:Sendnya;
panose-1:0 0 4 0 0 0 0 0 0 0;}
@font-face
{font-family:Gautami;
panose-1:2 11 5 2 4 2 4 2 2 3;}
@font-face
{font-family:Tunga;
panose-1:2 11 5 2 4 2 4 2 2 3;}
@font-face
{font-family:"Estrangelo Edessa";
panose-1:3 8 6 0 0 0 0 0 0 0;}
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:"Arial Unicode MS";
panose-1:2 11 6 4 2 2 2 2 2 4;}
@font-face
{font-family:Cambria;
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:方正小标宋简体;}
@font-face
{font-family:"\@黑体";
panose-1:2 1 6 9 6 1 1 1 1 1;}
@font-face
{font-family:"\@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:"\@方正小标宋简体";}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
h1
{mso-style-link:"标题 1 Char";
margin-top:17.0pt;
margin-right:0cm;
margin-bottom:16.5pt;
margin-left:7.2pt;
text-align:center;
text-indent:-7.2pt;
page-break-after:avoid;
font-size:22.0pt;
font-family:;
font-weight:bold;}
h2
{mso-style-link:"标题 2 Char";
margin-top:13.0pt;
margin-right:0cm;
margin-bottom:13.0pt;
margin-left:0cm;
text-align:justify;
text-justify:inter-ideograph;
text-indent:0cm;
page-break-after:avoid;
font-size:16.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
h3
{mso-style-link:"标题 3 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:0cm;
page-break-after:avoid;
font-size:14.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
h4
{mso-style-link:"标题 4 Char";
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:28.8pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-28.8pt;
page-break-after:avoid;
font-size:12.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
h5
{mso-style-link:"标题 5 Char";
margin-top:14.0pt;
margin-right:0cm;
margin-bottom:14.5pt;
margin-left:36.0pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-36.0pt;
line-height:156%;
page-break-after:avoid;
font-size:14.0pt;
font-family:;
font-weight:bold;}
h6
{mso-style-link:"标题 6 Char";
margin-top:12.0pt;
margin-right:0cm;
margin-bottom:3.2pt;
margin-left:43.2pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-43.2pt;
line-height:133%;
page-break-after:avoid;
font-size:12.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
p.MsoHeading7, li.MsoHeading7, div.MsoHeading7
{mso-style-link:"标题 7 Char";
margin-top:12.0pt;
margin-right:0cm;
margin-bottom:3.2pt;
margin-left:50.4pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-50.4pt;
line-height:133%;
page-break-after:avoid;
font-size:12.0pt;
font-family:;
font-weight:bold;}
p.MsoHeading8, li.MsoHeading8, div.MsoHeading8
{mso-style-link:"标题 8 Char";
margin-top:12.0pt;
margin-right:0cm;
margin-bottom:3.2pt;
margin-left:57.6pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-72.0pt;
line-height:133%;
page-break-after:avoid;
font-size:12.0pt;
font-family:"Arial","sans-serif";}
p.MsoHeading9, li.MsoHeading9, div.MsoHeading9
{mso-style-link:"标题 9 Char";
margin-top:12.0pt;
margin-right:0cm;
margin-bottom:3.2pt;
margin-left:64.8pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-79.2pt;
line-height:133%;
page-break-after:avoid;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.MsoIndex1, li.MsoIndex1, div.MsoIndex1
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:10.5pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoIndex2, li.MsoIndex2, div.MsoIndex2
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoIndex3, li.MsoIndex3, div.MsoIndex3
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:31.5pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoIndex4, li.MsoIndex4, div.MsoIndex4
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:42.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoIndex5, li.MsoIndex5, div.MsoIndex5
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:52.5pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoIndex6, li.MsoIndex6, div.MsoIndex6
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:63.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoIndex7, li.MsoIndex7, div.MsoIndex7
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:73.5pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoIndex8, li.MsoIndex8, div.MsoIndex8
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:84.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoIndex9, li.MsoIndex9, div.MsoIndex9
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:94.5pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-10.5pt;
font-size:10.5pt;
font-family:;}
p.MsoToc1, li.MsoToc1, div.MsoToc1
{margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;
font-weight:bold;}
p.MsoToc2, li.MsoToc2, div.MsoToc2
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.MsoToc3, li.MsoToc3, div.MsoToc3
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:42.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.MsoToc4, li.MsoToc4, div.MsoToc4
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:31.5pt;
margin-bottom:.0001pt;
font-size:9.0pt;
font-family:;}
p.MsoToc5, li.MsoToc5, div.MsoToc5
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:42.0pt;
margin-bottom:.0001pt;
font-size:9.0pt;
font-family:;}
p.MsoToc6, li.MsoToc6, div.MsoToc6
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:52.5pt;
margin-bottom:.0001pt;
font-size:9.0pt;
font-family:;}
p.MsoToc7, li.MsoToc7, div.MsoToc7
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:63.0pt;
margin-bottom:.0001pt;
font-size:9.0pt;
font-family:;}
p.MsoToc8, li.MsoToc8, div.MsoToc8
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:73.5pt;
margin-bottom:.0001pt;
font-size:9.0pt;
font-family:;}
p.MsoToc9, li.MsoToc9, div.MsoToc9
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:84.0pt;
margin-bottom:.0001pt;
font-size:9.0pt;
font-family:;}
p.MsoFootnoteText, li.MsoFootnoteText, div.MsoFootnoteText
{mso-style-link:"脚注文本 Char";
margin:0cm;
margin-bottom:.0001pt;
layout-grid-mode:char;
font-size:9.0pt;
font-family:;}
p.MsoCommentText, li.MsoCommentText, div.MsoCommentText
{mso-style-link:"批注文字 Char";
margin:0cm;
margin-bottom:.0001pt;
font-size:10.5pt;
font-family:;}
p.MsoHeader, li.MsoHeader, div.MsoHeader
{mso-style-link:"页眉 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
layout-grid-mode:char;
border:none;
padding:0cm;
font-size:9.0pt;
font-family:;}
p.MsoFooter, li.MsoFooter, div.MsoFooter
{mso-style-link:"页脚 Char";
margin:0cm;
margin-bottom:.0001pt;
layout-grid-mode:char;
font-size:9.0pt;
font-family:;}
p.MsoIndexHeading, li.MsoIndexHeading, div.MsoIndexHeading
{mso-style-name:"索引标题\,索引类目\,索引类目1\,索引类目2";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.MsoCaption, li.MsoCaption, div.MsoCaption
{margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.MsoTof, li.MsoTof, div.MsoTof
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:42.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-21.0pt;
font-size:10.5pt;
font-family:;}
span.MsoFootnoteReference
{vertical-align:super;}
p.MsoList, li.MsoList, div.MsoList
{margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.0pt;
font-size:10.5pt;
font-family:;}
p.MsoList2, li.MsoList2, div.MsoList2
{margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.MsoList4, li.MsoList4, div.MsoList4
{margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.MsoDate, li.MsoDate, div.MsoDate
{mso-style-link:"日期 Char";
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:5.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
a:link, span.MsoHyperlink
{mso-style-name:"超链接\,超级链接";
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{color:purple;
text-decoration:underline;}
p
{mso-style-name:"普通\(网站\)\,普通 \(Web\)\,普通 \(Web\)1\,普通 \(Web\)2\,普通 \(Web\)3";
margin-right:0cm;
margin-left:0cm;
font-size:12.0pt;
font-family:;}
pre
{mso-style-name:"HTML 预设格式\,HTML 预先格式化\,HTML 预先格式化1\,HTML 预先格式化2\,HTML 预先格式化3";
mso-style-link:"HTML 预设格式 Char\,HTML 预先格式化 Char\,HTML 预先格式化1 Char\,HTML 预先格式化2 Char\,HTML 预先格式化3 Char";
margin:0cm;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:;}
tt
{font-family:;}
p.MsoCommentSubject, li.MsoCommentSubject, div.MsoCommentSubject
{mso-style-link:"批注主题 Char";
margin:0cm;
margin-bottom:.0001pt;
font-size:10.5pt;
font-family:;
font-weight:bold;}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
{mso-style-link:"批注框文本 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:9.0pt;
font-family:;}
p.1, li.1, div.1
{mso-style-name:1;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.0pt;
font-size:10.5pt;
font-family:;}
p.a, li.a, div.a
{mso-style-name:;
mso-style-link:"代码程序 Char";
margin:0cm;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:;}
span.Char
{mso-style-name:"代码程序 Char";
mso-style-link:;
font-family:;}
p.a0, li.a0, div.a0
{mso-style-name:;
mso-style-link:"图说明 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
span.Char0
{mso-style-name:"图说明 Char";
mso-style-link:;
font-family:;}
p.0, li.0, div.0
{mso-style-name:0;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:36.0pt;
font-family:;
font-weight:bold;}
p.10, li.10, div.10
{mso-style-name:1;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:18.0pt;
font-family:;
font-weight:bold;}
p.11, li.11, div.11
{mso-style-name:1;
margin-top:7.8pt;
margin-right:0cm;
margin-bottom:7.8pt;
margin-left:0cm;
text-align:center;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.a1, li.a1, div.a1
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.3CharChar, li.3CharChar, div.3CharChar
{mso-style-name:"图中文字3 Char Char";
mso-style-link:"图中文字3 Char Char Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
line-height:9.0pt;
font-size:8.0pt;
font-family:;}
span.3CharCharChar
{mso-style-name:"图中文字3 Char Char Char";
mso-style-link:"图中文字3 Char Char";
font-family:;}
p.post, li.post, div.post
{mso-style-name:post;
margin:0cm;
margin-bottom:.0001pt;
text-align:right;
line-height:11.0pt;
font-size:10.5pt;
font-family:;}
p.3, li.3, div.3
{mso-style-name:3;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.3CharChar1CharCharChar
{mso-style-name:"图中文字3 Char Char1 Char Char Char";
font-family:;}
span.3CharChar1CharChar
{mso-style-name:"图中文字3 Char Char1 Char Char";
font-family:;}
p.5Char, li.5Char, div.5Char
{mso-style-name:"图中文字5号 Char";
mso-style-link:"图中文字5号 Char Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
span.5CharChar
{mso-style-name:"图中文字5号 Char Char";
mso-style-link:"图中文字5号 Char";
font-family:;}
p.5CharChar0, li.5CharChar0, div.5CharChar0
{mso-style-name:"图中文字小5号 Char Char";
mso-style-link:"图中文字小5号 Char Char Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
span.5CharCharChar
{mso-style-name:"图中文字小5号 Char Char Char";
mso-style-link:"图中文字小5号 Char Char";
font-family:;}
p.5Char0, li.5Char0, div.5Char0
{mso-style-name:"图中文字小5号 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.5, li.5, div.5
{mso-style-name:5;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
layout-grid-mode:char;
font-size:9.0pt;
font-family:;}
p.2, li.2, div.2
{mso-style-name:2;
margin:0cm;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:;}
p.20, li.20, div.20
{mso-style-name:2;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.21, li.21, div.21
{mso-style-name:2;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.3CharCharCharCharChar, li.3CharCharCharCharChar, div.3CharCharCharCharChar
{mso-style-name:"图中文字3 Char Char Char Char Char";
mso-style-link:"图中文字3 Char Char Char Char Char Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
line-height:9.0pt;
font-size:8.0pt;
font-family:;}
span.3CharCharCharCharCharChar
{mso-style-name:"图中文字3 Char Char Char Char Char Char";
mso-style-link:"图中文字3 Char Char Char Char Char";
font-family:;}
p.a2, li.a2, div.a2
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.110, li.110, div.110
{mso-style-name:"样式 标题 1 + 居中1";
margin-right:0cm;
margin-left:0cm;
text-align:center;
page-break-after:avoid;
font-size:22.0pt;
font-family:;
font-weight:bold;}
span.1Char
{mso-style-name:"标题 1 Char";
mso-style-link:"标题 1";
font-weight:bold;}
p.22, li.22, div.22
{mso-style-name:"样式 列表 2 + 居中";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.23, li.23, div.23
{mso-style-name:2;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.50, li.50, div.50
{mso-style-name:5;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.111, li.111, div.111
{mso-style-name:11;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.0pt;
font-size:10.5pt;
font-family:;}
p.12, li.12, div.12
{mso-style-name:1;
margin:0cm;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:;}
p.13, li.13, div.13
{mso-style-name:1;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.01, li.01, div.01
{mso-style-name:01;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:36.0pt;
font-family:;
font-weight:bold;}
p.112, li.112, div.112
{mso-style-name:11;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:18.0pt;
font-family:;
font-weight:bold;}
p.113, li.113, div.113
{mso-style-name:11;
margin-top:7.8pt;
margin-right:0cm;
margin-bottom:7.8pt;
margin-left:0cm;
text-align:center;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.14, li.14, div.14
{mso-style-name:1;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.3Char1, li.3Char1, div.3Char1
{mso-style-name:"图中文字3 Char1";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
line-height:9.0pt;
font-size:8.0pt;
font-family:;}
p.post1, li.post1, div.post1
{mso-style-name:post1;
margin:0cm;
margin-bottom:.0001pt;
text-align:right;
line-height:11.0pt;
font-size:10.5pt;
font-family:;}
p.31, li.31, div.31
{mso-style-name:31;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.5Char1, li.5Char1, div.5Char1
{mso-style-name:"图中文字5号 Char1";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.5CharChar1, li.5CharChar1, div.5CharChar1
{mso-style-name:"图中文字小5号 Char Char1";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.5Char10, li.5Char10, div.5Char10
{mso-style-name:"图中文字小5号 Char1";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.51, li.51, div.51
{mso-style-name:51;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.120, li.120, div.120
{mso-style-name:12;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.0pt;
font-size:10.5pt;
font-family:;}
p.02, li.02, div.02
{mso-style-name:02;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:36.0pt;
font-family:;
font-weight:bold;}
p.121, li.121, div.121
{mso-style-name:12;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:18.0pt;
font-family:;
font-weight:bold;}
p.122, li.122, div.122
{mso-style-name:12;
margin-top:7.8pt;
margin-right:0cm;
margin-bottom:7.8pt;
margin-left:0cm;
text-align:center;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.3Char2, li.3Char2, div.3Char2
{mso-style-name:"图中文字3 Char2";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
line-height:9.0pt;
font-size:8.0pt;
font-family:;}
p.post2, li.post2, div.post2
{mso-style-name:post2;
margin:0cm;
margin-bottom:.0001pt;
text-align:right;
line-height:11.0pt;
font-size:10.5pt;
font-family:;}
p.32, li.32, div.32
{mso-style-name:32;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.5Char2, li.5Char2, div.5Char2
{mso-style-name:"图中文字小5号 Char2";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.52, li.52, div.52
{mso-style-name:52;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.3CharCharCharChar, li.3CharCharCharChar, div.3CharCharCharChar
{mso-style-name:"图中文字3 Char Char Char Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
line-height:9.0pt;
font-size:8.0pt;
font-family:;}
p.130, li.130, div.130
{mso-style-name:13;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.0pt;
font-size:10.5pt;
font-family:;}
p.30, li.30, div.30
{mso-style-name:3;
margin:0cm;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:;}
p.03, li.03, div.03
{mso-style-name:03;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:36.0pt;
font-family:;
font-weight:bold;}
p.131, li.131, div.131
{mso-style-name:13;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:18.0pt;
font-family:;
font-weight:bold;}
p.132, li.132, div.132
{mso-style-name:13;
margin-top:7.8pt;
margin-right:0cm;
margin-bottom:7.8pt;
margin-left:0cm;
text-align:center;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.33, li.33, div.33
{mso-style-name:3;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.3Char3, li.3Char3, div.3Char3
{mso-style-name:"图中文字3 Char3";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
line-height:9.0pt;
font-size:8.0pt;
font-family:;}
p.post3, li.post3, div.post3
{mso-style-name:post3;
margin:0cm;
margin-bottom:.0001pt;
text-align:right;
line-height:11.0pt;
font-size:10.5pt;
font-family:;}
p.330, li.330, div.330
{mso-style-name:33;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.5Char20, li.5Char20, div.5Char20
{mso-style-name:"图中文字5号 Char2";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.5CharChar2, li.5CharChar2, div.5CharChar2
{mso-style-name:"图中文字小5号 Char Char2";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.5Char3, li.5Char3, div.5Char3
{mso-style-name:"图中文字小5号 Char3";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.53, li.53, div.53
{mso-style-name:53;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:9.0pt;
font-family:;}
p.3Char, li.3Char, div.3Char
{mso-style-name:"图中文字3 Char";
mso-style-link:"图中文字3 Char Char5";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
line-height:9.0pt;
font-size:8.0pt;
font-family:;}
span.3CharChar5
{mso-style-name:"图中文字3 Char Char5";
mso-style-link:"图中文字3 Char";
font-family:;}
p.54, li.54, div.54
{mso-style-name:5;
margin:0cm;
margin-bottom:.0001pt;
line-height:9.0pt;
text-autospace:ideograph-numeric;
font-size:9.0pt;
font-family:;}
p.24, li.24, div.24
{mso-style-name:2;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.15, li.15, div.15
{mso-style-name:"样式 标题 1 + 居中";
margin-top:17.0pt;
margin-right:0cm;
margin-bottom:16.5pt;
margin-left:0cm;
text-align:center;
page-break-after:avoid;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.25, li.25, div.25
{mso-style-name:"样式 标题 2 + 行距\: 单倍行距";
margin-top:13.0pt;
margin-right:0cm;
margin-bottom:13.0pt;
margin-left:28.9pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-28.9pt;
page-break-after:avoid;
font-size:16.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
span.2Char
{mso-style-name:"标题 2 Char";
mso-style-link:"标题 2";
font-family:"Arial","sans-serif";
font-weight:bold;}
p.34, li.34, div.34
{mso-style-name:3;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.35, li.35, div.35
{mso-style-name:3;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.4, li.4, div.4
{mso-style-name:4;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.40, li.40, div.40
{mso-style-name:4;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.0pt;
font-size:10.5pt;
font-family:;}
p.41, li.41, div.41
{mso-style-name:4;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.55, li.55, div.55
{mso-style-name:5;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.56, li.56, div.56
{mso-style-name:5;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.57, li.57, div.57
{mso-style-name:5;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.6, li.6, div.6
{mso-style-name:6;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.60, li.60, div.60
{mso-style-name:6;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.61, li.61, div.61
{mso-style-name:6;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.7, li.7, div.7
{mso-style-name:7;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.70, li.70, div.70
{mso-style-name:7;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.71, li.71, div.71
{mso-style-name:7;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.8, li.8, div.8
{mso-style-name:8;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.9, li.9, div.9
{mso-style-name:9;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.90, li.90, div.90
{mso-style-name:9;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.100, li.100, div.100
{mso-style-name:10;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.101, li.101, div.101
{mso-style-name:10;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.114, li.114, div.114
{mso-style-name:11;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.115, li.115, div.115
{mso-style-name:11;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.116, li.116, div.116
{mso-style-name:11;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.123, li.123, div.123
{mso-style-name:12;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.124, li.124, div.124
{mso-style-name:12;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.133, li.133, div.133
{mso-style-name:13;
mso-style-link:"图说明13 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
span.13Char
{mso-style-name:"图说明13 Char";
mso-style-link:13;
font-family:;}
p.134, li.134, div.134
{mso-style-name:13;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.26, li.26, div.26
{mso-style-name:2;
margin-top:13.0pt;
margin-right:0cm;
margin-bottom:13.0pt;
margin-left:0cm;
text-align:justify;
text-justify:inter-ideograph;
page-break-after:avoid;
font-size:16.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
p.36, li.36, div.36
{mso-style-name:3;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
page-break-after:avoid;
font-size:14.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
span.3Char0
{mso-style-name:"标题 3 Char";
mso-style-link:"标题 3";
font-family:"Arial","sans-serif";
font-weight:bold;}
p.16, li.16, div.16
{mso-style-name:1;
margin-top:17.0pt;
margin-right:0cm;
margin-bottom:16.5pt;
margin-left:0cm;
text-align:center;
page-break-after:avoid;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.17, li.17, div.17
{mso-style-name:1;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.42, li.42, div.42
{mso-style-name:4;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
page-break-after:avoid;
font-size:12.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
span.4Char
{mso-style-name:"标题 4 Char";
mso-style-link:"标题 4";
font-family:"Arial","sans-serif";
font-weight:bold;}
p.a3, li.a3, div.a3
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.27, li.27, div.27
{mso-style-name:2;
margin-top:13.0pt;
margin-right:0cm;
margin-bottom:13.0pt;
margin-left:28.8pt;
text-align:justify;
text-justify:inter-ideograph;
text-indent:-28.8pt;
page-break-after:avoid;
font-size:16.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
p.a4, li.a4, div.a4
{mso-style-name:;
margin-top:7.8pt;
margin-right:0cm;
margin-bottom:7.8pt;
margin-left:0cm;
text-align:center;
page-break-after:avoid;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.18, li.18, div.18
{mso-style-name:1;
margin-top:7.8pt;
margin-right:0cm;
margin-bottom:7.8pt;
margin-left:0cm;
text-align:center;
page-break-after:avoid;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.19, li.19, div.19
{mso-style-name:1;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.25pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.25pt;
font-size:10.5pt;
font-family:;}
p.1a, li.1a, div.1a
{mso-style-name:1;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.25pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.25pt;
font-size:10.5pt;
font-family:;}
p.37, li.37, div.37
{mso-style-name:3;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.62, li.62, div.62
{mso-style-name:6;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
layout-grid-mode:char;
font-size:7.5pt;
font-family:;}
p.a5, li.a5, div.a5
{mso-style-name:;
mso-style-link:"正文代码 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char1
{mso-style-name:"正文代码 Char";
mso-style-link:;
font-family:;}
p.43, li.43, div.43
{mso-style-name:"样式 标题 4 +";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
page-break-after:avoid;
font-size:12.0pt;
font-family:"Arial","sans-serif";
font-weight:bold;}
p.140, li.140, div.140
{mso-style-name:14;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.25pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.25pt;
font-size:10.5pt;
font-family:;}
p.141, li.141, div.141
{mso-style-name:14;
mso-style-link:"图说明14 Char";
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:21.25pt;
margin-bottom:.0001pt;
text-align:center;
text-indent:-21.25pt;
font-size:10.5pt;
font-family:;}
span.14Char
{mso-style-name:"图说明14 Char";
mso-style-link:14;
font-family:;}
p.a6, li.a6, div.a6
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.a7, li.a7, div.a7
{mso-style-name:"样式 正文 +";
mso-style-link:"样式 正文 + Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char2
{mso-style-name:"样式 正文 + Char";
mso-style-link:"样式 正文 +";
font-family:"Times New Roman","serif";}
p.a8, li.a8, div.a8
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.a9, li.a9, div.a9
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.aa, li.aa, div.aa
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.ab, li.ab, div.ab
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.ac, li.ac, div.ac
{mso-style-name:;
margin-top:0cm;
margin-right:21.0pt;
margin-bottom:0cm;
margin-left:21.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
border:none;
padding:0cm;
font-size:9.0pt;
font-family:;}
p.125, li.125, div.125
{mso-style-name:"样式 标题 1 + 居中2";
margin-top:17.0pt;
margin-right:0cm;
margin-bottom:16.5pt;
margin-left:0cm;
text-align:center;
page-break-after:avoid;
font-size:22.0pt;
font-family:;
font-weight:bold;}
p.ad, li.ad, div.ad
{mso-style-name:"样式 题注 + 宋体 五号 居中";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.1b, li.1b, div.1b
{mso-style-name:1;
margin-top:17.0pt;
margin-right:0cm;
margin-bottom:16.5pt;
margin-left:0cm;
line-height:240%;
page-break-after:avoid;
font-size:16.0pt;
font-family:;
font-weight:bold;}
p.38, li.38, div.38
{mso-style-name:3;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
page-break-after:avoid;
font-size:12.0pt;
font-family:;}
p.63, li.63, div.63
{mso-style-name:6;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:7.5pt;
font-family:;}
p.64, li.64, div.64
{mso-style-name:6;
margin:0cm;
margin-bottom:.0001pt;
line-height:10.0pt;
layout-grid-mode:char;
font-size:7.5pt;
font-family:;}
p.65, li.65, div.65
{mso-style-name:6;
mso-style-link:"图中文字6号 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
line-height:10.0pt;
layout-grid-mode:char;
font-size:7.5pt;
font-family:;}
span.6Char
{mso-style-name:"图中文字6号 Char";
mso-style-link:6;
font-family:;}
p.ae, li.ae, div.ae
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.28, li.28, div.28
{mso-style-name:2;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
p.af, li.af, div.af
{mso-style-name:;
margin-top:6.0pt;
margin-right:0cm;
margin-bottom:0cm;
margin-left:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
page-break-after:avoid;
font-size:14.0pt;
font-family:;}
p.1c, li.1c, div.1c
{mso-style-name:1;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:16.0pt;
font-family:;}
p.af0, li.af0, div.af0
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.af1, li.af1, div.af1
{mso-style-name:"样式 题注 + 居中";
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:;}
p.ListTitle, li.ListTitle, div.ListTitle
{mso-style-name:ListTitle;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.FigureTitle, li.FigureTitle, div.FigureTitle
{mso-style-name:FigureTitle;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.TableTitle, li.TableTitle, div.TableTitle
{mso-style-name:TableTitle;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.ProgramTitle, li.ProgramTitle, div.ProgramTitle
{mso-style-name:ProgramTitle;
margin:0cm;
margin-bottom:.0001pt;
text-align:center;
font-size:10.5pt;
font-family:"Arial","sans-serif";}
p.RightText, li.RightText, div.RightText
{mso-style-name:RightText;
margin-top:0cm;
margin-right:21.0pt;
margin-bottom:0cm;
margin-left:42.0pt;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
border:none;
padding:0cm;
font-size:9.0pt;
font-family:;}
p.af2, li.af2, div.af2
{mso-style-name:;
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:9.0pt;
font-family:;}
p.af3, li.af3, div.af3
{mso-style-name:;
mso-style-link:"关键词 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char3
{mso-style-name:"关键词 Char";
mso-style-link:;
font-family:;}
p.af4, li.af4, div.af4
{mso-style-name:;
mso-style-link:"文件名 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char4
{mso-style-name:"文件名 Char";
mso-style-link:;
font-family:;}
p.af5, li.af5, div.af5
{mso-style-name:;
mso-style-link:"选项 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char5
{mso-style-name:"选项 Char";
mso-style-link:;
font-family:;}
p.af6, li.af6, div.af6
{mso-style-name:;
mso-style-link:"命令行 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char6
{mso-style-name:"命令行 Char";
mso-style-link:;
font-family:;}
p.af7, li.af7, div.af7
{mso-style-name:;
mso-style-link:"函数名 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char7
{mso-style-name:"函数名 Char";
mso-style-link:;
font-family:;}
p.af8, li.af8, div.af8
{mso-style-name:;
mso-style-link:"寄存器名 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char8
{mso-style-name:"寄存器名 Char";
mso-style-link:;
font-family:"Times New Roman","serif";}
p.af9, li.af9, div.af9
{mso-style-name:;
mso-style-link:"变量名 Char";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:;}
span.Char9
{mso-style-name:"变量名 Char";
mso-style-link:;
font-family:;}
p.58, li.58, div.58
{mso-style-name:5;
margin:0cm;
margin-bottom:.0001pt;
font-size:9.0pt;
font-family:;}
p.59, li.59, div.59
{mso-style-name:5;
margin:0cm;
margin-bottom:.0001pt;
layout-grid-mode:char;
font-size:9.0pt;
font-family:;}
p.926, li.926, div.926
{mso-style-name:"样式 代码程序 + 左侧\: 9\.26 厘米";
margin:0cm;
margin-bottom:.0001pt;
layout-grid-mode:char;
font-size:10.0pt;
font-family:;}
span.5Char4
{mso-style-name:"标题 5 Char";
mso-style-link:"标题 5";
font-weight:bold;}
span.6Char0
{mso-style-name:"标题 6 Char";
mso-style-link:"标题 6";
font-family:"Arial","sans-serif";
font-weight:bold;}
span.7Char
{mso-style-name:"标题 7 Char";
mso-style-link:"标题 7";
font-weight:bold;}
span.8Char
{mso-style-name:"标题 8 Char";
mso-style-link:"标题 8";
font-family:"Arial","sans-serif";}
span.9Char
{mso-style-name:"标题 9 Char";
mso-style-link:"标题 9";
font-family:"Arial","sans-serif";}
span.Chara
{mso-style-name:"脚注文本 Char";
mso-style-link:;
font-family:;}
span.Charb
{mso-style-name:"批注文字 Char";
mso-style-link:;
font-family:;}
span.Charc
{mso-style-name:"页眉 Char";
mso-style-link:;
font-family:;}
span.Chard
{mso-style-name:"页脚 Char";
mso-style-link:;
font-family:;}
span.Chare
{mso-style-name:"日期 Char";
mso-style-link:;
font-family:;}
span.HTMLChar
{mso-style-name:"HTML 预设格式 Char\,HTML 预先格式化 Char\,HTML 预先格式化1 Char\,HTML 预先格式化2 Char\,HTML 预先格式化3 Char";
mso-style-link:"HTML 预设格式\,HTML 预先格式化\,HTML 预先格式化1\,HTML 预先格式化2\,HTML 预先格式化3";
font-family:;}
span.Charf
{mso-style-name:"批注主题 Char";
mso-style-link:;
font-family:;
font-weight:bold;}
span.Charf0
{mso-style-name:"批注框文本 Char";
mso-style-link:;
font-family:;}
span.5CharCharChar0
{mso-style-name:"图中文字5号 Char Char Char";
font-family:;}
span.5CharCharCharChar
{mso-style-name:"图中文字小5号 Char Char Char Char";
font-family:;}
span.msoIns
{mso-style-name:"";
text-decoration:underline;
color:teal;}
span.msoDel
{mso-style-name:"";
text-decoration:line-through;
color:red;}
.MsoChpDefault
{font-size:10.0pt;}
/* Page Definitions */
@page WordSection1
{size:595.3pt 841.9pt;
margin:72.0pt 54.0pt 72.0pt 54.0pt;
layout-grid:15.6pt;}
div.WordSection1
{page:WordSection1;}
/* List Definitions */
ol
{margin-bottom:0cm;}
ul
{margin-bottom:0cm;}
-->
</style>
</head>
<body lang=ZH-CN link=blue vlink=purple style='text-justify-trim:punctuation'>
<div class=WordSection1 style='layout-grid:15.6pt'>
<p class=ab><a name="_Toc53320598"><span style='font-family:黑体'>程序</span><span
lang=EN-US> 6&#8209;2 linux/boot/setup.S</span></a></p>
<div class=a align=center style='text-align:center'><span lang=EN-US>
<hr size=4 width="100%" align=center>
</span></div>
<p class=a><span lang=EN-US>&nbsp; <a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L1">1</a> !</span></p>
<p class=a><span lang=EN-US>&nbsp; <a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L2">2</a>
!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
setup.s&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (C) 1991 Linus Torvalds</span></p>
<p class=a><span lang=EN-US>&nbsp; <a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L3">3</a> !</span></p>
<p class=a><span lang=EN-US>&nbsp; <a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L4">4</a> ! setup.s
is responsible for getting the system data from the BIOS,</span></p>
<p class=a><span lang=EN-US>&nbsp; <a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L5">5</a> ! and
putting them into the appropriate places in system memory.</span></p>
<p class=a><span lang=EN-US>&nbsp; <a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L6">6</a> ! both
setup.s and system has been loaded by the bootblock.</span></p>
<p class=a><span lang=EN-US>&nbsp; <a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L7">7</a> !</span></p>
<p class=a><span lang=EN-US>&nbsp; <a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L8">8</a> ! This
code asks the bios for memory/disk/other parameters, and</span></p>
<p class=a><span lang=EN-US>&nbsp; <a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L9">9</a> ! puts
them in a &quot;safe&quot; place: 0x90000-0x901FF, ie where the</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L10">10</a> !
boot-block used to be. It is then up to the protected mode</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L11">11</a> !
system to read them from there before the area is overwritten</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L12">12</a> ! for
buffer-blocks.</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L13">13</a> !</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! setup.s</span>负责从<span
lang=EN-US>BIOS</span>中获取系统数据,并将这些数据放到系统内存的适当</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>地方。此时<span lang=EN-US>setup.s</span><span
lang=EN-US>system</span>已经由<span lang=EN-US>bootsect</span>引导块加载到内存中。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>这段代码询问<span lang=EN-US>bios</span>有关内存<span
lang=EN-US>/</span>磁盘<span lang=EN-US>/</span>其他参数,并将这些参数放到一个</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>“安全的”地方:<span
lang=EN-US>0x90000-0x901FF</span>,也即原来<span lang=EN-US>bootsect</span>代码块曾经在</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>的地方,然后在被缓冲块覆盖掉之前由保护模式的<span
lang=EN-US>system</span>读取。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L14">14</a> </span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L15">15</a> ! NOTE!
These had better be the same as in bootsect.s!</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>以下这些参数最好和<span
lang=EN-US>bootsect.s</span>中的相同!</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L16">16</a>
#include &lt;linux/config.h&gt;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! config.h</span>中定义了<span
lang=EN-US>DEF_INITSEG = 0x9000</span><span lang=EN-US>DEF_SYSSEG = 0x1000</span><span
lang=EN-US>DEF_SETUPSEG = 0x9020</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L17">17</a> </span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L18">18</a>
INITSEG&nbsp; = DEF_INITSEG&nbsp; ! we move boot here - out of the way ! </span>原来<span
lang=EN-US>bootsect</span>所处的段。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L19">19</a>
SYSSEG&nbsp;&nbsp; = DEF_SYSSEG&nbsp;&nbsp; ! system loaded at 0x10000 (65536).&nbsp;
! system</span><span lang=EN-US>0x10000</span>处。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L20">20</a>
SETUPSEG = DEF_SETUPSEG ! this is the current segment&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
</span>本程序所在的段地址。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L21">21</a> </span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L22">22</a> .globl
begtext, begdata, begbss, endtext, enddata, endbss</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L23">23</a> .text</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L24">24</a>
begtext:</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L25">25</a> .data</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L26">26</a>
begdata:</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L27">27</a> .bss</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L28">28</a> begbss:</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L29">29</a> .text</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L30">30</a> </span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L31">31</a> entry
start</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L32">32</a> start:</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L33">33</a> </span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L34">34</a> ! ok,
the read went well so we get current cursor position and save it for</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L35">35</a> !
posterity.</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! ok</span>,整个读磁盘过程都正常,现在将光标位置保存以备今后使用(相关代码在<span
lang=EN-US>59--62</span>行)。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L36">36</a> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp; &nbsp;! </span>下句将<span lang=EN-US>ds</span>置成<span
lang=EN-US>INITSEG(0x9000)</span>。这已经在<span lang=EN-US>bootsect</span>程序中设置过,但是现在是<span
lang=EN-US>setup</span>程序,</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp; &nbsp;! Linus</span>觉得需要再重新设置一下。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L37">37</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#INITSEG </span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L38">38</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ds,ax</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L39">39</a> </span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L40">40</a> ! Get
memory size (extended mem, kB)</span></p>
<p class=a><span lang=EN-US>&nbsp; &nbsp;&nbsp;! </span>取扩展内存的大小值(<span
lang=EN-US>KB</span>)。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>利用<span lang=EN-US>BIOS</span>中断<span
lang=EN-US>0x15 </span>功能号<span lang=EN-US>ah = 0x88 </span>取系统所含扩展内存大小并保存在内存<span
lang=EN-US>0x90002</span>处。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>返回:<span lang=EN-US>ax
= </span><span lang=EN-US>0x100000</span><span
lang=EN-US>1M</span>)处开始的扩展内存大小<span lang=EN-US>(KB)</span>。若出错则<span
lang=EN-US>CF</span>置位,<span lang=EN-US>ax = </span>出错码。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L41">41</a> </span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L42">42</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ah,#0x88</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L43">43</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int&nbsp;&nbsp;&nbsp;&nbsp; 0x15</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L44">44</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; [2],ax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>将扩展内存数值存在<span lang=EN-US>0x90002</span>处(<span lang=EN-US>1</span>个字)。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L45">45</a> </span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L46">46</a> ! check
for EGA/VGA and some config parameters</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>检查显示方式(<span
lang=EN-US>EGA/VGA</span>)并取参数。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>调用<span lang=EN-US>BIOS</span>中断<span
lang=EN-US>0x10</span>,附加功能选择方式信息。功能号:<span lang=EN-US>ah = 0x12</span><span
lang=EN-US>bl = 0x10</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>返回:<span lang=EN-US>bh
=</span>显示状态。<span lang=EN-US>0x00 -</span>彩色模式,<span lang=EN-US>I/O</span>端口<span
lang=EN-US>=0x3dX</span><span lang=EN-US>0x01 -</span>单色模式,<span lang=EN-US>I/O</span>端口<span
lang=EN-US>=0x3bX</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! bl = </span>安装的显示内存。<span
lang=EN-US>0x00 - 64k</span><span lang=EN-US>0x01 - 128k</span><span
lang=EN-US>0x02 - 192k</span><span lang=EN-US>0x03 = 256k</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! cx = </span>显示卡特性参数<span
lang=EN-US>(</span>参见程序后对<span lang=EN-US>BIOS</span>视频中断<span lang=EN-US>0x10</span>的说明<span
lang=EN-US>)</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L47">47</a> </span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L48">48</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ah,#0x12</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L49">49</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; bl,#0x10</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L50">50</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int&nbsp;&nbsp;&nbsp;&nbsp; 0x10</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L51">51</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; [8],ax&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
0x90008 = ??</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L52">52</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; [10],bx&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
0x9000A =</span>安装的显示内存;<span
lang=EN-US>0x9000B=</span>显示状态<span lang=EN-US>(</span><span lang=EN-US>/</span>单色<span
lang=EN-US>)</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L53">53</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; [12],cx&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
0x9000C =</span>显示卡特性参数。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>检测屏幕当前行列值。若显示卡是<span
lang=EN-US>VGA</span>卡时则请求用户选择显示行列值,并保存到<span lang=EN-US>0x9000E</span>处。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L54">54</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#0x5019&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span><span
lang=EN-US>ax</span>中预置屏幕默认行列值(<span lang=EN-US>ah = 80</span>列;<span
lang=EN-US>al=25</span>行)。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L55">55</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; bl,#0x10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>若中断返回<span lang=EN-US>bl</span>值为<span lang=EN-US>0x10</span>,则表示不是<span
lang=EN-US>VGA</span>显示卡,跳转。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L56">56</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
je&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; novga</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L57">57</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; chsvga&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>检测显示卡厂家和类型,修改显示行列值(第<span lang=EN-US>215</span>行)。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L58">58</a>
novga:&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp; [14],ax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>保存屏幕当前行列值(<span lang=EN-US>0x9000E</span><span lang=EN-US>0x9000F</span>)。</p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>这段代码使用<span lang=EN-US>BIOS</span>中断取屏幕当前光标位置(列、行),并保存在内存<span
lang=EN-US>0x90000</span>处(<span lang=EN-US>2</span>字节)。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>控制台初始化程序会到此处读取该值。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! BIOS</span>中断<span lang=EN-US>0x10</span>功能号<span
lang=EN-US> ah = 0x03</span>,读光标位置。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>输入:<span lang=EN-US>bh
= </span>页号</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>返回:<span lang=EN-US>ch
= </span>扫描开始线;<span lang=EN-US>cl = </span>扫描结束线;<span lang=EN-US>dh = </span>行号<span
lang=EN-US>(0x00</span>顶端<span lang=EN-US>)</span><span lang=EN-US>dl = </span>列号<span
lang=EN-US>(0x00</span>最左边<span lang=EN-US>)</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L59">59</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ah,#0x03&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;!
read cursor pos</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L60">60</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
xor&nbsp;&nbsp;&nbsp;&nbsp; bh,bh</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L61">61</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int&nbsp;&nbsp;&nbsp;&nbsp;
0x10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;!
save it in known place, con_init fetches</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L62">62</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; [0],dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;!
it from 0x90000.</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L63">63</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L64">64</a> ! Get
video-card data:</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>下面这段用于取显示卡当前显示模式。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>调用<span lang=EN-US>BIOS</span>中断<span
lang=EN-US>0x10</span>,功能号<span lang=EN-US> ah = 0x0f</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>返回:<span lang=EN-US>ah
= </span>字符列数;<span lang=EN-US>al = </span>显示模式;<span lang=EN-US>bh = </span>当前显示页。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! 0x90004(1</span><span
lang=EN-US>)</span>存放当前页;<span lang=EN-US>0x90006</span>存放显示模式;<span
lang=EN-US>0x90007</span>存放字符列数。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L65">65</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L66">66</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ah,#0x0f</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L67">67</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int&nbsp;&nbsp;&nbsp;&nbsp; 0x10</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L68">68</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp;
[4],bx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! bh = display
page</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L69">69</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp;
[6],ax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! al = video mode,
ah = window width</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L70">70</a> </span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L71">71</a> ! Get
hd0 data</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>取第一个硬盘的信息(复制硬盘参数表)。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span><span lang=EN-US>1</span>个硬盘参数表的首地址竟然是中断向量<span
lang=EN-US>0x41</span>的向量值!而第<span lang=EN-US>2</span>个硬盘参数表紧接在第<span
lang=EN-US>1</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>表的后面,中断向量<span
lang=EN-US>0x46</span>的向量值也指向第<span lang=EN-US>2</span>个硬盘的参数表首址。表的长度是<span
lang=EN-US>16</span>个字节。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>下面两段程序分别复制<span
lang=EN-US>ROM BIOS</span>中有关两个硬盘的参数表,<span lang=EN-US>0x90080</span>处存放第<span
lang=EN-US>1</span>个硬盘的表,</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! 0x90090</span>处存放第<span
lang=EN-US>2</span>个硬盘的表。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L72">72</a> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span><span lang=EN-US>75</span>行语句从内存指定位置处读取一个长指针值并放入<span
lang=EN-US>ds</span><span lang=EN-US>si</span>寄存器中。<span lang=EN-US>ds</span>中放段地址,</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! si</span>是段内偏移地址。这里是把内存地址<span
lang=EN-US>4 * 0x41</span><span lang=EN-US>= 0x104</span>)处保存的<span
lang=EN-US>4</span>个字节读出。这<span lang=EN-US>4</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>节即是硬盘参数表所处位置的段和偏移值。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L73">73</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#0x0000</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L74">74</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ds,ax</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L75">75</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lds&nbsp;&nbsp;&nbsp;&nbsp; si,[4*0x41]&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
</span>取中断向量<span lang=EN-US>0x41</span>的值,即<span lang=EN-US>hd0</span>参数表的地址<span
lang=EN-US style='font-family:Wingdings'>è</span><span lang=EN-US>ds:si</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L76">76</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#INITSEG</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L77">77</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; es,ax</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L78">78</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; di,#0x0080&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
</span>传输的目的地址<span lang=EN-US>: 0x9000:0x0080 </span><span lang=EN-US
style='font-family:Wingdings'>è</span><span lang=EN-US> es:di</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L79">79</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; cx,#0x10&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
</span>共传输<span lang=EN-US>16</span>字节。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L80">80</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
rep</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L81">81</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
movsb</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L82">82</a> </span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L83">83</a> ! Get
hd1 data</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L84">84</a> </span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L85">85</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#0x0000</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L86">86</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ds,ax</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L87">87</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lds&nbsp;&nbsp;&nbsp;&nbsp; si,[4*0x46]&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
</span>取中断向量<span lang=EN-US>0x46</span>的值,即<span lang=EN-US>hd1</span>参数表的地址<span
lang=EN-US style='font-family:Wingdings'>è</span><span lang=EN-US>ds:si</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L88">88</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#INITSEG</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L89">89</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; es,ax</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L90">90</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; di,#0x0090&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
</span>传输的目的地址<span lang=EN-US>: 0x9000:0x0090 </span><span lang=EN-US
style='font-family:Wingdings'>è</span><span lang=EN-US> es:di</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L91">91</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; cx,#0x10</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L92">92</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
rep</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L93">93</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
movsb</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L94">94</a> </span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L95">95</a> ! Check
that there IS a hd1 :-)</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>检查系统是否有第<span
lang=EN-US>2</span>个硬盘。如果没有则把第<span lang=EN-US>2</span>个表清零。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>利用<span lang=EN-US>BIOS</span>中断调用<span
lang=EN-US>0x13</span>的取盘类型功能,功能号<span lang=EN-US> ah = 0x15</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>输入:<span lang=EN-US>dl
= </span>驱动器号(<span lang=EN-US>0x8X</span>是硬盘:<span lang=EN-US>0x80</span>指第<span
lang=EN-US>1</span>个硬盘,<span lang=EN-US>0x81</span><span lang=EN-US>2</span>个硬盘)</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>输出:<span lang=EN-US>ah
= </span>类型码;<span lang=EN-US>00 - </span>没有这个盘,<span lang=EN-US>CF</span>置位;<span
lang=EN-US>01 - </span>是软驱,没有<span lang=EN-US>change-line</span>支持;</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;
!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
02 - </span>是软驱<span lang=EN-US>(</span>或其他可移动设备<span lang=EN-US>)</span>,有<span
lang=EN-US>change-line</span>支持;<span lang=EN-US> 03 - </span>是硬盘。</p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L96">96</a> </span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L97">97</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#0x01500</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L98">98</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; dl,#0x81</span></p>
<p class=a><span lang=EN-US>&nbsp;<a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L99">99</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int&nbsp;&nbsp;&nbsp;&nbsp; 0x13</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L100">100</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; no_disk1</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L101">101</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; ah,#3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>是硬盘吗?<span lang=EN-US>(</span>类型<span lang=EN-US> = 3 </span><span
lang=EN-US>)</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L102">102</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
je&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is_disk1</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L103">103</a>
no_disk1:</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L104">104</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#INITSEG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span><span lang=EN-US>2</span>个硬盘不存在,则对第<span lang=EN-US>2</span>个硬盘表清零。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L105">105</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; es,ax</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L106">106</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; di,#0x0090</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L107">107</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; cx,#0x10</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L108">108</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#0x00</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L109">109</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
rep</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L110">110</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
stosb</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L111">111</a>
is_disk1:</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L112">112</a> </span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L113">113</a> ! now
we want to move to protected mode ...</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>现在我们要进入保护模式中了<span
lang=EN-US>...</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L114">114</a> </span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L115">115</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cli&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! no interrupts allowed !&nbsp;&nbsp;&nbsp;&nbsp; ! </span>从此开始不允许中断。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L116">116</a> </span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L117">117</a> !
first we move the system to it's rightful place</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>首先我们将<span lang=EN-US>system</span>模块移到正确的位置。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! bootsect</span>引导程序会把<span
lang=EN-US> system </span>模块读入到内存<span lang=EN-US> 0x10000</span><span
lang=EN-US>64KB</span>)开始的位置。由于当时假设</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! system</span>模块最大长度不会超过<span
lang=EN-US>0x80000</span><span lang=EN-US>512KB</span>),即其末端不会超过内存地址<span
lang=EN-US>0x90000</span>,所以</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! bootsect</span>会把自己移动到<span
lang=EN-US>0x90000</span>开始的地方,并把<span lang=EN-US>setup</span>加载到它的后面。下面这段程序的</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>用途是再把整个<span
lang=EN-US>system</span>模块移动到<span lang=EN-US> 0x00000</span>位置,即把从<span
lang=EN-US> 0x10000</span><span lang=EN-US>0x8ffff </span>的内存数据块</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span><span lang=EN-US>512KB</span>)整块地向内存低端移动了<span
lang=EN-US>0x10000</span><span lang=EN-US>64KB</span>)的位置。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L118">118</a> </span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L119">119</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#0x0000</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L120">120</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cld&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! 'direction'=0, movs moves forward</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L121">121</a>
do_move:</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L122">122</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp;
es,ax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! destination
segment ! es:di</span>是目的地址<span lang=EN-US>(</span>初始为<span lang=EN-US>0x0:0x0)</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L123">123</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
add&nbsp;&nbsp;&nbsp;&nbsp; ax,#0x1000</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L124">124</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; ax,#0x9000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>已经把最后一段(从<span
lang=EN-US>0x8000</span>段开始的<span lang=EN-US>64KB</span>)代码移动完?</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L125">125</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jz&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end_move&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>是,则跳转。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L126">126</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp;
ds,ax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! source
segment&nbsp; ! ds:si</span>是源地址<span lang=EN-US>(</span>初始为<span lang=EN-US>0x1000:0x0)</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L127">127</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
sub&nbsp; &nbsp;&nbsp;&nbsp;di,di</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L128">128</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
sub&nbsp;&nbsp;&nbsp;&nbsp; si,si</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L129">129</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; cx,#0x8000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>移动<span
lang=EN-US>0x8000</span>字(<span lang=EN-US>64KB</span>字节)。</p>
<p class=a><a name=L130></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L130"><span
lang=EN-US>130</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
rep</span></p>
<p class=a><a name=L131></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L131"><span
lang=EN-US>131</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
movsw</span></p>
<p class=a><a name=L132></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L132"><span
lang=EN-US>132</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jmp&nbsp;&nbsp;&nbsp;&nbsp; do_move</span></p>
<p class=a><a name=L133></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L133"><span
lang=EN-US>133</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L134></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L134"><span
lang=EN-US>134</span></a><span lang=EN-US> ! then we load the segment
descriptors</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>此后,我们加载段描述符。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>从这里开始会遇到<span
lang=EN-US>32</span>位保护模式的操作,因此需要<span lang=EN-US>Intel 32</span>位保护模式编程方面的知识了,</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>有关这方面的信息请查阅列表后的简单介绍或附录中的详细说明。这里仅作概要说明。在进入</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>保护模式中运行之前,我们需要首先设置好需要使用的段描述符表。这里需要设置全局描述符</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>表和中断描述符表。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; !</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>下面指令<span lang=EN-US>lidt</span>用于加载中断描述符表(<span
lang=EN-US>IDT</span>)寄存器。它的操作数(<span lang=EN-US>idt_48</span>)有<span
lang=EN-US>6</span>字节。前<span lang=EN-US>2</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>字节(字节<span lang=EN-US>0-1</span>)是描述符表的字节长度值;后<span
lang=EN-US>4</span>字节(字节<span lang=EN-US>2-5</span>)是描述符表的<span lang=EN-US>32</span>位线性基</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>地址,其形式参见下面<span
lang=EN-US>218--220</span>行和<span lang=EN-US>222--224</span>行说明。中断描述符表中的每一个<span
lang=EN-US>8</span>字节表项</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>指出发生中断时需要调用的代码信息。与中断向量有些相似,但要包含更多的信息。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; !</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! lgdt</span>指令用于加载全局描述符表(<span
lang=EN-US>GDT</span>)寄存器,其操作数格式与<span lang=EN-US>lidt</span>指令的相同。全局描述</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>符表中的每个描述符项(<span
lang=EN-US>8</span>字节)描述了保护模式下数据段和代码段(块)的信息。 其中包括</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>段的最大长度限制(<span
lang=EN-US>16</span>位)、段的线性地址基址(<span lang=EN-US>32</span>位)、段的特权级、段是否在内存、读写</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>许可权以及其他一些保护模式运行的标志。参见后面<span
lang=EN-US>205--216</span>行。</p>
<p class=a><a name=L135></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L135"><span
lang=EN-US>135</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L136></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L136"><span
lang=EN-US>136</span></a><span lang=EN-US> end_move:</span></p>
<p class=a><a name=L137></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L137"><span
lang=EN-US>137</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#SETUPSEG&nbsp;&nbsp;&nbsp; ! right, forgot this
at first. didn't work :-)</span></p>
<p class=a><a name=L138></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L138"><span
lang=EN-US>138</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ds,ax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! ds</span>指向本程序<span lang=EN-US>(setup)</span>段。</p>
<p class=a><a name=L139></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L139"><span
lang=EN-US>139</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lidt&nbsp;&nbsp;&nbsp;
idt_48&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! load idt with
0,0&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
</span>加载<span lang=EN-US>IDT</span>寄存器。</p>
<p class=a><a name=L140></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L140"><span
lang=EN-US>140</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lgdt&nbsp;&nbsp;&nbsp;
gdt_48&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! load gdt with
whatever appropriate ! </span>加载<span lang=EN-US>GDT</span>寄存器。</p>
<p class=a><a name=L141></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L141"><span
lang=EN-US>141</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L142></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L142"><span
lang=EN-US>142</span></a><span lang=EN-US> ! that was painless, now we enable
A20</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>以上的操作很简单,现在我们开启<span
lang=EN-US>A20</span>地址线。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>为了能够访问和使用<span
lang=EN-US>1MB</span>以上的物理内存,我们需要首先开启<span lang=EN-US>A20</span>地址线。参见本程序列表后</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>有关<span lang=EN-US>A20</span>信号线的说明。关于所涉及的一些端口和命令,可参考<span
lang=EN-US>kernel/chr_drv/keyboard.S</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>程序后对键盘接口的说明。至于机器是否真正开启了<span
lang=EN-US>A20</span>地址线,我们还需要在进入保护模式</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>之后(能访问<span lang=EN-US>1MB</span>以上内存之后)在测试一下。这个工作放在了<span
lang=EN-US>head.S</span>程序中(<span lang=EN-US>32--36</span>行)。</p>
<p class=a><a name=L143></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L143"><span
lang=EN-US>143</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L144></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L144"><span
lang=EN-US>144</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; empty_8042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>测试<span lang=EN-US>8042</span>状态寄存器,等待输入缓冲器空。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>只有当输入缓冲器为空时才可以对其执行写命令。</p>
<p class=a><a name=L145></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L145"><span
lang=EN-US>145</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp;
al,#0xD1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! command write ! 0xD1</span>命令码<span lang=EN-US>-</span>表示要写数据到</p>
<p class=a><a name=L146></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L146"><span
lang=EN-US>146</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; #0x64,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! 8042</span><span lang=EN-US>P2</span>端口。<span lang=EN-US>P2</span>端口位<span
lang=EN-US>1</span>用于<span lang=EN-US>A20</span>线的选通。</p>
<p class=a><a name=L147></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L147"><span
lang=EN-US>147</span></a><span lang=EN-US> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;
empty_8042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>等待输入缓冲器空,看命令是否被接受。</p>
<p class=a><a name=L148></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L148"><span
lang=EN-US>148</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp;
al,#0xDF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! A20 on &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;! </span>选通<span lang=EN-US>A20</span>地址线的参数。</p>
<p class=a><a name=L149></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L149"><span
lang=EN-US>149</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; #0x60,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>数据要写到<span lang=EN-US>0x60</span>口。</p>
<p class=a><a name=L150></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L150"><span
lang=EN-US>150</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; empty_8042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>若此时输入缓冲器为空,则表示<span lang=EN-US>A20</span>线已经选通。</p>
<p class=a><a name=L151></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L151"><span
lang=EN-US>151</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L152></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L152"><span
lang=EN-US>152</span></a><span lang=EN-US> ! well, that went ok, I hope. Now we
have to reprogram the interrupts :-(</span></p>
<p class=a><a name=L153></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L153"><span
lang=EN-US>153</span></a><span lang=EN-US> ! we put them right after the
intel-reserved hardware interrupts, at</span></p>
<p class=a><a name=L154></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L154"><span
lang=EN-US>154</span></a><span lang=EN-US> ! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really</span></p>
<p class=a><a name=L155></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L155"><span
lang=EN-US>155</span></a><span lang=EN-US> ! messed this up with the original
PC, and they haven't been able to</span></p>
<p class=a><a name=L156></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L156"><span
lang=EN-US>156</span></a><span lang=EN-US> ! rectify it afterwards. Thus the
bios puts interrupts at 0x08-0x0f,</span></p>
<p class=a><a name=L157></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L157"><span
lang=EN-US>157</span></a><span lang=EN-US> ! which is used for the internal
hardware interrupts as well. We just</span></p>
<p class=a><a name=L158></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L158"><span
lang=EN-US>158</span></a><span lang=EN-US> ! have to reprogram the 8259's, and
it isn't fun.</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>希望以上一切正常。现在我们必须重新对中断进行编程<span
lang=EN-US> :-( </span>我们将它们放在正好</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>处于<span lang=EN-US>Intel</span>保留的硬件中断后面,即<span
lang=EN-US>int 0x20--0x2F</span>。在那里它们不会引起冲突。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>不幸的是<span lang=EN-US>IBM</span>在原<span
lang=EN-US>PC</span>机中搞糟了,以后也没有纠正过来。所以<span lang=EN-US>PC</span><span
lang=EN-US>BIOS</span>把中断</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>放在了<span lang=EN-US>0x08--0x0f</span>,这些中断也被用于内部硬件中断。所以我们就必须重新对<span
lang=EN-US>8259</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>中断控制器进行编程,这一点都没意思。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; !</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! PC</span>机使用<span lang=EN-US>2</span><span
lang=EN-US>8259A</span>芯片,关于对可编程控制器<span
lang=EN-US>8259A</span>芯片的编程方法请参见本程序后的介绍。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span><span lang=EN-US>162</span>行上定义的两个字(<span
lang=EN-US>0x00eb</span>)是直接使用机器码表示的两条相对跳转指令,起延时作用。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! 0xeb</span>是直接近跳转指令的操作码,带<span
lang=EN-US>1</span>个字节的相对位移值。因此跳转范围是<span lang=EN-US>-127</span><span
lang=EN-US>127</span><span lang=EN-US>CPU</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>通过把这个相对位移值加到<span
lang=EN-US>EIP</span>寄存器中就形成一个新的有效地址。此时<span lang=EN-US>EIP</span>指向下一条被执行</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>的指令。执行时所花费的<span
lang=EN-US>CPU</span>时钟周期数是<span lang=EN-US>7</span><span lang=EN-US>10</span>个。<span
lang=EN-US>0x00eb </span>表示跳转值是<span lang=EN-US>0</span>的一条指令,因</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>此还是直接执行下一条指令。这两条指令共可提供<span
lang=EN-US>14--20</span><span lang=EN-US>CPU</span>时钟周期的延迟时间。在<span
lang=EN-US>as86</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>中没有表示相应指令的助记符,因此<span
lang=EN-US>Linus</span><span lang=EN-US>setup.s</span>等一些汇编程序中就直接使用机器码来表</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>示这种指令。另外,每个空操作指令<span
lang=EN-US>NOP</span>的时钟周期数是<span lang=EN-US>3</span>个,因此若要达到相同的延迟效果就</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>需要<span lang=EN-US>6</span><span
lang=EN-US>7</span><span lang=EN-US>NOP</span>指令。</p>
<p class=a><a name=L159></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L159"><span
lang=EN-US>159</span></a><span lang=EN-US> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! 8259</span>芯片主片端口是<span
lang=EN-US>0x20-0x21</span>,从片端口是<span lang=EN-US>0xA0-0xA1</span>。输出值<span
lang=EN-US>0x11</span>表示初始化命令开始,</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>它是<span lang=EN-US>ICW1</span>命令字,表示边沿触发、多片<span
lang=EN-US>8259</span>级连、最后要发送<span lang=EN-US>ICW4</span>命令字。</p>
<p class=a><a name=L160></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L160"><span
lang=EN-US>160</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp;
al,#0x11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! initialization sequence</span></p>
<p class=a><a name=L161></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L161"><span
lang=EN-US>161</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp;
#0x20,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! send it to 8259A-1 &nbsp;! </span>发送到<span
lang=EN-US>8259A</span>主芯片。</p>
<p class=a><a name=L162></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L162"><span
lang=EN-US>162</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp;
0x00eb,0x00eb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! jmp
$+2, jmp $+2&nbsp;&nbsp;&nbsp; ! '$'</span>表示当前指令的地址,</p>
<p class=a><a name=L163></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L163"><span
lang=EN-US>163</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp;
#0xA0,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! and to 8259A-2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>再发送到<span
lang=EN-US>8259A</span>从芯片。</p>
<p class=a><a name=L164></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L164"><span
lang=EN-US>164</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x00eb,0x00eb</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! Linux</span>系统硬件中断号被设置成从<span
lang=EN-US>0x20</span>开始。参见表<span lang=EN-US>3-2</span>:硬件中断请求信号与中断号对应表。</p>
<p class=a><a name=L165></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L165"><span
lang=EN-US>165</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp;
al,#0x20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! start of hardware int's (0x20)</span></p>
<p class=a><a name=L166></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L166"><span
lang=EN-US>166</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp; &nbsp;#0x21,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>送主芯片<span lang=EN-US>ICW2</span>命令字,设置起始中断号,要送奇端口。</p>
<p class=a><a name=L167></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L167"><span
lang=EN-US>167</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x00eb,0x00eb</span></p>
<p class=a><a name=L168></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L168"><span
lang=EN-US>168</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;
al,#0x28&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! start of hardware int's 2 (0x28)</span></p>
<p class=a><a name=L169></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L169"><span
lang=EN-US>169</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; #0xA1,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>送从芯片<span lang=EN-US>ICW2</span>命令字,从芯片的起始中断号。</p>
<p class=a><a name=L170></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L170"><span
lang=EN-US>170</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x00eb,0x00eb</span></p>
<p class=a><a name=L171></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L171"><span
lang=EN-US>171</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp;
al,#0x04&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! 8259-1 is master</span></p>
<p class=a><a name=L172></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L172"><span
lang=EN-US>172</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; #0x21,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>送主芯片<span lang=EN-US>ICW3</span>命令字,主芯片的<span lang=EN-US>IR2</span>连从芯片<span
lang=EN-US>INT</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>!参见代码列表后的说明。</p>
<p class=a><a name=L173></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L173"><span
lang=EN-US>173</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x00eb,0x00eb</span></p>
<p class=a><a name=L174></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L174"><span
lang=EN-US>174</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp;
al,#0x02&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! 8259-2 is slave</span></p>
<p class=a><a name=L175></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L175"><span
lang=EN-US>175</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; #0xA1,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>送从芯片<span lang=EN-US>ICW3</span>命令字,表示从芯片的<span lang=EN-US>INT</span>连到主芯</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;! </span>片的<span
lang=EN-US>IR2</span>引脚上。</p>
<p class=a><a name=L176></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L176"><span
lang=EN-US>176</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x00eb,0x00eb</span></p>
<p class=a><a name=L177></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L177"><span
lang=EN-US>177</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp;
al,#0x01&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! 8086 mode for both</span></p>
<p class=a><a name=L178></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L178"><span
lang=EN-US>178</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; #0x21,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>送主芯片<span lang=EN-US>ICW4</span>命令字。<span lang=EN-US>8086</span>模式;普通<span
lang=EN-US>EOI</span>、非缓冲</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>方式,需发送指令来复位。初始化结束,芯片就绪。</p>
<p class=a><a name=L179></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L179"><span
lang=EN-US>179</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x00eb,0x00eb</span></p>
<p class=a><a name=L180></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L180"><span
lang=EN-US>180</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; #0xA1,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>!送从芯片<span lang=EN-US>ICW4</span>命令字,内容同上。</p>
<p class=a><a name=L181></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L181"><span
lang=EN-US>181</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x00eb,0x00eb</span></p>
<p class=a><a name=L182></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L182"><span
lang=EN-US>182</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp;
al,#0xFF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! mask off all interrupts for now</span></p>
<p class=a><a name=L183></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L183"><span
lang=EN-US>183</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp; &nbsp;&nbsp;#0x21,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>屏蔽主芯片所有中断请求。</p>
<p class=a><a name=L184></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L184"><span
lang=EN-US>184</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x00eb,0x00eb</span></p>
<p class=a><a name=L185></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L185"><span
lang=EN-US>185</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; #0xA1,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>!屏蔽从芯片所有中断请求。</p>
<p class=a><a name=L186></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L186"><span
lang=EN-US>186</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L187></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L187"><span
lang=EN-US>187</span></a><span lang=EN-US> ! well, that certainly wasn't fun
:-(. Hopefully it works, and we don't</span></p>
<p class=a><a name=L188></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L188"><span
lang=EN-US>188</span></a><span lang=EN-US> ! need no steenking BIOS anyway
(except for the initial loading :-).</span></p>
<p class=a><a name=L189></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L189"><span
lang=EN-US>189</span></a><span lang=EN-US> ! The BIOS-routine wants lots of
unnecessary data, and it's less</span></p>
<p class=a><a name=L190></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L190"><span
lang=EN-US>190</span></a><span lang=EN-US> ! &quot;interesting&quot; anyway.
This is how REAL programmers do it.</span></p>
<p class=a><a name=L191></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L191"><span
lang=EN-US>191</span></a><span lang=EN-US> !</span></p>
<p class=a><a name=L192></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L192"><span
lang=EN-US>192</span></a><span lang=EN-US> ! Well, now's the time to actually
move into protected mode. To make</span></p>
<p class=a><a name=L193></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L193"><span
lang=EN-US>193</span></a><span lang=EN-US> ! things as simple as possible, we
do no register set-up or anything,</span></p>
<p class=a><a name=L194></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L194"><span
lang=EN-US>194</span></a><span lang=EN-US> ! we let the gnu-compiled 32-bit
programs do that. We just jump to</span></p>
<p class=a><a name=L195></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L195"><span
lang=EN-US>195</span></a><span lang=EN-US> ! absolute address 0x00000, in
32-bit protected mode.</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>哼,上面这段编程当然没劲<span
lang=EN-US>:-(</span>,但希望这样能工作,而且我们也不再需要乏味的<span lang=EN-US>BIOS </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>了(除了初始加载<span
lang=EN-US>:-)</span><span lang=EN-US>BIOS</span>子程序要求很多不必要的数据,而且它一点都没趣。那是</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>“真正”的程序员所做的事。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>好了,现在是真正开始进入保护模式的时候了。为了把事情做得尽量简单,我们并不对</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>寄存器内容进行任何设置。我们让<span
lang=EN-US>gnu</span>编译的<span lang=EN-US>32</span>位程序去处理这些事。在进入<span
lang=EN-US>32</span>位保</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>护模式时我们仅是简单地跳转到绝对地址<span
lang=EN-US>0x00000</span>处。</p>
<p class=a><a name=L196></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L196"><span
lang=EN-US>196</span></a><span lang=EN-US> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>下面设置并进入<span
lang=EN-US>32</span>位保护模式运行。首先加载机器状态字<span lang=EN-US>(lmsw-Load Machine Status
Word)</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>也称控制寄存器<span
lang=EN-US>CR0</span>,其比特位<span lang=EN-US>0</span><span lang=EN-US>1</span>将导致<span
lang=EN-US>CPU</span>切换到保护模式,并且运行在特权级<span lang=EN-US>0</span>中,即</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>当前特权级<span lang=EN-US>CPL=0</span>。此时段寄存器仍然指向与实地址模式中相同的线性地址处(在实地址模式下</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>线性地址与物理内存地址相同)。在设置该比特位后,随后一条指令必须是一条段间跳转指令以</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>用于刷新<span lang=EN-US>CPU</span>当前指令队列。因为<span
lang=EN-US>CPU</span>是在执行一条指令之前就已从内存读取该指令并对其进行</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>解码。然而在进入保护模式以后那些属于实模式的预先取得的指令信息就变得不再有效。而一条</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>段间跳转指令就会刷新<span
lang=EN-US>CPU</span>的当前指令队列,即丢弃这些无效信息。另外,在<span lang=EN-US>Intel</span>公司的手册</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>上建议<span lang=EN-US>80386</span>或以上<span
lang=EN-US>CPU</span>应该使用指令<span lang=EN-US>“mov cr0,ax</span>”切换到保护模式。<span
lang=EN-US>lmsw</span>指令仅用于兼容以</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>前的<span lang=EN-US>286 CPU</span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><a name=L197></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L197"><span
lang=EN-US>197</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#0x0001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !
protected mode (PE) bit &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;! </span>保护模式比特位<span
lang=EN-US>(PE)</span></p>
<p class=a><a name=L198></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L198"><span
lang=EN-US>198</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lmsw&nbsp;&nbsp;&nbsp;
ax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! This is it!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>就这样加载机器状态字<span lang=EN-US>!</span></p>
<p class=a><a name=L199></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L199"><span
lang=EN-US>199</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jmpi&nbsp;&nbsp;&nbsp;
0,8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !
jmp offset 0 of segment 8 (cs) ! </span>跳转至<span lang=EN-US>cs</span>段偏移<span
lang=EN-US>0</span>处。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>我们已经将<span lang=EN-US>system</span>模块移动到<span
lang=EN-US>0x00000</span>开始的地方,所以上句中的偏移地址是<span lang=EN-US>0</span>。而段值<span
lang=EN-US>8</span>已经</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>是保护模式下的段选择符了,用于选择描述符表和描述符表项以及所要求的特权级。段选择符长</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>度为<span lang=EN-US>16</span>位(<span
lang=EN-US>2</span>字节);位<span lang=EN-US>0-1</span>表示请求的特权级<span lang=EN-US>0--3</span>,但<span
lang=EN-US>Linux</span>操作系统只用到两级:<span lang=EN-US>0</span>级(内</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>核级)和<span lang=EN-US>3</span>级(用户级);位<span
lang=EN-US>2</span>用于选择全局描述符表(<span lang=EN-US>0</span>)还是局部描述符表<span
lang=EN-US>(1)</span>;位<span lang=EN-US>3-15</span>是描</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>述符表项的索引,指出选择第几项描述符。所以段选择符<span
lang=EN-US>8</span><span lang=EN-US>0b0000,0000,0000,1000</span>)表示请求</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>特权级<span lang=EN-US>0</span>、使用全局描述符表<span
lang=EN-US>GDT</span>中第<span lang=EN-US>2</span>个段描述符项,该项指出代码的基地址是<span
lang=EN-US>0</span>(参见<span lang=EN-US>571</span>行),</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>因此这里的跳转指令就会去执行<span
lang=EN-US>system</span>中的代码。另外,</p>
<p class=a><a name=L200></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L200"><span
lang=EN-US>200</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L201></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L201"><span
lang=EN-US>201</span></a><span lang=EN-US> ! This routine checks that the
keyboard command queue is empty</span></p>
<p class=a><a name=L202></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L202"><span
lang=EN-US>202</span></a><span lang=EN-US> ! No timeout is used - if this hangs
there is something wrong with</span></p>
<p class=a><a name=L203></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L203"><span
lang=EN-US>203</span></a><span lang=EN-US> ! the machine, and we probably
couldn't proceed anyway.</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>下面这个子程序检查键盘命令队列是否为空。这里不使用超时方法<span
lang=EN-US> - </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>如果这里死机,则说明<span
lang=EN-US>PC</span>机有问题,我们就没有办法再处理下去了。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>只有当输入缓冲器为空时(键盘控制器状态寄存器位<span
lang=EN-US>1 = 0</span>)才可以对其执行写命令。</p>
<p class=a><a name=L204></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L204"><span
lang=EN-US>204</span></a><span lang=EN-US> empty_8042:</span></p>
<p class=a><a name=L205></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L205"><span
lang=EN-US>205</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x00eb,0x00eb</span></p>
<p class=a><a name=L206></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L206"><span
lang=EN-US>206</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
al,#0x64&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! 8042 status port&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span><span lang=EN-US>AT</span>键盘控制器状态寄存器。</p>
<p class=a><a name=L207></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L207"><span
lang=EN-US>207</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
test&nbsp;&nbsp;&nbsp;
al,#2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! is input
buffer full?&nbsp;&nbsp;&nbsp; ! </span>测试位<span lang=EN-US>1</span>,输入缓冲器满?</p>
<p class=a><a name=L208></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L208"><span
lang=EN-US>208</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jnz&nbsp;&nbsp;&nbsp;&nbsp; empty_8042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! yes -
loop</span></p>
<p class=a><a name=L209></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L209"><span
lang=EN-US>209</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ret</span></p>
<p class=a><a name=L210></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L210"><span
lang=EN-US>210</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L211></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L211"><span
lang=EN-US>211</span></a><span lang=EN-US> ! Routine trying to recognize type
of SVGA-board present (if any)</span></p>
<p class=a><a name=L212></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L212"><span
lang=EN-US>212</span></a><span lang=EN-US> ! and if it recognize one gives the
choices of resolution it offers.</span></p>
<p class=a><a name=L213></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L213"><span
lang=EN-US>213</span></a><span lang=EN-US> ! If one is found the resolution
chosen is given by al,ah (rows,cols).</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>下面是用于识别<span
lang=EN-US>SVGA</span>显示卡(若有的话)的子程序。若识别出一块就向用户</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>提供选择分辨率的机会,并把分辨率放入寄存器<span
lang=EN-US>al</span><span lang=EN-US>ah</span>(行、列)中返回。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>注意下面<span lang=EN-US>215--566</span>行代码牵涉到众多显示卡端口信息,因此比较复杂。但由于这段代码与内核</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>运行关系不大,因此可以跳过不看。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>下面首先显示<span lang=EN-US>588</span>行上的<span
lang=EN-US>msg1</span>字符串(<span lang=EN-US>&quot;</span><span lang=EN-US>&lt;</span>回车键<span
lang=EN-US>&gt;</span>查看存在的<span lang=EN-US>SVGA</span>模式,或按任意键继续<span
lang=EN-US>&quot;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>然后循环读取键盘控制器输出缓冲器,等待用户按键。如果用户按下回车键就去检查系统具有</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span><span lang=EN-US>SVGA</span>模式,并在<span
lang=EN-US>AL</span><span lang=EN-US>AH</span>中返回最大行列值,否则设置默认值<span
lang=EN-US>AL=25</span>行、<span lang=EN-US>AH=80</span>列并返回。</p>
<p class=a><a name=L214></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L214"><span
lang=EN-US>214</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L215></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L215"><span
lang=EN-US>215</span></a><span lang=EN-US> chsvga: cld</span></p>
<p class=a><a name=L216></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L216"><span
lang=EN-US>216</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
push&nbsp;&nbsp;&nbsp; ds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>保存<span lang=EN-US>ds</span>值。将在<span lang=EN-US>231</span>行(或<span
lang=EN-US>490</span><span lang=EN-US>492</span>行)弹出。</p>
<p class=a><a name=L217></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L217"><span
lang=EN-US>217</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp;
cs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>把默认数据段设置成和代码段同一个段。</p>
<p class=a><a name=L218></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L218"><span
lang=EN-US>218</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop&nbsp;&nbsp;&nbsp;&nbsp; ds</span></p>
<p class=a><a name=L219></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L219"><span
lang=EN-US>219</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#0xc000</span></p>
<p class=a><a name=L220></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L220"><span
lang=EN-US>220</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; es,ax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! es </span>指向<span lang=EN-US>0xc000</span>段。此处是<span lang=EN-US>VGA</span>卡上的<span
lang=EN-US>ROM BIOS</span>区。</p>
<p class=a><a name=L221></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L221"><span
lang=EN-US>221</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea &nbsp;&nbsp;&nbsp;&nbsp;si,msg1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! ds:si</span>指向<span lang=EN-US>msg1</span>字符串。</p>
<p class=a><a name=L222></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L222"><span
lang=EN-US>222</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; prtstr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>显示以<span lang=EN-US>NULL</span>结尾的<span lang=EN-US>msg1</span>字符串。</p>
<p class=a><a name=L223></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L223"><span
lang=EN-US>223</span></a><span lang=EN-US> nokey:&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; al,#0x60&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>读取键盘控制器输出缓冲器(来自键盘的扫描码或命令)。</p>
<p class=a><a name=L224></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L224"><span
lang=EN-US>224</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; al,#0x82&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>如果收到比<span lang=EN-US>0x82</span>小的扫描码则是接通扫描码,因为<span lang=EN-US>0x82</span></p>
<p class=a><a name=L225></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L225"><span
lang=EN-US>225</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nokey&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>最小断开扫描码值。小于<span lang=EN-US>0x82</span>表示还没有按键松开。</p>
<p class=a><a name=L226></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L226"><span
lang=EN-US>226</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; al,#0xe0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>如果扫描码大于<span lang=EN-US>0xe0</span>,表示收到的是扩展扫描码前缀。</p>
<p class=a><a name=L227></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L227"><span
lang=EN-US>227</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ja&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nokey</span></p>
<p class=a><a name=L228></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L228"><span
lang=EN-US>228</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; al,#0x9c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>如果断开扫描码是<span lang=EN-US>0x9c</span>,表示用户按下<span
lang=EN-US>/</span>松开了回车键,</p>
<p class=a><a name=L229></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L229"><span
lang=EN-US>229</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
je&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; svga&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>于是程序跳转去检查系统是否具有<span lang=EN-US>SVGA</span>模式。</p>
<p class=a><a name=L230></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L230"><span
lang=EN-US>230</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#0x5019&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>否则把<span
lang=EN-US>AX</span>中返回行列值默认设置为<span lang=EN-US>AL=25</span>行、<span lang=EN-US>AH=80</span>列。</p>
<p class=a><a name=L231></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L231"><span
lang=EN-US>231</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop&nbsp;&nbsp;&nbsp;&nbsp; ds</span></p>
<p class=a><a name=L232></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L232"><span
lang=EN-US>232</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ret</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>下面根据<span lang=EN-US>VGA</span>显示卡上的<span
lang=EN-US>ROM BIOS</span>指定位置处的特征数据串或者支持的特别功能来判断机器上</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>安装的是什么牌子的显示卡。本程序共支持<span
lang=EN-US>10</span>种显示卡的扩展功能。注意,此时程序已经在第</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! 220</span>行把<span lang=EN-US>es</span>指向<span
lang=EN-US>VGA</span>卡上<span lang=EN-US>ROM BIOS</span>所在的段<span lang=EN-US>0xc000</span>(参见第<span
lang=EN-US>2</span>章)。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>首先判断是不是<span
lang=EN-US>ATI</span>显示卡。我们把 <span lang=EN-US>ds:si</span>指向<span lang=EN-US>595</span>行上<span
lang=EN-US>ATI</span>显示卡特征数据串,并把<span lang=EN-US>es:si</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span><span lang=EN-US>VGA
BIOS</span>中指定位置(偏移<span lang=EN-US>0x31</span>)处。因为该特征串共有<span lang=EN-US>9</span>个字符(<span
lang=EN-US>&quot;761295520&quot;</span>),因此我</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>们循环比较这个特征串。如果相同则表示机器中的<span
lang=EN-US>VGA</span>卡是<span lang=EN-US>ATI</span>牌子的,于是让<span lang=EN-US>ds:si</span>指向该显</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>示卡可以设置的行列模式值<span
lang=EN-US>dscati</span>(第<span lang=EN-US>615</span>行),让<span lang=EN-US>di</span>指向<span
lang=EN-US>ATI</span>卡可设置的行列个数和模式,</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>并跳转到标号<span lang=EN-US>selmod</span><span
lang=EN-US>438</span>行)处进一步进行设置。</p>
<p class=a><a name=L233></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L233"><span
lang=EN-US>233</span></a><span lang=EN-US> svga:&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp;
si,idati&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! Check ATI 'clues'&nbsp;
! </span>检查判断<span lang=EN-US> ATI</span>显示卡的数据。</p>
<p class=a><a name=L234></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L234"><span
lang=EN-US>234</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; di,#0x31&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>特征串从<span lang=EN-US>0xc000:0x0031</span>开始。</p>
<p class=a><a name=L235></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L235"><span
lang=EN-US>235</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; cx,#0x09&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>特征串有<span lang=EN-US>9</span>个字节。</p>
<p class=a><a name=L236></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L236"><span
lang=EN-US>236</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
repe</span></p>
<p class=a><a name=L237></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L237"><span
lang=EN-US>237</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmpsb</span></p>
<p class=a><a name=L238></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L238"><span
lang=EN-US>238</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jne&nbsp;&nbsp;&nbsp;&nbsp; noati&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;! </span>若特征串不同则表示不是<span lang=EN-US>ATI</span>显示卡。跳转继续检测卡。</p>
<p class=a><a name=L239></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L239"><span
lang=EN-US>239</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; si,dscati&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>如果<span lang=EN-US>9</span>个字节都相同,表示系统中有一块<span lang=EN-US>ATI</span>牌显示卡。</p>
<p class=a><a name=L240></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L240"><span
lang=EN-US>240</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; di,moati&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>于是<span lang=EN-US>si</span>指向<span lang=EN-US>ATI</span>卡具有的可选行列值,<span
lang=EN-US>di</span>指向可选个数</p>
<p class=a><a name=L241></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L241"><span
lang=EN-US>241</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; cx,selmod&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>和模式列表,然后跳转到<span lang=EN-US>selmod</span><span lang=EN-US>438</span>行)处继续处理。</p>
<p class=a><a name=L242></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L242"><span
lang=EN-US>242</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jmp&nbsp;&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>现在来判断是不是<span
lang=EN-US>Ahead</span>牌子的显示卡。首先向<span lang=EN-US>EGA/VGA </span>图形索引寄存器<span
lang=EN-US>0x3ce</span>写入想访问的</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>主允许寄存器索引号<span
lang=EN-US>0x0f</span>,同时向<span
lang=EN-US>0x3cf</span>端口(此时对应主允许寄存器)写入开启扩展寄存器</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>标志值<span lang=EN-US>0x20</span>。然后通过<span
lang=EN-US>0x3cf</span>端口读取主允许寄存器值,以检查是否可以设置开启扩展寄存器</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>标志。如果可以则说明是<span
lang=EN-US>Ahead</span>牌子的显示卡。注意<span lang=EN-US>word</span>输出时<span
lang=EN-US>al</span><span lang=EN-US style='font-family:Wingdings'>è</span>端口<span
lang=EN-US>n</span><span lang=EN-US>ah</span><span lang=EN-US
style='font-family:Wingdings'>è</span>端口<span lang=EN-US>n+1</span></p>
<p class=a><a name=L243></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L243"><span
lang=EN-US>243</span></a><span lang=EN-US> noati:&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#0x200f&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! Check Ahead 'clues'</span></p>
<p class=a><a name=L244></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L244"><span
lang=EN-US>244</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; dx,#0x3ce&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>数据端口指向主允许寄存器(<span lang=EN-US>0x0f</span><span
lang=EN-US style='font-family:Wingdings'>è</span><span lang=EN-US>0x3ce</span>端口),</p>
<p class=a><a name=L245></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L245"><span
lang=EN-US>245</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,ax &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
</span>并设置开启扩展寄存器标志(<span lang=EN-US>0x20</span><span lang=EN-US
style='font-family:Wingdings'>è</span><span lang=EN-US>0x3cf</span>端口)。</p>
<p class=a><a name=L246></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L246"><span
lang=EN-US>246</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
inc&nbsp;&nbsp;&nbsp;&nbsp; dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>然后再读取该寄存器,检查该标志是否被设置上。</p>
<p class=a><a name=L247></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L247"><span
lang=EN-US>247</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; al,dx</span></p>
<p class=a><a name=L248></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L248"><span
lang=EN-US>248</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; al,#0x20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>如果读取值是<span lang=EN-US>0x20</span>,则表示是<span lang=EN-US>Ahead A</span>显示卡。</p>
<p class=a><a name=L249></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L249"><span
lang=EN-US>249</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
je&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isahed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>如果读取值是<span lang=EN-US>0x21</span>,则表示是<span lang=EN-US>Ahead B</span>显示卡。</p>
<p class=a><a name=L250></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L250"><span
lang=EN-US>250</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; al,#0x21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>否则说明不是<span lang=EN-US>Ahead</span>显示卡,于是跳转继续检测其余卡。</p>
<p class=a><a name=L251></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L251"><span
lang=EN-US>251</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jne&nbsp;&nbsp;&nbsp;&nbsp; noahed</span></p>
<p class=a><a name=L252></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L252"><span
lang=EN-US>252</span></a><span lang=EN-US> isahed: lea&nbsp;&nbsp;&nbsp;&nbsp;
si,dscahead&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! si </span>指向<span lang=EN-US>Ahead</span>显示卡可选行列值表,<span
lang=EN-US>di</span>指向扩展模式个</p>
<p class=a><a name=L253></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L253"><span
lang=EN-US>253</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; di,moahead&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>数和扩展模式号列表。然后跳转到<span
lang=EN-US>selmod</span><span lang=EN-US>438</span>行)处继</p>
<p class=a><a name=L254></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L254"><span
lang=EN-US>254</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; cx,selmod&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>续处理。</p>
<p class=a><a name=L255></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L255"><span
lang=EN-US>255</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jmp&nbsp;&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>现在来检查是不是<span
lang=EN-US>Chips &amp; Tech</span>生产的显示卡。通过端口<span lang=EN-US>0x3c3</span><span
lang=EN-US>0x94</span><span lang=EN-US>0x46e8</span>)设置<span lang=EN-US>VGA</span>允许</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>寄存器的进入设置模式标志(位<span
lang=EN-US>4</span>),然后从端口<span lang=EN-US>0x104</span>读取显示卡芯片集标识值。如果该标识值</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span><span lang=EN-US>0xA5</span>,则说明是<span
lang=EN-US>Chips &amp; Tech</span>生产的显示卡。</p>
<p class=a><a name=L256></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L256"><span
lang=EN-US>256</span></a><span lang=EN-US> noahed: mov&nbsp;&nbsp;&nbsp;&nbsp;
dx,#0x3c3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! Check Chips &amp; Tech. 'clues'</span></p>
<p class=a><a name=L257></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L257"><span
lang=EN-US>257</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; al,dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span><span lang=EN-US>0x3c3</span>端口读取<span
lang=EN-US>VGA</span>允许寄存器值,添加上进入设置模式</p>
<p class=a><a name=L258></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L258"><span
lang=EN-US>258</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
or&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; al,#0x10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>标志(位<span lang=EN-US>4</span>)后再写回。</p>
<p class=a><a name=L259></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L259"><span
lang=EN-US>259</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,al</span></p>
<p class=a><a name=L260></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L260"><span
lang=EN-US>260</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; dx,#0x104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>在设置模式时从全局标识端口<span lang=EN-US>0x104</span>读取显示卡芯片标识值,</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L261">261</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; al,dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>并暂时存放在<span lang=EN-US>bl</span>寄存器中。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L262">262</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; bl,al</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L263">263</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; dx,#0x3c3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>然后把<span lang=EN-US>0x3c3</span>端口中的进入设置模式标志复位。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L264">264</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; al,dx</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L265">265</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
and&nbsp;&nbsp;&nbsp;&nbsp; al,#0xef</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L266">266</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,al</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L267">267</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; bl,[idcandt]&nbsp;&nbsp;&nbsp;&nbsp; ! </span>再把<span
lang=EN-US>bl</span>中标识值与位于<span lang=EN-US>idcandt</span>处(第<span lang=EN-US>596</span>行)的<span
lang=EN-US>Chips &amp;</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L268">268</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jne&nbsp;&nbsp;&nbsp;&nbsp; nocant&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! Tech</span>的标识值<span lang=EN-US>0xA5</span>作比较。如果不同则跳转比较下一种显卡。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L269">269</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; si,dsccandt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span><span
lang=EN-US>si</span>指向这种显示卡的可选行列值表,<span lang=EN-US>di</span>指向扩展模式个数</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L270">270</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; di,mocandt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>和扩展模式号列表。然后跳转到<span
lang=EN-US>selmod</span><span lang=EN-US>438</span>行)进行设置</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L271">271</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; cx,selmod&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>显示模式的操作。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L272">272</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jmp&nbsp;&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>现在检查是不是<span
lang=EN-US>Cirrus</span>显示卡。方法是使用<span lang=EN-US>CRT</span>控制器索引号<span
lang=EN-US>0x1f</span>寄存器的内容来尝试禁止扩展</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>功能。该寄存器被称为鹰标(<span
lang=EN-US>Eagle ID</span>)寄存器,将其值高低半字节交换一下后写入端口<span lang=EN-US>0x3c4</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>引的<span lang=EN-US>6</span>号(定序<span
lang=EN-US>/</span>扩展)寄存器应该会禁止<span lang=EN-US>Cirrus</span>显示卡的扩展功能。如果不会则说明不是<span
lang=EN-US>Cirrus</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>显示卡。因为从端口<span
lang=EN-US>0x3d4</span>索引的<span lang=EN-US>0x1f</span>鹰标寄存器中读取的内容是鹰标值与<span
lang=EN-US>0x0c</span>索引号对应的显</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>存起始地址高字节寄存器内容异或操作之后的值,因此在读<span
lang=EN-US>0x1f</span>中内容之前我们需要先把显存起始</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>高字节寄存器内容保存后清零,并在检查后恢复之。另外,将没有交换过的<span
lang=EN-US>Eagle ID</span>值写到<span lang=EN-US>0x3c4</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>端口索引的<span lang=EN-US>6</span>号定序<span
lang=EN-US>/</span>扩展寄存器会重新开启扩展功能。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L273">273</a>
nocant: mov&nbsp;&nbsp;&nbsp;&nbsp;
dx,#0x3d4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! Check Cirrus 'clues'</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L274">274</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x0c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>首先向<span lang=EN-US>CRT</span>控制寄存器的索引寄存器端口<span lang=EN-US>0x3d4</span>写入要访问</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L275">275</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>的寄存器索引号<span lang=EN-US>0x0c</span>(对应显存起始地址高字节寄存器),</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L276">276</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
inc&nbsp;&nbsp;&nbsp;&nbsp; dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>然后从<span lang=EN-US>0x3d5</span>端口读入显存起始地址高字节并暂存在<span lang=EN-US>bl</span>中,</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L277">277</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; al,dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>再把显存起始地址高字节寄存器清零。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L278">278</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; bl,al</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L279">279</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
xor&nbsp;&nbsp;&nbsp;&nbsp; al,al</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L280">280</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,al</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L281">281</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
dec&nbsp;&nbsp;&nbsp; &nbsp;dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>接着向<span lang=EN-US>0x3d4</span>端口输出索引<span lang=EN-US>0x1f</span>,指出我们要在<span
lang=EN-US>0x3d5</span>端口</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L282">282</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x1f&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>访问读取“<span lang=EN-US>Eagle ID</span>”寄存器内容。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L283">283</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,al</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L284">284</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
inc&nbsp;&nbsp;&nbsp;&nbsp; dx</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L285">285</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; al,dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span><span lang=EN-US>0x3d5</span>端口读取“<span lang=EN-US>Eagle ID</span>”寄存器值,并暂存在<span
lang=EN-US>bh</span>中。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L286">286</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; bh,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>然后把该值高低<span lang=EN-US>4</span>比特互换位置存放到<span lang=EN-US>cl</span>中。再左移<span
lang=EN-US>8</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L287">287</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
xor&nbsp;&nbsp;&nbsp;&nbsp; ah,ah&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>后放入<span lang=EN-US>ch</span>中,而<span lang=EN-US>cl</span>中放入数值<span
lang=EN-US>6</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L288">288</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
shl&nbsp;&nbsp;&nbsp;&nbsp; al,#4</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L289">289</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; cx,ax</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L290">290</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,bh</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L291">291</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
shr&nbsp;&nbsp;&nbsp;&nbsp; al,#4</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L292">292</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
add&nbsp;&nbsp;&nbsp;&nbsp; cx,ax</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L293">293</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
shl&nbsp;&nbsp;&nbsp;&nbsp; cx,#8</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L294">294</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
add&nbsp;&nbsp;&nbsp;&nbsp; cx,#6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>最后把<span lang=EN-US>cx</span>值存放入<span lang=EN-US>ax</span>中。此时<span
lang=EN-US>ah</span>中是换位后的“<span lang=EN-US>Eagle</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L295">295</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,cx&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
ID</span>”值,<span lang=EN-US>al</span>中是索引号<span lang=EN-US>6</span>,对应定序<span
lang=EN-US>/</span>扩展寄存器。把<span lang=EN-US>ah</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L296">296</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; dx,#0x3c4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>写到<span lang=EN-US>0x3c4</span>端口索引的定序<span
lang=EN-US>/</span>扩展寄存器应该会导致<span lang=EN-US>Cirrus</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L297">297</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,ax&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
</span>显示卡禁止扩展功能。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L298">298</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
inc&nbsp;&nbsp;&nbsp;&nbsp; dx</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L299">299</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; al,dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>如果扩展功能真的被禁止,那么此时读入的值应该为<span lang=EN-US>0</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L300">300</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
and&nbsp;&nbsp;&nbsp;&nbsp; al,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>如果不为<span lang=EN-US>0</span>则表示不是<span lang=EN-US>Cirrus</span>显示卡,跳转继续检查其他卡。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L301">301</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jnz&nbsp;&nbsp;&nbsp;&nbsp; nocirr</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L302">302</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,bh&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span><span lang=EN-US>Cirrus</span>显示卡,则利用第<span lang=EN-US>286</span>行保存在<span
lang=EN-US>bh</span>中的“<span lang=EN-US>Eagle</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L303">303</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! ID</span>”原值再重新开启<span lang=EN-US>Cirrus</span>卡扩展功能。此时读取的返回</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L304">304</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; al,dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>值应该为<span lang=EN-US>1</span>。若不是,则仍然说明不是<span lang=EN-US>Cirrus</span>显示卡。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L305">305</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; al,#0x01</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L306">306</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jne&nbsp;&nbsp;&nbsp;&nbsp; nocirr</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L307">307</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; rst3d4&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
</span>恢复<span lang=EN-US>CRT</span>控制器的显示起始地址高字节寄存器内容。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L308">308</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; si,dsccirrus&nbsp;&nbsp;&nbsp;&nbsp; ! si</span>指向<span
lang=EN-US>Cirrus</span>显示卡的可选行列值,<span lang=EN-US>di</span>指向扩展模式个数</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L309">309</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; di,mocirrus&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>和对应模式号。然后跳转到<span
lang=EN-US>selmod</span>处去选择显示模式。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L310">310</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; cx,selmod</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L311">311</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jmp&nbsp;&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>该子程序利用保存在<span
lang=EN-US>bl</span>中的值(第<span lang=EN-US>278</span>行)恢复<span lang=EN-US>CRT</span>控制器的显示起始地址高字节寄存器内容。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L312">312</a>
rst3d4: mov&nbsp;&nbsp;&nbsp;&nbsp; dx,#0x3d4</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L313">313</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,bl</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L314">314</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
xor&nbsp;&nbsp;&nbsp;&nbsp; ah,ah</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L315">315</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
shl&nbsp;&nbsp;&nbsp;&nbsp; ax,#8</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L316">316</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
add&nbsp;&nbsp;&nbsp;&nbsp; ax,#0x0c</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L317">317</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,ax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>注意,这是<span lang=EN-US>word</span>输出!! <span lang=EN-US>al </span><span
lang=EN-US style='font-family:Wingdings'>è</span><span lang=EN-US>0x3d4</span><span
lang=EN-US>ah </span><span lang=EN-US style='font-family:Wingdings'>è</span><span
lang=EN-US>0x3d5</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L318">318</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ret&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>现在检查系统中是不是<span
lang=EN-US>Everex</span>显示卡。方法是利用中断<span lang=EN-US>int 0x10</span>功能<span
lang=EN-US>0x70</span><span lang=EN-US>ax =0x7000</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! bx=0x0000</span>)调用<span
lang=EN-US>Everex</span>的扩展视频<span lang=EN-US>BIOS</span>功能。对于<span lang=EN-US>Everes</span>类型显示卡,该中断调用应该</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>会返回模拟状态,即有以下返回信息:</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! al = 0x70</span>,若是基于<span
lang=EN-US>Trident</span><span lang=EN-US>Everex</span>显示卡;</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! cl = </span>显示器类型:<span
lang=EN-US>00-</span>单色;<span lang=EN-US>01-CGA</span><span lang=EN-US>02-EGA</span><span
lang=EN-US>03-</span>数字多频;<span lang=EN-US>04-PS/2</span><span lang=EN-US>05-IBM
8514</span><span lang=EN-US>06-SVGA</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! ch = </span>属性:位<span
lang=EN-US>7-6</span><span lang=EN-US>00-256K</span><span lang=EN-US>01-512K</span><span
lang=EN-US>10-1MB</span><span lang=EN-US>11-2MB</span>;位<span lang=EN-US>4-</span>开启<span
lang=EN-US>VGA</span>保护;位<span lang=EN-US>0-6845</span>模拟。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! dx = </span>板卡型号:位<span
lang=EN-US>15-4</span>:板类型标识号;位<span lang=EN-US>3-0</span>:板修正标识号。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; !&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
0x2360-Ultragraphics II</span><span lang=EN-US>0x6200-Vision VGA</span><span
lang=EN-US>0x6730-EVGA</span><span lang=EN-US>0x6780-Viewpoint</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! di = </span><span lang=EN-US>BCD</span>码表示的视频<span
lang=EN-US>BIOS</span>版本号。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L319">319</a>
nocirr: call&nbsp;&nbsp;&nbsp;
rst3d4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! Check
Everex 'clues'</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L320">320</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#0x7000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>设置<span
lang=EN-US>ax = 0x7000, bx=0x0000</span>,调用<span lang=EN-US>int 0x10</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L321">321</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
xor&nbsp;&nbsp;&nbsp;&nbsp; bx,bx</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L322">322</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int&nbsp;&nbsp;&nbsp;&nbsp; 0x10</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L323">323</a>&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;cmp&nbsp;&nbsp;&nbsp;&nbsp; al,#0x70&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>对于<span lang=EN-US>Everes</span>显示卡,<span lang=EN-US>al</span>中应该返回值<span
lang=EN-US>0x70</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L324">324</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jne&nbsp;&nbsp;&nbsp;&nbsp; noevrx</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L325">325</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
shr&nbsp;&nbsp;&nbsp;&nbsp; dx,#4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>忽律板修正号(位<span lang=EN-US>3-0</span>)。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L326">326</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; dx,#0x678&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>板类型号是<span lang=EN-US>0x678</span>表示是一块<span lang=EN-US>Trident</span>显示卡,则跳转。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L327">327</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
je&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; istrid</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L328">328</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; dx,#0x236&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>板类型号是<span lang=EN-US>0x236</span>表示是一块<span lang=EN-US>Trident</span>显示卡,则跳转。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L329">329</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
je&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; istrid</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L330">330</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; si,dsceverex&nbsp;&nbsp;&nbsp;&nbsp; ! </span><span
lang=EN-US>si</span>指向<span lang=EN-US>Everex</span>显示卡的可选行列值表,让<span
lang=EN-US>di</span>指向扩展</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L331">331</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; di,moeverex&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>模式个数和模式号列表。然后跳转到<span
lang=EN-US>selmod</span>去执行选择</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L332">332</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; cx,selmod &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
</span>显示模式的操作。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L333">333</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jmp&nbsp;&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L334">334</a>
istrid: lea&nbsp;&nbsp;&nbsp;&nbsp; cx,ev2tri&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span><span lang=EN-US>Trident</span>类型的<span lang=EN-US>Everex</span>显示卡,则跳转到<span
lang=EN-US>ev2tri</span>处理。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L335">335</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jmp&nbsp;&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>现在检查是不是<span
lang=EN-US>Genoa</span>显示卡。方式是检查其视频<span lang=EN-US>BIOS</span>中的特征数字串(<span
lang=EN-US>0x77</span><span lang=EN-US>0x00</span><span lang=EN-US>0x66</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! 0x99</span>)。注意,此时<span
lang=EN-US>es</span>已经在第<span lang=EN-US>220</span>行被设置成指向<span lang=EN-US>VGA</span>卡上<span
lang=EN-US>ROM BIOS</span>所在的段<span lang=EN-US>0xc000</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L336">336</a>
noevrx: lea&nbsp;&nbsp;&nbsp;&nbsp;
si,idgenoa&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! Check Genoa 'clues'</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L337">337</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
xor&nbsp;&nbsp;&nbsp;&nbsp; ax,ax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span><span lang=EN-US>ds:si</span>指向第<span lang=EN-US>597</span>行上的特征数字串。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L338">338</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
seg es</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L339">339</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,[0x37]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span><span lang=EN-US>VGA</span>卡上<span lang=EN-US>BIOS</span><span
lang=EN-US>0x37</span>处的指针(它指向特征串)。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L340">340</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; di,ax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>因此此时<span lang=EN-US>es:di</span>指向特征数字串开始处。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L341">341</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; cx,#0x04</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L342">342</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
dec&nbsp;&nbsp;&nbsp;&nbsp; si</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L343">343</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
dec&nbsp;&nbsp;&nbsp;&nbsp; di</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L344">344</a>
l1:&nbsp;&nbsp;&nbsp;&nbsp; inc&nbsp;&nbsp;&nbsp;&nbsp; si&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>然后循环比较这<span lang=EN-US>4</span>个字节的特征数字串。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L345">345</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
inc&nbsp;&nbsp;&nbsp;&nbsp; di</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L346">346</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,(si)</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L347">347</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
seg es</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L348">348</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
and&nbsp;&nbsp;&nbsp;&nbsp; al,(di)</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L349">349</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; al,(si)</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L350">350</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
loope&nbsp;&nbsp; l1</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L351">351</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; cx,#0x00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>如果特征数字串完全相同,则表示是<span lang=EN-US>Genoa</span>显示卡,</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L352">352</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jne&nbsp;&nbsp;&nbsp;&nbsp; nogen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;! </span>否则跳转去检查其他类型的显示卡。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L353">353</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; si,dscgenoa&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span><span
lang=EN-US>si</span>指向<span lang=EN-US>Genoa</span>显示卡的可选行列值表,让<span
lang=EN-US>di</span>指向扩展</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L354">354</a>&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lea&nbsp;&nbsp;&nbsp;&nbsp; di,mogenoa&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>模式个数和模式号列表。然后跳转到<span lang=EN-US>selmod</span>去执行选择</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L355">355</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; cx,selmod&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>显示模式的操作。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L356">356</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jmp&nbsp;&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>现在检查是不是<span
lang=EN-US>Paradise</span>显示卡。同样是采用比较显示卡上<span lang=EN-US>BIOS</span>中特征串(“<span
lang=EN-US>VGA=</span>”)的方式。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L357">357</a>
nogen:&nbsp; lea&nbsp; &nbsp;&nbsp;&nbsp;si,idparadise&nbsp;&nbsp;&nbsp; !
Check Paradise 'clues'</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L358">358</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; di,#0x7d&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! es:di</span>指向<span lang=EN-US>VGA ROM BIOS</span><span lang=EN-US>0xc000:0x007d</span>处,该处应该有</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L359">359</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; cx,#0x04&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! 4</span>个字符“<span lang=EN-US>VGA=</span>”。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L360">360</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
repe</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L361">361</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmpsb</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L362">362</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jne&nbsp;&nbsp;&nbsp;&nbsp; nopara&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>若有不同的字符,表示不是<span lang=EN-US>Paradise</span>显示卡,于是跳转。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L363">363</a>&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;lea&nbsp;&nbsp;&nbsp;&nbsp; si,dscparadise&nbsp;&nbsp; !
</span>否则让<span lang=EN-US>si</span>指向<span lang=EN-US>Paradise</span>显示卡的可选行列值表,让<span
lang=EN-US>di</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L364">364</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; di,moparadise&nbsp;&nbsp;&nbsp; ! </span>向扩展模式个数和模式号列表。然后跳转到<span
lang=EN-US>selmod</span>处去选</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L365">365</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; cx,selmod&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;!
</span>择想要使用的显示模式。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L366">366</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jmp&nbsp;&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>现在检查是不是<span
lang=EN-US>Trident</span><span lang=EN-US>TVGA</span>)显示卡。<span lang=EN-US>TVGA</span>显示卡扩充的模式控制寄存器<span
lang=EN-US>1</span><span lang=EN-US>0x3c4</span>端口索引</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span><span lang=EN-US>0x0e</span>)的位<span
lang=EN-US>3--0</span><span lang=EN-US>64K</span>内存页面个数值。这个字段值有一个特性:当写入时,我们需要首先把</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>值与<span lang=EN-US>0x02</span>进行异或操作后再写入;当读取该值时则不需要执行异或操作,即异或前的值应该与写</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>入后再读取的值相同。下面代码就利用这个特性来检查是不是<span
lang=EN-US>Trident</span>显示卡。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L367">367</a>
nopara: mov&nbsp;&nbsp;&nbsp;&nbsp; dx,#0x3c4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! Check Trident 'clues'</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L368">368</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x0e&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>首先在端口<span lang=EN-US>0x3c4</span>输出索引号<span
lang=EN-US>0x0e</span>,索引模式控制寄存器<span lang=EN-US>1</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L369">369</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>然后从<span lang=EN-US>0x3c5</span>数据端口读入该寄存器原值,并暂存在<span lang=EN-US>ah</span>中。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L370">370</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
inc&nbsp;&nbsp;&nbsp;&nbsp; dx</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L371">371</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; al,dx</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L372">372</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
xchg&nbsp;&nbsp;&nbsp; ah,al</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L373">373</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>然后我们向该寄存器写入<span lang=EN-US>0x00</span>,再读取其值<span lang=EN-US
style='font-family:Wingdings'>è</span><span lang=EN-US>al</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L374">374</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;!
</span>写入<span lang=EN-US>0x00</span>就相当于“原值”<span lang=EN-US>0x02</span>异或<span
lang=EN-US>0x02</span>后的写入值,</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L375">375</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; al,dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>因此若是<span lang=EN-US>Trident</span>显示卡,则此后读入的值应该是<span lang=EN-US>0x02</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L376">376</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
xchg&nbsp;&nbsp;&nbsp; al,ah&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>交换后,<span lang=EN-US>al=</span>原模式控制寄存器<span lang=EN-US>1</span>的值,<span
lang=EN-US>ah=</span>最后读取的值。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>下面语句右则英文注释是“真奇怪<span
lang=EN-US>...</span>书中并没有要求这样操作,但是这对我的<span lang=EN-US>Trident</span>显示卡</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>起作用。如果不这样做,屏幕就会变模糊<span
lang=EN-US>...</span>”。这几行附带有英文注释的语句执行如下操作:</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>如果<span lang=EN-US>bl</span>中原模式控制寄存器<span
lang=EN-US>1</span>的位<span lang=EN-US>1</span>在置位状态的话就将其复位,否则就将位<span
lang=EN-US>1</span>置位。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>实际上这几条语句就是对原模式控制寄存器<span
lang=EN-US>1</span>的值执行异或<span lang=EN-US> 0x02</span>的操作,然后用结果值去设置</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>(恢复)原寄存器值。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L377">377</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp;
bl,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;!
Strange thing ... in the book this wasn't</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L378">378</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
and&nbsp;&nbsp;&nbsp;&nbsp; bl,#0x02&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;!
necessary but it worked on my card which</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L379">379</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jz&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
setb2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;! is a
trident. Without it the screen goes</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L380">380</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
and&nbsp;&nbsp;&nbsp;&nbsp; al,#0xfd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;!
blurred ...</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L381">381</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jmp&nbsp;&nbsp;&nbsp;&nbsp;
clrb2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;!</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L382">382</a>
setb2:&nbsp; or&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
al,#0x02&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;!</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L383">383</a>
clrb2:&nbsp; out&nbsp;&nbsp;&nbsp;&nbsp; dx,al</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L384">384</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
and&nbsp;&nbsp;&nbsp;&nbsp; ah,#0x0f&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span><span lang=EN-US>375</span>行最后读入值的页面个数字段(位<span lang=EN-US>3--0</span>),如果</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L385">385</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; ah,#0x02&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;!
</span>该字段值等于<span lang=EN-US>0x02</span>,则表示是<span lang=EN-US>Trident</span>显示卡。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L386">386</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jne&nbsp;&nbsp;&nbsp;&nbsp; notrid</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L387">387</a>
ev2tri: lea&nbsp;&nbsp;&nbsp;&nbsp; si,dsctrident&nbsp;&nbsp;&nbsp; ! </span><span
lang=EN-US>Trident</span>显示卡,于是让<span lang=EN-US>si</span>指向该显示卡的可选行列</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L388">388</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; di,motrident&nbsp;&nbsp;&nbsp;&nbsp; ! </span>值列表,让<span
lang=EN-US>di</span>指向对应扩展模式个数和模式号列表,然</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L389">389</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; cx,selmod&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>后跳转到<span lang=EN-US>selmod</span>去执行模式选择操作。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L390">390</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jmp&nbsp;&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>现在检查是不是<span
lang=EN-US>Tseng</span>显示卡(<span lang=EN-US>ET4000AX</span><span lang=EN-US>ET4000/W32</span>类)。方法是对<span
lang=EN-US>0x3cd</span>端口对应的段</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>选择(<span lang=EN-US>Segment
Select</span>)寄存器执行读写操作。该寄存器高<span lang=EN-US>4</span>位(位<span lang=EN-US>7--4</span>)是要进行读操作的</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! 64KB</span>段号(<span
lang=EN-US>Bank number</span>),低<span lang=EN-US>4</span>位(位<span lang=EN-US>3--0</span>)是指定要写的段号。如果指定段选择寄存器的</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>的值是<span lang=EN-US>
0x55</span>(表示读、写第<span lang=EN-US>6</span><span lang=EN-US>64KB</span>段),那么对于<span
lang=EN-US>Tseng</span>显示卡来说,把该值写入寄存器</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>后再读出应该还是<span
lang=EN-US>0x55</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L391">391</a>
notrid: mov&nbsp;&nbsp;&nbsp;&nbsp;
dx,#0x3cd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! Check Tseng 'clues'</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L392">392</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
al,dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! Could
things be this simple ! :-)</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L393">393</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; bl,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>先从<span lang=EN-US>0x3cd</span>端口读取段选择寄存器原值,并保存在<span lang=EN-US>bl</span>中。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L394">394</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>然后我们向该寄存器中写入<span lang=EN-US>0x55</span>。再读入并放在<span lang=EN-US>ah</span>中。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L395">395</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,al</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L396">396</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; al,dx</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L397">397</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ah,al</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L398">398</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,bl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>接着恢复该寄存器的原值。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L399">399</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,al</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L400">400</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; ah,#0x55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>如果读取的就是我们写入的值,则表明是<span lang=EN-US>Tseng</span>显示卡。</p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L401">401</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jne&nbsp;&nbsp;&nbsp;&nbsp; notsen</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L402">402</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; si,dsctseng&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>于是让<span
lang=EN-US>si</span>指向<span lang=EN-US>Tseng</span>显示卡的可选行列值的列表,让<span
lang=EN-US>di</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L403">403</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; di,motseng&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>指向对应扩展模式个数和模式号列表,然后跳转到<span
lang=EN-US>selmod</span></p>
<p class=a><span lang=EN-US><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L404">404</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; cx,selmod &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
</span>去执行模式选择操作。</p>
<p class=a><a name=L405></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L405"><span
lang=EN-US>405</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jmp&nbsp;&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>下面检查是不是<span
lang=EN-US>Video7</span>显示卡。端口<span lang=EN-US>0x3c2</span>是混合输出寄存器写端口,而<span
lang=EN-US>0x3cc</span>是混合输出寄存</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>器读端口。该寄存器的位<span
lang=EN-US>0</span>是单色<span lang=EN-US>/</span>彩色标志。如果为<span lang=EN-US>0</span>则表示是单色,否则是彩色。判断是不是</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! Video7</span>显示卡的方式是利用这种显示卡的<span
lang=EN-US>CRT</span>控制扩展标识寄存器(索引号是<span lang=EN-US>0x1f</span>)。该寄存器</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>的值实际上就是显存起始地址高字节寄存器(索引号<span
lang=EN-US>0x0c</span>)的内容和<span
lang=EN-US>0xea</span>进行异或操作后的值。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>因此我们只要向显存起始地址高字节寄存器中写入一个特定值,然后从标识寄存器中读取标识值</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>进行判断即可。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>通过对以上显示卡和这里<span
lang=EN-US>Video7</span>显示卡的检查分析,我们可知检查过程通常分为三个基本步骤。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>首先读取并保存测试需要用到的寄存器原值,然后使用特定测试值进行写入和读出操作,最后恢</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>复原寄存器值并对检查结果作出判断。</p>
<p class=a><a name=L406></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L406"><span
lang=EN-US>406</span></a><span lang=EN-US> notsen: mov&nbsp;&nbsp;&nbsp;&nbsp;
dx,#0x3cc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! Check Video7 'clues'</span></p>
<p class=a><a name=L407></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L407"><span
lang=EN-US>407</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; al,dx</span></p>
<p class=a><a name=L408></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L408"><span
lang=EN-US>408</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; dx,#0x3b4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;!
</span>先设置<span lang=EN-US>dx</span>为单色显示<span lang=EN-US>CRT</span>控制索引寄存器端口号<span
lang=EN-US>0x3b4</span></p>
<p class=a><a name=L409></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L409"><span
lang=EN-US>409</span></a><span lang=EN-US> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;&nbsp;&nbsp;&nbsp;
al,#0x01&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>如果混合输出寄存器的位<span
lang=EN-US>0</span>等于<span lang=EN-US>0</span>(单色)则直接跳转,</p>
<p class=a><a name=L410></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L410"><span
lang=EN-US>410</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jz&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; even7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>否则<span lang=EN-US>dx</span>设置为彩色显示<span lang=EN-US>CRT</span>控制索引寄存器端口号<span
lang=EN-US>0x3d4</span></p>
<p class=a><a name=L411></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L411"><span
lang=EN-US>411</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; dx,#0x3d4</span></p>
<p class=a><a name=L412></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L412"><span
lang=EN-US>412</span></a><span lang=EN-US> even7:&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x0c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>设置寄存器索引号为<span lang=EN-US>0x0c</span>,对应显存起始地址高字节寄存器。</p>
<p class=a><a name=L413></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L413"><span
lang=EN-US>413</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,al</span></p>
<p class=a><a name=L414></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L414"><span
lang=EN-US>414</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
inc&nbsp;&nbsp;&nbsp;&nbsp; dx</span></p>
<p class=a><a name=L415></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L415"><span
lang=EN-US>415</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
al,dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>读取显示内存起始地址高字节寄存器内容,并保存在<span
lang=EN-US>bl</span>中。</p>
<p class=a><a name=L416></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L416"><span
lang=EN-US>416</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; bl,al</span></p>
<p class=a><a name=L417></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L417"><span
lang=EN-US>417</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>然后在显存起始地址高字节寄存器中写入值<span lang=EN-US>0x55</span>,再读取出来。</p>
<p class=a><a name=L418></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L418"><span
lang=EN-US>418</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,al</span></p>
<p class=a><a name=L419></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L419"><span
lang=EN-US>419</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; al,dx</span></p>
<p class=a><a name=L420></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L420"><span
lang=EN-US>420</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
dec&nbsp;&nbsp;&nbsp;&nbsp; dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>然后通过<span lang=EN-US>CRTC</span>索引寄存器端口<span lang=EN-US>0x3b4</span><span
lang=EN-US>0x3d4</span>选择索引号是</p>
<p class=a><a name=L421></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L421"><span
lang=EN-US>421</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x1f&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! 0x1f</span><span
lang=EN-US>Video7</span>显示卡标识寄存器。该寄存器内容实际上就是</p>
<p class=a><a name=L422></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L422"><span
lang=EN-US>422</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>显存起始地址高字节和<span lang=EN-US>0xea</span>进行异或操作后的结果值。</p>
<p class=a><a name=L423></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L423"><span
lang=EN-US>423</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
inc&nbsp;&nbsp;&nbsp;&nbsp; dx</span></p>
<p class=a><a name=L424></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L424"><span
lang=EN-US>424</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; al,dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>读取<span lang=EN-US>Video7</span>显示卡标识寄存器值,并保存在<span lang=EN-US>bh</span>中。</p>
<p class=a><a name=L425></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L425"><span
lang=EN-US>425</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; bh,al</span></p>
<p class=a><a name=L426></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L426"><span
lang=EN-US>426</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
dec&nbsp;&nbsp;&nbsp;&nbsp; dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>然后再选择显存起始地址高字节寄存器,恢复其原值。</p>
<p class=a><a name=L427></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L427"><span
lang=EN-US>427</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x0c</span></p>
<p class=a><a name=L428></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L428"><span
lang=EN-US>428</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,al</span></p>
<p class=a><a name=L429></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L429"><span
lang=EN-US>429</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
inc &nbsp;&nbsp;&nbsp;&nbsp;dx</span></p>
<p class=a><a name=L430></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L430"><span
lang=EN-US>430</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,bl</span></p>
<p class=a><a name=L431></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L431"><span
lang=EN-US>431</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
out&nbsp;&nbsp;&nbsp;&nbsp; dx,al</span></p>
<p class=a><a name=L432></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L432"><span
lang=EN-US>432</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>随后我们来验证“<span lang=EN-US>Video7</span>显示卡标识寄存器值就是显存起始</p>
<p class=a><a name=L433></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L433"><span
lang=EN-US>433</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
xor&nbsp;&nbsp;&nbsp;&nbsp; al,#0xea&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>地址高字节和<span lang=EN-US>0xea</span>进行异或操作后的结果值<span lang=EN-US></span>。因此<span
lang=EN-US>0x55</span></p>
<p class=a><a name=L434></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L434"><span
lang=EN-US>434</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; al,bh&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span><span lang=EN-US>0xea</span>进行异或操作的结果就应该等于标识寄存器的测试值。</p>
<p class=a><a name=L435></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L435"><span
lang=EN-US>435</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jne&nbsp;&nbsp;&nbsp;&nbsp; novid7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>若不是<span lang=EN-US>Video7</span>显示卡,则设置默认显示行列值(<span lang=EN-US>492</span>行)。</p>
<p class=a><a name=L436></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L436"><span
lang=EN-US>436</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; si,dscvideo7&nbsp;&nbsp;&nbsp;&nbsp; ! </span><span
lang=EN-US>Video7</span>显示卡,于是让<span lang=EN-US>si</span>指向该显示卡行列值表,让<span
lang=EN-US>di</span></p>
<p class=a><a name=L437></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L437"><span
lang=EN-US>437</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; di,movideo7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>指向扩展模式个数和模式号列表。</p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>下面根据上述代码判断出的显示卡类型以及取得的相关扩展模式信息(<span
lang=EN-US>si</span>指向的行列值列表;<span lang=EN-US>di</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>指向扩展模式个数和模式号列表),提示用户选择可用的显示模式,并设置成相应显示模式。最后</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>子程序返回系统当前设置的屏幕行列值(<span
lang=EN-US>ah = </span>列数;<span lang=EN-US>al=</span>行数)。例如,如果系统中是<span
lang=EN-US>ATI</span>显示卡,</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>那么屏幕上会显示以下信息:</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! Mode:&nbsp; COLSxROWS:</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! 0.&nbsp;&nbsp;&nbsp;&nbsp; 132
x 25</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! 1.&nbsp;&nbsp;&nbsp;&nbsp; 132
x 44</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! Choose mode by pressing the
corresponding number.</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>这段程序首先在屏幕上显示<span
lang=EN-US>NULL</span>结尾的字符串信息“<span lang=EN-US>Mode:&nbsp; COLSxROWS:</span>”。</p>
<p class=a><a name=L438></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L438"><span
lang=EN-US>438</span></a><span lang=EN-US> selmod: push&nbsp;&nbsp;&nbsp; si</span></p>
<p class=a><a name=L439></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L439"><span
lang=EN-US>439</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; si,msg2</span></p>
<p class=a><a name=L440></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L440"><span
lang=EN-US>440</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; prtstr</span></p>
<p class=a><a name=L441></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L441"><span
lang=EN-US>441</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
xor&nbsp;&nbsp;&nbsp;&nbsp; cx,cx</span></p>
<p class=a><a name=L442></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L442"><span
lang=EN-US>442</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; cl,(di)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>此时<span lang=EN-US>cl</span>中是检查出的显示卡的扩展模式个数。</p>
<p class=a><a name=L443></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L443"><span
lang=EN-US>443</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop&nbsp;&nbsp;&nbsp;&nbsp; si</span></p>
<p class=a><a name=L444></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L444"><span
lang=EN-US>444</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
push&nbsp;&nbsp;&nbsp; si</span></p>
<p class=a><a name=L445></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L445"><span
lang=EN-US>445</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
push&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>然后并在每一行上显示出当前显示卡可选择的扩展模式行列值,供用户选用。</p>
<p class=a><a name=L446></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L446"><span
lang=EN-US>446</span></a><span lang=EN-US> tbl:&nbsp;&nbsp;&nbsp;
pop&nbsp;&nbsp;&nbsp;&nbsp; bx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! bx = </span>显示卡的扩展模式总个数。</p>
<p class=a><a name=L447></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L447"><span
lang=EN-US>447</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
push&nbsp;&nbsp;&nbsp; bx</span></p>
<p class=a><a name=L448></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L448"><span
lang=EN-US>448</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,bl</span></p>
<p class=a><a name=L449></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L449"><span
lang=EN-US>449</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
sub&nbsp;&nbsp;&nbsp;&nbsp; al,cl</span></p>
<p class=a><a name=L450></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L450"><span
lang=EN-US>450</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; dprnt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>以十进制格式显示<span lang=EN-US>al</span>中的值。</p>
<p class=a><a name=L451></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L451"><span
lang=EN-US>451</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; spcing&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>显示一个点再空<span lang=EN-US>4</span>个空格。</p>
<p class=a><a name=L452></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L452"><span
lang=EN-US>452</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lodsw&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span><span lang=EN-US>ax</span>中加载<span lang=EN-US>si</span>指向的行列值,随后<span
lang=EN-US>si</span>指向下一个<span lang=EN-US>word</span>值。</p>
<p class=a><a name=L453></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L453"><span
lang=EN-US>453</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
xchg&nbsp;&nbsp;&nbsp; al,ah&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>交换位置后<span lang=EN-US>al = </span>列数。</p>
<p class=a><a name=L454></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L454"><span
lang=EN-US>454</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; dprnt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;! </span>显示列数;</p>
<p class=a><a name=L455></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L455"><span
lang=EN-US>455</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
xchg&nbsp;&nbsp;&nbsp; ah,al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>此时<span lang=EN-US>al</span>中是行数值。</p>
<p class=a><a name=L456></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L456"><span
lang=EN-US>456</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
push&nbsp;&nbsp;&nbsp; ax</span></p>
<p class=a><a name=L457></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L457"><span
lang=EN-US>457</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x78&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>显示一个小“<span lang=EN-US>x”</span>,即乘号。</p>
<p class=a><a name=L458></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L458"><span
lang=EN-US>458</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; prnt1</span></p>
<p class=a><a name=L459></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L459"><span
lang=EN-US>459</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop&nbsp;&nbsp;&nbsp;&nbsp; ax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;! </span>此时<span lang=EN-US>al</span>中是行数值。</p>
<p class=a><a name=L460></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L460"><span
lang=EN-US>460</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; dprnt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>显示行数。</p>
<p class=a><a name=L461></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L461"><span
lang=EN-US>461</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; docr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>回车换行。</p>
<p class=a><a name=L462></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L462"><span
lang=EN-US>462</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
loop&nbsp;&nbsp;&nbsp; tbl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>再显示下一个行列值。<span lang=EN-US>cx</span>中扩展模式计数值递减<span lang=EN-US>1</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>在扩展模式行列值都显示之后,显示“<span
lang=EN-US>Choose mode by pressing the corresponding number.</span>”,</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>然后从键盘口读取用户按键的扫描码,根据该扫描码确定用户选择的行列值模式号,并利用<span
lang=EN-US>ROM </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! BIOS</span>的显示中断<span
lang=EN-US>int 0x10</span>功能<span lang=EN-US>0x00</span>来设置相应的显示模式。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span><span lang=EN-US>468</span>行的<span
lang=EN-US></span>模式个数值<span lang=EN-US>+0x80”</span>是所按数字键<span
lang=EN-US>-1</span>的松开扫描码。对于<span lang=EN-US>0--9</span>数字键,它们的松开</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>扫描码分别是:<span
lang=EN-US>0 - 0x8B</span><span lang=EN-US>1 - 0x82</span><span lang=EN-US>2
- 0x83</span><span lang=EN-US>3 - 0x84</span><span lang=EN-US>4 - 0x85</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; !&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
5 - 0x86</span><span lang=EN-US>6 - 0x87</span><span lang=EN-US>7 - 0x88</span><span
lang=EN-US>8 - 0x89</span><span lang=EN-US>9 - 0x8A</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>因此,如果读取的键盘松开扫描码小于<span
lang=EN-US>0x82</span>就表示不是数字键;如果扫描码等于<span lang=EN-US>0x8B</span>则表示用户</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>按下数字<span lang=EN-US>0</span>键。</p>
<p class=a><a name=L463></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L463"><span
lang=EN-US>463</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop&nbsp;&nbsp;&nbsp;&nbsp; cx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! cl</span>中是显示卡扩展模式总个数值。</p>
<p class=a><a name=L464></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L464"><span
lang=EN-US>464</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; docr</span></p>
<p class=a><a name=L465></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L465"><span
lang=EN-US>465</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lea&nbsp;&nbsp;&nbsp;&nbsp; si,msg3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>显示“请按相应数字键来选择模式。”</p>
<p class=a><a name=L466></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L466"><span
lang=EN-US>466</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; prtstr</span></p>
<p class=a><a name=L467></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L467"><span
lang=EN-US>467</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop&nbsp;&nbsp;&nbsp;&nbsp; si&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>弹出原行列值指针(指向显示卡行列值表开始处)。</p>
<p class=a><a name=L468></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L468"><span
lang=EN-US>468</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
add&nbsp;&nbsp;&nbsp;&nbsp; cl,#0x80&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! cl + 0x80 = </span>对应“数字键<span
lang=EN-US>-1</span>”的松开扫描码。</p>
<p class=a><a name=L469></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L469"><span
lang=EN-US>469</span></a><span lang=EN-US> nonum:&nbsp;
in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
al,#0x60&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;! Quick and dirty...</span></p>
<p class=a><a name=L470></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L470"><span
lang=EN-US>470</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; al,#0x82&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>若键盘松开扫描码小于<span lang=EN-US>0x82</span>则表示不是数字键,忽律该键。</p>
<p class=a><a name=L471></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L471"><span
lang=EN-US>471</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nonum</span></p>
<p class=a><a name=L472></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L472"><span
lang=EN-US>472</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; al,#0x8b&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
</span>若键盘松开扫描码等于<span lang=EN-US>0x8b</span>,表示按下了数字键<span lang=EN-US>0</span></p>
<p class=a><a name=L473></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L473"><span
lang=EN-US>473</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
je&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; zero</span></p>
<p class=a><a name=L474></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L474"><span
lang=EN-US>474</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; al,cl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;! </span>若扫描码大于扩展模式个数值对应的最大扫描码值,表示</p>
<p class=a><a name=L475></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L475"><span
lang=EN-US>475</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ja&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nonum&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>键入的值超过范围或不是数字键的松开扫描码。否则表示</p>
<p class=a><a name=L476></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L476"><span
lang=EN-US>476</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jmp&nbsp;&nbsp;&nbsp;&nbsp; nozero&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>用户按下并松开了一个非<span lang=EN-US>0</span>数字按键。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>下面把松开扫描码转换成对应的数字按键值,然后利用该值从模式个数和模式号列表中选择对应的</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>的模式号。接着调用机器<span
lang=EN-US>ROM BIOS</span>中断<span lang=EN-US>int 0x10</span>功能<span lang=EN-US>0</span>把屏幕设置成模式号指定的模式。最后再</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>利用模式号从显示卡行列值表中选择并在<span
lang=EN-US>ax</span>中返回对应的行列值。</p>
<p class=a><a name=L477></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L477"><span
lang=EN-US>477</span></a><span lang=EN-US> zero:&nbsp;&nbsp;
sub&nbsp;&nbsp;&nbsp;&nbsp; al,#0x0a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! al = 0x8b - 0x0a = 0x81</span></p>
<p class=a><a name=L478></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L478"><span
lang=EN-US>478</span></a><span lang=EN-US> nozero: sub&nbsp;&nbsp;&nbsp;&nbsp;
al,#0x80&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>再减去<span
lang=EN-US>0x80</span>就可以得到用户选择了第几个模式。</p>
<p class=a><a name=L479></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L479"><span
lang=EN-US>479</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
dec&nbsp;&nbsp;&nbsp;&nbsp; al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span><span lang=EN-US>0</span>起计数。</p>
<p class=a><a name=L480></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L480"><span
lang=EN-US>480</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
xor&nbsp;&nbsp;&nbsp;&nbsp; ah,ah&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! int 0x10</span>显示功能号<span lang=EN-US>=0</span>(设置显示模式)。</p>
<p class=a><a name=L481></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L481"><span
lang=EN-US>481</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
add&nbsp;&nbsp;&nbsp;&nbsp; di,ax</span></p>
<p class=a><a name=L482></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L482"><span
lang=EN-US>482</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
inc&nbsp;&nbsp;&nbsp;&nbsp; di&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! di</span>指向对应的模式号(跳过第<span lang=EN-US>1</span>个模式个数字节值)。</p>
<p class=a><a name=L483></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L483"><span
lang=EN-US>483</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
push&nbsp;&nbsp;&nbsp; ax</span></p>
<p class=a><a name=L484></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L484"><span
lang=EN-US>484</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,(di)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>取模式号<span lang=EN-US style='font-family:Wingdings'>è</span><span
lang=EN-US>al</span>中,并调用系统<span lang=EN-US>BIOS</span>显示中断功能<span lang=EN-US>0</span></p>
<p class=a><a name=L485></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L485"><span
lang=EN-US>485</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int&nbsp;&nbsp;&nbsp;&nbsp; 0x10</span></p>
<p class=a><a name=L486></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L486"><span
lang=EN-US>486</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop&nbsp;&nbsp;&nbsp;&nbsp; ax</span></p>
<p class=a><a name=L487></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L487"><span
lang=EN-US>487</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
shl&nbsp;&nbsp;&nbsp;&nbsp; ax,#1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>模式号乘<span lang=EN-US>2</span>,转换成为行列值表中对应值的指针。</p>
<p class=a><a name=L488></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L488"><span
lang=EN-US>488</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
add&nbsp;&nbsp;&nbsp;&nbsp; si,ax</span></p>
<p class=a><a name=L489></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L489"><span
lang=EN-US>489</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
lodsw&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>取对应行列值到<span lang=EN-US>ax</span>中(<span lang=EN-US>ah = </span>列数,<span
lang=EN-US>al = </span>行数)。</p>
<p class=a><a name=L490></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L490"><span
lang=EN-US>490</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop&nbsp;&nbsp;&nbsp;&nbsp; ds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>恢复第<span lang=EN-US>216</span>行保存的<span lang=EN-US>ds</span>原值。在<span
lang=EN-US>ax</span>中返回当前显示行列值。</p>
<p class=a><a name=L491></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L491"><span
lang=EN-US>491</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ret</span></p>
<p class=a><span lang=EN-US>&nbsp;</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>若都不是上面检测的显示卡,那么我们只好采用默认的<span
lang=EN-US>80 x 25 </span>的标准行列值。</p>
<p class=a><a name=L492></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L492"><span
lang=EN-US>492</span></a><span lang=EN-US> novid7: pop&nbsp;&nbsp;&nbsp;&nbsp;
ds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
Here could be code to support standard 80x50,80x30</span></p>
<p class=a><a name=L493></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L493"><span
lang=EN-US>493</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ax,#0x5019&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p class=a><a name=L494></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L494"><span
lang=EN-US>494</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ret</span></p>
<p class=a><a name=L495></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L495"><span
lang=EN-US>495</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L496></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L496"><span
lang=EN-US>496</span></a><span lang=EN-US> ! Routine that 'tabs' to next col.</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>光标移动到下一制表位的子程序。</p>
<p class=a><a name=L497></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L497"><span
lang=EN-US>497</span></a><span lang=EN-US> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>显示一个点字符<span
lang=EN-US>'.'</span><span lang=EN-US>4</span>个空格。</p>
<p class=a><a name=L498></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L498"><span
lang=EN-US>498</span></a><span lang=EN-US> spcing: mov&nbsp;&nbsp;&nbsp;&nbsp;
al,#0x2e&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! </span>显示一个点字符<span
lang=EN-US>'.'</span></p>
<p class=a><a name=L499></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L499"><span
lang=EN-US>499</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; prnt1</span></p>
<p class=a><a name=L500></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L500"><span
lang=EN-US>500</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x20</span></p>
<p class=a><a name=L501></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L501"><span
lang=EN-US>501</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; prnt1&nbsp;&nbsp; </span></p>
<p class=a><a name=L502></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L502"><span
lang=EN-US>502</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x20</span></p>
<p class=a><a name=L503></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L503"><span
lang=EN-US>503</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; prnt1&nbsp;&nbsp; </span></p>
<p class=a><a name=L504></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L504"><span
lang=EN-US>504</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x20</span></p>
<p class=a><a name=L505></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L505"><span
lang=EN-US>505</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; prnt1&nbsp;&nbsp; </span></p>
<p class=a><a name=L506></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L506"><span
lang=EN-US>506</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x20</span></p>
<p class=a><a name=L507></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L507"><span
lang=EN-US>507</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; prnt1</span></p>
<p class=a><a name=L508></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L508"><span
lang=EN-US>508</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ret&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p class=a><a name=L509></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L509"><span
lang=EN-US>509</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L510></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L510"><span
lang=EN-US>510</span></a><span lang=EN-US> ! Routine to print asciiz-string at
DS:SI</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>显示位于<span lang=EN-US>DS:SI</span>处以<span
lang=EN-US>NULL</span><span lang=EN-US>0x00</span>)结尾的字符串。</p>
<p class=a><a name=L511></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L511"><span
lang=EN-US>511</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L512></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L512"><span
lang=EN-US>512</span></a><span lang=EN-US> prtstr: lodsb</span></p>
<p class=a><a name=L513></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L513"><span
lang=EN-US>513</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
and&nbsp;&nbsp;&nbsp;&nbsp; al,al</span></p>
<p class=a><a name=L514></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L514"><span
lang=EN-US>514</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jz&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fin</span></p>
<p class=a><a name=L515></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L515"><span
lang=EN-US>515</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; prnt1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>显示<span lang=EN-US>al</span>中的一个字符。</p>
<p class=a><a name=L516></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L516"><span
lang=EN-US>516</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jmp&nbsp;&nbsp;&nbsp;&nbsp; prtstr</span></p>
<p class=a><a name=L517></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L517"><span
lang=EN-US>517</span></a><span lang=EN-US> fin:&nbsp;&nbsp;&nbsp; ret</span></p>
<p class=a><a name=L518></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L518"><span
lang=EN-US>518</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L519></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L519"><span
lang=EN-US>519</span></a><span lang=EN-US> ! Routine to print a decimal value
on screen, the value to be</span></p>
<p class=a><a name=L520></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L520"><span
lang=EN-US>520</span></a><span lang=EN-US> ! printed is put in al (i.e 0-255). </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>显示十进制数字的子程序。显示值放在寄存器<span
lang=EN-US>al</span>中(<span lang=EN-US>0--255</span>)。</p>
<p class=a><a name=L521></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L521"><span
lang=EN-US>521</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L522></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L522"><span
lang=EN-US>522</span></a><span lang=EN-US> dprnt:&nbsp; push&nbsp;&nbsp;&nbsp;
ax</span></p>
<p class=a><a name=L523></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L523"><span
lang=EN-US>523</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
push&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><a name=L524></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L524"><span
lang=EN-US>524</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp;
ah,#0x00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></p>
<p class=a><a name=L525></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L525"><span
lang=EN-US>525</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; cl,#0x0a</span></p>
<p class=a><a name=L526></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L526"><span
lang=EN-US>526</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
idiv&nbsp;&nbsp;&nbsp; cl</span></p>
<p class=a><a name=L527></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L527"><span
lang=EN-US>527</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
cmp&nbsp;&nbsp;&nbsp;&nbsp; al,#0x09</span></p>
<p class=a><a name=L528></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L528"><span
lang=EN-US>528</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jbe&nbsp;&nbsp;&nbsp;&nbsp; lt100</span></p>
<p class=a><a name=L529></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L529"><span
lang=EN-US>529</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; dprnt</span></p>
<p class=a><a name=L530></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L530"><span
lang=EN-US>530</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jmp&nbsp;&nbsp;&nbsp;&nbsp; skip10</span></p>
<p class=a><a name=L531></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L531"><span
lang=EN-US>531</span></a><span lang=EN-US> lt100:&nbsp;
add&nbsp;&nbsp;&nbsp;&nbsp; al,#0x30</span></p>
<p class=a><a name=L532></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L532"><span
lang=EN-US>532</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; prnt1</span></p>
<p class=a><a name=L533></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L533"><span
lang=EN-US>533</span></a><span lang=EN-US> skip10: mov&nbsp;&nbsp;&nbsp;&nbsp;
al,ah</span></p>
<p class=a><a name=L534></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L534"><span
lang=EN-US>534</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
add&nbsp;&nbsp;&nbsp;&nbsp; al,#0x30</span></p>
<p class=a><a name=L535></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L535"><span
lang=EN-US>535</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call&nbsp;&nbsp;&nbsp; prnt1&nbsp;&nbsp; </span></p>
<p class=a><a name=L536></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L536"><span
lang=EN-US>536</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop&nbsp;&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><a name=L537></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L537"><span
lang=EN-US>537</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop&nbsp;&nbsp;&nbsp;&nbsp; ax</span></p>
<p class=a><a name=L538></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L538"><span
lang=EN-US>538</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret</span></p>
<p class=a><a name=L539></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L539"><span
lang=EN-US>539</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L540></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L540"><span
lang=EN-US>540</span></a><span lang=EN-US> ! Part of above routine, this one
just prints ascii al</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>上面子程序的一部分。显示<span
lang=EN-US>al</span>中的一个字符。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>该子程序使用中断<span
lang=EN-US>0x10</span><span lang=EN-US>0x0E</span>功能,以电传方式在屏幕上写一个字符。光标会自动移到下一个</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>位置处。如果写完一行光标就会移动到下一行开始处。如果已经写完一屏最后一行,则整个屏幕</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>会向上滚动一行。字符<span
lang=EN-US>0x07</span><span lang=EN-US>BEL</span>)、<span lang=EN-US>0x08</span><span
lang=EN-US>BS</span>)、<span lang=EN-US>0x0A(LF)</span><span
lang=EN-US>0x0D</span><span lang=EN-US>CR</span>)被作为命令不会显示。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>输入:<span lang=EN-US>AL
-- </span>欲写字符;<span lang=EN-US>BH -- </span>显示页号;<span lang=EN-US>BL -- </span>前景显示色(图形方式时)。</p>
<p class=a><a name=L541></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L541"><span
lang=EN-US>541</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L542></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L542"><span
lang=EN-US>542</span></a><span lang=EN-US> prnt1:&nbsp; push&nbsp;&nbsp;&nbsp;
ax</span></p>
<p class=a><a name=L543></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L543"><span
lang=EN-US>543</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
push&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><a name=L544></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L544"><span
lang=EN-US>544</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; bh,#0x00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>显示页面。</p>
<p class=a><a name=L545></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L545"><span
lang=EN-US>545</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; cx,#0x01</span></p>
<p class=a><a name=L546></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L546"><span
lang=EN-US>546</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ah,#0x0e</span></p>
<p class=a><a name=L547></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L547"><span
lang=EN-US>547</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int&nbsp;&nbsp;&nbsp;&nbsp; 0x10</span></p>
<p class=a><a name=L548></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L548"><span
lang=EN-US>548</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop&nbsp;&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><a name=L549></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L549"><span
lang=EN-US>549</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop&nbsp;&nbsp;&nbsp;&nbsp; ax</span></p>
<p class=a><a name=L550></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L550"><span
lang=EN-US>550</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ret</span></p>
<p class=a><a name=L551></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L551"><span
lang=EN-US>551</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L552></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L552"><span
lang=EN-US>552</span></a><span lang=EN-US> ! Prints &lt;CR&gt; + &lt;LF&gt;&nbsp;&nbsp;&nbsp;
! </span>显示回车<span lang=EN-US>+</span>换行。</p>
<p class=a><a name=L553></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L553"><span
lang=EN-US>553</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L554></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L554"><span
lang=EN-US>554</span></a><span lang=EN-US> docr:&nbsp;&nbsp;
push&nbsp;&nbsp;&nbsp; ax</span></p>
<p class=a><a name=L555></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L555"><span
lang=EN-US>555</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
push&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><a name=L556></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L556"><span
lang=EN-US>556</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; bh,#0x00</span></p>
<p class=a><a name=L557></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L557"><span
lang=EN-US>557</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; ah,#0x0e</span></p>
<p class=a><a name=L558></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L558"><span
lang=EN-US>558</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x0a</span></p>
<p class=a><a name=L559></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L559"><span
lang=EN-US>559</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; cx,#0x01</span></p>
<p class=a><a name=L560></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L560"><span
lang=EN-US>560</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int&nbsp;&nbsp;&nbsp;&nbsp; 0x10</span></p>
<p class=a><a name=L561></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L561"><span
lang=EN-US>561</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov&nbsp;&nbsp;&nbsp;&nbsp; al,#0x0d</span></p>
<p class=a><a name=L562></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L562"><span
lang=EN-US>562</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
int&nbsp;&nbsp;&nbsp;&nbsp; 0x10</span></p>
<p class=a><a name=L563></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L563"><span
lang=EN-US>563</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop&nbsp;&nbsp;&nbsp;&nbsp; cx</span></p>
<p class=a><a name=L564></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L564"><span
lang=EN-US>564</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop&nbsp;&nbsp;&nbsp;&nbsp; ax</span></p>
<p class=a><a name=L565></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L565"><span
lang=EN-US>565</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ret&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p class=a><a name=L566></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L566"><span
lang=EN-US>566</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>全局描述符表开始处。描述符表由多个<span
lang=EN-US>8</span>字节长的描述符项组成。这里给出了<span lang=EN-US>3</span>个描述符项。</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span><span lang=EN-US>1</span>项无用(<span
lang=EN-US>568</span>行),但须存在。第<span lang=EN-US>2</span>项是系统代码段描述符(<span
lang=EN-US>570-573</span>行),第<span lang=EN-US>3</span>项是系</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>统数据段描述符<span
lang=EN-US>(575-578</span><span lang=EN-US>)</span></p>
<p class=a><a name=L567></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L567"><span
lang=EN-US>567</span></a><span lang=EN-US> gdt:</span></p>
<p class=a><a name=L568></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L568"><span
lang=EN-US>568</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0,0,0,0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !
dummy&nbsp;&nbsp; ! </span><span lang=EN-US>1</span>个描述符,不用。</p>
<p class=a><a name=L569></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L569"><span
lang=EN-US>569</span></a><span lang=EN-US> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span><span lang=EN-US>GDT</span>表中这里的偏移量是<span
lang=EN-US>0x08</span>。它是内核代码段选择符的值。</p>
<p class=a><a name=L570></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L570"><span
lang=EN-US>570</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x07FF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! 8Mb - limit=2047 &nbsp;(0--2047</span>,因此是<span lang=EN-US>2048*4096=8Mb)</span></p>
<p class=a><a name=L571></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L571"><span
lang=EN-US>571</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x0000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! base address=0</span></p>
<p class=a><a name=L572></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L572"><span
lang=EN-US>572</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x9A00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! code read/exec &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;! </span>代码段为只读、可执行。</p>
<p class=a><a name=L573></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L573"><span
lang=EN-US>573</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x00C0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! granularity=4096, 386&nbsp; ! </span>颗粒度为<span lang=EN-US>4096</span><span
lang=EN-US>32</span>位模式。</p>
<p class=a><a name=L574></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L574"><span
lang=EN-US>574</span></a><span lang=EN-US> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span><span lang=EN-US>GDT</span>表中这里的偏移量是<span
lang=EN-US>0x10</span>。它是内核数据段选择符的值。</p>
<p class=a><a name=L575></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L575"><span
lang=EN-US>575</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x07FF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;!
8Mb - limit=2047 (2048*4096=8Mb)</span></p>
<p class=a><a name=L576></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L576"><span
lang=EN-US>576</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x0000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! base address=0</span></p>
<p class=a><a name=L577></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L577"><span
lang=EN-US>577</span></a><span lang=EN-US> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.word&nbsp;&nbsp;
0x9200&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! data read/write &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
</span>数据段为可读可写。</p>
<p class=a><a name=L578></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L578"><span
lang=EN-US>578</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x00C0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! granularity=4096, 386 &nbsp;! </span>颗粒度为<span lang=EN-US>4096</span><span
lang=EN-US>32</span>位模式。</p>
<p class=a><a name=L579></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L579"><span
lang=EN-US>579</span></a><span lang=EN-US> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>下面是加载中断描述符表寄存器<span
lang=EN-US>idtr</span>的指令<span lang=EN-US>lidt</span>要求的<span lang=EN-US>6</span>字节操作数。前<span
lang=EN-US>2</span>字节是<span lang=EN-US>IDT</span>表的</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>限长,后<span lang=EN-US>4</span>字节是<span
lang=EN-US>idt</span>表在线性地址空间中的<span lang=EN-US>32</span>位基地址。<span lang=EN-US>CPU</span>要求在进入保护模式之前需设</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span><span lang=EN-US>IDT</span>表,因此这里先设置一个长度为<span
lang=EN-US>0</span>的空表。</p>
<p class=a><a name=L580></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L580"><span
lang=EN-US>580</span></a><span lang=EN-US> idt_48:</span></p>
<p class=a><a name=L581></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L581"><span
lang=EN-US>581</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp;
0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! idt limit=0</span></p>
<p class=a><a name=L582></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L582"><span
lang=EN-US>582</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp;
0,0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !
idt base=0L</span></p>
<p class=a><a name=L583></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L583"><span
lang=EN-US>583</span></a><span lang=EN-US> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>这是加载全局描述符表寄存器<span
lang=EN-US>gdtr</span>的指令<span lang=EN-US>lgdt</span>要求的<span lang=EN-US>6</span>字节操作数。前<span
lang=EN-US>2</span>字节是<span lang=EN-US>gdt</span>表的限</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>长,后<span lang=EN-US>4</span>字节是
<span lang=EN-US>gdt</span>表的线性基地址。这里全局表长度设置为<span lang=EN-US> 2KB</span><span
lang=EN-US>0x7ff</span>即可),因为每<span lang=EN-US>8</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>字节组成一个段描述符项,所以表中共可有<span
lang=EN-US> 256</span>项。<span lang=EN-US>4</span>字节的线性基地址为<span lang=EN-US>
0x0009&lt;&lt;16 +</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! 0x0200 + gdt</span>,即<span
lang=EN-US>0x90200 + gdt</span><span lang=EN-US>(</span>符号<span lang=EN-US>gdt</span>是全局表在本程序段中的偏移地址,见<span
lang=EN-US>205</span><span lang=EN-US>)</span></p>
<p class=a><a name=L584></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L584"><span
lang=EN-US>584</span></a><span lang=EN-US> gdt_48:</span></p>
<p class=a><a name=L585></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L585"><span
lang=EN-US>585</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp;
0x800&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! gdt
limit=2048, 256 GDT entries</span></p>
<p class=a><a name=L586></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L586"><span
lang=EN-US>586</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 512+gdt,0x9&nbsp;&nbsp;&nbsp;&nbsp; ! gdt base = 0X9xxxx</span></p>
<p class=a><a name=L587></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L587"><span
lang=EN-US>587</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L588></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L588"><span
lang=EN-US>588</span></a><span lang=EN-US> msg1: &nbsp;&nbsp;.ascii&nbsp;
&quot;Press &lt;RETURN&gt; to see SVGA-modes available or any other key to continue.&quot;</span></p>
<p class=a><a name=L589></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L589"><span
lang=EN-US>589</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
db&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x0d, 0x0a, 0x0a, 0x00</span></p>
<p class=a><a name=L590></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L590"><span
lang=EN-US>590</span></a><span lang=EN-US>
msg2:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ascii&nbsp;
&quot;Mode:&nbsp; COLSxROWS:&quot;</span></p>
<p class=a><a name=L591></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L591"><span
lang=EN-US>591</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
db&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x0d, 0x0a, 0x0a, 0x00</span></p>
<p class=a><a name=L592></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L592"><span
lang=EN-US>592</span></a><span lang=EN-US>
msg3:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ascii&nbsp;
&quot;Choose mode by pressing the corresponding number.&quot;</span></p>
<p class=a><a name=L593></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L593"><span
lang=EN-US>593</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
db&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x0d, 0x0a, 0x00</span></p>
<p class=a><a name=L594></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L594"><span
lang=EN-US>594</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>下面是<span lang=EN-US>4</span>个显示卡的特征数据串。</p>
<p class=a><a name=L595></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L595"><span
lang=EN-US>595</span></a><span lang=EN-US>
idati:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ascii&nbsp;
&quot;761295520&quot;</span></p>
<p class=a><a name=L596></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L596"><span
lang=EN-US>596</span></a><span lang=EN-US> idcandt:&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.byte&nbsp;&nbsp;
0xa5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
! </span>标号<span lang=EN-US>idcandt</span>意思是<span lang=EN-US>ID of Chip AND
Tech.</span></p>
<p class=a><a name=L597></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L597"><span
lang=EN-US>597</span></a><span lang=EN-US>
idgenoa:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .byte&nbsp;&nbsp; 0x77,
0x00, 0x66, 0x99</span></p>
<p class=a><a name=L598></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L598"><span
lang=EN-US>598</span></a><span lang=EN-US> idparadise:&nbsp;&nbsp;&nbsp;&nbsp;
.ascii&nbsp; &quot;VGA=&quot;</span></p>
<p class=a><a name=L599></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L599"><span
lang=EN-US>599</span></a><span lang=EN-US> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>下面是各种显示卡可使用的扩展模式个数和对应的模式号列表。其中每一行第<span
lang=EN-US>1</span>个字节是模式个</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>数值,随后的一些值是中断<span
lang=EN-US>0x10</span>功能<span lang=EN-US>0</span><span lang=EN-US>AH=0</span>)可使用的模式号。例如从<span
lang=EN-US>602</span>行可知,对于<span lang=EN-US>ATI</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>牌子的显示卡,除了标准模式以外还可使用两种扩展模式:<span
lang=EN-US>0x23</span><span lang=EN-US>0x33</span></p>
<p class=a><a name=L600></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L600"><span
lang=EN-US>600</span></a><span lang=EN-US> ! Manufacturer:&nbsp;&nbsp;
Numofmodes:&nbsp;&nbsp; Mode:</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>厂家:<span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;</span>模式数量:<span lang=EN-US>&nbsp;&nbsp;&nbsp; </span>模式列表:</p>
<p class=a><a name=L601></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L601"><span
lang=EN-US>601</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L602></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L602"><span
lang=EN-US>602</span></a><span lang=EN-US>
moati:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .byte&nbsp;&nbsp;
0x02,&nbsp;&nbsp; 0x23, 0x33 </span></p>
<p class=a><a name=L603></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L603"><span
lang=EN-US>603</span></a><span lang=EN-US>
moahead:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .byte&nbsp;&nbsp;
0x05,&nbsp;&nbsp; 0x22, 0x23, 0x24, 0x2f, 0x34</span></p>
<p class=a><a name=L604></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L604"><span
lang=EN-US>604</span></a><span lang=EN-US>
mocandt:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .byte&nbsp;&nbsp;
0x02,&nbsp;&nbsp; 0x60, 0x61</span></p>
<p class=a><a name=L605></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L605"><span
lang=EN-US>605</span></a><span lang=EN-US>
mocirrus:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .byte&nbsp;&nbsp;
0x04,&nbsp;&nbsp; 0x1f, 0x20, 0x22, 0x31</span></p>
<p class=a><a name=L606></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L606"><span
lang=EN-US>606</span></a><span lang=EN-US>
moeverex:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .byte&nbsp;&nbsp; 0x0a,&nbsp;&nbsp; 0x03, 0x04, 0x07, 0x08, 0x0a, 0x0b, 0x16, 0x18, 0x21, 0x40</span></p>
<p class=a><a name=L607></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L607"><span
lang=EN-US>607</span></a><span lang=EN-US>
mogenoa:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .byte&nbsp;&nbsp; 0x0a,&nbsp;&nbsp; 0x58, 0x5a, 0x60, 0x61, 0x62, 0x63, 0x64, 0x72, 0x74, 0x78</span></p>
<p class=a><a name=L608></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L608"><span
lang=EN-US>608</span></a><span lang=EN-US> moparadise:&nbsp;&nbsp;&nbsp;&nbsp;
.byte&nbsp;&nbsp; 0x02,&nbsp;&nbsp; 0x55, 0x54</span></p>
<p class=a><a name=L609></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L609"><span
lang=EN-US>609</span></a><span lang=EN-US>
motrident:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .byte&nbsp;&nbsp; 0x07,&nbsp;&nbsp;
0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a</span></p>
<p class=a><a name=L610></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L610"><span
lang=EN-US>610</span></a><span lang=EN-US>
motseng:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .byte&nbsp;&nbsp;
0x05,&nbsp;&nbsp; 0x26, 0x2a, 0x23, 0x24, 0x22</span></p>
<p class=a><a name=L611></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L611"><span
lang=EN-US>611</span></a><span lang=EN-US>
movideo7:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .byte&nbsp;&nbsp;
0x06,&nbsp;&nbsp; 0x40, 0x43, 0x44, 0x41, 0x42, 0x45</span></p>
<p class=a><a name=L612></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L612"><span
lang=EN-US>612</span></a><span lang=EN-US> </span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>下面是各种牌子<span
lang=EN-US>VGA</span>显示卡可使用的模式对应的列、行值列表。例如第<span lang=EN-US>615</span>行表示<span
lang=EN-US>ATI</span>显示卡两</p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; ! </span>种扩展模式的列、行值分别是 <span
lang=EN-US>132 x 25</span><span lang=EN-US>132 x 44</span></p>
<p class=a><a name=L613></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L613"><span
lang=EN-US>613</span></a><span lang=EN-US>
!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
msb = Cols &nbsp;&nbsp;lsb = Rows:</span></p>
<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;
!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>高字节<span lang=EN-US>=</span>列数<span lang=EN-US>&nbsp; </span>低字节<span
lang=EN-US>=</span>行数:</p>
<p class=a><a name=L614></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L614"><span
lang=EN-US>614</span></a><span lang=EN-US> </span></p>
<p class=a><a name=L615></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L615"><span
lang=EN-US>615</span></a><span lang=EN-US>
dscati:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .word&nbsp;&nbsp;
0x8419, 0x842c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!
ATI</span>卡可设置列、行值。</p>
<p class=a><a name=L616></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L616"><span
lang=EN-US>616</span></a><span lang=EN-US> dscahead:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x842c, 0x8419, 0x841c, 0xa032, 0x5042&nbsp;&nbsp; ! Ahead</span>卡可设置值。</p>
<p class=a><a name=L617></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L617"><span
lang=EN-US>617</span></a><span lang=EN-US>
dsccandt:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .word&nbsp;&nbsp; 0x8419, 0x8432</span></p>
<p class=a><a name=L618></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L618"><span
lang=EN-US>618</span></a><span lang=EN-US>
dsccirrus:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .word&nbsp;&nbsp; 0x8419, 0x842c, 0x841e, 0x6425</span></p>
<p class=a><a name=L619></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L619"><span
lang=EN-US>619</span></a><span lang=EN-US> dsceverex: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.word&nbsp;&nbsp;
0x5022, 0x503c, 0x642b, 0x644b, 0x8419, 0x842c, 0x501e, 0x641b, 0xa040, 0x841e</span></p>
<p class=a><a name=L620></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L620"><span
lang=EN-US>620</span></a><span lang=EN-US>
dscgenoa:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .word&nbsp;&nbsp; 0x5020, 0x642a, 0x8419, 0x841d, 0x8420, 0x842c, 0x843c, 0x503c, 0x5042, 0x644b</span></p>
<p class=a><a name=L621></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L621"><span
lang=EN-US>621</span></a><span lang=EN-US> dscparadise:&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x8419, 0x842b</span></p>
<p class=a><a name=L622></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L622"><span
lang=EN-US>622</span></a><span lang=EN-US> dsctrident:&nbsp;&nbsp;&nbsp;&nbsp;
.word&nbsp;&nbsp; 0x501e, 0x502b, 0x503c, 0x8419, 0x841e, 0x842b, 0x843c</span></p>
<p class=a><a name=L623></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L623"><span
lang=EN-US>623</span></a><span lang=EN-US>
dsctseng:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .word&nbsp;&nbsp; 0x503c, 0x6428, 0x8419, 0x841c, 0x842c</span></p>
<p class=a><a name=L624></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L624"><span
lang=EN-US>624</span></a><span lang=EN-US>
dscvideo7:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .word&nbsp;&nbsp; 0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c</span></p>
<p class=a><a name=L625></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L625"><span
lang=EN-US>625</span></a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></p>
<p class=a><a name=L626></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L626"><span
lang=EN-US>626</span></a><span lang=EN-US> .text</span></p>
<p class=a><a name=L627></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L627"><span
lang=EN-US>627</span></a><span lang=EN-US> endtext:</span></p>
<p class=a><a name=L628></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L628"><span
lang=EN-US>628</span></a><span lang=EN-US> .data</span></p>
<p class=a><a name=L629></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L629"><span
lang=EN-US>629</span></a><span lang=EN-US> enddata:</span></p>
<p class=a><a name=L630></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L630"><span
lang=EN-US>630</span></a><span lang=EN-US> .bss</span></p>
<p class=a><a name=L631></a><a
href="http://plinux.org/lxr/http/source/boot/setup.S?v=0.12#L631"><span
lang=EN-US>631</span></a><span lang=EN-US> endbss:</span></p>
<div class=a align=center style='text-align:center'><span lang=EN-US>
<hr size=4 width="100%" align=center>
</span></div>
<p class=MsoNormal><span lang=EN-US>&nbsp;</span></p>
</div>
</body>
</html>