mirror of
https://github.com/ctm/executor.git
synced 2024-11-27 01:49:33 +00:00
1 line
200 KiB
HTML
1 line
200 KiB
HTML
<html xmlns:o="urn:schemas-microsoft-com:office:office"
|
|
xmlns:w="urn:schemas-microsoft-com:office:word"
|
|
xmlns="http://www.w3.org/TR/REC-html40">
|
|
|
|
<head>
|
|
<meta name=Title content="Executor Internals">
|
|
<meta name=Keywords content="">
|
|
<meta http-equiv=Content-Type content="text/html; charset=macintosh">
|
|
<meta name=ProgId content=Word.Document>
|
|
<meta name=Generator content="Microsoft Word 9">
|
|
<meta name=Originator content="Microsoft Word 9">
|
|
<link rel=File-List href="MacHack_96_files/filelist.xml">
|
|
<title>Executor Internals</title>
|
|
<!--[if gte mso 9]><xml>
|
|
<o:DocumentProperties>
|
|
<o:Subject>How to efficiently run Mac Programs on PCs</o:Subject>
|
|
<o:Author>ctm + mat</o:Author>
|
|
<o:Template>Normal</o:Template>
|
|
<o:LastAuthor>ctm</o:LastAuthor>
|
|
<o:Revision>2</o:Revision>
|
|
<o:TotalTime>1</o:TotalTime>
|
|
<o:Created>2002-02-27T23:21:00Z</o:Created>
|
|
<o:LastSaved>2002-02-27T23:21:00Z</o:LastSaved>
|
|
<o:Pages>3</o:Pages>
|
|
<o:Words>7412</o:Words>
|
|
<o:Characters>42250</o:Characters>
|
|
<o:Company>ardi</o:Company>
|
|
<o:Lines>352</o:Lines>
|
|
<o:Paragraphs>84</o:Paragraphs>
|
|
<o:CharactersWithSpaces>51885</o:CharactersWithSpaces>
|
|
<o:Version>9.2511</o:Version>
|
|
</o:DocumentProperties>
|
|
<o:OfficeDocumentSettings>
|
|
<o:PixelsPerInch>800x600</o:PixelsPerInch>
|
|
</o:OfficeDocumentSettings>
|
|
</xml><![endif]--><!--[if gte mso 9]><xml>
|
|
<w:WordDocument>
|
|
<w:PrintFractionalCharacterWidth/>
|
|
<w:HyphenationZone>0</w:HyphenationZone>
|
|
<w:DoNotHyphenateCaps/>
|
|
<w:DrawingGridHorizontalSpacing>6 pt</w:DrawingGridHorizontalSpacing>
|
|
<w:DrawingGridVerticalSpacing>6 pt</w:DrawingGridVerticalSpacing>
|
|
<w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery>
|
|
<w:DisplayVerticalDrawingGridEvery>0</w:DisplayVerticalDrawingGridEvery>
|
|
<w:UseMarginsForDrawingGridOrigin/>
|
|
<w:DoNotShadeFormData/>
|
|
<w:Compatibility>
|
|
<w:OrigWordTableRules/>
|
|
<w:NoLeading/>
|
|
<w:SpaceForUL/>
|
|
<w:BalanceSingleByteDoubleByteWidth/>
|
|
<w:DoNotLeaveBackslashAlone/>
|
|
<w:ULTrailSpace/>
|
|
<w:DoNotExpandShiftReturn/>
|
|
<w:SpacingInWholePoints/>
|
|
<w:ShowBreaksInFrames/>
|
|
<w:SuppressTopSpacing/>
|
|
<w:SuppressTopSpacingMac5/>
|
|
<w:MWSmallCaps/>
|
|
<w:UsePrinterMetrics/>
|
|
<w:WW6BorderRules/>
|
|
<w:FootnoteLayoutLikeWW8/>
|
|
<w:ShapeLayoutLikeWW8/>
|
|
<w:AlignTablesRowByRow/>
|
|
<w:ForgetLastTabAlignment/>
|
|
<w:DoNotUseHTMLParagraphAutoSpacing/>
|
|
<w:LayoutRawTableWidth/>
|
|
<w:LayoutTableRowsApart/>
|
|
<w:UseWord97LineBreakingRules/>
|
|
</w:Compatibility>
|
|
</w:WordDocument>
|
|
</xml><![endif]-->
|
|
<style>
|
|
<!--
|
|
/* Font Definitions */
|
|
@font-face
|
|
{font-family:"Times New Roman";
|
|
panose-1:0 2 2 6 3 5 4 5 2 3;
|
|
mso-font-charset:0;
|
|
mso-generic-font-family:auto;
|
|
mso-font-pitch:variable;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:Arial;
|
|
panose-1:0 2 11 6 4 2 2 2 2 2;
|
|
mso-font-charset:0;
|
|
mso-generic-font-family:auto;
|
|
mso-font-pitch:variable;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:"Courier New";
|
|
panose-1:0 2 7 3 9 2 2 5 2 4;
|
|
mso-font-charset:77;
|
|
mso-generic-font-family:modern;
|
|
mso-font-format:other;
|
|
mso-font-pitch:fixed;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:Geneva;
|
|
panose-1:0 2 11 5 3 3 4 4 4 2;
|
|
mso-font-charset:77;
|
|
mso-generic-font-family:swiss;
|
|
mso-font-format:other;
|
|
mso-font-pitch:variable;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:"Tms Rmn";
|
|
panose-1:0 0 0 0 0 0 0 0 0 0;
|
|
mso-font-charset:77;
|
|
mso-generic-font-family:roman;
|
|
mso-font-format:other;
|
|
mso-font-pitch:variable;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:Helv;
|
|
panose-1:0 0 0 0 0 0 0 0 0 0;
|
|
mso-font-charset:77;
|
|
mso-generic-font-family:swiss;
|
|
mso-font-format:other;
|
|
mso-font-pitch:variable;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:"MS Serif";
|
|
panose-1:0 0 0 0 0 0 0 0 0 0;
|
|
mso-font-charset:77;
|
|
mso-generic-font-family:roman;
|
|
mso-font-format:other;
|
|
mso-font-pitch:variable;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:"MS Sans Serif";
|
|
panose-1:0 0 0 0 0 0 0 0 0 0;
|
|
mso-font-charset:77;
|
|
mso-generic-font-family:swiss;
|
|
mso-font-format:other;
|
|
mso-font-pitch:variable;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:"New York";
|
|
panose-1:0 2 2 5 2 6 3 5 6 2;
|
|
mso-font-charset:77;
|
|
mso-generic-font-family:roman;
|
|
mso-font-format:other;
|
|
mso-font-pitch:variable;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:System;
|
|
panose-1:0 0 0 0 0 0 0 0 0 0;
|
|
mso-font-charset:77;
|
|
mso-generic-font-family:swiss;
|
|
mso-font-format:other;
|
|
mso-font-pitch:variable;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:Wingdings;
|
|
panose-1:0 5 2 1 2 1 8 4 8 7;
|
|
mso-font-charset:2;
|
|
mso-generic-font-family:auto;
|
|
mso-font-pitch:variable;
|
|
mso-font-signature:0 16 0 0 -2147483648 0;}
|
|
@font-face
|
|
{font-family:"FE Roman font face";
|
|
panose-1:0 0 0 0 0 0 0 0 0 0;
|
|
mso-font-charset:0;
|
|
mso-generic-font-family:roman;
|
|
mso-font-format:other;
|
|
mso-font-pitch:fixed;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:"FE Modern font face";
|
|
panose-1:0 0 0 0 0 0 0 0 0 0;
|
|
mso-font-charset:0;
|
|
mso-generic-font-family:modern;
|
|
mso-font-format:other;
|
|
mso-font-pitch:fixed;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:"FE Truetype Roman font face";
|
|
panose-1:0 0 0 0 0 0 0 0 0 0;
|
|
mso-font-charset:0;
|
|
mso-generic-font-family:roman;
|
|
mso-font-format:other;
|
|
mso-font-pitch:fixed;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:"FE Truetype Modern font face";
|
|
panose-1:0 0 0 0 0 0 0 0 0 0;
|
|
mso-font-charset:0;
|
|
mso-generic-font-family:modern;
|
|
mso-font-format:other;
|
|
mso-font-pitch:fixed;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:Century;
|
|
panose-1:0 0 0 0 0 0 0 0 0 0;
|
|
mso-font-charset:77;
|
|
mso-generic-font-family:roman;
|
|
mso-font-format:other;
|
|
mso-font-pitch:variable;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:Chicago;
|
|
panose-1:0 2 11 8 6 8 6 4 4 2;
|
|
mso-font-charset:0;
|
|
mso-generic-font-family:auto;
|
|
mso-font-pitch:variable;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:Monaco;
|
|
panose-1:0 2 0 5 0 0 0 0 0 0;
|
|
mso-font-charset:0;
|
|
mso-generic-font-family:auto;
|
|
mso-font-pitch:variable;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
@font-face
|
|
{font-family:Palatino;
|
|
panose-1:0 2 0 5 0 0 0 0 0 0;
|
|
mso-font-charset:0;
|
|
mso-generic-font-family:auto;
|
|
mso-font-pitch:variable;
|
|
mso-font-signature:50331648 0 0 0 1 0;}
|
|
/* Style Definitions */
|
|
p.MsoNormal, li.MsoNormal, div.MsoNormal
|
|
{mso-style-parent:"";
|
|
margin:0in;
|
|
margin-bottom:.0001pt;
|
|
mso-pagination:widow-orphan;
|
|
font-size:10.0pt;
|
|
font-family:Palatino;}
|
|
h1
|
|
{mso-style-next:Normal;
|
|
margin-top:12.0pt;
|
|
margin-right:0in;
|
|
margin-bottom:0in;
|
|
margin-left:0in;
|
|
margin-bottom:.0001pt;
|
|
mso-pagination:widow-orphan;
|
|
mso-outline-level:1;
|
|
font-size:12.0pt;
|
|
font-family:Helvetica;
|
|
mso-font-kerning:0pt;
|
|
text-decoration:underline;
|
|
text-underline:single;}
|
|
h2
|
|
{mso-style-next:Normal;
|
|
margin-top:6.0pt;
|
|
margin-right:0in;
|
|
margin-bottom:0in;
|
|
margin-left:0in;
|
|
margin-bottom:.0001pt;
|
|
mso-pagination:widow-orphan;
|
|
mso-outline-level:2;
|
|
font-size:12.0pt;
|
|
font-family:Helvetica;}
|
|
h3
|
|
{mso-style-next:Normal;
|
|
margin-top:6.0pt;
|
|
margin-right:0in;
|
|
margin-bottom:0in;
|
|
margin-left:.25in;
|
|
margin-bottom:.0001pt;
|
|
mso-pagination:widow-orphan;
|
|
mso-outline-level:3;
|
|
font-size:12.0pt;
|
|
font-family:Palatino;}
|
|
h4
|
|
{mso-style-next:Normal;
|
|
margin-top:0in;
|
|
margin-right:0in;
|
|
margin-bottom:0in;
|
|
margin-left:.25in;
|
|
margin-bottom:.0001pt;
|
|
mso-pagination:widow-orphan;
|
|
mso-outline-level:4;
|
|
font-size:12.0pt;
|
|
font-family:Palatino;
|
|
text-decoration:underline;
|
|
text-underline:single;
|
|
font-weight:normal;}
|
|
h5
|
|
{mso-style-next:Normal;
|
|
margin-top:0in;
|
|
margin-right:0in;
|
|
margin-bottom:0in;
|
|
margin-left:.5in;
|
|
margin-bottom:.0001pt;
|
|
mso-pagination:widow-orphan;
|
|
mso-outline-level:5;
|
|
font-size:10.0pt;
|
|
font-family:Palatino;}
|
|
h6
|
|
{mso-style-next:Normal;
|
|
margin-top:0in;
|
|
margin-right:0in;
|
|
margin-bottom:0in;
|
|
margin-left:.5in;
|
|
margin-bottom:.0001pt;
|
|
mso-pagination:widow-orphan;
|
|
mso-outline-level:6;
|
|
font-size:10.0pt;
|
|
font-family:Palatino;
|
|
text-decoration:underline;
|
|
text-underline:single;
|
|
font-weight:normal;}
|
|
p.MsoFootnoteText, li.MsoFootnoteText, div.MsoFootnoteText
|
|
{margin:0in;
|
|
margin-bottom:.0001pt;
|
|
mso-pagination:widow-orphan;
|
|
font-size:12.0pt;
|
|
font-family:Palatino;}
|
|
p.MsoFooter, li.MsoFooter, div.MsoFooter
|
|
{margin:0in;
|
|
margin-bottom:.0001pt;
|
|
mso-pagination:widow-orphan;
|
|
tab-stops:center 3.0in right 6.0in;
|
|
font-size:10.0pt;
|
|
font-family:Palatino;}
|
|
span.MsoFootnoteReference
|
|
{font-size:8.0pt;
|
|
mso-text-raise:3.0pt;}
|
|
span.MsoEndnoteReference
|
|
{vertical-align:super;}
|
|
/* Page Definitions */
|
|
@page
|
|
{mso-mirror-margins:yes;
|
|
mso-page-border-surround-header:no;
|
|
mso-page-border-surround-footer:no;}
|
|
@page Section1
|
|
{size:8.5in 11.0in;
|
|
margin:-1.0in .5in -1.0in .5in;
|
|
mso-header-margin:.5in;
|
|
mso-footer-margin:.5in;
|
|
mso-gutter-margin:.75in;
|
|
mso-footer:url(":MacHack_96_files:header.htm") f1;
|
|
mso-paper-source:0;}
|
|
div.Section1
|
|
{page:Section1;}
|
|
@page Section2
|
|
{size:8.5in 11.0in;
|
|
margin:-1.0in .5in -1.0in .5in;
|
|
mso-header-margin:.5in;
|
|
mso-footer-margin:.5in;
|
|
mso-gutter-margin:.75in;
|
|
mso-columns:2 even .5in;
|
|
mso-footer:url(":MacHack_96_files:header.htm") f1;
|
|
mso-paper-source:0;}
|
|
div.Section2
|
|
{page:Section2;}
|
|
@page Section3
|
|
{size:8.5in 11.0in;
|
|
margin:-1.0in .5in -1.0in .5in;
|
|
mso-header-margin:.5in;
|
|
mso-footer-margin:.5in;
|
|
mso-gutter-margin:.75in;
|
|
mso-footer:url(":MacHack_96_files:header.htm") f1;
|
|
mso-paper-source:0;}
|
|
div.Section3
|
|
{page:Section3;}
|
|
@page Section4
|
|
{size:8.5in 11.0in;
|
|
margin:-1.0in .5in -1.0in .5in;
|
|
mso-header-margin:.5in;
|
|
mso-footer-margin:.5in;
|
|
mso-gutter-margin:.75in;
|
|
mso-columns:2 even .5in;
|
|
mso-footer:url(":MacHack_96_files:header.htm") f1;
|
|
mso-paper-source:0;}
|
|
div.Section4
|
|
{page:Section4;}
|
|
@page Section5
|
|
{size:8.5in 11.0in;
|
|
margin:-1.0in .5in -1.0in .5in;
|
|
mso-header-margin:.5in;
|
|
mso-footer-margin:.5in;
|
|
mso-gutter-margin:.75in;
|
|
mso-footer:url(":MacHack_96_files:header.htm") f1;
|
|
mso-paper-source:0;}
|
|
div.Section5
|
|
{page:Section5;}
|
|
@page Section6
|
|
{size:8.5in 11.0in;
|
|
margin:-1.0in .5in -1.0in .5in;
|
|
mso-header-margin:.5in;
|
|
mso-footer-margin:.5in;
|
|
mso-gutter-margin:.75in;
|
|
mso-columns:2 even .5in;
|
|
mso-footer:url(":MacHack_96_files:header.htm") f1;
|
|
mso-paper-source:0;}
|
|
div.Section6
|
|
{page:Section6;}
|
|
@page Section7
|
|
{size:8.5in 11.0in;
|
|
margin:-1.0in .5in -1.0in .5in;
|
|
mso-header-margin:.5in;
|
|
mso-footer-margin:.5in;
|
|
mso-gutter-margin:.75in;
|
|
mso-footer:url(":MacHack_96_files:header.htm") f1;
|
|
mso-paper-source:0;}
|
|
div.Section7
|
|
{page:Section7;}
|
|
@page Section8
|
|
{size:8.5in 11.0in;
|
|
margin:-1.0in .5in -1.0in .5in;
|
|
mso-header-margin:.5in;
|
|
mso-footer-margin:.5in;
|
|
mso-gutter-margin:.75in;
|
|
mso-columns:2 even .5in;
|
|
mso-footer:url(":MacHack_96_files:header.htm") f1;
|
|
mso-paper-source:0;}
|
|
div.Section8
|
|
{page:Section8;}
|
|
@page Section9
|
|
{size:8.5in 11.0in;
|
|
margin:-1.0in .5in -1.0in .5in;
|
|
mso-header-margin:.5in;
|
|
mso-footer-margin:.5in;
|
|
mso-gutter-margin:.75in;
|
|
mso-footer:url(":MacHack_96_files:header.htm") f1;
|
|
mso-paper-source:0;}
|
|
div.Section9
|
|
{page:Section9;}
|
|
@page Section10
|
|
{size:8.5in 11.0in;
|
|
margin:-1.0in .5in -1.0in .5in;
|
|
mso-header-margin:.5in;
|
|
mso-footer-margin:.5in;
|
|
mso-gutter-margin:.75in;
|
|
mso-columns:2 even .5in;
|
|
mso-footer:url(":MacHack_96_files:header.htm") f1;
|
|
mso-paper-source:0;}
|
|
div.Section10
|
|
{page:Section10;}
|
|
@page Section11
|
|
{size:8.5in 11.0in;
|
|
margin:-1.0in .5in -1.0in .5in;
|
|
mso-header-margin:.5in;
|
|
mso-footer-margin:.5in;
|
|
mso-gutter-margin:.75in;
|
|
mso-footer:url(":MacHack_96_files:header.htm") f1;
|
|
mso-paper-source:0;}
|
|
div.Section11
|
|
{page:Section11;}
|
|
@page Section12
|
|
{size:8.5in 11.0in;
|
|
margin:-1.0in .5in -1.0in .5in;
|
|
mso-header-margin:.5in;
|
|
mso-footer-margin:.5in;
|
|
mso-gutter-margin:.75in;
|
|
mso-columns:2 even .5in;
|
|
mso-footer:url(":MacHack_96_files:header.htm") f1;
|
|
mso-paper-source:0;}
|
|
div.Section12
|
|
{page:Section12;}
|
|
@page Section13
|
|
{size:8.5in 11.0in;
|
|
margin:-1.0in .5in -1.0in .5in;
|
|
mso-header-margin:.5in;
|
|
mso-footer-margin:.5in;
|
|
mso-gutter-margin:.75in;
|
|
mso-footer:url(":MacHack_96_files:header.htm") f1;
|
|
mso-paper-source:0;}
|
|
div.Section13
|
|
{page:Section13;}
|
|
@page Section14
|
|
{size:8.5in 11.0in;
|
|
margin:-1.0in .5in -1.0in .5in;
|
|
mso-header-margin:.5in;
|
|
mso-footer-margin:.5in;
|
|
mso-gutter-margin:.75in;
|
|
mso-columns:2 even .5in;
|
|
mso-footer:url(":MacHack_96_files:header.htm") f1;
|
|
mso-paper-source:0;}
|
|
div.Section14
|
|
{page:Section14;}
|
|
@page Section15
|
|
{size:8.5in 11.0in;
|
|
margin:-1.0in .5in -1.0in .5in;
|
|
mso-header-margin:.5in;
|
|
mso-footer-margin:.5in;
|
|
mso-gutter-margin:.75in;
|
|
mso-footer:url(":MacHack_96_files:header.htm") f1;
|
|
mso-paper-source:0;}
|
|
div.Section15
|
|
{page:Section15;}
|
|
-->
|
|
</style>
|
|
</head>
|
|
|
|
<body bgcolor=white lang=EN-US style='tab-interval:.5in'>
|
|
|
|
<div class=Section1>
|
|
|
|
<p class=MsoNormal align=center style='text-align:center'><span
|
|
style='font-size:18.0pt'>Executor Internals:<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal align=center style='text-align:center'><span
|
|
style='font-size:18.0pt'>How to Efficiently Run Mac Programs on PCs<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal align=center style='text-align:center'><span
|
|
style='font-size:18.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal align=center style='text-align:center'><span
|
|
style='font-size:12.0pt'>Mathew J. Hostetter </span><span style='font-size:
|
|
12.0pt;font-family:Courier'><mat@ardi.com></span><span style='font-size:
|
|
12.0pt'><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal align=center style='text-align:center'><span
|
|
style='font-size:12.0pt'>Clifford T. Matthews </span><span style='font-size:
|
|
12.0pt;font-family:Courier'><ctm@ardi.com><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal align=center style='text-align:center'><span
|
|
style='font-size:9.0pt'>After MacHack '96, this paper will be available from</span><span
|
|
style='font-size:9.0pt;font-family:Courier'> http://www.ardi.com</span><span
|
|
style='font-size:9.0pt'><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal align=center style='text-align:center'><span
|
|
style='font-size:12.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal>Executor is a commercial Macintosh emulator that uses no
|
|
software from Apple, but is still able to run much 680x0 based Macintosh
|
|
software faster on Pentiums than the same software runs on 680x0 based
|
|
Macs.<span style="mso-spacerun: yes"> </span>This paper contains some
|
|
implementation details, including descriptions of Executor's synthetic CPU,
|
|
graphics subsystem and debugging environment.<span style="mso-spacerun:
|
|
yes"> </span>Portability issues, current limitations and future plans are
|
|
also presented.<span style='font-size:18.0pt'><o:p></o:p></span></p>
|
|
|
|
</div>
|
|
|
|
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
|
|
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
|
|
</span>
|
|
|
|
<div class=Section2>
|
|
|
|
<h1>Executor Overview</h1>
|
|
|
|
<h2>What Executor is</h2>
|
|
|
|
<p class=MsoNormal>Executor is a commercial emulator that allows PCs to run
|
|
many Macintosh applications.<span style="mso-spacerun: yes">
|
|
</span>Executor does not require Macintosh ROMs or a Macintosh System file and
|
|
contains no Appple code itself.<span style="mso-spacerun: yes">
|
|
</span>Executor was written entiredly by engineers without Macintosh
|
|
backgrounds who have not disassembled any of Apple's ROMs or System file.</p>
|
|
|
|
<h2>Limitations</h2>
|
|
|
|
<p class=MsoNormal>Because Executor was written strictly from publicly
|
|
available documentation (Inside Macintosh, Tech. Notes, etc.), programs which
|
|
make use of undocumented features of MacOS may fail under Executor.<span
|
|
style="mso-spacerun: yes"> </span>Furthermore,<span style="mso-spacerun:
|
|
yes"> </span>there are some portions of MacOS that we haven't implemented
|
|
yet.<span style="mso-spacerun: yes"> </span>Executor is sufficiently
|
|
large that there are probably bugs in some of our code as well.<span
|
|
style="mso-spacerun: yes"> </span>We realize these are major limitations,
|
|
but this paper is primarily concerned with implementation details that are
|
|
interesting to our fellow programmers as opposed to feature sets and limitations
|
|
which are of more concern to end users and our marketing department.</p>
|
|
|
|
<h1>Design Goals</h1>
|
|
|
|
<p class=MsoNormal>Our goal is for Executor to be accurate, fast and
|
|
portable.<span style="mso-spacerun: yes"> </span>Beyond that,
|
|
completeness is a secondary issue.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Accuracy means that each subsystem that we implement should
|
|
behave exactly according to the functional specs for the subsystem that we've
|
|
derived from a combination of reading documentation, writing test cases and
|
|
running programs under Executor.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Fast is harder to qualify.<span style="mso-spacerun:
|
|
yes"> </span>As programmers we like to use advanced techniques that will
|
|
result in programs running under Executor as quickly as possible.<span
|
|
style="mso-spacerun: yes"> </span>Unfortunately, we have a limited number
|
|
of engineer hours in a week and most engineering time is spent implementing new
|
|
subsystems or finding and fixing subtle incompatibilities.<span
|
|
style="mso-spacerun: yes"> </span>We're proud of the speed that we've
|
|
obtained so far, but we know that we can do better in the future.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Portability is the ability to support multiple platforms
|
|
from the same source base.<span style="mso-spacerun: yes"> </span>A
|
|
platform is a combination of CPU, operating system and graphics device or
|
|
windowing system.<span style="mso-spacerun: yes"> </span>Executor
|
|
currently supports Intel 80[3456]86 and compatible CPUs, Motorola m680[34]0
|
|
CPUs, the operating systems DOS, Linux and NEXTSTEP and can interact with VGA,
|
|
SVGA,<span style="mso-spacerun: yes"> </span>Display PostScript and
|
|
X-Windows.<span style="mso-spacerun: yes"> </span>To get the best
|
|
performance on some architectures we do use architecture specific code,
|
|
but<span style="mso-spacerun: yes"> </span>we also write portable
|
|
versions to be used where the platform specific versions can't be.<span
|
|
style="mso-spacerun: yes"> </span>Although not supported as a product,
|
|
Executor was ported to DEC's Alpha, but since ARDI has no Alpha and DEC lost
|
|
interest, the Alpha port is no longer current.<span style="mso-spacerun:
|
|
yes"> </span>Although not recently, ROMlib, ARDI's rewrite of the MacOS
|
|
OS and Toolbox routines, has been ported to a wide variety of platforms,
|
|
including MIPS , m88k , Clipper, IBM RT, SPARC and even VAX based systems.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Those three design goals have led us in the direction of
|
|
dynamic code generation for both the 680x0 emulation and for our blitter.<span
|
|
style="mso-spacerun: yes"> </span>In both cases we use high level
|
|
descriptions of what we want accomplished and then use special purpose tools at
|
|
compile time to translate these high level descriptions into constructs that we
|
|
can then use at run time.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>High level descriptions are less error prone, allowing us to
|
|
document the semantics that we wish to see in our synthetic CPU or blitter
|
|
using a special purpose language that is directly suited to the task at hand,
|
|
rather than a general purpose language like C or the traditional language of
|
|
speed freaks -- assembler.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>High level descriptions also lend themselves to
|
|
portability.<span style="mso-spacerun: yes"> </span>We have our tools
|
|
generate portable constructs for the general case and, with a little more
|
|
programming effort, faster architecture specific constructs for the architectures
|
|
that we consider most important.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Since the conversion from high level description to useful
|
|
construct takes place at compile time, there is no need to worry about the CPU
|
|
cycles spent doing the mapping.<span style="mso-spacerun: yes">
|
|
</span>This allows us to design our code by thinking:<span style="mso-spacerun:
|
|
yes"> </span>"At <i>runtime</i><span style='font-style:normal'>,
|
|
what would be the optimal instruction sequence to perform a specific
|
|
task?"<span style="mso-spacerun: yes"> </span>Once we know the
|
|
answer to that question we can ask:<span style="mso-spacerun: yes">
|
|
</span>"How can we represent at a high level, the task is being
|
|
accomplished by that optimal set of instructions?". <span
|
|
style="mso-spacerun: yes"> </span>Then, the final question is "Given
|
|
what we want to generate and how we want to represent it, what does the compile
|
|
time mapping look like?".<span style="mso-spacerun: yes">
|
|
</span>The entire time we're pondering those three questions, we're keeping
|
|
accuracy, portability and efficiency in mind.</span></p>
|
|
|
|
<h1>Executor Subsystems</h1>
|
|
|
|
<h2>Synthetic CPU</h2>
|
|
|
|
<h3>Overview</h3>
|
|
|
|
<p class=MsoNormal>Syn68k is the name of the synthetic CPU that Executor 2
|
|
uses.<span style="mso-spacerun: yes"> </span>Syn68k is both highly
|
|
portable and fast.<span style="mso-spacerun: yes"> </span>The portable
|
|
core of Syn68k, which works by dynamically compiling 680x0 code into an
|
|
efficient interpreted form, was designed to run on all major CPU's.<span
|
|
style="mso-spacerun: yes"> </span>On supported architectures, Syn68k can
|
|
also translate 680x0 code into native code that the host processor can run
|
|
directly.</p>
|
|
|
|
<h3>Syngen</h3>
|
|
|
|
<p class=MsoNormal>Syngen analyzes a lisp-like file describing the bit patterns
|
|
and semantics of the 680x0 instruction set and produces lookup tables and C code
|
|
for the runtime system to use.<span style="mso-spacerun: yes"> </span>The
|
|
code and tables generated by syngen depend somewhat on the characteristics of
|
|
the host processor; for example, on a little endian machine it is advantageous
|
|
to byte swap some extracted 680x0 operands at translation time instead of at
|
|
runtime.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The 680x0 description file can describe multiple ways to
|
|
emulate any particular 680x0 opcode.<span style="mso-spacerun: yes">
|
|
</span>The runtime system looks at what CC bits are live after the instruction
|
|
and chooses the fastest variant it can legally use.<span style="mso-spacerun:
|
|
yes"> </span>In Figure 1, we have two CC variants of lsrw; one computes
|
|
no CC bits, and the other computes all of them.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The 680x0 description file can also specify which 680x0
|
|
operands should be "expanded" to become implicitly known by the
|
|
corresponding synthetic opcode.<span style="mso-spacerun: yes">
|
|
</span>For example, fully expanding out "addl dx,dy" would result in
|
|
64 synthetic opcodes, one </p>
|
|
|
|
<p class=MsoNormal>for each combination of data register operands.<span
|
|
style="mso-spacerun: yes"> </span>This results in smaller and faster
|
|
synthetic opcodes at the expense of increasing the total number of synthetic
|
|
opcodes.<span style="mso-spacerun: yes"> </span>To conserve space, we
|
|
only "expand out " common 680x0 opcodes. On host architectures where
|
|
we can compile to native code, we don't waste space by "expanding
|
|
out" common synthetic opcodes.</p>
|
|
|
|
<h3>Interpreted Code</h3>
|
|
|
|
<p class=MsoNormal>Our interpreted code consists of contiguous sequences of
|
|
"synthetic opcodes" and their operands.<span style="mso-spacerun:
|
|
yes"> </span>Syngen can generate ANSI C, but when </p>
|
|
|
|
</div>
|
|
|
|
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
|
|
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
|
|
</span>
|
|
|
|
<div class=Section3>
|
|
|
|
<div style='mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-element-top:bottom;mso-height-rule:exactly'>
|
|
|
|
<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=center>
|
|
<tr>
|
|
<td valign=top align=left style='padding-top:9.0pt;padding-right:9.0pt;
|
|
padding-bottom:9.0pt;padding-left:9.0pt'>
|
|
<div style='border:solid windowtext .75pt;padding:0in 0in 0in 0in;background:
|
|
#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>(defopcode lsrw_ea<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun: yes">
|
|
</span>(list 68000 amode_alterable_memory () (list
|
|
"1110001011mmmmmm"))<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun: yes">
|
|
</span>(list "-----" "-----" dont_expand<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>(assign
|
|
$1.muw (>> $1.muw 1)))<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun: yes">
|
|
</span>(list "CN0XZ" "-----" dont_expand<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>(list<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span><span
|
|
style="mso-spacerun: yes"> </span>(assign ccx (assign ccc (& $1.muw
|
|
1)))<o:p></o:p></span></p>
|
|
<p class=MsoNormal align=center style='text-align:center;border:none;
|
|
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
|
|
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span><span
|
|
style="mso-spacerun: yes"> </span>(ASSIGN_NNZ_WORD (assign $1.muw
|
|
(>> $1.muw 1))))))<o:p></o:p></span></p>
|
|
<p class=MsoNormal align=center style='text-align:center;border:none;
|
|
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
|
|
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><![if !supportEmptyParas]> <![endif]><o:p></o:p></span></p>
|
|
<p class=MsoNormal align=center style='text-align:center;border:none;
|
|
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
|
|
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-size:12.0pt'>Figure 1.<span style="mso-spacerun: yes">
|
|
</span>Syn68k description of lsrw</span><span style='font-family:Courier'><o:p></o:p></span></p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
|
|
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
|
|
</span>
|
|
|
|
<div class=Section4>
|
|
|
|
<p class=MsoNormal>compiled with GCC it uses C language extensions that make
|
|
synthetic opcodes be pointers to the C code responsible for interpreting that
|
|
opcode.<span style="mso-spacerun: yes"> </span>This "threaded
|
|
interpreting" entirely eliminates switch dispatch and loop overhead.</p>
|
|
|
|
<h3>Native Code</h3>
|
|
|
|
<p class=MsoNormal>For the 80x86 architecture, Syn68k supports an optional
|
|
architecture-specific native code extension that tries to generate native code
|
|
whenever possible.<span style="mso-spacerun: yes"> </span>In those rare
|
|
cases when it cannot, it reverts to our interpreted code.<span
|
|
style="mso-spacerun: yes"> </span>Since Syn68k supports both native and
|
|
synthetic code, the runtime system automatically inserts gateways between the
|
|
two whenever there is a transition. </p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Three major problems make translating 680x0 code to 80x86
|
|
code difficult:</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>• The
|
|
80x86 has only 8 registers, while the 680x0 has 16.</p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>• The
|
|
80x86 is little endian, while the 680x0 is big endian.</p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>• The
|
|
80x86 does not have general-purpose postincrement and predecrement<span
|
|
style="mso-spacerun: yes"> </span>operators, which are used frequently in
|
|
680x0 code.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>On the other hand, several factors make the job easier than
|
|
it would be for RISC machines:</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>• The
|
|
80x86 has all of the CISC addressing modes commonly used in 680x0 code.</p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>• The
|
|
80x86 has CC bits that map directly to their 680x0 counterparts (except for the
|
|
680x0's X bit).</p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>• The
|
|
80x86 supports 8-, 16- and 32-bit operations, (although it can only support 8
|
|
bit operations on four of its registers).</p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>• The
|
|
80x86 and 680x0 have analogous conditional branch instructions.</p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>• The
|
|
80x86 allows unaligned memory accesses without substantial overhead.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The toughest problem is the lack of registers.<span
|
|
style="mso-spacerun: yes"> </span>On 32-register RISC architectures it's
|
|
easy to allocate one RISC register for each 680x0 register, but on the 80x86 a
|
|
different approach is needed. The obvious solution is to perform full-blown
|
|
inter-block register allocation, but we fear that using traditional compiler
|
|
techniques would be unacceptably slow.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>For now, we have adopted a simple constraint: between basic
|
|
blocks, all registers and live CC bits must reside in their canonical home in
|
|
memory.<span style="mso-spacerun: yes"> </span>Within a block, anything
|
|
goes.<span style="mso-spacerun: yes"> </span>So what liberties does Syn68k
|
|
take within a block?</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The 80x86 register set is treated as a cache for recently
|
|
used 680x0 registers, and the 80x86 CC bits are used as a cache for the 680x0
|
|
CC bits.<span style="mso-spacerun: yes"> </span>At any particular point
|
|
within a block, each 680x0 register is either sitting in its memory home or is
|
|
cached in an 80x86 register, and each live 680x0 CC bit is either cached in its
|
|
80x86 equivalent or stored in its memory home.<span style="mso-spacerun:
|
|
yes"> </span>Cached registers may be in canonical form, may be byte
|
|
swapped, may have only their low two bytes swapped, or may be offset by a known
|
|
constant from their actual value.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Each 680x0 instruction can require that 680x0 registers be
|
|
cached in particular ways.<span style="mso-spacerun: yes"> </span>For
|
|
example, <span style='font-family:Courier'>movel d0, mem</span> requires d0 to
|
|
be cached in big endian byte order.<span style="mso-spacerun: yes">
|
|
</span>The compilation engine generates the minimal code needed to satisfy
|
|
those constraints and then calls a sequence of routines to generate the native
|
|
code.<span style="mso-spacerun: yes"> </span>As each 680x0 instruction is
|
|
processed, each 680x0 register's cache status is updated.<span
|
|
style="mso-spacerun: yes"> </span>Dirty registers are canonicalized and
|
|
spilled back to memory at the end of each block (or when we run out of 80x86
|
|
registers and we need to make room).</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>We allow 680x0 registers to be cached with varying byte
|
|
orders and offsets so that we can perform the optimizations of lazy byte
|
|
swapping and lazy constant offsetting.<span style="mso-spacerun: yes">
|
|
</span>If the 680x0 program loads a register from memory and then ends up
|
|
writing it out later, we avoid unnecessary byte swaps by not canonicalizing the
|
|
value immediately.<span style="mso-spacerun: yes"> </span>Lazy constant
|
|
offsetting mitigates </p>
|
|
|
|
</div>
|
|
|
|
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
|
|
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
|
|
</span>
|
|
|
|
<div class=Section5>
|
|
|
|
<div style='mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-element-top:top;mso-height-rule:exactly'>
|
|
|
|
<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=center>
|
|
<tr>
|
|
<td valign=top align=left style='padding-top:9.0pt;padding-right:9.0pt;
|
|
padding-bottom:9.0pt;padding-left:9.0pt'>
|
|
<div style='border:solid windowtext .75pt;padding:0in 0in 0in 0in;background:
|
|
#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>pea<span
|
|
style='mso-tab-count:2'> </span>0x1<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>pea<span
|
|
style='mso-tab-count:2'> </span>0x2<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>pea<span
|
|
style='mso-tab-count:2'> </span>0x3<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>pea<span
|
|
style='mso-tab-count:2'> </span>0x4<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='mso-tab-count:1'> </span>...</p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'>becomes
|
|
this 80x86 code:</p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>_a7,%edi<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>$0x01000000,-4(%edi)<span
|
|
style='mso-tab-count:1'> </span>; "push"
|
|
big-endian constant<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>$0x02000000,-8(%edi)<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>$0x03000000,-12(%edi)<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>$0x04000000,-16(%edi)<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>...
|
|
<more uses of a7 may follow, and they'll use %edi><o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>subl<span
|
|
style='mso-tab-count:1'> </span>$16,%edi<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>$edi,_a7<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='mso-tab-count:1'> </span>...</p>
|
|
<p class=MsoNormal align=center style='text-align:center;border:none;
|
|
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
|
|
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-element-top:top;mso-height-rule:exactly'><span style='font-size:
|
|
12.0pt'>Figure 2.<span style="mso-spacerun: yes"> </span>Lazy Constant
|
|
Offsetting<o:p></o:p></span></p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
|
|
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
|
|
</span>
|
|
|
|
<div class=Section6>
|
|
|
|
<p class=MsoNormal>the overhead of postincrement and predecrement side
|
|
effects.<span style="mso-spacerun: yes"> </span>Figure 2 is an example of
|
|
lazy constant offsetting.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>As mentioned above, we use the 80x86 condition code bits as
|
|
a cache for the real 680x0 CC bits.<span style="mso-spacerun: yes">
|
|
</span>Although live cached CC bits are occasionally spilled back to memory
|
|
because some 80x86 instruction is about to clobber them, this trick almost
|
|
always works.<span style="mso-spacerun: yes"> </span>Using 80x86 CC bits,
|
|
we can frequently get away with extremely concise code sequences; for example,
|
|
a 680x0 compare and conditional branch becomes an 80x86 compare and conditional
|
|
branch.</p>
|
|
|
|
<h3>Self-modifying Code</h3>
|
|
|
|
<p class=MsoNormal>Like most dynamically compiling emulators, Syn68k doesn't
|
|
detect self-modifying code; the overhead is too high.<span style="mso-spacerun:
|
|
yes"> </span>Fortunately, self-modifying programs don't work on the real
|
|
68040 either.<span style="mso-spacerun: yes"> </span>We rely on the
|
|
program making explicit system calls to flush the caches whenever 680x0 code
|
|
may have been modified or created.<span style="mso-spacerun: yes">
|
|
</span>Some programs (like HyperCard) flush the caches very often, which can
|
|
cause real performance headaches if code is continuously recompiled.<span
|
|
style="mso-spacerun: yes"> </span>We have solved this problem by
|
|
checksumming 680x0 blocks as they are compiled and only decompiling blocks
|
|
which fail their checksums.<span style="mso-spacerun: yes"> </span>This
|
|
optimization alone sped up some HyperCard stacks by a factor of three or so.</p>
|
|
|
|
<h3>Examples</h3>
|
|
|
|
<p class=MsoNormal>Figure 3 contains two sample 680x0 code sequences from real
|
|
applications, and the 80x86 code that Syn68k generates for them.<span
|
|
style="mso-spacerun: yes"> </span>We chose these code sequences
|
|
specifically to showcase several of the techniques we use, so you shouldn't use
|
|
them as a substitute for benchmarks. Not all 680x0 code translates as well as
|
|
these examples do, but these examples are far from exotic.</p>
|
|
|
|
</div>
|
|
|
|
<span style='font-size:12.0pt;font-family:Helvetica;mso-ansi-language:EN-US'><b><br
|
|
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
|
|
</b></span>
|
|
|
|
<div class=Section7>
|
|
|
|
<div style='mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-height-rule:exactly'>
|
|
|
|
<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=center>
|
|
<tr>
|
|
<td valign=top align=left style='padding-top:9.0pt;padding-right:9.0pt;
|
|
padding-bottom:9.0pt;padding-left:9.0pt'>
|
|
<div style='border:solid windowtext .75pt;padding:0in 0in 0in 0in;background:
|
|
#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'>Example 1 (Solarian):</p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'>680x0 code:</p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>addqb<span
|
|
style='mso-tab-count:1'> </span>#1,a4@(1)<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movel<span
|
|
style='mso-tab-count:1'> </span>#0,d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>moveb<span
|
|
style='mso-tab-count:1'> </span>a4@,d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>swap<span
|
|
style='mso-tab-count:1'> </span>d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>clrw<span
|
|
style='mso-tab-count:1'> </span>d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>swap<span
|
|
style='mso-tab-count:1'> </span>d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>asll<span
|
|
style='mso-tab-count:1'> </span>#2,d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>lea<span
|
|
style='mso-tab-count:1'> </span>a5@(-13462),a0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>addal<span
|
|
style='mso-tab-count:1'> </span>d0,a0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>moveal<span
|
|
style='mso-tab-count:1'> </span>a0@,a0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movel<span
|
|
style='mso-tab-count:1'> </span>#0,d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>moveb<span
|
|
style='mso-tab-count:1'> </span>a4@(1),d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>cmpw<span
|
|
style='mso-tab-count:1'> </span>a0@,d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>bcs<span
|
|
style='mso-tab-count:1'> </span>0x3fffee2</span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'>80x86 code:</p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>_a4,%edi<span style='mso-tab-count:
|
|
2'> </span>; addqb
|
|
#1,a4@(1)<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>addb<span
|
|
style='mso-tab-count:1'> </span>$0x1,0x1(%edi)<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>xorl<span
|
|
style='mso-tab-count:1'> </span>%ebx,%ebx<span style='mso-tab-count:
|
|
2'> </span>; movel #0,d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movb<span
|
|
style='mso-tab-count:1'> </span>(%edi),%bl<span style='mso-tab-count:
|
|
2'> </span>; moveb a4@,d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>rorl<span
|
|
style='mso-tab-count:1'> </span>$0x10,%ebx<span style='mso-tab-count:
|
|
2'> </span>; swap d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>xorw<span
|
|
style='mso-tab-count:1'> </span>%bx,%bx<span style='mso-tab-count:2'> </span>;
|
|
clrw d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>rorl<span
|
|
style='mso-tab-count:1'> </span>$0x10,%ebx<span style='mso-tab-count:
|
|
2'> </span>; swap d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>shll<span
|
|
style='mso-tab-count:1'> </span>$0x2,%ebx<span style='mso-tab-count:
|
|
2'> </span>; asll #2,d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>_a5,%esi<span style='mso-tab-count:
|
|
2'> </span>; lea
|
|
a5@(-13462),a0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>leal<span
|
|
style='mso-tab-count:1'> </span>0xffffcb6a(%esi),%edx<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>addl<span
|
|
style='mso-tab-count:1'> </span>%ebx,%edx<span style='mso-tab-count:
|
|
2'> </span>; addal d0,a0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>(%edx),%edx<span style='mso-tab-count:
|
|
2'> </span>; moveal a0@,a0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>xorl<span
|
|
style='mso-tab-count:1'> </span>%ebx,%ebx<span style='mso-tab-count:
|
|
2'> </span>; movel #0,d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movb<span
|
|
style='mso-tab-count:1'> </span>0x1(%edi),%bl<span style='mso-tab-count:
|
|
1'> </span>; moveb a4@(1),d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>bswap<span
|
|
style='mso-tab-count:1'> </span>%edx<span style='mso-tab-count:3'> </span>;
|
|
cmpw a0@,d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movw<span
|
|
style='mso-tab-count:1'> </span>(%edx),%cx<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>rorw<span
|
|
style='mso-tab-count:1'> </span>$0x8,%cx<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>cmpw<span
|
|
style='mso-tab-count:1'> </span>%cx,%bx<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>%edx,_a0<span style='mso-tab-count:
|
|
2'> </span>; <spill
|
|
dirty 68k<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>%ebx,_d0<span style='mso-tab-count:
|
|
2'> </span>;<span
|
|
style="mso-spacerun: yes"> </span>registers back to memory><o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>jb<span
|
|
style='mso-tab-count:1'> </span>0x6fae0c<span
|
|
style='mso-tab-count:2'> </span>;
|
|
bcs 0x3fffee2<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>jmp<span
|
|
style='mso-tab-count:1'> </span>0x6faf0c<span style='mso-tab-count:
|
|
2'> </span>; <go to
|
|
"fall through" code></span></p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
</div>
|
|
|
|
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
|
|
clear=ALL style='page-break-before:always'>
|
|
</span>
|
|
|
|
<div style='mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-element-top:top;mso-height-rule:exactly'>
|
|
|
|
<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=center>
|
|
<tr>
|
|
<td valign=top align=left style='padding-top:9.0pt;padding-right:9.0pt;
|
|
padding-bottom:9.0pt;padding-left:9.0pt'>
|
|
<div style='border:solid windowtext .75pt;padding:0in 0in 0in 0in;background:
|
|
#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'>Example
|
|
2 (PageMaker):</p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'>680x0
|
|
code:</p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movel<span
|
|
style='mso-tab-count:1'> </span>#0,d2<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>moveb<span
|
|
style='mso-tab-count:1'> </span>d0,d2<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>lslw<span
|
|
style='mso-tab-count:1'> </span>#8,d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>orw<span
|
|
style='mso-tab-count:1'> </span>d0,d2<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movel<span
|
|
style='mso-tab-count:1'> </span>d2,d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>swap<span
|
|
style='mso-tab-count:1'> </span>d2<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>orl<span
|
|
style='mso-tab-count:1'> </span>d2,d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movel<span
|
|
style='mso-tab-count:1'> </span>a0,d2<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>lsrb<span
|
|
style='mso-tab-count:1'> </span>#1,d2<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>bcc<span
|
|
style='mso-tab-count:1'> </span>0x3fffed4</span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'>80x86
|
|
code:</p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>xorl<span
|
|
style='mso-tab-count:1'> </span>%ebx,%ebx<span style='mso-tab-count:
|
|
2'> </span>; movel #0,d2<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>_d0,%edx<span style='mso-tab-count:
|
|
2'> </span>; moveb
|
|
d0,d2<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movb<span
|
|
style='mso-tab-count:1'> </span>%dl,%bl<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>shlw<span
|
|
style='mso-tab-count:1'> </span>$0x8,%dx<span style='mso-tab-count:
|
|
2'> </span>; lslw #8,d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>orw<span
|
|
style='mso-tab-count:1'> </span>%dx,%bx<span style='mso-tab-count:
|
|
2'> </span>; orw
|
|
d0,d2<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>%ebx,%edx<span style='mso-tab-count:
|
|
2'> </span>; movel d2,d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>rorl<span
|
|
style='mso-tab-count:1'> </span>$0x10,%ebx<span style='mso-tab-count:
|
|
2'> </span>; swap d2<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>orl<span
|
|
style='mso-tab-count:1'> </span>%ebx,%edx<span style='mso-tab-count:
|
|
2'> </span>; orl d2,d0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>_a0,%ecx<span style='mso-tab-count:
|
|
2'> </span>; movel
|
|
a0,d2<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>%ecx,%ebx<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>shrb<span
|
|
style='mso-tab-count:1'> </span>%bl<span style='mso-tab-count:3'> </span>;
|
|
lsrb #1,d2<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>%ebx,_d2<span style='mso-tab-count:
|
|
2'> </span>; <spill dirty
|
|
68k<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>%edx,_d0<span style='mso-tab-count:
|
|
2'> </span>;<span
|
|
style="mso-spacerun: yes"> </span>registers back to memory><o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>jae<span
|
|
style='mso-tab-count:1'> </span>0x3b734c<span style='mso-tab-count:
|
|
2'> </span>; bcc
|
|
0x3fffed4<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>jmp<span
|
|
style='mso-tab-count:1'> </span>0x43d48c<span style='mso-tab-count:
|
|
2'> </span>; <go to
|
|
"fall through" 68k code><o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:top;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><![if !supportEmptyParas]> <![endif]><o:p></o:p></span></p>
|
|
<p class=MsoNormal align=center style='text-align:center;border:none;
|
|
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
|
|
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-element-top:top;mso-height-rule:exactly'><span style='font-size:
|
|
12.0pt'>Figure 3.<span style="mso-spacerun: yes"> </span>680x0 -> 80x86
|
|
examples<o:p></o:p></span></p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<span style='font-size:12.0pt;font-family:Helvetica;mso-ansi-language:EN-US'><b><br
|
|
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
|
|
</b></span>
|
|
|
|
<div class=Section8>
|
|
|
|
<h2>Graphics</h2>
|
|
|
|
<h3>SVGA Graphics</h3>
|
|
|
|
<p class=MsoNormal>The DOS world is one of standards.<span style="mso-spacerun:
|
|
yes"> </span><i>Many</i><span style='font-style:normal'> standards.<span
|
|
style="mso-spacerun: yes"> </span>Standards made by engineers who were
|
|
even more short-sighted than the folks who brought you ROM85, only to be
|
|
replaced by SysEnvirons which was then replaced by Gestalt.<span
|
|
style="mso-spacerun: yes"> </span>The first color graphics adapter for
|
|
the PC (CGA) was replaced with EGA, which was then replaced by VGA, which
|
|
eventually gave way to several different Super Video Graphics Array (SVGA)
|
|
cards.</span></p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>SVGA cards have a couple of properties that make them less
|
|
than perfect targets for the output of Macintosh emulators.<span
|
|
style="mso-spacerun: yes"> </span>First, the default is for SVGA's video
|
|
memory to only be mapped into the PC address space through a 64k window (or
|
|
bank).<span style="mso-spacerun: yes"> </span>If you want to display
|
|
640x480x8 bits you need to write 64k of information to the 64k screen address
|
|
range, then tell the video card that you want that same address to represent a
|
|
different 64k chunk of the screen, then you write to that address range again,
|
|
then you switch banks again, and so forth.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The second major complication is that under DPMI, the
|
|
address space that contains the SVGA video memory is not in the same address space
|
|
that a 32-bit application uses.<span style="mso-spacerun: yes">
|
|
</span>For those of you used to programming in a flat address space, it might
|
|
be hard to believe that you need special machine language address space
|
|
overriding prefixes to access screen memory, but under DPMI 0.9 (which is the
|
|
version of DPMI that Microsoft supports; we wouldn't have to do this under 1.0)
|
|
"selector" overrides really are necessary.</p>
|
|
|
|
<span style='font-size:12.0pt;font-family:Palatino;mso-ansi-language:EN-US'><b><br
|
|
clear=ALL style='mso-column-break-before:always'>
|
|
</b></span>
|
|
|
|
<h3>Blitter Overview</h3>
|
|
|
|
<p class=MsoNormal>A Region is a data structure that describes a set of
|
|
pixels.<span style="mso-spacerun: yes"> </span>Regions can be created by
|
|
the application by calling various MacOS toolbox routines.<span
|
|
style="mso-spacerun: yes"> </span>In addition the toolbox routines
|
|
themselves sometimes create Regions for their own purposes.<span
|
|
style="mso-spacerun: yes"> </span></p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>A blitter is a set of software or hardware which takes sets
|
|
of bits, representing pixels, and combines them with other sets of bits in a
|
|
variety of different ways.<span style="mso-spacerun: yes"> </span>A
|
|
Region blitter is a blitter that processes pixels by Regions (rather than by
|
|
rectangles or rectangle lists).</p>
|
|
|
|
<h3>A Simple Blitter </h3>
|
|
|
|
<p class=MsoNormal>One way to write a simple Region blitter is to start with a
|
|
subroutine that parses the start/stop pairs of a Region scanline and draws the
|
|
corresponding pixels.<span style="mso-spacerun: yes"> </span>This
|
|
subroutine is then called once for each row of pixels to be displayed.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Unfortunately, this approach is slow since each scanline
|
|
gets re-parsed every time it is drawn.<span style="mso-spacerun: yes">
|
|
</span>The Region for a 300 pixel tall rectangle consists of a single scanline
|
|
with a repeat count of "300"; this "simple Region blitter"
|
|
will parse that scanline 300 times! That's a lot of redundant work.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>There are many possible ways to get away with parsing each
|
|
scanline only once.<span style="mso-spacerun: yes"> </span>One approach
|
|
is to convert the start/stop pairs into a bit mask where the bits in the mask
|
|
correspond to the bits in the target bitmap that are to be changed.<span
|
|
style="mso-spacerun: yes"> </span>The inner blitting loop then becomes an
|
|
exercise in bitwise arithmetic.<span style="mso-spacerun: yes"> </span>In
|
|
C, such a loop might look something like this:<span style='font-family:Courier'><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><![if !supportEmptyParas]> <![endif]><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>for (x = left; x <
|
|
right; x++)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>dst[x] = (dst[x] & ~mask[x]) <o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>| (pattern_value & mask[x]);<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><![if !supportEmptyParas]> <![endif]><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal>That's not bad, but we can do better.</p>
|
|
|
|
<h3>A Dynamically Recompiling Blitter </h3>
|
|
|
|
<p class=MsoNormal>Using an explicit bit mask array is unnecessarily slow in
|
|
the common case of filling a rectangle.<span style="mso-spacerun: yes">
|
|
</span>For a rectangular Region, mask[x] is usually all one bits, making the
|
|
bit munging a waste of time.<span style="mso-spacerun: yes"> </span>And
|
|
even when the masks are never solid (e.g. when drawing a thin vertical line),
|
|
this technique is still unnecessarily slow.<span style="mso-spacerun:
|
|
yes"> </span>As it turns out, even the cycles the CPU spends loading mask
|
|
bits from memory are unnecessary.<span style="mso-spacerun: yes">
|
|
</span>Furthermore, even if we were satisfied with the level of performance
|
|
that C code like the above provides, we couldn't use it on a stock SVGA system
|
|
because it wouldn't know how to access the SVGA portion of memory.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Executor's blitter uses the techniques of partial evaluation
|
|
and dynamic code generation to eliminate redundant work and also give us access
|
|
to SVGA memory.<span style="mso-spacerun: yes"> </span>On the 80x86 each
|
|
scanline is quickly translated into executable code, and that code gets
|
|
executed once each time the scanline needs to be drawn.<span
|
|
style="mso-spacerun: yes"> </span>On non-80x86 platforms, each scanline
|
|
is compiled into threaded code which is executed by a machine-generated interpreter
|
|
to draw the scanlines.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Before describing how the dynamic compilation process works,
|
|
let's take a look at an example.<span style="mso-spacerun: yes">
|
|
</span>Consider the case where a 401x300 rectangle is to be filled with white
|
|
pixels (pixel value zero on the Macintosh).<span style="mso-spacerun:
|
|
yes"> </span>This might happen, for example, when erasing a window.
|
|
Furthermore, let's assume that the target bitmap has four bits per pixel, since
|
|
that's somewhat tricker to handle than 8 bits per pixel.<span
|
|
style="mso-spacerun: yes"> </span>Figure 4 shows the subroutine that
|
|
Executor dynamically generates to draw this rectangle on a Pentium.</p>
|
|
|
|
</div>
|
|
|
|
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
|
|
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
|
|
</span>
|
|
|
|
<div class=Section9>
|
|
|
|
<div style='mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-element-top:bottom;mso-height-rule:exactly'>
|
|
|
|
<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=center>
|
|
<tr>
|
|
<td valign=top align=left style='padding-top:9.0pt;padding-right:9.0pt;
|
|
padding-bottom:9.0pt;padding-left:9.0pt'>
|
|
<div style='border:solid windowtext .75pt;padding:0in 0in 0in 0in;background:
|
|
#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>loop:<span style='mso-tab-count:1'> </span>andl<span
|
|
style='mso-tab-count:1'> </span>$0xff,0x50(%edi)<span style='mso-tab-count:
|
|
1'> </span><span style='mso-tab-count:1'> </span>;
|
|
clear leftmost 6 boundary pixels<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>addl<span
|
|
style='mso-tab-count:1'> </span>$0x54,%edi<span style='mso-tab-count:
|
|
2'> </span><span style='mso-tab-count:
|
|
1'> </span>; set up pointer for loop<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movl<span
|
|
style='mso-tab-count:1'> </span>$0x31,%ecx<span style='mso-tab-count:
|
|
2'> </span><span style='mso-tab-count:
|
|
1'> </span>; set up loop counter<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>rep<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>stosl<span
|
|
style='mso-tab-count:3'> </span><span
|
|
style='mso-tab-count:1'> </span><span
|
|
style='mso-tab-count:1'> </span>; slam out 49
|
|
aligned longs<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>andl<span
|
|
style='mso-tab-count:1'> </span>$0xffff0f00,0x0(%edi)<span
|
|
style='mso-tab-count:1'> </span>; clear 3 right boundary pixels<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>addl<span
|
|
style='mso-tab-count:1'> </span>$0x28,%edi<span style='mso-tab-count:
|
|
3'> </span>;
|
|
move to next row<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>decl<span
|
|
style='mso-tab-count:1'> </span>%edx<span style='mso-tab-count:4'> </span>;
|
|
decrement # of rows left<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>jne<span
|
|
style='mso-tab-count:1'> </span>loop<span style='mso-tab-count:
|
|
4'> </span>;
|
|
continue looping if appropriate<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>ret<span
|
|
style='mso-tab-count:5'> </span>;
|
|
we're done!<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><![if !supportEmptyParas]> <![endif]><o:p></o:p></span></p>
|
|
<p class=MsoNormal align=center style='text-align:center;border:none;
|
|
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
|
|
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-size:12.0pt'>Figure 4.<span style="mso-spacerun: yes">
|
|
</span>Dynamically generated blitting code</span></p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
|
|
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
|
|
</span>
|
|
|
|
<div class=Section10>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
|
|
clear=ALL style='mso-column-break-before:always'>
|
|
<br clear=ALL style='mso-column-break-before:always'>
|
|
</span>
|
|
|
|
<p class=MsoNormal>This code, when called with the proper values in its input
|
|
registers, will draw the entire rectangle.<span style="mso-spacerun:
|
|
yes"> </span>Note how the inner loop is merely a</p>
|
|
|
|
<p class=MsoNormal>"<span style='font-family:Courier'>rep ; stosl</span>"...it
|
|
doesn't get much more concise than that!<span style="mso-spacerun: yes">
|
|
</span>The astute reader will know that on certain 80x86 processors "rep ;
|
|
stosl" is not the fastest possible way to set a range of memory.<span
|
|
style="mso-spacerun: yes"> </span>This is true, but because our code
|
|
generation is dynamic, in the future we can tailor the specific code sequence
|
|
generated to the processor on which Executor is currently running.<span
|
|
style="mso-spacerun: yes"> </span>The blitter already does this when it
|
|
needs to emit a byte swap; on the 80486 and up we use the "bswap"
|
|
instruction, and on the 80386 (which doesn't support "bswap") we use
|
|
a sequence of rotates.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>One thing you may notice in this example is that the bit
|
|
masks used to clear the boundary pixels look strange.<span style="mso-spacerun:
|
|
yes"> </span>They are actually correct, since 80x86 processors are little
|
|
endian.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Unlike some processors, such as the 68040, the 80x86
|
|
instruction and data caches are always coherent.<span style="mso-spacerun:
|
|
yes"> </span>Consequently, no cache flushes need to be performed before
|
|
the dynamically created code can be executed.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Figure 5 contains another example, this time drawn from a
|
|
real application.<span style="mso-spacerun: yes"> </span>The program
|
|
"Globe", by Paul Mercer, draws a spinning globe </p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>on the screen as fast as it can.<span style="mso-spacerun:
|
|
yes"> </span>Each "globe frame" is a 128x128 Pixmap.<span
|
|
style="mso-spacerun: yes"> </span>Here is the code that Executor
|
|
generates and runs when Globe uses CopyBits to transfer one frame to the screen
|
|
at 8 bits per pixel.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Again the inner loop is very tight, just a "rep ;
|
|
movsl" this time.</p>
|
|
|
|
<span style='font-size:12.0pt;font-family:Palatino;mso-ansi-language:EN-US'><b><br
|
|
clear=ALL style='mso-column-break-before:always'>
|
|
</b></span>
|
|
|
|
<h3>Meta-Assembler </h3>
|
|
|
|
<p class=MsoNormal>No matter how fast the generated code, if Executor spends
|
|
too much time generating that code then any speedup will be negated by the
|
|
increased time required for dynamic compilation.<span style="mso-spacerun:
|
|
yes"> </span>Consequently, the dynamic compilation from Region to 80x86
|
|
code needs to be fast. We solved this problem with a "meta-assembler"
|
|
written in Perl.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Whereas an assembler tells a computer how to translate
|
|
assembly instructions into machine code, our meta-assembler tells the computer
|
|
how to generate tiny translators.<span style="mso-spacerun: yes">
|
|
</span>These translators will then be used to translate pixel manipulation requests
|
|
into machine code.<span style="mso-spacerun: yes"> </span>Another way of
|
|
looking at it is that the meta-assembler generates code that generates code.<span
|
|
style="mso-spacerun: yes"> </span>This meta-assembly process is done only
|
|
once:<span style="mso-spacerun: yes"> </span>when Executor is compiled.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The blitter operates on aligned longs in the destination
|
|
bitmap.<span style="mso-spacerun: yes"> </span>As the compilation engine
|
|
strides through the scanline's start/stop pairs from left to right, it identifies
|
|
which bits in each long are part of the Region and determines which of several pixel
|
|
manipulation requests to issue to the tiny translators that were created by the
|
|
meta-assembler.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>• Some
|
|
but not all bits in the current long are in the Region.</p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>• All
|
|
bits in the current long are in the Region.</p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>• All
|
|
bits in this long and the next long are in the Region.</p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>• All
|
|
bits in this long and the next two longs are in the Region.</p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>• All
|
|
bits in this long and the next three longs are in the Region.</p>
|
|
|
|
</div>
|
|
|
|
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
|
|
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
|
|
</span>
|
|
|
|
<div class=Section11>
|
|
|
|
<div style='mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-element-top:bottom;mso-height-rule:exactly'>
|
|
|
|
<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=center>
|
|
<tr>
|
|
<td valign=top align=left style='padding-top:9.0pt;padding-right:9.0pt;
|
|
padding-bottom:9.0pt;padding-left:9.0pt'>
|
|
<div style='border:solid windowtext .75pt;padding:0in 0in 0in 0in;background:
|
|
#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>loop:<span style='mso-tab-count:1'> </span>movl<span
|
|
style="mso-spacerun: yes"> </span>$0x20,%ecx<span
|
|
style='mso-tab-count:2'> </span>; set up
|
|
loop counter for 32 longs<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>rep<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>movsl<span
|
|
style='mso-tab-count:2'> </span><span
|
|
style='mso-tab-count:1'> </span><span
|
|
style='mso-tab-count:1'> </span>; copy one row
|
|
(128 bytes)<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>addl<span
|
|
style="mso-spacerun: yes"> </span>$0xffffff00,%esi<span
|
|
style='mso-tab-count:1'> </span>; advance to previous src row<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>addl<span
|
|
style="mso-spacerun: yes"> </span>$0xfffffd00,%edi<span
|
|
style='mso-tab-count:1'> </span>; advance to previous dst row<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>decl<span
|
|
style="mso-spacerun: yes"> </span>%edx<span style='mso-tab-count:
|
|
3'> </span>;
|
|
decrement # of rows remaining<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>jne<span
|
|
style="mso-spacerun: yes"> </span>loop<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>ret<o:p></o:p></span></p>
|
|
<p class=MsoNormal align=center style='text-align:center;border:none;
|
|
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
|
|
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-element-top:bottom;mso-height-rule:exactly'><span
|
|
style='font-size:12.0pt'>Figure 5.<span style="mso-spacerun: yes">
|
|
</span>Blitting code from Globe</span></p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
|
|
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
|
|
</span>
|
|
|
|
<div class=Section12><br clear=ALL style='mso-column-break-before:always'>
|
|
<br clear=ALL style='mso-column-break-before:always'>
|
|
|
|
<p class=MsoNormal style='margin-left:.25in;text-indent:-9.0pt'>• More
|
|
than four contiguous longs are</p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt'>completely in the Region, and the
|
|
number of longs equals 0 mod 4.</p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>• More
|
|
than four contiguous longs are completely in the Region, and the number of
|
|
longs equals 1 mod 4.</p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>• More
|
|
than four contiguous longs are completely in the Region, and the number of
|
|
longs equals 2 mod 4.</p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal style='margin-left:27.0pt;text-indent:-9.0pt'>• More
|
|
than four contiguous longs are completely in the Region, and the number of
|
|
longs equals 3 mod 4.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The particular case encountered determines which function
|
|
pointer to load from a lookup table corresponding to the current drawing mode.
|
|
For example, the "patCopy" drawing mode has one table of function
|
|
pointers, "patXor" another.<span style="mso-spacerun: yes">
|
|
</span>There are also some special case tables for drawing patterns that are
|
|
either all zero bits or all one bits.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The main blitter doesn't care what drawing mode is being
|
|
used, since it does all mode-specific work through the supplied function
|
|
pointer table.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Each function pointer points to a function that generates
|
|
80x86 code for the appropriate case.<span style="mso-spacerun: yes">
|
|
</span>For example, one function generates code for a "patCopy" to
|
|
three contiguous longs, one generates code for "patXor" only to
|
|
certain specified bits within one long, etc.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The blitter compilation engine marches through the Region
|
|
scanline from left to right, calling code generation functions as it goes.<span
|
|
style="mso-spacerun: yes"> </span>The generated code is accrued into a
|
|
32-byte aligned buffer on the stack. In this way, the blitter constructs a
|
|
subroutine to draw the Region.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The compilation engine isn't very complicated.<span
|
|
style="mso-spacerun: yes"> </span>The tricky part is the numerous
|
|
generation subroutines, which need to be fast since they are called so often
|
|
and need to be easy to write since there are so many of them. For each drawing
|
|
mode there's one for each case the compilation engine cares about.<span
|
|
style="mso-spacerun: yes"> </span>For pattern drawing modes, there are
|
|
separate specialized subroutines for cases like patterns that can be entirely
|
|
expressed in one 32-bit value ("short/narrow") patterns, patterns
|
|
which can be expressed as one 32-bit value for each row, but which vary per row
|
|
("tall/narrow"), as well as "wide" variants of both. Beyond
|
|
that, there are some versions specialized for 80486 and higher processors (which
|
|
have the "bswap" instruction).</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Generating fast and robust code generators is where the Perl
|
|
meta-assembler comes into play.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The meta-assembler takes as input an assembly language
|
|
template, and generates as output Pentium-scheduled assembly code that outputs
|
|
an 80x86 binary for the input template.<span style="mso-spacerun: yes">
|
|
</span>This process only takes place when Executor is compiled.<span
|
|
style="mso-spacerun: yes"> </span>Got it?<span style="mso-spacerun:
|
|
yes"> </span>This can be a little confusing, so a few examples are in
|
|
order.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Here is perhaps the simplest template:</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>@meta copy_short_narrow_1<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>movl<span style='mso-tab-count:1'> </span>%eax,@param_offset@(%edi)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>@endmeta<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>This template describes what should be done when the blitter
|
|
wants to write one long to memory.<span style="mso-spacerun: yes">
|
|
</span>The meta-assembler processes that into this 80x86 assembly code which is
|
|
to be called by the blitter compilation engine:</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>.align<span style='mso-tab-count:1'> </span>4,0x90<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>_xdblt_copy_short_narrow_1:<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>movw<span style='mso-tab-count:1'> </span>$0x8789,(%edi)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>movl<span style='mso-tab-count:1'> </span>%eax,2(%edi)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>addl<span style='mso-tab-count:1'> </span>$6,%edi<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>ret<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The subroutine that the meta-assembler has produced above,
|
|
when executed, will generate the movl instruction (i.e. the movl instruction in
|
|
the template) followed by its argument. <span style="mso-spacerun:
|
|
yes"> </span>The meta-assembler has deduced that "movl" in
|
|
the example template is 80x86 opcode 0x8789. <span style="mso-spacerun:
|
|
yes"> </span></p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
|
|
clear=ALL style='mso-column-break-before:always'>
|
|
</span>
|
|
|
|
<p class=MsoNormal>Let's take a look at a more complicated template.<span
|
|
style="mso-spacerun: yes"> </span>This template handles the case where we
|
|
want to bitwise OR a pattern to the destination bitmap, and the number of longs
|
|
to transfer equals zero mod 4 (e.g. if the blitter wants to OR 36 longs to
|
|
memory):</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>@meta
|
|
or_short_narrow_many_mod_0<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>addl<span style='mso-tab-count:1'> </span>$@param_offset@,%edi<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>movl<span style='mso-tab-count:1'> </span>$@param_l_cnt_div_4@,%ecx<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>1:<span style='mso-tab-count:
|
|
1'> </span>orl<span style='mso-tab-count:1'> </span>%eax,(%edi)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>orl<span style='mso-tab-count:1'> </span>%eax,4(%edi)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>orl<span style='mso-tab-count:1'> </span>%eax,8(%edi)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>orl<span style='mso-tab-count:1'> </span>%eax,12(%edi)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>addl<span style='mso-tab-count:1'> </span>$16,%edi<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>decl<span style='mso-tab-count:1'> </span>%ecx<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>jnz<span style='mso-tab-count:1'> </span>1b<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>@lit<span
|
|
style='mso-tab-count:1'> </span>leal<span style='mso-tab-count:1'> </span>(%eax,%edx,4),%ecx<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>@lit<span
|
|
style='mso-tab-count:1'> </span>addl<span style='mso-tab-count:1'> </span>%ecx,edi_offset<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>@endmeta<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The meta-assembler compiles that to this:</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>.align<span style='mso-tab-count:1'> </span>4,0x90<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>_xdblt_or_short_narrow_many_mod_0:<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>movw<span style='mso-tab-count:1'> </span>$0xC781,(%edi)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>movl<span style='mso-tab-count:1'> </span>%eax,2(%edi)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>movl<span style='mso-tab-count:1'> </span>$0x47090709,11(%edi)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>movb<span style='mso-tab-count:1'> </span>$0xB9,6(%edi)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>movl<span style='mso-tab-count:1'> </span>$0x8470904,15(%edi)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>movl<span style='mso-tab-count:1'> </span>$0x754910C7,23(%edi)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>movl<span style='mso-tab-count:1'> </span>$0x830C4709,19(%edi)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>movb<span style='mso-tab-count:1'> </span>$0xEF,27(%edi)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>movl<span style='mso-tab-count:1'> </span>%edx,%ecx<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>shrl<span style='mso-tab-count:1'> </span>$2,%ecx<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>movl<span style='mso-tab-count:1'> </span>%ecx,7(%edi)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>addl<span style='mso-tab-count:1'> </span>$28,%edi<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>leal<span style='mso-tab-count:1'> </span>(%eax,%edx,4),%ecx<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>addl<span style='mso-tab-count:1'> </span>%ecx,edi_offset<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
1'> </span>ret<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>This mechanically generated subroutine generates the
|
|
executable 80x86 binary for the "or_short_narrow_many_mod_0"
|
|
template.<span style="mso-spacerun: yes"> </span>It gets called by the
|
|
blitter compilation engine when it needs code to OR a bunch of longs to memory.<span
|
|
style="mso-spacerun: yes"> </span></p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The output of the meta-assembler isn't meant for human
|
|
consumption.<span style="mso-spacerun: yes"> </span>As such, the output
|
|
contains a hodge-podge of magic numbers (<span style='font-family:Courier'>0x47090709,
|
|
0xB9, 0x8470904,</span> etc.).<span style="mso-spacerun: yes">
|
|
</span>These numbers are fixed machine code values corresponding to opcodes, constant
|
|
operands, and other values.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Even though this subroutine is longer than the previous
|
|
example, it still doesn't take very long to execute.<span style="mso-spacerun:
|
|
yes"> </span>Furthermore, it only gets called when the blitter has
|
|
determined that many longs are to be ORed to memory, so the time taken actually
|
|
blitting to memory will typically dwarf the time taken to execute these 15 code
|
|
generation instructions.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The meta-assembler is a Perl script that works by running
|
|
numerous syntactically modified versions of the assembly template through
|
|
"gas", the GNU assembler, and examining the output bytes to discover
|
|
which bits are fixed opcode bits and which bits correspond to operands.<span
|
|
style="mso-spacerun: yes"> </span>Once it has figured out what goes
|
|
where, it generates 80x86 assembly code which writes out the constant bytes and
|
|
computes and writes out the operand bytes.<span style="mso-spacerun:
|
|
yes"> </span>That code is run through a simple Pentium instruction
|
|
scheduler and the meta-assembler is done.<span style="mso-spacerun: yes">
|
|
</span>This entire process is, of course, done only once, when Executor is
|
|
compiled.</p>
|
|
|
|
<h3>A Portable Dynamically Recompiling Blitter</h3>
|
|
|
|
<p class=MsoNormal>Although the meta-assembler-based blitter works only on
|
|
80x86 processors, Executor itself can run on non-Intel processors.<span
|
|
style="mso-spacerun: yes"> </span>On other CPUs (such as the 68040 used
|
|
in the NeXTstation) Executor's blitter works somewhat differently.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The basic idea is still the same: translate Region scanlines
|
|
into an efficient form once and then use that efficient form each time the
|
|
scanline gets drawn.<span style="mso-spacerun: yes"> </span>This time,
|
|
however, the "efficient form" is processor independent, and the
|
|
blitter is written entirely in C.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>As is the case with the 80x86-specific blitter, the portable
|
|
blitter compilation engine examines scanline start/stop pairs and identifies
|
|
which of several cases is appropriate.<span style="mso-spacerun: yes">
|
|
</span>One case is "output three longs", another is "output only
|
|
certain pixels within the current long", and so on.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Like the 80x86-specific blitter, the particular case
|
|
encountered determines which entry in a lookup table will be used.<span
|
|
style="mso-spacerun: yes"> </span>But there the similarity ends.<span
|
|
style="mso-spacerun: yes"> </span>The lookup tables contain pointers to C
|
|
code labels<a style='mso-footnote-id:ftn1' href="#_ftn1" name="_ftnref1"
|
|
title=""><span class=MsoFootnoteReference><span style='mso-special-character:
|
|
footnote'><![if !supportFootnotes]>[1]<![endif]></span></span></a> rather than
|
|
to routines that generates 80x86 code on the fly.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Each scanline gets translated into an array of opcodes for
|
|
the "blitter opcode interpreter" (which will be described
|
|
below).<span style="mso-spacerun: yes"> </span>Each opcode is stored in
|
|
one of these C structs:</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>struct<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>{<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>/* Pointer to C code to handle<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>this opcode. */<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>const void *label;<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><![if !supportEmptyParas]> <![endif]><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>/* Offset into scanline */<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>int32 offset;<span style='mso-tab-count:2'> </span><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><![if !supportEmptyParas]> <![endif]><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>/* Extra operand with<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>different uses. */<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>int32 arg;<span style='mso-tab-count:2'> </span><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>};<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>For example, consider the case where the blitter wants to
|
|
write out five contiguous longs from a "simple" pattern starting 64
|
|
bytes into the current row.<span style="mso-spacerun: yes"> </span>In
|
|
this case, "label" would equal
|
|
"&&copy_short_narrow_many_5", "offset" would equal
|
|
64, and "arg" would equal 5.</p>
|
|
|
|
<h3>The Blitter Opcode Interpreter</h3>
|
|
|
|
<p class=MsoNormal>The blitter opcode interpreter is machine generated C code
|
|
created by a Perl script when Executor is compiled.<span style="mso-spacerun:
|
|
yes"> </span>That Perl script takes as input C code snippets that tell it
|
|
how to handle particular drawing modes, and produces as output C code for an
|
|
interpreter.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Here is the template taken as input by the Perl script for
|
|
the "copy_short_narrow" case.<span style="mso-spacerun: yes">
|
|
</span>This is the simple case where the pixels for the pattern being displayed
|
|
can be stored entirely within one 32-bit long (for example, solid white or
|
|
solid black).</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>begin_mode cpy_shrt_narrow
|
|
max_unwrap<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>repeat<span style='mso-tab-count:1'> </span>@dst@
|
|
= v;<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>mask<span style='mso-tab-count:1'> </span><span
|
|
style="mso-spacerun: yes"> </span>@dst@ = (@dst@
|
|
& ~arg)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style='mso-tab-count:
|
|
3'> </span>|
|
|
(v & arg);<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>end_mode<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The "<span style='font-family:Courier'>repeat</span>"
|
|
field tells the Perl script what C code to generate for the simple case where
|
|
all pixels in the destination long are to be affected.<span
|
|
style="mso-spacerun: yes"> </span>The "mask" case tells it what
|
|
to do when it must only modify certain bits in the target long and must leave
|
|
others alone.<span style="mso-spacerun: yes"> </span>Max_unwrap tells the
|
|
Perl script to unroll the new blitting loop.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The generated interpreter takes as input an array of blitter
|
|
opcode structs, which it then proceeds to interpret once for each row to be
|
|
drawn.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Here is the section of the (machine-generated) interpreter
|
|
that handles the copy_short_narrow cases.<span style="mso-spacerun: yes">
|
|
</span>Remember that each "blitter opcode" is really just a pointer
|
|
to one of these C labels.<span style="mso-spacerun: yes"> </span>This
|
|
code would get used when filling a rectangle with a solid color.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_mask:<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>*dst = (*dst & ~arg) | (v & arg);<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>JUMP_TO_NEXT;<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_loop:<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>dst += 8;<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_8:<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>dst[0] = v;<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_7:<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>dst[1] = v;<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_6:<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>dst[2] = v;<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_5:<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>dst[3] = v;<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_4:<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>dst[4] = v;<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_3:<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>dst[5] = v;<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_2:<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>dst[6] = v;<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>copy_short_narrow_many_1:<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>dst[7] = v;<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>if ((arg -= 8) > 0)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>goto copy_short_narrow_many_loop;<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>JUMP_TO_NEXT;<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Note how the inner blitting loop is "unwrapped"
|
|
for speed.<span style="mso-spacerun: yes"> </span>A blitter opcode would
|
|
specify that 39 longs are to be output by making its "arg" field be
|
|
39 and the "label" field point to "copy_short_narrow_many_7",
|
|
in the middle of the unwrapped loop (39 mod 8 equals 7).<span
|
|
style="mso-spacerun: yes"> </span>The interpreter would jump there and
|
|
loop until all of the pixels had been written out, at 32 bytes per loop
|
|
iteration.<span style="mso-spacerun: yes"> </span>This is very fast,
|
|
especially for portable code.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Of course, if any other pixels needed to be drawn, there
|
|
would be additional blitter opcode structs telling the interpreter what to do.
|
|
The interpreter dispatches to the next opcode by executing the
|
|
"JUMP_TO_NEXT" macro, which automatically uses GCC's "goto void
|
|
*" extension to "goto" the C label that handles the next opcode.</p>
|
|
|
|
<h1>Development Tools</h1>
|
|
|
|
<h2>Free Software</h2>
|
|
|
|
<p class=MsoNormal>It is true that ARDI has a very tight R&D budget, but we
|
|
really don't skimp on the tools that we use to build Executor.<span
|
|
style="mso-spacerun: yes"> </span>We use free software to develop
|
|
Executor because we like to push the tools that we use very hard and the only
|
|
way we can do that and still sleep at night is when we know that if we find
|
|
bugs in our tools that they can be fixed quickly.<span style="mso-spacerun:
|
|
yes"> </span>With free software the worst case is to fix bugs ourselves,
|
|
and that worst case is actually much better than the average case with non-free
|
|
software where you report a bug and pray for a patch.<span style="mso-spacerun:
|
|
yes"> </span>In reality it's rare that we even have to resort to the
|
|
worst case since bugs reported are often fixed in less than a day.</p>
|
|
|
|
<h3>GCC</h3>
|
|
|
|
<p class=MsoNormal>GCC is the Free Software Foundation's C compiler.<span
|
|
style="mso-spacerun: yes"> </span>It produces good code and has a
|
|
powerful inline assembly syntax that allows optimization to be done on the
|
|
expressions in the inline assembly without the optimization ruining the
|
|
assembly you've written.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Another handy GCC extension is "<span style='font-family:
|
|
Courier'>typeof</span>" which can be used in macros to cast a value to the
|
|
type of a different value.<span style="mso-spacerun: yes"> </span>The
|
|
combination of powerful inline assembly and typeof allows us to have efficient
|
|
macros that swap bytes in a 16 bit or 32 bit quantity.<span
|
|
style="mso-spacerun: yes"> </span>Since the Mac and PC are of different
|
|
endianness, quick byte swapping routines are very important.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>As mentioned above in our synthetic CPU and portable blitter
|
|
descriptions, we also use GCC's ability to take the address of a label and
|
|
store it in a variable so that we can produce our own threaded code on the fly.</p>
|
|
|
|
<h3>Hacked GCC</h3>
|
|
|
|
<p class=MsoNormal>Because the source to GCC is available, it is possible,
|
|
although not necessarily advisable, to hack in custom extensions.<span
|
|
style="mso-spacerun: yes"> </span>At ARDI we've done this twice in the
|
|
past.<span style="mso-spacerun: yes"> </span>At one time we used a set of
|
|
locally written modifications to support the pascal keyword so that we could
|
|
automatically call functions using Pascal calling conventions.<span
|
|
style="mso-spacerun: yes"> </span>At the same time we also supported '<span
|
|
style='font-family:Courier'>1234'</span> (i.e. the ability to construct a
|
|
32-bit quantity out of four character constants inside apostrophes).<span
|
|
style="mso-spacerun: yes"> </span><span style="mso-spacerun:
|
|
yes"> </span>Eventually we decided that we didn't get enough benefit
|
|
from these extensions to make it worth patching new versions of GCC as they
|
|
came out.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The other time we modified GCC was when we were porting
|
|
Executor to DEC's Alpha processor.<span style="mso-spacerun: yes">
|
|
</span>We were doing this under OSF/1 which uses 64-bit pointers.<span
|
|
style="mso-spacerun: yes"> </span>Since Executor needs to use the same
|
|
internal representation that Macs use, we wanted a way to easily write 32-bit
|
|
pointers to memory in such a way that they would be extended to 64-bits when
|
|
they were read into a register for use.<span style="mso-spacerun: yes">
|
|
</span>To do this we made GCC support "pointer bit fields", a logical
|
|
extension that allowed bit-field notation to be used when specifying
|
|
pointers.<span style="mso-spacerun: yes"> </span>At that time we didn't
|
|
have a resident GCC expert, so we were lucky that such modifications basically
|
|
consisted in taking out a few checks that disallowed such constructs.<span
|
|
style="mso-spacerun: yes"> </span>Once those checks were removed, pointer
|
|
bit-fields, "just worked".</p>
|
|
|
|
<h3>DJGPP</h3>
|
|
|
|
<p class=MsoNormal>DJGPP is DJ Delorie's (see <span style='font-family:Courier'>http://www.delorie.com</span>)
|
|
port of GCC to MSDOS.<span style="mso-spacerun: yes"> </span>It allows
|
|
DOS users to compile UNIX programs under DOS and to run them with little or no
|
|
modification.<span style="mso-spacerun: yes"> </span>DJGPP is GCC and
|
|
associated development tools with a special UNIX like C-library and a "DOS
|
|
Extender".<span style="mso-spacerun: yes"> </span>DOS extenders are
|
|
used to combat OS inferiority.<span style="mso-spacerun: yes"> </span>DOS
|
|
is a 16-bit OS, whereas most relatively modern OSes are 32-bit.<span
|
|
style="mso-spacerun: yes"> </span>DOS extenders allow 32-bit programs to
|
|
run under DOS.<span style="mso-spacerun: yes"> </span>Executor is one
|
|
such program.<span style="mso-spacerun: yes"> </span>In fact, we use the
|
|
djgpp libraries and DOS extender but we don't actually use the DOS port of GCC,
|
|
because we don't like DOS.<span style="mso-spacerun: yes"> </span>We like
|
|
Linux and GCC is well structured so we can do cross-compilation and
|
|
cross-linking with the djgpp libraries and build our DOS product under
|
|
Linux.<span style="mso-spacerun: yes"> </span>We completely compile the DOS
|
|
version of Executor under Linux.<span style="mso-spacerun: yes">
|
|
</span>We then copy the new Executor binary to a DOS partition, reboot to DOS,
|
|
test Executor and then get the heck out of DOS.<span style="mso-spacerun:
|
|
yes"> </span>Time spent using Executor is more like a Mac than it is like
|
|
DOS.</p>
|
|
|
|
<span style='font-size:12.0pt;font-family:Helvetica;mso-ansi-language:EN-US'><b><u><br
|
|
clear=ALL style='mso-column-break-before:always'>
|
|
</u></b></span>
|
|
|
|
<h1>Debugging Tools</h1>
|
|
|
|
<p class=MsoNormal>Internally we have many debugging tools to help us figure
|
|
out why an application may die or misbehave under Executor.</p>
|
|
|
|
<h2>More Free Software</h2>
|
|
|
|
<h3>GDB in General</h3>
|
|
|
|
<p class=MsoNormal>Almost all of our debugging is done under the GDB
|
|
debugger.<span style="mso-spacerun: yes"> </span>As with GCC, we're not
|
|
using GDB because it's the free debugger; we're using the free debugger because
|
|
it's GDB.<span style="mso-spacerun: yes"> </span>GDB is quite powerful.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Whenever we find that a given application fails under
|
|
Executor, we try to reproduce the failure under Linux.<span
|
|
style="mso-spacerun: yes"> </span>Debugging on a system that has complete
|
|
memory protection and pre-emptive multi-tasking means that your system stays up
|
|
even when your application crashes.<span style="mso-spacerun: yes">
|
|
</span>There's also no need to worry that when a program is misbehaving that
|
|
it's subtly corrupting other programs on the system.</p>
|
|
|
|
<h4>hardware watch points</h4>
|
|
|
|
<p class=MsoNormal>Beyond the features that are handed to us due to the
|
|
underlying robustness of the OS, GDB also supports hardware watch points, at
|
|
least on 80x86 based PCs.<span style="mso-spacerun: yes"> </span>"80x86"s
|
|
have the ability to use hardware to watch a small set of memory locations to
|
|
see when they change.<span style="mso-spacerun: yes"> </span>Since the
|
|
checking is done by hardware, the program runs at full speed until the memory
|
|
location is modified, at which point the debugger stops, tells us which
|
|
instruction modified which memory address and what the old and new values are
|
|
for that address.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>As an example, assume we want to know when the low-memory
|
|
global <span style='font-family:Courier'>TheMenu</span> is changing, here is
|
|
how it might look under GDB:</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>(gdb) watch TheMenu<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>Hardware watchpoint 1:
|
|
TheMenu<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>(gdb) c<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>Continuing.<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>Hardware watchpoint 1:
|
|
TheMenu<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><![if !supportEmptyParas]> <![endif]><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>Old value = 0<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>New value = 768<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>C_HiliteMenu (mid=3) at
|
|
menu.c:877<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>(gdb) swap16 768<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>$2 = 0x3<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>(gdb) c<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>Continuing.<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>Hardware watchpoint 1:
|
|
TheMenu<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><![if !supportEmptyParas]> <![endif]><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>Old value = 768<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>New value = 0<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>C_HiliteMenu (mid=0) at
|
|
menu.c:877<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>(gdb) delete 3<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>(gdb) c<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>Continuing.<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>At the first <span style='font-family:Courier'>(gdb) </span>prompt
|
|
above, we tell GDB that we want to be alerted whenever the expression
|
|
"TheMenu" changes.<span style="mso-spacerun: yes"> </span>GDB
|
|
is clever enough to realize that it can watch that expression with a hardware
|
|
watchpoint, so it assigns watchpoint 1 to the task.<span style="mso-spacerun:
|
|
yes"> </span>We then continue, which allows Executor to continue running whatever
|
|
program it was already running.<a style='mso-footnote-id:ftn2' href="#_ftn2"
|
|
name="_ftnref2" title=""><span class=MsoFootnoteReference><span
|
|
style='mso-special-character:footnote'><![if !supportFootnotes]>[2]<![endif]></span></span></a></p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Eventually, when the menu bar was accessed, GDB told us that
|
|
TheMenu had changed from 0 to 768.<span style="mso-spacerun: yes">
|
|
</span>768 may sound like a weird value for TheMenu to take, but this is on a
|
|
byte swapped machine, so we need to swap that 16-bit value to see what the
|
|
TheMenu would look like to a Mac program and we find that it's 3, a sane value
|
|
for TheMenu, after all.<span style="mso-spacerun: yes"> </span>We let the
|
|
program continue and later TheMenu is changed back to zero.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>You can't see it, but in another window the source to
|
|
Executor is displayed so that we are automatically shown the 877th line of
|
|
menu.c when GDB's watch point triggers there.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>The argument to the watch command is an arbitrary
|
|
expression, so it is possible to watch for much more complex changes than our
|
|
example demonstrated.<span style="mso-spacerun: yes"> </span>Although
|
|
only relatively simple watchpoints will be handled by hardware watchpoints, the
|
|
others will be handled by software watchpoints which are much slower.</p>
|
|
|
|
<span style='font-size:12.0pt;font-family:Palatino;mso-ansi-language:EN-US'><b><br
|
|
clear=ALL style='mso-column-break-before:always'>
|
|
</b></span>
|
|
|
|
<h3>Hacked GDB</h3>
|
|
|
|
<p class=MsoNormal>Unlike GCC, where we made local modifications and then, upon
|
|
reflection, threw them out, we have made a slight change to GDB that is a big
|
|
win for debugging Executor (and Mac programs running under Executor) on
|
|
PCs.<span style="mso-spacerun: yes"> </span>GDB always knows how to
|
|
disassemble the object code that it's running, and GDB is available for many
|
|
architectures, so we modified GDB so that on the 80x86 we can do both 80x86
|
|
disassembly and 680x0 disassembly.<span style="mso-spacerun: yes">
|
|
</span>That allows us to look at sections of memory within our emulator and see
|
|
what 680x0 code is there.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>In the example below, Executor is running the game Risk,
|
|
when we interrupt Executor and then tell GDB to break in the routine
|
|
alinehandler.<span style="mso-spacerun: yes"> </span>We then continue
|
|
until alinehandler is hit.<span style="mso-spacerun: yes"> </span>We then
|
|
disassemble, in 680x0 format, the first nine instructions at the location from
|
|
which alinehandler was dispatched.<span style="mso-spacerun: yes">
|
|
</span>After doing that we disassemble in 80x86 format the first nine
|
|
instructions of alinehandler itself.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>(gdb) b alinehandler<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>Breakpoint 6 at 0x17ce2d:
|
|
file executor.c, line 369.<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>(gdb) c<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>Continuing.<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><![if !supportEmptyParas]> <![endif]><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>Breakpoint 6, alinehandler
|
|
(pc=3652006, ignored=0x0) at executor.c:369<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>(gdb) set m68k<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>(gdb) x/9i pc<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>0x37b9a6 :<span
|
|
style='mso-tab-count:1'> </span>_SystemTask<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>0x37b9a8 :<span
|
|
style='mso-tab-count:1'> </span>clrw sp@-<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>0x37b9aa :<span
|
|
style='mso-tab-count:1'> </span>movew #-1,sp@-<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>0x37b9ae :<span
|
|
style='mso-tab-count:1'> </span>pea a5@(-27598)<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>0x37b9b2 :<span
|
|
style='mso-tab-count:1'> </span>_GetNextEvent<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>0x37b9b4 :<span
|
|
style='mso-tab-count:1'> </span>moveb sp@+,d0<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>0x37b9b6 :<span
|
|
style='mso-tab-count:1'> </span>tstb d0<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>0x37b9b8 :<span
|
|
style='mso-tab-count:1'> </span>beqw 0x37ba0e <end+667542><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>0x37b9bc :<span
|
|
style='mso-tab-count:1'> </span>movew a5@(-27598),d0<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>(gdb) set m68k off<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'>(gdb) x/9i alinehandler<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><alinehandler>:<span
|
|
style="mso-spacerun: yes">
|
|
</span>pushl<span style="mso-spacerun: yes"> </span>%ebp<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><alinehandler+1>:<span
|
|
style='mso-tab-count:1'> </span>movl<span style="mso-spacerun:
|
|
yes"> </span>%esp,%ebp<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><alinehandler+3>:<span
|
|
style='mso-tab-count:1'> </span>subl<span style="mso-spacerun:
|
|
yes"> </span>$0x28,%esp<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><alinehandler+6>:<span
|
|
style='mso-tab-count:1'> </span>pushl<span style="mso-spacerun: yes">
|
|
</span>%esi<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><alinehandler+7>:<span
|
|
style='mso-tab-count:1'> </span>pushl<span style="mso-spacerun: yes">
|
|
</span>%ebx<o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><alinehandler+8>:<span
|
|
style='mso-tab-count:1'> </span>jmp<span style="mso-spacerun:
|
|
yes"> </span>0x17ce10 <alinehandler+48><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><alinehandler+10>:<span
|
|
style='mso-tab-count:1'> </span>nop<span
|
|
style="mso-spacerun: yes"> </span><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><alinehandler+11>:<span
|
|
style='mso-tab-count:1'> </span>nop<span
|
|
style="mso-spacerun: yes"> </span><o:p></o:p></span></p>
|
|
|
|
<p class=MsoNormal><span style='font-family:Courier'><alinehandler+12>:<span
|
|
style='mso-tab-count:1'> </span>nop</span><span
|
|
style="mso-spacerun: yes"> </span></p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Being able to disassemble 680x0 code on the 80x86 required
|
|
us to change approximately 50 source lines of GDB (remember, the 680x0
|
|
disassembly code was already present for use in GDB on 680x0 machines).<span
|
|
style="mso-spacerun: yes"> </span>We also added a set of tables so that
|
|
a-line traps and low-memory globals are displayed by name, rather than by
|
|
number.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Although our special circumstances led us to modify the GDB
|
|
source code, GDB is customizable out of the box.<span style="mso-spacerun:
|
|
yes"> </span>We've defined a handful of macros that automate debugging
|
|
tasks.<span style="mso-spacerun: yes"> </span>Figure 6 is a macro that
|
|
crawls through the stack in mac space.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>For comparison, Figure 7 is what GDB produces when
|
|
backtracking code that is compiled with GDB debugging symbols.</p>
|
|
|
|
</div>
|
|
|
|
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
|
|
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
|
|
</span>
|
|
|
|
<div class=Section13>
|
|
|
|
<div style='mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-height-rule:exactly'>
|
|
|
|
<table cellspacing=0 cellpadding=0 hspace=0 vspace=0 align=center>
|
|
<tr>
|
|
<td valign=top align=left style='padding-top:9.0pt;padding-right:9.0pt;
|
|
padding-bottom:9.0pt;padding-left:9.0pt'>
|
|
<div style='border:solid windowtext .75pt;padding:0in 0in 0in 0in;background:
|
|
#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>define macktrace<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun: yes"> </span>set
|
|
$_fp = cpu_state.regs[14].ul.n + 0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun: yes">
|
|
</span>silentswap32 (((uint32*)$_fp)[1]+0)<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun: yes"> </span>set
|
|
$_pc = $_val + 0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun: yes">
|
|
</span>silentswap32 (((uint32*)$_fp)[0]+0)<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun: yes"> </span>set
|
|
$_fp = $_val + 0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun: yes">
|
|
</span>while $_fp > 100 && $_fp < 30000000<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>set $_start = (long) $_pc + 0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>while $_start > (long)&end &&
|
|
*(uint16 *)$_start != 0x564E<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>set
|
|
$_start = $_start - 2<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>end<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>printf "func=0x%lX, ret=0x%lX, fp=0x%lX,
|
|
args=0x%02X%02X%02X%02X 0x%02X%02X%02X%02X 0x%02X%02X%02X%02X\n",\<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>$_start,
|
|
$_pc, $_fp,\<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>((uint8
|
|
*)$_fp)[8], ((uint8 *)$_fp)[9], ((uint8 *)$_fp)[10],\<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>((uint8
|
|
*)$_fp)[11], ((uint8 *)$_fp)[12], ((uint8 *)$_fp)[13],\<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>((uint8
|
|
*)$_fp)[14], ((uint8 *)$_fp)[15], ((uint8 *)$_fp)[16],\<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style='mso-tab-count:1'> </span>((uint8
|
|
*)$_fp)[17], ((uint8 *)$_fp)[18], ((uint8 *)$_fp)[19]<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>silentswap32 ((uint32*)$_fp)[1]+0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>set $_pc = $_val + 0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>silentswap32 ((uint32*)$_fp)[0]+0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>set $_fp = $_val + 0<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun: yes"> </span>end<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>end<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>(gdb) macktrace<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>func=0x3824F8, ret=0x38250E, fp=0xB28E3C,
|
|
args=0x00B2E852 0x000300B2 0x8E580037<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>func=0x37A2BE, ret=0x37A3A6, fp=0xB28E4A,
|
|
args=0x0037BA12 0x000000B2 0x8F840037<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>func=0x37AECE, ret=0x37AFF0, fp=0xB28E58,
|
|
args=0x0001002E 0xE0BC0000 0x00010035<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>func=0x379D58, ret=0x379E0C, fp=0xB28F84,
|
|
args=0x000100B2 0x8F9200B2 0x8F9A0000<o:p></o:p></span></p>
|
|
<p class=MsoNormal align=center style='text-align:center;border:none;
|
|
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
|
|
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-height-rule:exactly'><span style='font-size:12.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></span></p>
|
|
<p class=MsoNormal align=center style='text-align:center;border:none;
|
|
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
|
|
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-height-rule:exactly'><span style='font-size:12.0pt'>Figure 6.<span
|
|
style="mso-spacerun: yes"> </span>Macktrace Definition and Example<o:p></o:p></span></p>
|
|
<p class=MsoNormal align=center style='text-align:center;border:none;
|
|
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
|
|
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-height-rule:exactly'><span style='font-family:Courier'><![if !supportEmptyParas]> <![endif]><o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>(gdb) backtrace<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>#0<span style="mso-spacerun: yes">
|
|
</span>C_SysBeep (i=10) at osutil.c:837<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>#1<span style="mso-spacerun: yes">
|
|
</span>0x18934d in PascalToCCall (ignoreme=2271560241, infop=0x29faa4)<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>at emutrap.c:94<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>#2<span style="mso-spacerun: yes">
|
|
</span>0x17d0c9 in alinehandler (pc=3661160, ignored=0x0)<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>at executor.c:399<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>#3<span style="mso-spacerun: yes">
|
|
</span>0x1c1b85 in trap_direct (trap_number=10, exception_pc=3661160, <o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>exception_address=0) at trap.c:201<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>#4<span style="mso-spacerun: yes">
|
|
</span>0x197cfc in S68K_HANDLE_0x00B5 () at syn68k.c:1038<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>#5<span style="mso-spacerun: yes">
|
|
</span>0x196067 in interpret_code (start_code=0x2df6c4) at syn68k.c:587<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>#6<span style="mso-spacerun: yes">
|
|
</span>0x12d476 in beginexecutingat (startpc=11730018)<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>at launch.c:328<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>#7<span style="mso-spacerun: yes">
|
|
</span>0x12e1ce in launchchain (fName=0x2b53f8 "\004Risk",
|
|
vRefNum=-32717, <o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>resetmemory=1 '\001') at launch.c:575<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>#8<span style="mso-spacerun: yes">
|
|
</span>0x12f6e0 in Launch (<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>fName_arg=0x910 "\004Riskutor",
|
|
'ˇ' <repeats 27 times>, vRefNum_arg=-32717)<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>at launch.c:1142<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>#9<span style="mso-spacerun: yes">
|
|
</span>0x17e1f7 in executor_main ()<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>at executor.c:589<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'>#10 0x13371a in main (argc=2, argv=0xbffffa04)<o:p></o:p></span></p>
|
|
<p class=MsoNormal style='border:none;mso-border-alt:solid windowtext .75pt;
|
|
padding:0in;mso-padding-alt:0in 0in 0in 0in;mso-element:frame;mso-element-frame-hspace:
|
|
9.0pt;mso-element-frame-vspace:9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:
|
|
margin;mso-element-left:center;mso-height-rule:exactly'><span
|
|
style='font-family:Courier'><span style="mso-spacerun:
|
|
yes"> </span>at main.c:2112</span></p>
|
|
<p class=MsoNormal align=center style='text-align:center;border:none;
|
|
mso-border-alt:solid windowtext .75pt;padding:0in;mso-padding-alt:0in 0in 0in 0in;
|
|
mso-element:frame;mso-element-frame-hspace:9.0pt;mso-element-frame-vspace:
|
|
9.0pt;mso-element-wrap:auto;mso-element-anchor-horizontal:margin;mso-element-left:
|
|
center;mso-height-rule:exactly'><span style='font-size:12.0pt'>Figure 7.<span
|
|
style="mso-spacerun: yes"> </span>GDB backtrace</span></p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
|
|
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
|
|
</span>
|
|
|
|
<div class=Section14><br clear=ALL style='mso-column-break-before:always'>
|
|
<br clear=ALL style='mso-column-break-before:always'>
|
|
|
|
<p class=MsoNormal>As you might guess, this disparity of information makes it
|
|
much easier for for us to track down bugs in our own code then finding bizarre
|
|
incompatibilities in the code that is being run under the emulator.</p>
|
|
|
|
<h2>Disassembler</h2>
|
|
|
|
<p class=MsoNormal>Since GDB already knows how to disassemble 680x0 code it was
|
|
possible to write a driver for GDB so that it can disassemble Mac
|
|
programs.<span style="mso-spacerun: yes"> </span>The driver is about
|
|
1,000 lines of C code, with another 500 lines describing the low-memory
|
|
globals.<span style="mso-spacerun: yes"> </span>Basically the driver knows
|
|
about CODE resources and how intersegment jumps work.<span style="mso-spacerun:
|
|
yes"> </span>GDB normally doesn't produce labels for jump targets or the
|
|
beginning of subroutines, so the driver adds those too, to make the output that
|
|
much easier to read.</p>
|
|
|
|
<h2>Run-time Aids</h2>
|
|
|
|
<p class=MsoNormal>Because we're using our own set of OS and Toolbox routines,
|
|
we can add code that is conditionally compiled into debug versions of Executor
|
|
that can provide still more information than GDB or GDB macros can.</p>
|
|
|
|
<h3>Debugtable, Debugnumber</h3>
|
|
|
|
<p class=MsoNormal>Our A-line trap handler has a table, known as debugtable, of
|
|
4096 32-bit ints that it updates each time a trap is taken.<span
|
|
style="mso-spacerun: yes"> </span>Each time alinehandler is called, a
|
|
variable known as "debugnumber" is incremented and then the value of
|
|
debugnumber is stored in the slot in debugtable corresponding to the aline trap
|
|
that was called.<span style="mso-spacerun: yes"> </span>This allows us to
|
|
see both what traps were recently executed and a complete list of every trap
|
|
that an application makes, no matter how long the application has run.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>This scheme has its drawbacks.<span style="mso-spacerun:
|
|
yes"> </span>Traps that are dispatched via selectors are all lumped
|
|
together.<span style="mso-spacerun: yes"> </span>Traps whose addresses
|
|
are taken and then are called by jumps through the address don't show up in
|
|
debugtable.<span style="mso-spacerun: yes"> </span>Although debugtable
|
|
and debugnumber are perhaps the least sophisticated portion of Executor,
|
|
they're still quite handy, since a visual inspection of the last 100 traps made
|
|
before an application died often gives a good idea of where to start looking
|
|
for the source of the incompatibility.</p>
|
|
|
|
<h3>XX_slam</h3>
|
|
|
|
<p class=MsoNormal>In the course of developing Executor, we did a major rewrite
|
|
of our memory manager and our TextEdit replacement.<span style="mso-spacerun:
|
|
yes"> </span>In both cases it's not enough to just implement the APIs
|
|
that are defined in Inside Macintosh, we also have to duplicate the in-memory
|
|
data structures so that programs which count on them will run properly.<span
|
|
style="mso-spacerun: yes"> </span>To help us verify that we weren't
|
|
adding new bugs when we rewrote those subsystems we added routines that would
|
|
consistency check the data structures that each of those subsystems support.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Because these consistency checks are thorough but time
|
|
consuming, we call them "slams", and by default they are not enabled,
|
|
even in debugging versions of Executor.<span style="mso-spacerun: yes">
|
|
</span>When they are enabled, the data structures for each subsystem are
|
|
slammed at the entry to a call that might modify one of the data structures and
|
|
the data structure is slammed once again on exit of the routine.<span
|
|
style="mso-spacerun: yes"> </span>We can turn them on at run-time either
|
|
by using a command line option when Executor is started or by using GDB to
|
|
enable the slamming.<span style="mso-spacerun: yes"> </span>This is
|
|
something we should have done for all of Executor's subsystems from day one,
|
|
since it's ever so helpful to be told that going into routine XXX, the heap was
|
|
fine, but coming out the heap was corrupted.</p>
|
|
|
|
<h3>Image Viewer</h3>
|
|
|
|
<p class=MsoNormal>Reading disassembled code is much easier than staring at hex
|
|
numbers.<span style="mso-spacerun: yes"> </span>Similarly, being able to
|
|
view a portion of memory as some sort of PixMap (assuming that the memory
|
|
really is a bit image) is also better than staring at a bunch of hex
|
|
numbers.<span style="mso-spacerun: yes"> </span>When we build Executor
|
|
for X-Windows, we also build an image server that uses UNIX interprocess
|
|
communication to communicate with the process being debugged under GDB.<span
|
|
style="mso-spacerun: yes"> </span>This allows us to monitor offscreen
|
|
graphics, which can be very important when an application makes many graphics
|
|
calls and eventually an abomination is drawn on the screen instead of what
|
|
should have been drawn.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Our debugging arsenal includes other, more prosaic,
|
|
tools.<span style="mso-spacerun: yes"> </span>In fact, our debugging
|
|
environment encourages the development of new tools, because it's so easy to
|
|
leverage existing tools into new tools and even write new tools from scratch.</p>
|
|
|
|
<span style='font-size:12.0pt;font-family:Helvetica;mso-ansi-language:EN-US'><b><u><br
|
|
clear=ALL style='mso-column-break-before:always'>
|
|
</u></b></span>
|
|
|
|
<h1>Future Plans</h1>
|
|
|
|
<p class=MsoNormal>Much of VCPU, a successor to Syn68k, has already been
|
|
written.<span style="mso-spacerun: yes"> </span>VCPU performs many
|
|
optimizations that Syn68k does not, including improved register allocation,
|
|
dead subregister elimination, opcode "widening", and moving work
|
|
outside of loops.<span style="mso-spacerun: yes"> </span>VCPU has a clean
|
|
high-level syntax for specifying both front ends and back ends, allowing it to
|
|
dynamically compile both PowerPC and m68k binaries on any architecture we
|
|
decide to support.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Although we don't explicitly mention it, the graphic
|
|
subsystem one layer above the blitter already has hooks in it to allow use of
|
|
graphics accelerators, where present.<span style="mso-spacerun: yes">
|
|
</span>We plan a native port to Win32 and OS/2 and those ports should be able
|
|
to use fancier graphic subsystems and also make use of the underlying network
|
|
APIs.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Currently INITs and CDEVs do not run under Executor, but the
|
|
same mechanisms that allow applications to run can also allow INITs and CDEVs
|
|
to run.<span style="mso-spacerun: yes"> </span>QuickTime and ATM will
|
|
both be high priorities after Executor 2 ships.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>We will also be developing compiler tools that will allow ISVs
|
|
to natively compile CPU specific routines to be used when their applications
|
|
are run under Executor.<span style="mso-spacerun: yes"> </span>Executor
|
|
already uses such gateways internally.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>Already, multiple simultaneous instances of Executor can be
|
|
run under NEXTSTEP and Linux (and to a lesser extent under Windows '95).<span
|
|
style="mso-spacerun: yes"> </span>Currently only Executor/NEXTSTEP
|
|
handles PICT pasteboard cutting and pasting from one instantiation of Executor
|
|
to another, and no versions of Executor do enough file locking to allow
|
|
concurrent access of the same HFS volumes at once.<span style="mso-spacerun:
|
|
yes"> </span>This needs to be fixed, since either through shared text
|
|
segments under UNIX and UNIX like operating systems or through DLLs under Microsoft
|
|
operating systems, it can be made fairly efficient to run multiple instances of
|
|
Executor simultaneously.<span style="mso-spacerun: yes"> </span>When that
|
|
is done, each instance of Executor has its own address space and is
|
|
automatically scheduled by the underlying operating system scheduler.<span
|
|
style="mso-spacerun: yes"> </span>That means that Executor
|
|
"inherits" memory-protection and pre-emptive multi-tasking from the
|
|
underlying core operating system.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>By properly exploiting this inheritance it should be
|
|
possible to provide an environment that allows well-behaved Mac applications to
|
|
run efficiently under a variety of PC operating systems with automatic
|
|
protection from non-well-behaved applications.</p>
|
|
|
|
<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
|
|
|
|
<p class=MsoNormal>One interesting variant on this theme would be to use Linux
|
|
as the core OS, but to hide it from the end-user, for a net result of an 80x86
|
|
box that boots an efficient, robust MacOS-like environment.<span
|
|
style="mso-spacerun: yes"> </span></p>
|
|
|
|
</div>
|
|
|
|
<span style='font-size:10.0pt;font-family:Palatino;mso-ansi-language:EN-US'><br
|
|
clear=ALL style='page-break-before:auto;mso-break-type:section-break'>
|
|
</span>
|
|
|
|
<div class=Section15>
|
|
|
|
<p class=MsoNormal><span style='font-size:12.0pt'><![if !supportEmptyParas]> <![endif]><o:p></o:p></span></p>
|
|
|
|
</div>
|
|
|
|
<div style='mso-element:footnote-list'><![if !supportFootnotes]><br clear=all>
|
|
|
|
<hr align=left size=1 width="33%">
|
|
|
|
<![endif]>
|
|
|
|
<div style='mso-element:footnote' id=ftn1>
|
|
|
|
<p class=MsoFootnoteText><a style='mso-footnote-id:ftn1' href="#_ftnref1"
|
|
name="_ftn1" title=""><span class=MsoFootnoteReference><span style='mso-special-character:
|
|
footnote'><![if !supportFootnotes]>[1]<![endif]></span></span></a>"What
|
|
the heck is a pointer to a C code label?", you ask?<span
|
|
style="mso-spacerun: yes"> </span>gcc (the GNU C compiler) has a
|
|
"pointer to label" extension to the C language which makes the
|
|
statement "<span style='font-family:Courier'>&&my_label"</span>
|
|
evaluate to a</p>
|
|
|
|
<p class=MsoFootnoteText>"<span style='font-family:Courier'>void *</span>"
|
|
that points to the compiled code for "<span style='font-family:Courier'>my_label:</span>"
|
|
within a C function. This, combined with gcc's "<span style='font-family:
|
|
Courier'>goto void *</span>" extension, allows C programs to execute goto
|
|
statements whose destinations are not known at compile time.</p>
|
|
|
|
</div>
|
|
|
|
<div style='mso-element:footnote' id=ftn2>
|
|
|
|
<p class=MsoFootnoteText><a style='mso-footnote-id:ftn2' href="#_ftnref2"
|
|
name="_ftn2" title=""><span class=MsoFootnoteReference><span style='mso-special-character:
|
|
footnote'><![if !supportFootnotes]>[2]<![endif]></span></span></a>I actually
|
|
set this watchpoint in the session of Executor that I am using to run Word 5.1
|
|
for the Macintosh to compose this document (Executor/Linux on a 90 MHz Pentium).</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</body>
|
|
|
|
</html>
|