%!PS-Adobe-2.0 %%Creator: dvips by Radical Eye Software %%Title: dospaper.dvi %%Pages: 13 1 %%BoundingBox: 0 0 612 792 %%EndComments %%BeginDocument: tex.pro /TeXDict 200 dict def TeXDict begin /bdf{bind def}def /bop-aux{}bdf /@rigin{ /@page-height exch def /@page-width exch def 72 Resolution div dup neg scale translate}bdf /@letter{Resolution dup -10 mul 8.5 11 @rigin}bdf /@landscape{[ 0 1 -1 0 0 0]concat Resolution dup 8.5 11 @rigin}bdf /@a4{Resolution dup -10.6929133858 mul 21 2.54 div 29.7 2.54 div @rigin}bdf /@legal{Resolution dup -13 mul 8.5 14 @rigin}bdf /@11x17{statusdict /11x17tray known{statusdict begin 11x17tray end}if Resolution dup -16 mul 11 17 @rigin}bdf /@manualfeed{ statusdict /manualfeed true put}bdf /@copies{/#copies exch def}bdf /@draft{ /bop-aux{gsave initmatrix 72 dup scale @page-width 2 div @page-height 2 div translate @page-height @page-width atan rotate /Helvetica-Bold findfont 2 scalefont setfont(DRAFT)dup stringwidth pop 2 div neg -1 moveto .95 setgray show grestore}bdf}bdf /@FontMatrix[1 0 0 -1 0 0]def /@FontBBox[0 0 0 0]def /dmystr(ZZf@@@)def /newname{dmystr cvn}bdf /df{/fontname exch def dmystr 2 fontname cvx(@@@@)cvs putinterval newname 7 dict def newname load begin /FontType 3 def /FontMatrix @FontMatrix def /FontBBox @FontBBox def /BitMaps 256 array def /BuildChar{CharBuilder}def /Encoding IdentityEncoding def end fontname{/foo setfont}2 array copy cvx def fontname load 0 dmystr 6 string copy cvn cvx put}bdf /dfe{newname dup load definefont setfont}bdf /ch-image{ ch-data 0 get}bdf /ch-width{ch-data 1 get}bdf /ch-height{ch-data 2 get}bdf /ch-xoff{ch-data 3 get}bdf /ch-yoff{ch-data 4 get}bdf /ch-dx{ch-data 5 get} bdf /CharBuilder{save 3 1 roll exch /BitMaps get exch get /ch-data exch def ch-data null ne{ch-dx 0 ch-xoff ch-yoff neg ch-xoff ch-width add ch-height ch-yoff sub setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-height ch-yoff sub .1 add]{ch-image}imagemask}if restore}bdf /dc{/ch-code exch def /ch-data exch def newname load /BitMaps get ch-code ch-data put}bdf /bop{gsave /SaveImage save def /bop-aux load exec 0 0 moveto}bdf /eop{clear SaveImage restore showpage grestore}bdf /@start{/Resolution exch def /IdentityEncoding 256 array def 0 1 255{IdentityEncoding exch 1 string dup 0 3 index put cvn put}for}bdf /p{show}bdf /RuleMatrix[1 0 0 -1 -.1 -.1]def /BlackDots 8 string def /v{gsave currentpoint translate false RuleMatrix{ BlackDots}imagemask grestore}bdf /a{moveto}bdf /delta 0 def /tail{dup /delta exch def 0 rmoveto}bdf /b{exch show tail}bdf /c{show delta 4 sub tail}bdf /d{ show delta 3 sub tail}bdf /e{show delta 2 sub tail}bdf /f{show delta 1 sub tail}bdf /g{show delta 0 rmoveto}bdf /h{show delta 1 add tail}bdf /i{show delta 2 add tail}bdf /j{show delta 3 add tail}bdf /k{show delta 4 add tail} bdf /l{show -4 0 rmoveto}bdf /m{show -3 0 rmoveto}bdf /n{show -2 0 rmoveto} bdf /o{show -1 0 rmoveto}bdf /q{show 1 0 rmoveto}bdf /r{show 2 0 rmoveto}bdf /s{show 3 0 rmoveto}bdf /t{show 4 0 rmoveto}bdf /w{0 rmoveto}bdf /x{0 exch rmoveto}bdf /y{3 2 roll show moveto}bdf /bos{/section save def}bdf /eos{clear section restore}bdf end %%EndDocument %%BeginDocument: texps.pro TeXDict begin /rf{655360 div mul Resolution mul 7227 div /PixPerEm exch def findfont dup length 1 add dict /newfont exch def{1 index /FID ne{newfont 3 1 roll put}{pop pop}ifelse}forall 256 dict begin newfont /Encoding get 255 -1 0{ 2 copy get 4 -1 roll 1000 mul PixPerEm div def pop}for pop newfont /Metrics currentdict put end /fontname exch def dmystr 2 fontname cvx(@@@@)cvs putinterval newname dup newfont definefont[PixPerEm 0 0 PixPerEm neg 0 0] makefont def fontname{/foo setfont}2 array copy cvx def fontname load 0 dmystr 6 string copy cvn cvx put}bdf /ObliqueSlant{dup sin exch cos div neg}bdf /SlantFont{/foo exch def[1 0 foo 1 0 0]TransFont}bdf /ExtendFont{/foo exch def 258 2 roll 0 1 255{pop foo div 256 1 roll}for 258 -2 roll[foo 0 0 1 0 0] TransFont}bdf /TransFont{exch findfont exch makefont dup length dict /newfont exch def{1 index /FID ne{newfont 3 1 roll put}{pop pop}ifelse}forall dup newfont definefont pop}bdf end %%EndDocument %%BeginDocument: special.pro TeXDict begin /SDict 200 dict def SDict begin /@SpecialDefaults{/hs 612 def /vs 792 def /ho 0 def /vo 0 def /hsc 1 def /vsc 1 def /ang 0 def /CLIP false def /BBcalc false def}bdf /@scaleunit 1 def /@hscale{@scaleunit div /hsc exch def}bdf /@vscale{@scaleunit div /vsc exch def}bdf /@hsize{/hs exch def /CLIP true def}bdf /@vsize{/vs exch def /CLIP true def}bdf /@hoffset{/ho exch def} bdf /@voffset{/vo exch def}bdf /@angle{/ang exch def}bdf /@rwi{10 div /rwi exch def}bdf /@llx{/llx exch def}bdf /@lly{/lly exch def}bdf /@urx{/urx exch def}bdf /@ury{/ury exch def /BBcalc true def}bdf end /@MacSetUp{userdict /md known{userdict /md get type /dicttype eq{md begin /letter{}def /note{}def /legal{}def /od{txpose 1 0 mtx defaultmatrix dtransform exch atan/pa exch def newpath clippath mark{transform{itransform moveto}}{transform{itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{ itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{ closepath}}pathforall newpath counttomark array astore /gc xdf pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack}if}def /txpose{pxs pys scale ppr aload pop por{noflips{pop exch neg exch translate pop 1 -1 scale}if xflip yflip and{pop exch neg exch translate 180 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg translate}if xflip yflip not and{pop exch neg exch translate pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 translate}if yflip xflip not and{ppr 1 get neg ppr 0 get neg translate} if}{noflips{translate pop pop 270 rotate 1 -1 scale}if xflip yflip and{ translate pop pop 90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg translate}if xflip yflip not and{translate pop pop 90 rotate ppr 3 get ppr 1 get neg sub neg 0 translate}if yflip xflip not and{ translate pop pop 270 rotate ppr 2 get ppr 0 get neg sub neg 0 exch translate} if}ifelse scaleby96{ppr aload pop 4 -1 roll add 2 div 3 1 roll add 2 div 2 copy translate .96 dup scale neg exch neg exch translate}if}def /cp{pop pop showpage pm restore}def end}if}if}def /psf$TeXscale{65536 div}def /startTexFig {/psf$SavedState save def userdict maxlength dict begin Resolution 72 div dup neg scale currentpoint translate /psf$ury exch psf$TeXscale def /psf$urx exch psf$TeXscale def /psf$lly exch psf$TeXscale def /psf$llx exch psf$TeXscale def /psf$y exch psf$TeXscale def /psf$x exch psf$TeXscale def currentpoint /psf$cy exch def /psf$cx exch def /psf$sx psf$x psf$urx psf$llx sub div def /psf$sy psf$y psf$ury psf$lly sub div def psf$sx psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub translate /showpage{}def /erasepage{ }def /copypage{}def @MacSetUp}def /doclip{psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 roll moveto 6 -1 roll exch lineto exch lineto exch lineto closepath clip newpath moveto}def /endTexFig{end psf$SavedState restore}def /@beginspecial{SDict begin /SpecialSave save def Resolution 72 div dup neg scale currentpoint translate @SpecialDefaults}bdf /@setspecial{CLIP{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto closepath clip}{initclip}ifelse ho vo translate hsc vsc scale ang rotate BBcalc{rwi urx llx sub div dup scale llx neg lly neg translate}if /showpage{}def newpath}bdf /@endspecial{clear SpecialSave restore end}bdf /@defspecial{SDict begin}bdf /@fedspecial{end}bdf /li{lineto}bdf /rl{rlineto} bdf /rc{rcurveto}bdf /np{/SaveX currentpoint /SaveY exch def def newpath}bdf /st{stroke SaveX SaveY moveto}bdf /fil{fill SaveX SaveY moveto}bdf /ellipse{ /endangle exch def /startangle exch def /yrad exch def /xrad exch def /savematrix matrix currentmatrix def translate xrad yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}bdf end %%EndDocument TeXDict begin @defspecial /@scaleunit 100 def @fedspecial end TeXDict begin 300 @start /fa 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 14 17 21 21 35 32 14 14 14 21 28 10 14 10 12 21 21 21 21 21 21 21 21 21 21 14 14 28 28 28 21 38 25 25 28 30 25 25 30 30 14 18 28 23 35 28 30 25 30 25 21 23 30 25 35 25 23 23 16 12 16 18 21 14 21 21 18 21 18 12 21 21 12 12 18 12 30 21 21 21 21 16 16 12 21 18 28 18 18 16 17 11 17 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 21 21 7 21 21 21 21 9 23 21 14 14 21 21 0 21 21 21 10 0 22 15 14 23 23 21 37 42 0 21 0 14 14 14 14 14 14 14 14 0 14 14 0 14 14 14 37 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 37 0 11 0 0 0 0 23 30 39 13 0 0 0 0 0 28 0 0 0 12 0 0 12 21 28 21 0 0 0 0 /Times-Italic 1000 655360 rf /fb 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 25 25 25 25 25 25 25 25 25 25 25 25 25 0 0 0 25 25 25 25 0 25 25 25 25 25 25 25 0 0 25 0 25 25 25 25 25 25 25 25 0 25 25 0 25 25 25 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 25 0 0 0 0 25 25 0 25 0 0 0 0 0 0 0 0 0 25 0 0 25 25 0 25 0 0 0 0 /Courier 1000 655360 rf /fc 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 14 23 21 21 42 35 14 14 14 21 24 10 14 10 12 21 21 21 21 21 21 21 21 21 21 14 14 24 24 24 21 39 30 28 30 30 28 25 32 32 16 21 32 28 39 30 32 25 32 30 23 28 30 30 42 30 30 28 14 12 14 24 21 14 21 23 18 23 18 14 21 23 12 14 23 12 35 23 21 23 23 18 16 14 23 21 30 21 21 18 16 9 16 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 21 21 7 21 21 21 21 12 21 21 14 14 23 23 0 21 21 21 10 0 22 15 14 21 21 21 42 42 0 21 0 14 14 14 14 14 14 14 14 0 14 14 0 14 14 14 42 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 42 0 12 0 0 0 0 28 32 42 14 0 0 0 0 0 30 0 0 0 12 0 0 12 21 30 23 0 0 0 0 /Times-Bold 1000 655360 rf /fd 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 11 14 17 17 28 26 11 11 11 17 19 8 11 8 9 17 17 17 17 17 17 17 17 17 17 9 9 19 19 19 15 31 24 22 22 24 20 18 24 24 11 13 24 20 30 24 24 18 24 22 18 20 24 24 31 24 24 20 11 9 11 16 17 11 15 17 15 17 15 11 17 17 9 9 17 9 26 17 17 17 17 11 13 9 17 17 24 17 17 15 16 7 16 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 17 17 6 17 17 17 17 6 15 17 11 11 18 18 0 17 17 17 8 0 15 12 11 15 15 17 33 33 0 15 0 11 11 11 11 11 11 11 11 0 11 11 0 11 11 11 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 30 0 9 0 0 0 0 20 24 30 10 0 0 0 0 0 22 0 0 0 9 0 0 9 17 24 17 0 0 0 0 /Times-Roman 1000 524288 rf /fe df[<03C00FF01FF83FFC7FFE7FFEFFFFFFFFFFFFFFFF7FFE7FFE3FFC1FF80FF003C0>16 16 2 -2 21]15 dc dfe /ff 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 14 17 21 21 35 32 14 14 14 21 23 10 14 10 12 21 21 21 21 21 21 21 21 21 21 12 12 23 23 23 18 38 30 28 28 30 25 23 30 30 14 16 30 25 37 30 30 23 30 28 23 25 30 30 39 30 30 25 14 12 14 19 21 14 18 21 18 21 18 14 21 21 12 12 21 12 32 21 21 21 21 14 16 12 21 21 30 21 21 18 20 8 20 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 21 21 7 21 21 21 21 7 18 21 14 14 23 23 0 21 21 21 10 0 19 15 14 18 18 21 42 42 0 18 0 14 14 14 14 14 14 14 14 0 14 14 0 14 14 14 42 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 37 0 11 0 0 0 0 25 30 37 13 0 0 0 0 0 28 0 0 0 12 0 0 12 21 30 21 0 0 0 0 /Times-Roman 1000 655360 rf /fg 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 17 28 25 25 50 41 17 17 17 25 28 12 17 12 14 25 25 25 25 25 25 25 25 25 25 17 17 28 28 28 25 46 36 33 36 36 33 30 39 39 19 25 39 33 47 36 39 30 39 36 28 33 36 36 50 36 36 33 17 14 17 29 25 17 25 28 22 28 22 17 25 28 14 17 28 14 41 28 25 28 28 22 19 17 28 25 36 25 25 22 20 11 20 26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 25 25 8 25 25 25 25 14 25 25 17 17 28 28 0 25 25 25 12 0 27 17 17 25 25 25 50 50 0 25 0 17 17 17 17 17 17 17 17 0 17 17 0 17 17 17 50 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50 0 15 0 0 0 0 33 39 50 16 0 0 0 0 0 36 0 0 0 14 0 0 14 25 36 28 0 0 0 0 /Times-Bold 1000 786432 rf /fh 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 12 15 19 19 31 29 12 12 12 19 21 9 12 9 10 19 19 19 19 19 19 19 19 19 19 10 10 21 21 21 17 34 27 25 25 27 23 21 27 27 12 15 27 23 33 27 27 21 27 25 21 23 27 27 35 27 27 23 12 10 12 18 19 12 17 19 17 19 17 12 19 19 10 10 19 10 29 19 19 19 19 12 15 10 19 19 27 19 19 17 18 7 18 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 19 19 6 19 19 19 19 7 17 19 12 12 21 21 0 19 19 19 9 0 17 13 12 17 17 19 37 37 0 17 0 12 12 12 12 12 12 12 12 0 12 12 0 12 12 12 37 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 33 0 10 0 0 0 0 23 27 33 12 0 0 0 0 0 25 0 0 0 10 0 0 10 19 27 19 0 0 0 0 /Times-Roman 1000 589824 rf /fi 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 12 21 19 19 37 31 12 12 12 19 21 9 12 9 10 19 19 19 19 19 19 19 19 19 19 12 12 21 21 21 19 35 27 25 27 27 25 23 29 29 15 19 29 25 35 27 29 23 29 27 21 25 27 27 37 27 27 25 12 10 12 22 19 12 19 21 17 21 17 12 19 21 10 12 21 10 31 21 19 21 21 17 15 12 21 19 27 19 19 17 15 8 15 19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 19 19 6 19 19 19 19 10 19 19 12 12 21 21 0 19 19 19 9 0 20 13 12 19 19 19 37 37 0 19 0 12 12 12 12 12 12 12 12 0 12 12 0 12 12 12 37 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 37 0 11 0 0 0 0 25 29 37 12 0 0 0 0 0 27 0 0 0 10 0 0 10 19 27 21 0 0 0 0 /Times-Bold 1000 589824 rf /fj 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 17 21 25 25 41 39 17 17 17 25 34 12 17 12 14 25 25 25 25 25 25 25 25 25 25 17 17 34 34 34 25 46 30 30 33 36 30 30 36 36 17 22 33 28 41 33 36 30 36 30 25 28 36 30 41 30 28 28 19 14 19 21 25 17 25 25 22 25 22 14 25 25 14 14 22 14 36 25 25 25 25 19 19 14 25 22 33 22 22 19 20 14 20 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19 25 25 8 25 25 25 25 11 28 25 17 17 25 25 0 25 25 25 12 0 26 17 17 28 28 25 44 50 0 25 0 17 17 17 17 17 17 17 17 0 17 17 0 17 17 17 44 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 44 0 14 0 0 0 0 28 36 47 15 0 0 0 0 0 33 0 0 0 14 0 0 14 25 33 25 0 0 0 0 /Times-Italic 1000 786432 rf /fk 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 20 33 30 30 60 50 20 20 20 30 34 15 20 15 17 30 30 30 30 30 30 30 30 30 30 20 20 34 34 34 30 56 43 40 43 43 40 37 47 47 23 30 47 40 56 43 47 37 47 43 33 40 43 43 60 43 43 40 20 17 20 35 30 20 30 33 27 33 27 20 30 33 17 20 33 17 50 33 30 33 33 27 23 20 33 30 43 30 30 27 24 13 24 31 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20 30 30 10 30 30 30 30 17 30 30 20 20 33 33 0 30 30 30 15 0 32 21 20 30 30 30 60 60 0 30 0 20 20 20 20 20 20 20 20 0 20 20 0 20 20 20 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 60 0 18 0 0 0 0 40 47 60 20 0 0 0 0 0 43 0 0 0 17 0 0 17 30 43 33 0 0 0 0 /Times-Bold 1000 943718 rf end TeXDict begin @letter %%EndProlog %%Page: 1 1 bop 567 199 a fk(DOS)15 b(as)g(a)g(Mach)g(3.0)g(Application)333 361 y fj(Ger\ ald)d(Malan,)h(Richar)o(d)f(Rashid,)i(David)e(Golub,)g(and)h(Robert)g(Bar)n (on)693 419 y(School)g(of)f(Computer)g(Science)696 477 y(Carnegie)g(Mellon)h (University)445 535 y(5000)f(Forbes)h(A)n(venue)g(Pittsbur)n(gh,)g(Pennsylvan\ ia)g(15213)819 652 y(\(412\))f(268-8744)170 768 y(Internet:)17 b(grm@cs.cmu.e\ du,)e(rfr@cs.cmu.edu,)f(dbg@cs.cmu.edu,)g(rvb@cs.cmu.edu)905 939 y fi(Abstrac\ t)235 1033 y fh(W)m(e)7 b(have)e(implemented)i(support)f(for)h(the)g(DOS)g (operating)f(system)g(on)g(top)h(of)h(the)e(Mach)g(3.0)h(kernel.)13 b(This)6 b (support)179 1078 y(included)t(machine-dependent)s(kernel)f(modi\256cations)g (for)i(the)e(i386/i486)g(architecture)h(to)g(handle)f(virtual)h(8086)f(mode,) 179 1124 y(a)10 b(multithreaded)h(emulation)f(of)h(the)f(IBM)i(PC')n(s)e(VGA) h(display)f(and)f(I/O)j(devices,)e(direct)g(support)g(for)i(a)e(number)g(of) 179 1170 y(common)e(DOS)i(functions)f(and)f(frequently)i(loaded)e(DOS)h(drive\ rs,)h(and)f(code)f(to)i(integrate)g(DOS)f(functionality)h(with)179 1215 y(the) d(existing)g(4.3BSD)g(Unix)g(Server)m(.)14 b(The)6 b(resulting)h(system)g(all\ ows)g(multiple)h(virtual)g(DOS)f(environments,)g(supports)179 1261 y(DOS)h (versions)f(3.1)h(to)g(5.0,)h(and)e(is)i(capable)d(of)j(running)e(common)h (DOS)g(software)g(including)f(performance)g(sensitive)179 1307 y(PC)i(enterta\ inment)g(software)g(such)e(as)i(W)o(ing)g(Commander)f(\261)h(a)g(high-speed)e (space)g(combat)i(simulation)g(system.)235 1352 y(Many)h(lessons)g(were)h(lea\ rned)g(during)g(the)g(course)f(of)h(this)h(work.)20 b(DOS)11 b(stresses)f(a)h (number)g(of)g(Mach)g(features)179 1398 y(infrequently)h(used)f(by)h(Unix)g (emulation.)23 b(The)12 b(timing)h(and)f(latency)f(demands)g(of)h(DOS)h(appli\ cations,)f(especially)179 1444 y(those)6 b(with)i(animation)f(and)g(sound,)f (are)h(dramatically)h(dif)o(ferent)g(from)g(those)f(of)g(typical)h(Unix)f(app\ lications.)12 b(Because)179 1489 y(most)f(DOS)h(programs)f(interact)h(intimat\ ely)g(with)h(the)e(underlying)g(PC)h(hardware,)f(DOS)h(emulation)f(expanded)e (our)179 1535 y(knowledge)c(about)h(the)h(behavior)f(of)h(Mach)g(3.0)g(when)f (asked)f(to)j(provide)e(a)h(virtual)h(machine)d(environment)i(rather)g(than) 179 1581 y(pure)k(client/server)g(support.)19 b(In)11 b(particular)o(,)h(quir\ ks)f(of)g(the)h(PC)f(architecture)f(\261)h(such)f(as)h(support)f(for)i(the)f (so-called)179 1626 y(\252high)d(memory)h(area\272)f(above)g(0x100000)e(\261) j(had)g(to)g(be)g(precisely)f(emulated.)235 1672 y(This)h(paper)f(describes)g (our)i(implementation,)f(its)h(capabilities)f(and)f(limitations,)j(and)e(the) g(lessons)f(learned)g(about)179 1718 y(Mach)g(in)i(the)f(course)e(of)j(our)f (development)e(effort.)75 1882 y fg(1.)50 b(Intr)o(oduction)75 2016 y ff(Appr\ oximately)7 b(one)i(year)g(ago)f(we)h(undertook,)f(as)h(an)g(experiment,)g (the)g(implementation)e(of)h(support)f(for)h(the)h(i386/i486)75 2066 y(family\ ')m(s)h(\252virtual)f(8086\272)h(mode)h(and)f(the)g(DOS)g(operating)f(system.) 16 b(W)m(e)10 b(were)h(encouraged)g(to)e(begin)h(this)f(work)h(by)f(the)75 2116 y(success)j(already)f(achieved)g(in)f(the)h(implementation)e(on)h(the)h (Macintosh)f(of)g(support)f(for)h(the)h(MacOS)g(and)g(Multi\256nder)75 2166 y (under)f(Mach)h(2.5.)k(W)m(e)c(felt)e(that)h(DOS)g(and)g(the)g(implementation) f(of)h(a)h(virtual)e(x86)g(machine)i(would)e(present)i(a)f(new)h(set)75 2216 y (of)f(challenges)h(for)e(Mach')n(s)i(abstractions)f(and)g(implementation.)137 2307 y(T)n(oday)g(Mach)h(3.0)f(DOS)g(support)f(consists)h(of:)137 2440 y fe (\017)21 b ff(machine-dependent)10 b(kernel)g(support)f(for)h(virtual)f(8086) g(mode)75 2488 y 720 2 v 73 x fd(This)f(research)g(was)g(sponsored)e(in)i(par\ t)g(by)g(The)g(Defense)f(Advanced)f(Research)h(Projects)i(Agency)n(,)d(Inform\ ation)h(Science)h(and)g(T)n(echnology)d(Of)o(\256ce,)75 2600 y(under)h(the)h (title)h(\252Research)e(on)h(Parallel)h(Computing\272,)e(ARP)m(A)i(Order)f (No.)12 b(7330,)6 b(issued)h(by)f(DARP)m(A/CMO)i(under)e(Contract)h(MDS972-90\ -C-0035)75 2640 y(and)g(in)h(part)f(by)g(the)h(Open)f(Software)g(Foundation)g (\(OSF\).)i(The)e(views)h(and)f(conclusions)e(contained)h(in)i(this)g(documen\ t)e(are)h(those)g(of)h(the)f(authors)g(and)75 2679 y(should)g(not)h(be)f(inte\ rpreted)g(as)h(representing)f(the)h(of)o(\256cial)h(policies,)e(either)h(expr\ essed)f(or)h(implied,)g(of)g(DARP)m(A,)h(OSF)m(,)h(or)e(the)f(U.S.)j(governme\ nt.)p eop %%Page: 2 2 bop 137 42 a fe(\017)21 b ff(a)11 b(multithreaded)e(emulator)h(task)g(which) g(provides:)229 126 y fc(\261)20 b ff(virtual)9 b(Industry)g(Standard)h(Archi\ tecture)f(\(ISA\))h(I/O)g(devices;)229 188 y fc(\261)20 b ff(BIOS)10 b(emulat\ ion;)229 250 y fc(\261)20 b ff(DOS)11 b(ISA)f(device)g(drivers;)229 312 y fc (\261)20 b ff(emulation)8 b(of)h(common)g(DOS)g(extensions)f(such)h(as)h(Expa\ nded)f(Memory)f(\(LIM)h(3.2\),)h(Extended)e(Memory)n(,)270 362 y(High)i(Memor\ y)g(and)g(Upper)g(Memory)h(Block)e(management)j(\(XMS)e(2.0\);)229 424 y fc (\261)20 b ff(direct)10 b(implementation)f(of)h(many)h(common)f(DOS)h(functio\ ns;)d(and)229 486 y fc(\261)20 b ff(software)10 b(to)g(integrate)g(DOS)g(with) f(Mach')n(s)i(existing)e(Unix)g(server)n(.)137 602 y(The)i(system)g(supports) e(DOS)i(versions)f(3.1)g(to)g(5.0)g(and)g(runs)g(W)o(indows)f(3.0)i(in)f(real\ -mode.)15 b(W)m(e)c(have)g(successfully)75 651 y(run)16 b(over)h(100)f(DOS)g (applications)g(ranging)f(from)i(business)f(software)h(such)g(as)g(Lotus)g (123)f(and)g(Microsoft)g(W)m(ord)75 701 y(to)e(entertainment)f(software)i(suc\ h)f(as)h(W)o(ing)e(Commander)o(,)j(Space)f(Quest)f(IV)-5 b(,)15 b(King')l(s)g (Quest)f(V)-5 b(,)15 b(Populous,)f(and)g(the)75 751 y(Microsoft)d(Flight)f (Simulator)l(.)20 b(Many)11 b(of)h(these)g(applications)e(are)j(extremely)f (demanding)f(in)g(terms)h(of)g(both)e(graphics)75 801 y(performance)h(for)f (VGA)g(displays)g(and)g(sound)g(generated)g(by)g(commercial)h(monaural)g(and) f(stereo)g(sound)g(boards.)137 892 y(This)h(paper)g(describes)h(our)e(impleme\ ntation,)g(our)g(experiences,)j(the)d(lessons)h(we)h(have)f(learned)g(and)g (the)g(potential)75 942 y(impact)f(of)g(our)g(work)g(on)g(future)f(Mach)i(dev\ elopment.)75 1105 y fg(2.)50 b(Overview)12 b(of)g(DOS)75 1239 y ff(A)f(limite\ d)e(knowledge)h(of)g(DOS)g(and)h(the)f(Intel)g(80386)f(processor)i(is)f(neede\ d)h(to)f(understand)g(the)g(Mach)h(DOS)g(support.)75 1289 y(There)h(are)f(thr\ ee)g(main)g(areas)h(of)e(interest:)k(the)d(way)g(DOS)g(programs)f(call)h(the) f(operating)g(system,)h(the)g(or)o(ganization)e(of)75 1338 y(a)i(DOS)f(machin\ e')n(s)h(physical)f(memory)m(,)h(and)f(the)g(operation)g(of)g(the)g(Intel)f (80386)g(processor)r(')m(s)i(V)m(irtual)e(8086)h(mode.)137 1430 y(T)n(wo)i (operating)e(system)j(modules)f(are)h(used)f(by)f(DOS)i(programs)f(for)f(syst\ em)h(support,)g(the)g(BIOS)g(ROM)f(and)h(the)75 1480 y(DOS)f(kernel.)18 b(The) 11 b(BIOS)g(is)g(a)h(set)f(of)g(ROM)f(routines)g(that)h(support)e(device)j (speci\256c)g(system)f(calls.)18 b(The)12 b(DOS)f(kernel)75 1529 y(is)f(locat\ ed)f(in)h(RAM)f(and)h(supports)e(a)j(general)f(operating)f(system)h(interface\ .)15 b(The)c(DOS)f(kernel)f(uses)i(BIOS)e(routines)g(to)75 1579 y(perform)h (many)h(operations,)e(but)h(DOS)g(programs)g(frequently)f(bypass)i(the)f(DOS) g(kernel)g(and)h(directly)e(call)h(the)g(BIOS.)137 1671 y(DOS)e(programs)g (perform)g(system)g(calls)g(by)g(loading)e(call)i(parameters)h(into)e(machine) i(registers)e(and)h(then)g(generating)75 1720 y(a)j(numbered)f(exception.)16 b (The)11 b(registers)f(used)g(to)g(pass)h(parameters)h(vary)e(depending)g(on)g (the)g(system)h(call.)16 b(Exceptions)75 1770 y(are)11 b(generated)g(by)f(DOS) h(programs)f(with)g(the)g fb(INT)h ff(machine)g(instruction.)j(The)d fb(INT)f ff(instruction)e(takes)j(the)g(exception)75 1820 y(number)f(as)h(an)g(argumen\ t)f(which)g(is)g(used)g(as)h(an)g(index)f(into)f(the)h(interrupt)f(vector)h (table)g(located)g(in)g(low)g(memory)n(.)15 b(The)75 1870 y(interrupt)c(vecto\ r)i(selected)i(by)d(the)i fb(INT)f ff(instruction)e(determines)i(which)g(inte\ rrupt)e(service)j(routine)e(will)g(handle)h(the)75 1920 y(exception.)k(Dif)n (ferent)11 b(exception)g(numbers)g(are)h(used)f(by)f(dif)o(ferent)h(DOS)g(and) g(BIOS)f(system)i(calls.)17 b(DOS)12 b(provides)e(a)75 1969 y(general)j(opera\ ting)f(system)h(interface)g(that)f(only)f(has)i(one)g(of)f(these)h(exception) g(\252entry)f(points.\272)22 b(The)13 b(BIOS)f(routines)75 2019 y(are)h(group\ ed)f(by)h(device)g(services,)h(so)f(there)g(are)g(many)g(dif)n(ferent)g(BIOS) f(exception)h(numbers)f(\(eg.)23 b(the)12 b(BIOS)h(video)75 2069 y(services)e (are)g(all)f(entered)h(via)f(exception)f(number)i(0x10,)e(the)i(disk)e(routin\ es)g(all)h(use)h(exception)f(0x13\).)137 2160 y(The)15 b(address)g(space)g (of)f(a)h(typical)e(DOS)h(machine)h(is)f(shown)f(in)h(\256gure)g(1.)26 b(Key) 15 b(areas)g(are)g(the)f(interrupt)e(vector)75 2210 y(table,)g(the)f(BIOS)f (scratch)i(pad)f(RAM,)h(and)f(the)g(memory)h(above)f(0xA0000.)17 b(The)11 b (interrupt)f(vector)h(table)g(contains)f(the)75 2260 y(addresses)i(for)e(the) g(exception)g(handling)f(routines,)h(referred)h(to)f(below)g(as)h(Interrupt)e (Service)i(Routines)f(or)g(ISRs.)16 b(DOS)75 2310 y(programs)9 b(often)f(mani\ pulate)h(these)g(ISR)g(addresses)h(to)e(redirect)h(dif)o(ferent)g(interrupts) e(into)g(their)i(own)f(ISRs.)15 b(The)9 b(BIOS)75 2360 y(scratch)j(pad)f(RAM) g(is)g(used)g(to)f(keep)i(device)f(state)h(information)d(for)i(several)g(impo\ rtant)f(devices.)18 b(It)11 b(is)g(in)f(this)g(scratch)75 2409 y(pad)g(RAM)f (that)g(the)g(BIOS)g(keyboard)h(routines)e(keep)i(the)f(queue)h(of)f(incoming) g(keyboard)g(characters,)j(the)d(video)g(driver)75 2459 y(keeps)15 b(the)f (scan)h(line)f(state,)i(and)f(the)f(disk)f(driver)h(saves)h(motor)f(status)g (and)h(small)f(input)f(buf)n(fers.)28 b(The)15 b(area)h(above)75 2509 y(0xA00\ 00)8 b(contains)h(the)g(video)g(RAM,)g(Extended)h(Memory)f(Manager)h(swap)g (buf)o(fers,)g(BIOS)f(ROM)g(routines)g(and)g(High)75 2559 y(Memory)h(area.) 137 2650 y(Central)g(to)f(the)h(Mach)h(DOS)f(support)f(is)h(the)g(V)m(irtual) f(8086)g(\(V86\))g(operating)g(mode)i(of)f(the)g(Intel)f(80386)g(processor)n (.)75 2700 y(When)f(the)h(processor)f(is)g(in)g(this)f(V86)h(mode,)h(it)e(int\ erprets)g(memory)i(and)f(executes)i(instructions)c(as)j(if)e(the)h(machine)h (were)p eop %%Page: 3 3 bop 75 855 a @beginspecial 75 @hscale 75 @vscale -250 @voffset -25 @hoffset @setspecial %%BeginDocument: dosmem.ps 50 dict begin /arrowHeight 8 def /arrowWidth 4 def /none null def /numGraphicParameters 17 def /stringLimit 65535 def /Begin { save numGraphicParameters dict begin } def /End { end restore } def /SetB { dup type /nulltype eq { pop false /brushRightArrow idef false /brushLeftArrow idef true /brushNone idef } { /brushDashOffset idef /brushDashArray idef 0 ne /brushRightArrow idef 0 ne /brushLeftArrow idef /brushWidth idef false /brushNone idef } ifelse } def /SetCFg { /fgblue idef /fggreen idef /fgred idef } def /SetCBg { /bgblue idef /bggreen idef /bgred idef } def /SetF { /printSize idef /printFont idef } def /SetP { dup type /nulltype eq { pop true /patternNone idef } { /patternGrayLevel idef patternGrayLevel -1 eq { /patternString idef } if false /patternNone idef } ifelse } def /BSpl { 0 begin storexyn newpath n 1 gt { 0 0 0 0 0 0 1 1 true subspline n 2 gt { 0 0 0 0 1 1 2 2 false subspline 1 1 n 3 sub { /i exch def i 1 sub dup i dup i 1 add dup i 2 add dup false subspline } for n 3 sub dup n 2 sub dup n 1 sub dup 2 copy false subspline } if n 2 sub dup n 1 sub dup 2 copy 2 copy false subspline patternNone not brushLeftArrow not brushRightArrow not and and { ifill } if brushNone not { istroke } if 0 0 1 1 leftarrow n 2 sub dup n 1 sub dup rightarrow } if end } dup 0 4 dict put def /Circ { newpath 0 360 arc patternNone not { ifill } if brushNone not { istroke } if } def /CBSpl { 0 begin dup 2 gt { storexyn newpath n 1 sub dup 0 0 1 1 2 2 true subspline 1 1 n 3 sub { /i exch def i 1 sub dup i dup i 1 add dup i 2 add dup false subspline } for n 3 sub dup n 2 sub dup n 1 sub dup 0 0 false subspline n 2 sub dup n 1 sub dup 0 0 1 1 false subspline patternNone not { ifill } if brushNone not { istroke } if } { Poly } ifelse end } dup 0 4 dict put def /Elli { 0 begin newpath 4 2 roll translate scale 0 0 1 0 360 arc patternNone not { ifill } if brushNone not { istroke } if end } dup 0 1 dict put def /Line { 0 begin 2 storexyn newpath x 0 get y 0 get moveto x 1 get y 1 get lineto brushNone not { istroke } if 0 0 1 1 leftarrow 0 0 1 1 rightarrow end } dup 0 4 dict put def /MLine { 0 begin storexyn newpath n 1 gt { x 0 get y 0 get moveto 1 1 n 1 sub { /i exch def x i get y i get lineto } for patternNone not brushLeftArrow not brushRightArrow not and and { ifill } if brushNone not { istroke } if 0 0 1 1 leftarrow n 2 sub dup n 1 sub dup rightarrow } if end } dup 0 4 dict put def /Poly { 3 1 roll newpath moveto -1 add { lineto } repeat closepath patternNone not { ifill } if brushNone not { istroke } if } def /Rect { 0 begin /t exch def /r exch def /b exch def /l exch def newpath l b moveto l t lineto r t lineto r b lineto closepath patternNone not { ifill } if brushNone not { istroke } if end } dup 0 4 dict put def /Text { ishow } def /idef { dup where { pop pop pop } { exch def } ifelse } def /ifill { 0 begin gsave patternGrayLevel -1 ne { fgred bgred fgred sub patternGrayLevel mul add fggreen bggreen fggreen sub patternGrayLevel mul add fgblue bgblue fgblue sub patternGrayLevel mul add setrgbcolor eofill } { eoclip originalCTM setmatrix pathbbox /t exch def /r exch def /b exch def /l exch def /w r l sub ceiling cvi def /h t b sub ceiling cvi def /imageByteWidth w 8 div ceiling cvi def /imageHeight h def bgred bggreen bgblue setrgbcolor eofill fgred fggreen fgblue setrgbcolor w 0 gt h 0 gt and { l b translate w h scale w h true [w 0 0 h neg 0 h] { patternproc } imagemask } if } ifelse grestore end } dup 0 8 dict put def /istroke { gsave brushDashOffset -1 eq { [] 0 setdash 1 setgray } { brushDashArray brushDashOffset setdash fgred fggreen fgblue setrgbcolor } ifelse brushWidth setlinewidth originalCTM setmatrix stroke grestore } def /ishow { 0 begin gsave fgred fggreen fgblue setrgbcolor /fontDict printFont findfont printSize scalefont dup setfont def /descender fontDict begin 0 [FontBBox] 1 get FontMatrix end transform exch pop def /vertoffset 0 descender sub printSize sub printFont /Courier ne printFont /Courier-Bold ne and { 1 add } if def { 0 vertoffset moveto show /vertoffset vertoffset printSize sub def } forall grestore end } dup 0 3 dict put def /patternproc { 0 begin /patternByteLength patternString length def /patternHeight patternByteLength 8 mul sqrt cvi def /patternWidth patternHeight def /patternByteWidth patternWidth 8 idiv def /imageByteMaxLength imageByteWidth imageHeight mul stringLimit patternByteWidth sub min def /imageMaxHeight imageByteMaxLength imageByteWidth idiv patternHeight idiv patternHeight mul patternHeight max def /imageHeight imageHeight imageMaxHeight sub store /imageString imageByteWidth imageMaxHeight mul patternByteWidth add string def 0 1 imageMaxHeight 1 sub { /y exch def /patternRow y patternByteWidth mul patternByteLength mod def /patternRowString patternString patternRow patternByteWidth getinterval def /imageRow y imageByteWidth mul def 0 patternByteWidth imageByteWidth 1 sub { /x exch def imageString imageRow x add patternRowString putinterval } for } for imageString end } dup 0 12 dict put def /min { dup 3 2 roll dup 4 3 roll lt { exch } if pop } def /max { dup 3 2 roll dup 4 3 roll gt { exch } if pop } def /arrowhead { 0 begin transform originalCTM itransform /taily exch def /tailx exch def transform originalCTM itransform /tipy exch def /tipx exch def /dy tipy taily sub def /dx tipx tailx sub def /angle dx 0 ne dy 0 ne or { dy dx atan } { 90 } ifelse def gsave originalCTM setmatrix tipx tipy translate angle rotate newpath 0 0 moveto arrowHeight neg arrowWidth 2 div lineto arrowHeight neg arrowWidth 2 div neg lineto closepath patternNone not { originalCTM setmatrix /padtip arrowHeight 2 exp 0.25 arrowWidth 2 exp mul add sqrt brushWidth mul arrowWidth div def /padtail brushWidth 2 div def tipx tipy translate angle rotate padtip 0 translate arrowHeight padtip add padtail add arrowHeight div dup scale arrowheadpath ifill } if brushNone not { originalCTM setmatrix tipx tipy translate angle rotate arrowheadpath istroke } if grestore end } dup 0 9 dict put def /arrowheadpath { newpath 0 0 moveto arrowHeight neg arrowWidth 2 div lineto arrowHeight neg arrowWidth 2 div neg lineto closepath } def /leftarrow { 0 begin y exch get /taily exch def x exch get /tailx exch def y exch get /tipy exch def x exch get /tipx exch def brushLeftArrow { tipx tipy tailx taily arrowhead } if end } dup 0 4 dict put def /rightarrow { 0 begin y exch get /tipy exch def x exch get /tipx exch def y exch get /taily exch def x exch get /tailx exch def brushRightArrow { tipx tipy tailx taily arrowhead } if end } dup 0 4 dict put def /midpoint { 0 begin /y1 exch def /x1 exch def /y0 exch def /x0 exch def x0 x1 add 2 div y0 y1 add 2 div end } dup 0 4 dict put def /thirdpoint { 0 begin /y1 exch def /x1 exch def /y0 exch def /x0 exch def x0 2 mul x1 add 3 div y0 2 mul y1 add 3 div end } dup 0 4 dict put def /subspline { 0 begin /movetoNeeded exch def y exch get /y3 exch def x exch get /x3 exch def y exch get /y2 exch def x exch get /x2 exch def y exch get /y1 exch def x exch get /x1 exch def y exch get /y0 exch def x exch get /x0 exch def x1 y1 x2 y2 thirdpoint /p1y exch def /p1x exch def x2 y2 x1 y1 thirdpoint /p2y exch def /p2x exch def x1 y1 x0 y0 thirdpoint p1x p1y midpoint /p0y exch def /p0x exch def x2 y2 x3 y3 thirdpoint p2x p2y midpoint /p3y exch def /p3x exch def movetoNeeded { p0x p0y moveto } if p1x p1y p2x p2y p3x p3y curveto end } dup 0 17 dict put def /storexyn { /n exch def /y n array def /x n array def n 1 sub -1 0 { /i exch def y i 3 2 roll put x i 3 2 roll put } for } def Begin [ 0.8 0 0 0.8 0 0 ] concat /originalCTM matrix currentmatrix def Begin %I Text 0 0 0 SetCFg /Helvetica 12 SetF [ 1 0 0 1 251 728 ] concat [ (1 Meg) () (0xE0000) () (0xD0000) () (0xC0000) () (0xA0000) () () () () () () () () () (0x500) () (0x400) () (Bottom) ] Text End Begin %I Line 1 0 0 [] 0 SetB 0 0 0 SetCFg 1 1 1 SetCBg 0 SetP [ -0.709275 0 0 -2 561.534 1748 ] concat 91 517 356 517 Line End Begin %I Line 1 0 0 [] 0 SetB 0 0 0 SetCFg 1 1 1 SetCBg 0 SetP [ 0.698885 0 0 1 245.799 197 ] concat 90 493 358 493 Line End Begin %I Rect 1 0 0 [] 0 SetB 0 0 0 SetCFg 1 1 1 SetCBg none SetP %I p n [ 1 0 0 1 148 197 ] concat 161 251 350 540 Rect End Begin %I Line 1 0 0 [] 0 SetB 0 0 0 SetCFg 1 1 1 SetCBg none SetP %I p n [ 1 0 0 1 148 195 ] concat 161 470 350 470 Line End Begin %I Line 1 0 0 [] 0 SetB 0 0 0 SetCFg 1 1 1 SetCBg none SetP %I p n [ 1 0 0 1 148 190 ] concat 161 451 350 451 Line End Begin %I Line 1 0 0 [] 0 SetB 0 0 0 SetCFg 1 1 1 SetCBg none SetP %I p n [ 1 0 0 1 148 197 ] concat 161 421 350 421 Line End Begin %I Line 1 0 0 [] 0 SetB 0 0 0 SetCFg 1 1 1 SetCBg none SetP %I p n [ 1 0 0 1 149 203 ] concat 161 341 350 341 Line End Begin %I Line 1 0 0 [] 0 SetB 0 0 0 SetCFg 1 1 1 SetCBg none SetP %I p n [ 1 0 0 1 148 197 ] concat 161 321 350 321 Line End Begin %I Line 1 0 0 [] 0 SetB 0 0 0 SetCFg 1 1 1 SetCBg none SetP %I p n [ 1 0 0 1 148 194 ] concat 161 301 350 301 Line End Begin %I Line 1 0 0 [] 0 SetB 0 0 0 SetCFg 1 1 1 SetCBg none SetP %I p n [ 1 0 0 1 149 191 ] concat 161 281 350 281 Line End Begin %I Text 0 0 0 SetCFg /Helvetica 12 SetF [ 1 0 0 1 316 729 ] concat [ (High Memory Area) () (System BIOS ROM) () (EMS Buffer and Emulator Code) () (Video ROM and BIOS) () (Screen RAM) () () () (DOS Application Space) () () () (Command Parser) () (DOS Kernel & Device Drivers) () (BIOS Scratch Pad RAM) () (Interrupt Vector Table) ] Text End End %I eop showpage end %%EndDocument @endspecial 552 925 a ff(Figure)10 b(1:)k(DOS)d(Application)d(Memory)i(Or)o (ganization.)75 1059 y(a)k(native)f(DOS)h(8086)f(machine.)26 b(A)14 b(set)f (of)h fa(privileged)f ff(instructions)e(encountered)j(by)f(this)g(V86)g(machi\ ne)h(generates)75 1108 y(faults)h(that)g(are)h(passed)g(to)f(a)h(protected)f (mode)h(monitor)l(.)31 b(In)15 b(the)g(Mach)i(DOS)e(system,)j(a)e(thread)f (operating)f(in)h(the)75 1158 y(V86)e(mode)g(generates)i(General)e(Protection) f(\(GP\))h(faults)g(that)g(are)h(passed)g(to)e(the)h(Mach)h(Kernel)g(when)f (a)h(privileged)75 1208 y(instruction)9 b(is)j(executed.)20 b(The)13 b(instru\ ctions)c(that)j(are)g(privileged)e(under)i(V86)f(mode)h(are)h(those)e(that:) 17 b(manipulate)11 b(the)75 1258 y(interrupt)d(state)j(of)f(the)g(machine,)h (generate)g(or)f(return)g(from)g(interrupts,)f(and)h(access)i(privileged)d (I/O)h(ports.)75 1423 y fg(3.)50 b(The)13 b(Organization)d(of)i(DOS)g(as)h (a)f(Mach)h(Application)75 1557 y ff(The)g(implementation)d(of)i(DOS)g(as)g (a)h(Mach)f(application)f(consists)g(of)h(two)f(pieces,)j(support)c(within)h (the)g(Mach)i(kernel,)75 1606 y(and)f(a)g(Mach)g(task)f(used)h(as)g(a)g(DOS)g (emulator)m(.)20 b(The)12 b(Mach)g(kernel)f(manages)i(threads)f(running)e(in) h(V86)g(mode)h(and)f(the)75 1656 y(faults)i(that)g(they)g(generate.)25 b(The) 14 b(emulator)f(task)h(provides)e(DOS)i(and)f(BIOS)h(system)f(call)h(support.) 23 b(It)13 b(is)h(important)75 1706 y(to)e(note,)i(that)e(the)h(DOS)g(Emulato\ r)f(runs)h(the)g(native)f(DOS)h(kernel)g(in)f(a)i(V86)e(mode)h(thread)g(and)g (does)g(not)f(attempt)h(to)75 1756 y(reimplement)d(all)g(of)g(the)g(DOS)h(and) f(BIOS)g(system)h(calls.)75 1916 y fg(3.1.)51 b(Micr)o(okernel)12 b(support)f (for)h(DOS)75 2035 y ff(The)h(Mach)f(kernel)g(provides)f(management)i(for)e (V86)h(mode)g(threads,)g(and)g(the)g(interface)g(between)g(a)h(V86)e(thread)h (and)75 2085 y(its)e(associated)h(Emulator)e(task.)16 b(Speci\256cally)10 b (the)g(kernel)g(provides:)137 2210 y fe(\017)21 b ff(V86)10 b(thread)g(creati\ on)g(and)g(maintenance)h(through)e(existing)g(Mach)i(system)f(calls)137 2293 y fe(\017)21 b ff(V86)10 b(thread)g(interrupt)e(\257ag)j(management)g(using)f (a)g(\252virtual\272)g(interrupt)e(\257ag)137 2376 y fe(\017)21 b ff(Handling) 9 b(of)h(simple)g(V86)g(General)g(Protection)f(faults)137 2459 y fe(\017)21 b ff(Simulation)8 b(of)i(external)g(interrupts)f(within)f(the)j(V86)e(thread.)p eop %%Page: 4 4 bop 75 42 a fg(3.1.1.)51 b(Manipulation)10 b(of)i(the)g(V)n(irtual)f(Machine) 75 161 y ff(Support)c(for)h(the)h(creation)f(and)h(maintenance)h(of)e(V86)g (mode)h(threads)g(is)g(implemented)f(in)g(the)h(Mach)g(kernel)g(in)f(the)g (form)75 211 y(of)k(extensions)f(to)g(the)h(thread)f(get)h(and)g(set)g(state) g(system)g(calls.)20 b(Dif)o(ferent)12 b(types)f(of)h(thread)g fa(\257avors)g ff(determine)g(which)75 260 y(kinds)c(of)h(operations)g(the)g(thread)g(state) h(calls)f(will)g(perform.)14 b(The)c(existing)e fa(mode)i ff(thread)f(\257avo\ r)g(was)h(modi\256ed)f(and)h(two)75 310 y(new)h(\257avors)f(were)h(introduced\ ,)e(the)h fa(port)g(map)g ff(and)g fa(V86)g(assist)g ff(\257avors.)137 443 y fe(\017)21 b ff(The)12 b fa(mode)f ff(\257avor)h(is)f(used)h(to)f(take)g(a)h (thread)g(into)e(and)h(out)g(of)g(the)g(V86)g(operating)g(mode.)19 b(T)m(o)12 b(turn)e(on)h(the)h(V86)179 493 y(operating)d(mode,)i(the)e(VM)h(bit)f(in)h (the)g(thread')m(s)g(\257ag)h(register)f(is)f(set.)16 b(T)m(o)10 b(turn)f(of) o(f)h(the)g(V86)g(mode,)g(the)g(VM)g(bit)f(is)179 543 y(cleared.)137 626 y fe (\017)21 b ff(The)11 b fa(port)g(map)f ff(\257avor)h(enables)h(or)e(disables) h(the)g(threads)g(access)i(to)d(a)i(given)e(ISA)h(I/O)f(port.)17 b(In)10 b (this)g(way)n(,)h(direct)179 675 y(access)g(to)e(the)g(VGA)g(registers)g(can) h(be)g(given)e(to)h(the)g(V86)g(thread)g(to)g(speed)h(up)f(video)f(intensive) g(DOS)i(programs.)137 758 y fe(\017)21 b ff(The)15 b fa(v86)f(assist)g ff(\ \257avor)g(accesses)j(the)d(kernel')m(s)h(V86)f(support)e(data)j(structures)f (that)f(contain)h(a)h(pointer)e(to)g(the)179 808 y(Emulator)c(task')n(s)h(int\ errupt)e(queue,)i(and)g(the)g(value)g(for)f(the)h(V86)f(thread')m(s)h(\252vir\ tual\272)f(interrupt)f(\257ag)j(\(see)f(below\).)75 968 y fg(3.1.2.)51 b(Mana\ ging)11 b(the)h(Interrupt)g(Flag)75 1088 y ff(Many)6 b(of)h(the)f(V86)g(threa\ d')m(s)h(privileged)e(instructions)t(attempt)h(to)g(manipulate)g(the)g(machin\ e')n(s)h(interrupt)e(status,)i(requiring)75 1137 y(the)h(kernel)g(to)g(implem\ ent)g(a)g(\252virtual\272)g(interrupt)e(\257ag)j(for)f(each)h(V86)f(thread.) 14 b(The)9 b(kernel)f(alone)g(is)g(allowed)g(to)g(enable)g(or)75 1187 y(disab\ le)h(these)h(interrupts,)e(yet)h(DOS)g(programs)h(all)e(assume)j(that)e(they) g(are)h(in)e(total)h(control)f(of)h(the)g(machine.)15 b(Therefore)75 1237 y (it)9 b(was)i(necessary)g(to)f(modify)f(the)g(Mach)i(kernel)f(to)f(provide)g (a)i(\252virtual\272)e(interrupt)f(state)i(to)g(the)f(V86)h(thread.)15 b(Sinc\ e)10 b(the)75 1287 y(V86)f(thread)h(must)g(perform)f(a)i(privileged)d(instruc\ tion)f(to)j(inspect)f(or)h(modify)e(the)i(interrupt)e(\257ag,)j(the)e(Mach)i (kernel)e(can)75 1337 y(always)k(replace)h(the)e(true)h(interrupt)e(bit)g(wit\ h)h(this)g(\252virtual\272)g(interrupt)f(\257ag.)23 b(Space)14 b(was)g(made)f (in)g(the)f(V86)h(thread')m(s)75 1386 y(process)h(control)f(block)g(to)g(hold) f(the)i(\257ag,)h(and)f(the)f(kernel)h(was)g(modi\256ed)f(so)h(that)f(the)h fb (thread)r 13 2 v 12 w(get)r 13 2 v 13 w(state)f ff(and)75 1436 y fb(thread)r 13 2 v 12 w(set)s 13 2 v 12 w(state)d ff(routines)f(would)g(access)k(the)d (\252virtual\272)f(interrupt)g(\257ag)h(instead)g(of)g(the)g(true)g(one.)137 1528 y(Additional)g(kernel)h(support)f(is)i(also)g(required)f(because)i(of)e (the)h(peculiar)f(way)h(in)f(which)h(80x86)e(processors)i(delay)75 1577 y(the) e(setting)g(of)g(the)h(interrupt)d(bit)i(in)g(the)g(\257ag)h(register)f(after) h(an)g(STI)g(instruction.)j(The)d(STI)g(instruction)d(doesn')o(t)i(set)h(the) 75 1627 y(interrupt)g(\257ag)i(during)e(its)h(execution,)i(but)d(delays)i(the) g(setting)f(of)g(that)g(\257ag)h(until)e(after)i(the)g fa(next)g ff(instructi\ on)d(\256nishes)75 1677 y(executing.)15 b(Some)10 b(DOS)g(programs)g(rely)f (on)h(this)f(feature,)i(so)e(its)h(emulation)f(was)h(critical.)15 b(T)m(o)10 b (solve)g(this)e(problem,)i(the)75 1727 y(trace)i(\257ag)g(is)g(set)g(in)f(the) g(V86)g(thread')n(s)g(\257ag)h(register)g(during)e(the)h(STI)h(instruction') -5 b(s)12 b(emulation.)19 b(Possibly)10 b(by)h(design,)75 1777 y(the)i(trace) h(exception)f(then)g(occurs)h(at)g(the)f(same)i(point)d(that)g(the)i(interrup\ t)d(\257ag)j(bit)e(should)h(be)g(set.)25 b(When)14 b(this)e(trace)75 1826 y (exception)g(occurs,)h(the)f(kernel)h(sets)f(the)g(interrupt)f(bit)g(in)h(the) g(\252virtual\272)f(\257ag)i(register)f(and)g(clears)h(the)f(trace)h(bit)f (in)f(the)75 1876 y(V86)f(thread')m(s)h(\257ags.)75 2036 y fg(3.1.3.)51 b(Gen\ eral)12 b(Protection)f(Fault)h(Handling)75 2156 y ff(The)g(privileged)f(instr\ uctions)e(that)i(are)i(generated)f(by)g(the)f(V86)g(thread)h(and)g(are)g(not) f(DOS)h(or)g(BIOS)f(system)h(calls)g(are)75 2205 y(emulated)f(in)f(the)g(Mach) h(Kernel.)16 b(These)c(instructions)c(are)j(the)f(set)h(and)g(clear)g(interru\ pt)d(\(STI)j(and)g(CLI\),)f(push)g(and)h(pop)75 2255 y(of)g(the)h(\257ag)g (register)g(\(PUSHF)f(and)h(POPF\),)h(and)e(the)h(return)f(from)h(interrupt)d (\(IRET\))j(instructions.)18 b(The)12 b(instructions)75 2305 y(are)f(emulated) g(in)e(the)h(kernel)h(as)f(follows:)137 2438 y fe(\017)21 b ff(CLI:)10 b(Clea\ rs)g(the)g(\252virtual\272)g(interrupt)e(\257ag)137 2521 y fe(\017)21 b ff (STI:)10 b(Sets)h(the)f(\252virtual\272)f(interrupt)g(\257ag)h(as)h(described) g(above)137 2604 y fe(\017)21 b ff(PUSHF:)10 b(Pushes)g(the)g(\257ag)g(regist\ er)g(onto)f(the)g(V86)h(thread')m(s)h(stack.)k(The)c(\252virtual\272)e(interr\ upt)f(\257ag)i(bit)f(is)h(masked)179 2654 y(onto)f(this)g(value.)p eop %%Page: 5 5 bop 137 42 a fe(\017)21 b ff(POPF:)11 b(Pops)h(the)g(\257ag)g(register)f(fro\ m)h(the)f(V86)h(thread')m(s)g(stack.)20 b(The)13 b(\252virtual\272)e(interrup\ t)f(\257ag)i(bit)f(is)g(set)h(to)f(the)179 91 y(value)f(from)g(the)g(stack.) 137 174 y fe(\017)21 b ff(IRET)n(:)13 b(The)h(kernel)f(pops)g(the)g(\257ag)h (register)f(from)g(the)h(stack)f(like)g(a)h(POPF)m(,)g(and)f(then)g(pops)g (the)h(V86)f(thread')m(s)179 224 y(instruction)8 b(pointer)h(from)h(the)g(sta\ ck.)75 384 y fg(3.1.4.)51 b(Simulating)11 b(Interrupts)h(W)o(ithin)f(the)h (V)n(irtual)f(Machine)75 503 y ff(The)e(Mach)g(kernel)f(is)g(responsible)f (for)h(generating)f(external)h(interrupts)f(within)f(the)i(V86)g(thread)g(tha\ t)g(have)g(been)h(queued)75 553 y(by)h(I/O)g(threads)g(in)g(the)h(Emulator)f (task.)15 b(Using)10 b(the)g(data)h(structures)f(in)g(the)g(V86)g(thread')n (s)g(pcb,)h(the)g(kernel)f(determines)75 603 y(whether)g(or)g(not)f(there)i (are)g(any)f(external)g(interrupts)f(that)g(need)i(to)f(be)g(delivered)g(to)g (the)g(V86)g(thread.)137 694 y(T)n(o)g(allow)g(for)h(smoother)f(execution,)h (the)f(kernel)h(interrupts)e(the)h(V86)g(thread)h(sequentially)l(.)17 b(That) 11 b(is,)g(it)e(waits)i(until)75 744 y(the)d(last)g(kernel)g(interrupt)e(has) j(completed)f(before)g(it)g(generates)h(another)e(one.)15 b(The)9 b(kernel)f (sets)g(a)h(\257ag)g(when)f(it)f(generates)75 794 y(an)12 b(interrupt)e(withi\ n)h(the)h(V86)f(thread)h(and)g(clears)h(it)e(when)h(an)h(interrupt)d(return)h (instruction)f(is)i(emulated.)21 b(While)11 b(the)75 844 y(\257ag)g(is)f(set,) h(the)f(kernel)g(does)g(not)g(generate)h(any)f(further)f(external)h(interrupt\ s.)75 1004 y fg(3.2.)51 b(The)12 b(Emulator)g(T)l(ask)75 1123 y ff(The)e(Emul\ ator)f(task)h(is)f(a)i(multithreaded)d(Mach)i(task)g(that)f(supplies)f(input) h(to)g(the)g(V86)g(thread)h(and)f(provides)g(emulation)75 1173 y(for)k(DOS)h (and)g(BIOS)g(system)g(calls.)26 b(Five)14 b(threads)g(execute)g(simultaneous\ ly)f(in)g(the)h(Emulator)f(task:)22 b(the)13 b(Monitor)m(,)75 1223 y(V86,)h (T)o(imer)o(,)h(Mouse,)f(and)g(Keyboard)f(threads.)26 b(The)14 b(Monitor)e (thread)h(initializes)f(the)i(DOS)f(support)f(and)i(provides)75 1273 y(system) c(call)g(emulation.)15 b(The)10 b(V86)g(thread)g(executes)h(the)f(DOS)g(code) g(in)f(virtual)g(8086)g(mode.)16 b(The)10 b(T)o(imer)n(,)h(Mouse)f(and)75 1322 y(Keyboard)g(threads)g(all)g(generate)h(the)f(input)f(and)h(interrupts)f(that) g(drive)h(the)g(DOS)h(applications.)137 1414 y(The)16 b(\256rst)f(1.15)g(Mega\ bytes)h(of)f(the)g(task')m(s)h(memory)g(is)f(set)g(up)g(by)g(the)g(Emulator)g (to)g(resemble)h(a)g(typical)e(DOS)75 1464 y(machine.)32 b(This)16 b(is)f(acc\ omplished)h(by)f(setting)g(up)g(the)g(interrupt)f(table,)j(scratch)g(pad)e (RAM,)h(screen)h(RAM,)e(BIOS)75 1513 y(ROM,)f(and)f(high)f(memory)i(area)h (as)f(shown)f(in)g(\256gure)g(1.)25 b(Several)14 b(\252snapshot\272)g(\256les) g(are)g(used)f(to)g(provide)g(the)g(DOS)75 1563 y(interrupt)8 b(table)i(and)g (BIOS)g(scratch)h(pad)f(RAM)g(areas.)16 b(These)c(\256les)e(are)h(created)g (during)e(a)h(one)h(time)f(setup)g(session.)15 b(T)m(o)75 1613 y(give)c(fast) h(access)i(to)d(the)g(screen)i(and)f(BIOS)f(ROM)h(routines,)f(the)h(machine') n(s)g(physical)f(memory)h(is)f(mapped)i(onto)d(the)75 1663 y(task')m(s)g(virt\ ual)e(address)j(space)f(using)f(Mach)h(system)g(calls.)16 b(Due)10 b(to)f(the) g(segmented)h(addressing)f(scheme,)j(the)e(8086)e(can)75 1713 y(generate)k (addresses)g(with)e(up)h(to)f(21)h(bits,)g(64)g(Kbytes)g(above)g(one)g(megaby\ te.)18 b(DOS)12 b(programs)f(expect)g(the)g(64K)g(High)75 1762 y(Memory)f(Are\ a)h(above)g(the)f(one)g(Megabyte)h(limit)d(to)i(wrap)g(back)h(around)f(to)f (the)h(beginning)f(of)h(physical)f(memory)n(.)15 b(The)75 1812 y(Emulator)c (maps)i(both)d(the)i(High)e(memory)i(area)h(and)f(the)f(\256rst)h(64K)f(bytes) g(of)g(low)g(memory)h(to)f(the)h(same)h(place)f(in)f(the)75 1862 y(task')m (s)g(virtual)e(address)i(space.)75 2022 y fg(3.2.1.)51 b(The)12 b(Monitor)g (\252INT\272)h(handler)e(thr)o(ead)75 2141 y ff(The)k(Monitor)d(thread,)j(for\ mally)e(the)h(V86)f(thread')n(s)h(exception)f(handler)n(,)j(provides)d(emulat\ ion)g(for)g(DOS)h(and)g(BIOS)75 2191 y(system)d(calls)g(as)g(well)f(as)h(supp\ ort)e(for)h(privileged)f(IN)h(and)h(OUT)g(instructions.)i(The)e(system)g(call) g(emulation)e(is)i(broken)75 2241 y(down)d(into)g(groups)g(depending)f(on)i (the)g(type)f(of)h(service)g(being)f(emulated.)15 b(Some)10 b(of)e(these)h (major)g(groups)f(are)i(the)e(BIOS)75 2291 y(disk,)i(video,)g(mouse,)h(and)f (memory)h(expansion)f(routines)f(as)i(well)f(as)h(the)f(DOS)g(calls)h(related) f(to)g(console)g(I/O.)137 2382 y(A)i(secondary)f(function)f(of)h(the)g(monito\ r)f(thread)h(is)g(to)f(support)g fb(IN)h ff(and)h fb(OUT)f ff(instructions)e (that)h(attempt)h(to)g(access)75 2432 y(privileged)e(I/O)i(ports.)16 b(T)m (o)11 b(enable)g(an)g(I/O)g(port)f(for)g(access,)k(the)c(emulator)h(must)f (use)i(the)f fb(thread)q 13 2 v 13 w(set)r 13 2 v 13 w(state)f ff(call)75 2482 y(using)g(the)h fa(port)g(map)f ff(\257avor)i(described)f(above.)18 b(The)12 b (majority)e(of)h(these)g(\252privileged\272)g(I/O)f(instructions)g(are)h(exec\ uted)75 2532 y(by)c(DOS)h(interrupt)e(service)j(routines.)k(By)8 b(catching)f (these)i(privileged)d(I/O)h(instructions)f(and)i(supplying)e(arti\256cial)h (return)75 2581 y(values,)k(the)f(Monitor)e(thread)i(is)g(able)h(to)f(support) e(several)j(types)f(of)g(DOS)h(device)f(drivers)g(including)e(the)i(W)o(indow\ s)f(3.0)75 2631 y(Logitech)h(Mouse)g(driver)g(and)g(many)h(types)f(of)g(DOS)g (keyboard)g(drivers.)p eop %%Page: 6 6 bop 137 42 a fe(\017)21 b fc(Emulator)9 b(Disk)h(Support)179 108 y ff(The)h (Emulator)q(')n(s)g(disk)f(support)g(provides)g(two)g(main)h(functions:)k(emu\ lation)10 b(for)g(BIOS)h(disk)f(system)h(calls,)h(and)179 158 y(access)i(to)e (the)g(unix)g(\256le)g(system)h(as)g(a)g(Network)f(DOS)g(drive.)21 b(By)12 b (emulating)g(the)g(BIOS)g(disk)g(routines,)g(we)h(in)179 208 y(ef)o(fect)c (emulate)h(the)f(DOS)f(disk)h(related)g(system)g(calls)g(which)f(all)h(use)g (BIOS)f(routines)g(to)g(perform)h(the)g(actual)g(disk)179 257 y(I/O.)179 324 y (Access)15 b(to)d(physical)h(disk)f(devices)i(and)f(to)f(UFS)i(\256les)f(is)g (provided)f(by)g(the)h(Emulator)n(.)23 b(Physical)13 b(devices)h(and)179 374 y (UFS)e(\256les)h(are)h(both)d(used)i(as)g(DOS)f(\256le)h(systems.)22 b(The)14 b(Emulator)e(uses)h(the)f(Unix)g(raw)g(device)h(\256les)g(to)f(access)179 423 y(the)g(hard)f(disk')m(s)h(DOS)h(partitions)d(and)i(DOS)g(\256le)g(systems)g (on)g(\257oppy)f(disks.)20 b(Unix)11 b(\256les)i(are)f(also)g(used)h(by)e(the) 179 473 y(Emulator)f(as)h(dos)f(\256le)g(system)h(images.)179 540 y(The)g(Uni\ x)e(\256le)i(system)g(is)f(also)g(used)h(as)g(a)g(Network)f(DOS)g(disk)g(driv\ e.)15 b(The)c(Emulator)f(uses)h(the)f(DOS)h(Network)179 589 y(Redirector)m (,)i(a)g(group)e(of)g(DOS)h(system)h(calls)f(to)f(achieve)i(this.)19 b(The)13 b(Network)e(Redirector)g(is)h(used)g(by)g(DOS)g(to)179 639 y(access)f(\256le) f(systems)g(that)e(do)h(not)g(use)h(DOS)f(\256le)h(allocation)e(tables.)15 b (W)n(ith)8 b(the)i(Network)e(Redirector)h(interface)h(in)179 689 y(place,)h (the)f(V86)g(thread)g(can)h(access)i(any)d(\256le)g(within)f(the)h(Unix)f(\ \256le)i(system.)137 772 y fe(\017)21 b fc(Emulator)9 b(V)n(ideo)h(Support) 179 839 y ff(The)j(Emulator)f(keeps)h(track)f(of)g(the)g(VGA)h(video)e(state,) j(emulates)f(BIOS)f(video)f(routines)h(and)g(redirects)g(some)179 888 y(video) i(exceptions)g(back)g(into)f(the)i(V86)f(thread.)27 b(The)15 b(Emulator)f(sav\ es)i(the)e(VGA)g(state)h(at)f(startup)g(time)g(and)179 938 y(restores)d(it)f (upon)g(exit.)16 b(This)11 b(video)f(state)h(consists)f(of)h(VGA)g(register)f (settings)g(and)h(the)g(contents)f(of)g(the)h(VGA)-5 b(')n(s)179 988 y(video) 11 b(RAM)h(banks.)22 b(V)m(ideo)12 b(state)h(for)f(each)h(of)f(the)g(VGA)l (')m(s)h(video)e(modes)i(is)f(stored)g(in)g(a)h(\256le.)22 b(The)12 b(Emulato\ r)179 1038 y(uses)e(the)f(information)f(in)h(this)g(\256le)g(to)g(change)h (the)g(VGA)-5 b(')n(s)10 b(state)f(when)h(a)g(mode)g(change)g(is)f(requested) h(by)f(a)h(BIOS)179 1088 y(system)g(call.)15 b(This)10 b(VGA)g(information)e (\256le)i(is)g(created)h(during)d(the)i(setup)f(session)h(described)g(above.) 16 b(A)10 b(copy)f(of)179 1137 y(the)h(machine')n(s)h(default)e(font)g(is)i (also)f(kept)g(in)f(a)i(\256le)g(that)e(is)h(used)h(with)e(VGA)h(text)g(modes\ .)179 1204 y(T)m(o)g(emulate)g(the)f(BIOS)g(video)g(routines,)g(the)g(emulato\ r)g(directly)f(writes)h(to)g(the)g(VGA)h(registers)f(and)h(video)e(RAM)179 1254 y(areas.)19 b(If)10 b(the)h(emulator)g(does)g(not)f(support)g(a)i(video) e(routine,)g(it)h(passes)h(the)f(routine)e(back)j(into)e(the)g(VGA)h(BIOS)179 1303 y(for)h(the)h(V86)g(thread)f(to)h(execute.)24 b(These)14 b(redirected)f (routines)f(generally)h(do)f(not)h(require)f(the)h(VGA)g(BIOS)g(to)179 1353 y (know)c(a)i(previous)f(state)g(and)g(will)f(not)h(crash)h(the)f(video)f(subsy\ stem.)137 1436 y fe(\017)21 b fc(Emulator)9 b(Mouse)i(support)179 1503 y ff (The)h(Emulator)f(task)g(supports)g(all)g(the)g(functions)f(of)h(a)h(DOS)g (memory)g(resident)e(mouse)i(device)g(driver)m(.)19 b(It)11 b(does)179 1553 y (this)g(using)g(both)g(the)h(Monitor)f(and)h(Mouse)g(threads.)21 b(The)13 b (Emulator)q(')n(s)f(mouse)h(driver)e(complies)i(with)e(version)179 1602 y(6.0) d(of)h(the)f(Microsoft)f(Mouse)i(speci\256cation.)15 b(This)8 b(speci\256cati\ on)h(is)f(comprised)h(of)f(both)f(a)i(set)g(of)f(Mouse)h(related)179 1652 y (system)15 b(calls,)h(and)f(hooks)f(that)g(allow)g(DOS)h(programs)f(to)h(supp\ ly)e(their)h(own)g(mouse)h(event)g(handlers.)28 b(The)179 1702 y(Monitor)7 b (thread)j(emulates)g(these)g(Mouse)g(BIOS)f(calls)h(while)e(the)i(Mouse)f(thr\ ead)h(provides)e(support)g(for)h(the)h(user)179 1752 y(supplied)f(mouse)i(eve\ nt)f(handlers.)137 1835 y fe(\017)21 b fc(Emulator)9 b(Expansion)g(support) 179 1901 y ff(Several)h(DOS)g(expansion)f(speci\256cations)h(are)h(supported) d(by)i(the)f(Emulator)h(including)e(the)h(EMS)h(3.2)g(and)g(XMS)179 1951 y (2.0)16 b(speci\256cations.)33 b(Both)15 b(of)h(these)g(speci\256cations,)i (like)e(the)g(Microsoft)e(Mouse)j(speci\256cation)f(mentioned)179 2001 y(abov\ e,)e(are)f(collections)f(of)g(system)h(calls)g(that)f(extend)g(DOS)h(and)f (BIOS)h(functionality)-6 b(.)23 b(In)12 b(1985)g(Lotus,)h(Intel)179 2051 y (and)h(Microsoft)e(agreed)j(to)e(support)g(a)h(standard)g(that)f(increased)h (the)g(amount)g(of)f(memory)h(DOS)g(applications)179 2100 y(could)8 b(access.) 17 b(This)10 b(standard,)f(supported)f(by)h(the)g(Emulator)g(task)g(with)f (the)h(Mach)h(virtual)e(memory)i(subsystem,)179 2150 y(is)g(known)f(as)i(the) f(LIM)h(EMS.)179 2217 y(The)18 b(Expanded)g(Memory)f(Speci\256cation)g(\(EMS\ \))h(allows)f(DOS)h(programs)f(to)g(access)j(memory)e(on)f(special)179 2267 y (hardware)9 b(boards)f(by)g(switching)f(this)g(memory)i(in)f(and)g(out)g(of)g (certain)g(banks)h(in)e(the)i(DOS)f(memory)h(space.)16 b(DOS)179 2316 y(progr\ ams)f(access)i(memory)f(in)e(this)g(special)i(hardware)f(by)g(gaining)f(handl\ es)h(to)f(certain)h(expanded)h(memory)179 2366 y(segments.)35 b(The)18 b(Emul\ ator)e(task)h(emulates)h(this)e(behavior)g(by)g fb(vm)s 13 2 v 12 w(allocatin\ g)g ff(memory)h(in)g(the)f(task')n(s)179 2416 y(address)11 b(space)h(to)f(use) g(as)h(this)d(special)j(expanded)f(memory)g(and)g(then)f(moving)g(this)g(memo\ ry)i(in)e(and)h(out)f(of)g(the)179 2466 y(special)g(DOS)h(memory)g(banks)f (whenever)h(necessary)n(.)179 2532 y(T)m(o)h(allow)g(DOS)g(programs)g(access) i(to)e(the)g(conventional)f(memory)h(in)g(the)g(machine)h(above)f(the)g(one)h (megabyte)179 2582 y(boundary)l(,)7 b(the)f(eXtended)h(Memory)f(Speci\256cati\ on)g(\(XMS\))g(was)h(created.)14 b(This)6 b(speci\256cation)h(also)f(is)g(a)g (collection)179 2632 y(of)i(BIOS)h(system)g(calls)g(that)f(switch)g(blocks)h (of)f(extended)h(memory)g(with)f(blocks)g(of)g(memory)i(in)e(the)g(addressabl\ e)179 2682 y(DOS)13 b(area.)25 b(This)13 b(is)g(implemented)g(on)f(native)h (DOS)g(machines)h(with)e(special)i(memory)f(drivers)g(that)f(take)h(the)p eop %%Page: 7 7 bop 179 42 a ff(machine)9 b(into)e(and)i(out)e(of)i(protected)f(mode)h(to)f (gain)g(access)i(to)e(the)h(extended)f(memory)n(.)14 b(The)c(Emulator)e(alloc\ ates)179 91 y(virtual)f(memory)j(in)f(the)g(same)h(way)g(that)e(it)h(does)g (for)g(the)g(EMS)g(speci\256cation)h(and)f(copies)g(this)g(memory)g(into)f (and)179 141 y(out)h(of)h(the)g(DOS)h(areas)g(on)f(demand.)75 301 y fg(3.2.2.) 51 b(The)12 b(V86)h(thr)n(ead)75 420 y ff(The)18 b(V86)g(thread)f(is)h(the)f (only)g(thread)h(that)f(operates)h(in)f(virtual)f(8086)h(mode.)38 b(This)18 b (thread)g(executes)g(the)g(DOS)75 470 y(application)d(and)i(kernel)f(code)h (that)f(generates)h(the)f(general)h(protection)e(faults.)33 b(These)18 b(faul\ ts)e(are)h(the)g(privileged)75 520 y(instructions)8 b(intercepted)i(by)g(the) g(Mach)h(kernel.)75 680 y fg(3.2.3.)51 b(I/O)12 b(thr)o(eads)75 799 y ff(Thre\ e)h(I/O)f(threads)h(provide)e(data)i(and)g(external)f(interrupts)f(for)h(DOS) h(programs)f(executing)g(in)g(the)g(V86)g(thread:)19 b(the)75 849 y(T)o(imer) n(,)c(Mouse)f(and)g(Keyboard)f(threads.)25 b(These)15 b(threads)f(provide)e (input)g(for)i(two)f(types)g(of)g(DOS)h(programs:)21 b fa(well-)75 899 y(beha\ ved)9 b ff(programs)g(that)f(get)h(their)f(information)f(from)h(BIOS)h(data)g (structures,)g(and)g fa(ill-behaved)e ff(programs)i(that)f(bypass)75 949 y (the)15 b(BIOS)f(and)h(redirect)g(external)f(device)i(interrupts)d(into)g(the\ ir)h(own)h(code.)29 b(W)m(ell-behaved)15 b(programs)f(access)j(the)75 999 y (BIOS)11 b(data)h(structures)f(through)e(DOS)j(or)f(BIOS)g(system)h(calls.)19 b(Ill-behaved)10 b(programs,)i(on)f(the)h(other)e(hand,)i(redirect)75 1048 y (the)h(noti\256cation)f(interrupts)f(away)j(from)f(the)h(BIOS)f(device)g(driv\ ers)g(and)h(into)e(their)g(own)h(ISRs.)24 b(These)15 b(Ill-behaved)75 1098 y (interrupt)10 b(service)j(routines)e(directly)f(access)15 b(the)c(input)g(dev\ ice')n(s)h(I/O)f(ports)h(to)f(gather)h(the)g(input)e(data.)21 b(T)m(o)12 b (determine)75 1148 y(which)d(types)g(of)h(programs)f(are)h(executing)f(within) f(the)i(V86)f(thread,)h(the)f(I/O)g(threads)g(check)i(the)e(interrupt)f(vecto\ r)h(table)75 1198 y(for)h(redirected)g(vectors.)137 1289 y(The)j(Monitor)c (and)j(the)g(I/O)f(threads)g(use)i(shared)f(data)g(structures)f(to)g(provide) f(input)g(data)i(for)g(well-behaved)f(DOS)75 1339 y(programs.)k(The)10 b(inpu\ t)d(data)j(for)e(these)i(programs)f(is)g(inserted)f(into)g(the)h(shared)h(dat\ a)f(structures)g(by)g(the)g(I/O)f(threads,)i(and)75 1389 y(is)h(extracted)h (by)g(the)f(monitor)g(thread.)19 b(In)11 b(general,)i(a)f(DOS)g(or)f(BIOS)h (system)g(call)g(will)e(direct)h(the)h(monitor)e(thread)i(to)75 1439 y(place) f(the)f(input)f(data)h(into)f(the)h(V86)g(thread')n(s)g(registers)g(and)g(the\ n)g(exit)g(to)g(continue)f(the)h(DOS)g(program')n(s)g(execution.)137 1530 y (When)i(providing)e(data)i(to)f(an)i(ill-behaved)d(DOS)i(program,)h(an)f(I/O) g(thread)f(queues)i(a)f(noti\256cation)e(interrupt,)h(and)75 1580 y(saves)k (the)e(device)h(input)e(data)i(in)e(an)i(interthread)f(data)g(structure.)25 b (After)13 b(the)g(ill-behaved)g(program')m(s)g(ISR)h(has)g(been)75 1630 y(act\ ivated)e(by)g(the)g(interrupt,)f(it)h(will)f(read)h(data)h(from)f(the)g(input) f(device)h(using)g(the)g(privileged)e fb(IN)j ff(instruction)c(on)j(the)75 1679 y(device')n(s)c(I/O)g(port.)14 b(When)8 b(the)h(Monitor)d(thread)i(catch\ es)i(this)d(attempt)h(to)g(access)j(the)d(privileged)e(I/O)i(port,)g(it)g(wil\ l)f(return)75 1729 y(the)j(data)h(stored)e(previously)g(by)h(the)g(I/O)g(thre\ ad)g(as)h(the)f(data)h(from)f(the)g(I/O)f(port,)h(completing)f(the)h(transact\ ion.)137 1821 y(The)i(I/O)f(threads)g(use)h(an)g fa(interrupt)e(generation)g (table)p ff(,)h(shared)h(with)e(the)i(Mach)f(kernel,)h(to)f(generate)h(the)f (external)75 1870 y(interrupts)g(within)g(the)h(V86)h(thread.)22 b(During)12 b (initialization,)f(the)h(Emulator)g(passes)i(the)f(address)g(of)g(this)f(tabl\ e)g(to)g(the)75 1920 y(Mach)k(kernel)f(using)f(the)i fa(v86)f(assist)g ff(\ \257avor)g(of)g(the)g fb(thread)r 13 2 v 12 w(set)s 13 2 v 12 w(state)g ff (system)h(call)f(described)h(above.)30 b(This)75 1970 y(shared)11 b(data)f (structure)g(contains)g(a)h(count)e(and)i(vector)f(number)g(for)g(all)g(the)g (dif)o(ferent)g(types)g(of)g(external)g(interrupts)f(that)75 2020 y(the)h(I/O) g(threads)g(can)h(generate.)16 b(When)10 b(an)g(I/O)g(thread)g(wants)g(to)g (generate)h(an)f(interrupt,)f(it)g(increments)h(the)g(interrupt')l(s)75 2070 y (count)g(\256eld)g(in)f(this)h(table,)g(which)g(causes)i(the)e(Mach)h(kernel) f(to)g(generate)h(the)f(appropriate)f(external)h(interrupt.)137 2161 y(Descri\ ptions)f(of)h(the)h(three)f(I/O)g(threads)g(follow)l(.)15 b(Some)c(of)f(the)g (most)g(dif)o(\256cult)f(problems)h(encountered)g(during)f(the)75 2211 y(impl\ ementation)f(of)h(the)g(DOS)h(Emulator)f(were)h(associated)g(with)f(the)g(Mou\ se)g(and)h(Keyboard)f(threads.)15 b(For)9 b(this)g(reason)75 2261 y(a)i(great\ er)f(depth)g(of)g(detail)g(has)g(been)h(provided)e(in)h(these)g(areas)i(of)e (the)g(paper)n(.)137 2393 y fe(\017)21 b fc(The)10 b(T)o(imer)h(Thr)o(ead)179 2460 y ff(T)m(wo)g(DOS)f(timer)h(interrupts)d(are)k(generated)f(by)f(the)g (T)o(imer)h(thread:)k(the)10 b(T)o(ime)h(of)f(Day)h(interrupt,)e(and)i(the)f (DOS)179 2510 y(timer)g(tick)g(interrupt.)j(On)e(a)g(native)f(DOS)g(machine,) i(the)e(T)o(ime)h(of)f(Day)h(interrupt)d(is)i(generated)h(by)f(a)h(clock)g (chip)179 2559 y(connected)h(to)g(interrupt)e(request)i(line)f(zero.)21 b(The) 12 b(BIOS')n(s)g(T)o(ime)g(of)g(Day)g(interrupt)e(service)j(routine)d(generat\ es)179 2609 y(18.2)g(DOS)h(timer)g(tick)f(interrupts)f(per)h(second.)18 b(The) 11 b(DOS)g(kernel)f(keeps)i(system)f(time)g(using)e(these)i(timer)g fa(ticks) 179 2659 y ff(in)e(the)i(BIOS)e(scratch)i(pad)g(RAM)f(area.)p eop %%Page: 8 8 bop 179 42 a ff(T)o(imeouts)8 b(on)g(Mach)h(ports)f(periodically)f(wake)i (up)f(the)h(timer)f(thread)h(to)f(check)h(the)f(V86)h(thread')m(s)g(timer)f (interrupt)179 91 y(status.)14 b(When)9 b(the)f(timer)h(thread)f(wakes)i(from) e(this)g(small)g(timeout)g(value,)h(it)f(sets)h(the)f(system)h(time)g(in)f (the)g(scratch)179 141 y(pad)h(ram)g(area)h(and)f(checks)h(the)f(two)f(timer) g(interrupt)f(vector)i(table)g(values.)15 b(If)8 b(either)h(of)f(these)h(vect\ ors)g(have)h(been)179 191 y(redirected)i(from)h(the)f(values)g(set)h(at)g(the) f(Emulator)q(')n(s)g(initialization,)f(the)h(timer)g(thread)g(queues)h(an)g (appropriate)179 241 y(interrupt)8 b(in)i(the)g(interrupt)e(generation)i(tabl\ e)g(that)g(triggers)f(an)h(external)g(interrupt)f(by)h(the)g(Mach)h(kernel.) 179 304 y(Many)j(DOS)h(programs)f(require)g(time)h(of)f(day)g(interrupts)f (in)h(shorter)f(time)i(segments)g(than)f(the)g(Mach)h(kernel)179 354 y(can)d (provide.)k(These)c(interrupts)e(are)i(needed)f(in)g(small)g(time)g(slices)g (to)g(drive)f(the)h(PC)g(speaker)h(and)f(other)g(sound)179 404 y(devices.)k (T)n(o)9 b(accomplish)g(this,)g(the)g(T)o(imer)g(thread)g(calculates)h(and)f (queues)h(the)f(number)g(of)g(timer)f(interrupts)g(that)179 453 y(should)i (have)i(occurred)g(during)e(it')m(s)i(timeout)e(period.)18 b(All)11 b(of)g (these)h(interrupts)e(are)j(delivered)e(by)g(the)g(kernel)h(in)179 503 y(shor\ t)d(succession,)i(generating)f(the)g(correct)h(sound)e(output.)137 580 y fe (\017)21 b fc(The)10 b(Mouse)h(Thread)179 643 y ff(Depending)g(on)g(the)g(typ\ e)g(of)h(mouse)g(input)e(expected)i(by)f(the)g(V86)h(thread,)g(the)f(Mouse)h (thread)f(emulates)h(either)179 693 y(a)g(mouse)g(device)h(driver)e(or)g(a)i (mouse)f(connected)g(to)g(a)g(serial)g(line.)19 b(When)12 b(emulating)f(a)i (mouse)f(device)g(driver)n(,)179 743 y(the)e(Mouse)g(thread)f(stores)h(inform\ ation)e(in)i(data)g(structures)f(shared)i(with)e(the)h(Monitor)e(thread,)i (queues)g(external)179 793 y(interrupts,)i(and)h(updates)g(the)g(mouse)g(poin\ ter)m(.)23 b(T)n(o)13 b(emulate)g(a)h(serial)f(line)f(mouse,)j(the)e(Mouse)g (thread)g(queues)179 842 y(interrupts)8 b(on)i(the)g(serial)h(line)e(for)h (the)g(V86)g(thread.)179 906 y(Acting)d(as)h(the)g(mouse)g(device)g(driver)m (,)h(the)f(Mouse)g(thread')m(s)g(main)g(tasks)g(are)g(to)f(keep)h(track)g(of) g(the)f(mouse')n(s)h(status,)179 955 y(to)k(update)i(the)f(mouse)g(pointer)f (in)h(the)g(VGA)h(screen)g(memory)n(,)g(and)g(to)e(provide)g(interrupts)g(for) h(user)g(supplied)179 1005 y(mouse)c(event)h(handlers.)k(T)n(o)9 b(keep)h(tra\ ck)f(of)g(the)g(mouse')n(s)g(status,)h(the)f(Mouse)g(thread)g(updates)g(inter\ nal)f(variables)179 1055 y(when)g(the)h(mouse)g(moves)g(or)f(generates)h(butt\ on)e(events.)15 b(When)8 b(the)h(mouse)g(pointer)e(is)h(enabled)h(by)f(Mouse) g(BIOS)179 1105 y(system)i(calls,)h(the)f(Mouse)h(thread)f(must)g(display)f (and)i(track)f(the)g(mouse)h(on)f(the)g(screen.)179 1168 y(By)i(far)h(the)f (most)h(interesting)e(aspect)i(of)f(the)h(Mouse)f(thread')n(s)g(device)i(driv\ er)d(support)h(is)g(the)g(implementation)179 1218 y(of)g(the)h(DOS)g(applicat\ ion-supplied)d(mouse)k(event)f(handlers.)23 b(The)13 b(Mouse)g(BIOS)g(speci\ \256cation)g(allows)f(DOS)179 1268 y(applications)d(to)h(specify)g(a)h(routin\ e)e(that)h(is)g(called)h(by)f(the)g(resident)g(mouse)h(driver)f(when)g(a)h (user)g(de\256ned)g(mouse)179 1317 y(event)e(occurs.)16 b(When)10 b(this)f (mouse)h(event)f(occurs,)i(the)e(mouse)i(device)f(driver)f(loads)g(the)g(mach\ ine)i(registers)e(with)179 1367 y(mouse)j(status)g(information)e(and)i(then)f (activates)i(the)e(application')l(s)i(routine)d(using)h(a)i fb(FAR)24 b(CALL) 12 b ff(instruction.)179 1417 y(Since)f(the)f(Mach)h(kernel)f(is)g(used)h(to) f(asynchronously)f(stop)h(and)g(redirect)g(control)g(\257ow)g(within)f(the)h (V86)g(thread,)179 1467 y(the)h(Mouse)h(thread)f(must)h(use)g(it)e(to)h(perfo\ rm)h(the)f(switch)g(to)g(the)g(user)h(event)g(handler)m(.)19 b(The)12 b(Mouse) g(thread)g(uses)179 1517 y(an)d(unde\256ned)g(interrupt)e(vector)i(as)g(a)h (special)f(Mouse)g(interrupt)e(vector)i(that)f(calls)h(the)g(DOS)g(event)g (handler)m(.)15 b(This)179 1567 y(poses)10 b(two)g(problems)g(for)g(the)g(Mou\ se)g(thread:)218 1648 y(1.)21 b(There)12 b(must)f(be)g(a)g(way)g(to)g(load)f (the)h(V86)f(registers)h(with)e(the)i(correct)g(calling)f(parameters)i(before) f(control)270 1698 y(is)f(given)g(to)f(the)i(user)f(event)g(handler)n(.)218 1758 y(2.)21 b(There)9 b(must)g(be)f(some)h(routine)f(used)g(as)h(an)g(interm\ ediary)f(that)f(will)g(receive)j(the)e(user)h(event)f(handler)q(')n(s)g fb (FAR)270 1808 y(RET)i ff(call)h(and)f(will)f(restore)h(the)g(previous)g(progr\ am')m(s)g(state.)179 1890 y(T)m(o)18 b(solve)g(these)g(problems,)i(the)d(Mous\ e)h(thread)g(uses)g(two)f(helper)h(routines)f(that)g(are)i(placed)f(in)f(the) h(DOS)179 1939 y(application')l(s)10 b(address)g(space)h(during)e(the)g(Emula\ tor)q(')n(s)h(initialization.)i(The)f(\256rst)e(problem)g(is)h(solved)f(by)h (the)f(\256rst)179 1989 y(helper)f(routine,)f(which)h(is)g(invoked)f(by)g(the) h(special)h(Mouse)f(interrupt)e(generated)j(by)e(the)h(Mach)h(kernel.)14 b (This)8 b(\256rst)179 2039 y(helper)h(routine)g(invokes)g(the)g(Monitor)f(thr\ ead)h(to)h(load)f(the)g(calling)g(parameters)i(into)d(the)i(V86)f(thread')m (s)h(registers)179 2089 y(and)h(to)f(set)h(up)f(the)h(stack)g(for)g(the)f(DOS) h(event)g(handler)q(')n(s)g fb(FAR)24 b(RET)11 b ff(instruction.)k(The)c(seco\ nd)g(helper)g(routine,)179 2139 y(the)i(address)h(of)f(which)g(has)h(been)g (placed)g(on)f(the)h(stack,)h(is)e(invoked)g(when)g(the)g(user)h(event)g(hand\ ler)f(\256nishes.)179 2188 y(This)e(second)h(helper)g(routine)e(restores)i (the)f(interrupted)f(program')m(s)i(register)f(state)g(from)h(the)f(stack)h (and)g(returns)179 2238 y(control)d(of)h(the)g(V86)g(thread)g(back)h(to)e(the) h(place)h(where)g(the)f(Mach)h(kernel')m(s)g(interrupt)d(occurred.)179 2301 y (The)17 b(mouse)h(thread)f(also)g(supports)f(the)g(W)o(indows)g(3.0)h(Logitec\ h)g(serial)g(mouse)g(driver)f(by)h(simulating)e(the)179 2351 y(behavior)f(of) h(the)h(Logitech)f(mouse)g(and)h(the)f(machine')n(s)h(COM)f(port.)29 b(W)o (indows)14 b(is)h(the)g(only)g(program)g(that)179 2401 y(bypasses)10 b(the)f (emulator)q(')n(s)g(internal)f(mouse)i(driver)f(and)g(demands)h(to)f(use)h (its)e(own.)15 b(T)m(o)9 b(simulate)h(the)f(behavior)f(of)179 2451 y(a)j(Logi\ tech)g(serial)g(mouse,)h(the)f(Mouse)g(thread)g(queues)h(interrupts)d(that)h (the)h(W)o(indow')l(s)g(device)h(driver)e(services)179 2501 y(by)k(accessing) h(privileged)e(I/O)g(ports.)27 b(The)15 b(Mouse)f(thread)g(keeps)h(track)f (of)g(the)g(serial)h(mouse)g(and)f(its)f(COM)179 2551 y(port)d(by)i(stepping) e(through)g(a)i(state)g(machine,)h(the)e(transitions)f(of)h(which)g(occur)h (in)f(response)h(to)f(privileged)f(I/O)179 2600 y(instructions)i(on)i(the)h (COM)f(device')n(s)h(I/O)f(ports.)28 b(Although)12 b(it)i(would)f(be)i(possib\ le)f(to)g(support)g(any)g(type)g(of)179 2650 y(mouse)c(driver)f(by)g(expandin\ g)g(this)g(state)h(machine,)h(no)e(advantages)i(would)d(be)i(gained)g(over)f (the)h(internal)f(mouse)179 2700 y(driver)g(already)i(present)f(in)g(the)g (Emulator)m(.)p eop %%Page: 9 9 bop 137 42 a fe(\017)21 b fc(The)10 b(Keyboard)h(Thread)179 108 y ff(The)k (function)d(of)i(the)g(Keyboard)g(thread)g(is)g(to)g(gather)g(raw)g(keyboard) g(data)g(and)h(to)e(pass)i(that)e(data)i(on)f(to)f(the)179 158 y(V86)c(thread\ .)15 b(Depending)9 b(on)g(the)h(type)f(of)h(DOS)g(program)f(that)g(is)h(execu\ ting,)g(the)f(Keyboard)h(thread)f(either)h(puts)179 208 y(the)h(keyboard)h (data)g(into)e(a)j(queue)f(or)f(passes)i(the)f(raw)g(scan)g(code)h(to)e(the)h (DOS)f(program')n(s)h(keyboard)f(interrupt)179 257 y(service)e(routine.)14 b (In)8 b(order)h(to)f(understand)g(the)h(way)g(the)g(emulator)f(handles)h(keyb\ oard)f(data,)i(a)g(knowledge)e(of)g(the)179 307 y(BIOS')m(s)k(default)f(keybo\ ard)g(ISR,)h(the)g(scratch)g(pad)g(RAM')m(s)g(keyboard)g(queue)g(and)g(the)f (four)g(general)h(strategies)179 357 y(DOS)e(programs)g(use)h(to)f(gather)g (keyboard)g(data)g(is)g(essential.)179 423 y(In)16 b(a)h(DOS)g(system)g(with) f fa(well-behaved)g ff(DOS)h(programs,)h(the)f(BIOS)f(keyboard)g(ISR)g(interc\ epts)h(keyboard)179 473 y(interrupts)12 b(and)i(places)h(decoded)f(characters) h(into)e(the)h(scratch)g(pad)g(RAM')m(s)g(keyboard)g(queue.)26 b(This)14 b fa (normal)179 523 y ff(DOS)9 b(system)h(is)g(one)f(in)g(which)g(the)g(keyboard) g(interrupt)f(vector)h(has)h(not)f(been)h(redirected.)15 b(W)m(ell-behaved)9 b (DOS)179 573 y(programs)14 b(get)g(their)f(only)g(keyboard)g(input)g(from)g (this)h(queue.)26 b(They)15 b(can)f(either)g(use)g(BIOS)g(system)h(calls)f (to)179 623 y(indirectly)9 b(manipulate)i(the)g(queue)g(or)g(bypass)h(the)f (BIOS)g(and)g(access)i(the)e(keyboard)g(queue)g(directly)l(.)19 b(Some)11 b (of)179 672 y(the)e(DOS)h(programs)f(that)g(perform)g(keyboard)g(input)f(in)h (this)g(manner)h(are)g(the)f(command.com)j(parser)n(,)f(Borland')l(s)179 722 y (T)o(urbo)e(C)h(editor)m(,)h(Lotus)f(123,)g(edlin.com,)h(and)f(debug.com.)179 789 y fa(Ill-behaved)h ff(DOS)h(programs)g(perform)g(keyboard)g(input)f(by)g (redirecting)g(keyboard)h(interrupts)e(into)h(their)h(own)179 839 y(code.)k (There)11 b(are)g(three)f(types)g(of)g(programs)g(that)g(gather)g(keyboard)g (input)f(in)g(this)h(way)m(.)15 b(These)d(are:)229 930 y fc(\261)20 b ff(A)10 b fa(Keyboar)o(d)g(Hog)f ff(program)h(redirects)h(keyboard)e(interrupts)g(int\ o)f(its)i(own)g(code)g(and)h(does)f(not)f(share)i(this)270 980 y(information) 6 b(with)i(other)f(DOS)i(programs.)14 b(This)8 b(type)g(of)g(program)g(does)g (not)g(place)h(character)g(information)270 1029 y(into)k(the)g(scratch)i(pad) f(RAM)f(keyboard)h(queue)g(and)g(does)g(not)f(pass)i(the)e(interrupt)f(to)i (another)f(interrupt)270 1079 y(service)e(routine.)k(In)10 b(effect)h(it)f (captures)g(the)h(keyboard)f(input)f(all)h(for)g(itself.)15 b(Epsilon,)10 b (an)h(Emacs-like)h(text)270 1129 y(editor)m(,)f(is)f(an)h(example)g(of)f(this) f(type)h(of)g(program.)229 1196 y fc(\261)20 b ff(A)10 b fa(T)l(erminate)g (and)g(Stay)f(Resident)h ff(\(TSR\))g(program)g(redirects)g(the)g(keyboard)g (interrupt)e(into)h(its)g(own)h(code)270 1245 y(like)15 b(the)g(hog,)i(but)e (after)g(\256nishing)f(with)h(the)g(scan)i(code,)g(it)e(jumps)g(to)g(the)g (ISR)h(it)e(replaced,)k(in)d(effect)270 1295 y(passing)d(the)h(interrupt)d (down)i(a)h(chain)g(of)f(DOS)g(interrupt)f(service)i(routines.)21 b(The)13 b (DOS)g(program)f(using)270 1345 y(this)g(strategy)g(would)g(not)g(use)h(the)f (scratch)i(pad)e(RAM')m(s)h(keyboard)g(queue,)g(but)f(would)g(allow)g(the)g (BIOS)270 1395 y(keyboard)e(ISR)g(to)g(update)g(the)g(queue)g(through)f(the)h (chaining)f(mechanism.)229 1461 y fc(\261)20 b ff(The)15 b fa(Middleman)e ff (program)h(uses)h(both)e(interrupt)g(chaining)g(and)i(the)f(scratch)h(pad)g (queue)g(for)f(keyboard)270 1511 y(input.)22 b(This)13 b(type)g(of)f(DOS)i (program)e(redirects)i(the)e(keyboard)h(interrupt)e(into)h(its)g(own)h(ISR,)g (chains)g(the)270 1561 y(interrupt)g(to)h(the)h(old)f(keyboard)g(ISR,)h(and)g (then)f(uses)i(BIOS)e(system)h(calls)h(for)e(character)i(input.)27 b(This)270 1611 y(allows)9 b(DOS)g(TSR)h(programs)f(to)f(\256lter)h(the)g(character)h (stream)g(before)g(it)e(reaches)j(the)e(program,)g(but)g(allows)270 1660 y (the)j(program)f(to)h(screen)g(some)h(keyboard)e(events)h(from)g(the)g(TSR)g (programs.)19 b(Examples)13 b(of)f(Middleman)270 1710 y(programs)e(are)g(Micr\ osoft)e(W)m(ord)h(5.0,)h(Microsoft)f(W)n(indows)g(3.0,)h(W)n(ing)f(Commander) o(,)h(Populous,)f(and)g(the)270 1760 y(Microsoft)g(M)h(text)g(editor)m(.)179 1851 y(The)16 b(Keyboard)e(thread)h(supports)f(all)h(four)g(types)f(of)h(DOS) h(programs.)29 b(The)16 b(well-behaved)f(DOS)g(programs)179 1901 y(are)g(easi\ ly)f(supported)g(by)g(putting)e(characters)k(into)d(the)h(scratch)i(pad')m (s)f(keyboard)f(queue)h(upon)e(arrival.)27 b(The)179 1951 y(ill-behaved)10 b (DOS)i(programs)g(are)g(supported)f(with)f(the)i(aid)f(of)g(a)i(helper)e(rout\ ine)f(used)i(as)h(a)f(smart)g(ISR)f(located)179 2001 y(in)f(the)h(DOS)g(appli\ cation')l(s)g(address)g(space.)18 b(When)11 b(executed,)h(the)f(helper)g(rout\ ine)e(puts)h(a)i(character)g(located)f(in)179 2051 y(its)f(data)i(area)h(into) d(the)h(scratch)h(pad')m(s)g(keyboard)f(queue.)18 b(At)11 b(startup)g(time)g (the)g(Emulator)g(saves)h(the)g(address)f(of)179 2100 y(this)f(helper)i(routi\ ne)e(in)h(the)g(keyboard)g(interrupt)f(vector)h(so)h(that)f(programs)g(that)g (chain)h(the)f(keyboard)g(interrupt)179 2150 y(will)e(call)h(the)g(helper)g (routine.)179 2217 y(When)15 b(the)h(keyboard)f(interrupt)e(vector)i(is)g(red\ irected,)i(the)f(Keyboard)f(thread)g(queues)h(the)f(scan)h(code)g(in)f(an)179 2267 y(emulator)j(data)h(structure,)h(then)e(queues)h(a)g(keyboard)f(interrup\ t)e(in)i(the)g(interrupt)f(generation)h(table.)39 b(The)179 2316 y(keyboard) 10 b(interrupts)g(are)i(handled)e(dif)o(ferently)g(than)h(other)f(external)h (interrupts)e(in)i(that)f(they)h(are)h(generated)f(by)179 2366 y(the)g(Emulat\ or)g(task)h(instead)f(of)g(the)g(Mach)h(kernel.)19 b(This)11 b(is)g(done)h (so)f(that)g(the)g(emulator)g(can)h(pass)g(the)g(decoded)179 2416 y(character) i(to)f(the)h(helper)f(ISR)g(in)g(the)g(DOS)h(application)e(space)j(before)f (the)f(interrupt)e(occurs.)26 b(This)13 b(way)h(any)179 2466 y(programs)7 b (that)g(chain)g(the)g(keyboard)g(interrupt)e(will)h(eventually)g(place)i(the) f(decoded)h(character)g(into)e(the)i(keyboard)179 2516 y(queue.)p eop %%Page: 10 10 bop 75 42 a fg(3.2.4.)51 b(Locking)12 b(issues)75 161 y ff(There)f(are)f(man\ y)g(objects)g(shared)g(between)g(the)g(Emulator)q(')n(s)g(threads)f(that)h (can)g(only)f(be)h(manipulated)f(by)h(one)f(thread)h(at)75 211 y(a)h(time)g (making)f(the)g(ability)f(to)h(lock)g(these)h(objects)g(important.)j(The)e (objects)e(that)g(can)h(only)f(be)g(accessed)j(sequentially)75 260 y(are)c (the)f(V86)g(thread')m(s)h(state,)g(data)f(structures)g(shared)h(between)f (I/O)g(threads)g(and)g(the)g(Monitor)f(thread,)i(and)f(the)g(interrupt)75 310 y(generation)15 b(table)g(that)g(is)h(shared)g(between)g(the)f(I/O)g(threads) h(and)f(the)h(Mach)g(kernel.)31 b(T)n(o)15 b(lock)g(these)h(objects,)h(the)75 360 y(emulator)10 b(uses)h(two)e(mutual)h(exclusion)g(objects:)k(a)d(critical) e(section)h(lock)g(and)g(a)h(mouse)g(lock.)137 451 y(T)n(o)e(insure)h(that)f (the)g(V86)h(thread')m(s)g(state)g(is)f(not)g(changed)h(by)g(more)g(than)f (one)h(thread)g(at)f(a)i(time,)f(threads)g(outside)e(the)75 501 y(kernel)f (use)g(the)f(critical)h(section)f(lock)h(and)f(the)h(the)g(V86)f(thread')m (s)h fa(r)o(esume)h ff(\257ag.)14 b(The)8 b(I/O)e(threads)h(take)g(the)f(crit\ ical)g(section)75 551 y(lock)j(before)h(attempting)f(to)g(suspend)h(the)g(V86) f(thread)h(so)g(that)f(only)g(one)h(of)f(them)h(is)g(able)g(to)f(modify)g(the) h(V86)g(thread')m(s)75 601 y(state.)k(The)8 b(emulator)q(')n(s)f(I/O)f(thread\ s)h(must)g(then)f(suspend)h(the)g(V86)f(thread)h(with)f(the)g(Mach)i fb(threa\ d)r 13 2 v 12 w(suspend)f ff(system)75 651 y(call)k(before)g(they)f(can)i(mod\ ify)d(its)i(state.)17 b(Once)11 b(the)g(I/O)f(thread)h(has)g(the)f(critical)h (section)f(lock)g(and)h(has)g(suspended)g(the)75 700 y(V86)d(thread,)i(it)e (checks)i(the)e(Resume)i(Flag)f(bit)e(in)h(the)h(V86)f(thread')n(s)h(\257ag)g (register)m(.)15 b(When)9 b(this)f(bit)g(is)g(set)h(the)g(V86)f(thread)75 750 y(has)i(generated)g(an)g(exception)g(and)f(is)h(being)f(serviced)h(by)g(eithe\ r)f(the)g(Mach)i(kernel)e(or)h(the)f(emulator)q(')n(s)h(Monitor)e(thread.)75 800 y(Since)k(the)g(Mach)h(kernel')m(s)f(V86)g(support)f(routines)g(are)h(onl\ y)f(invoked)g(when)h(the)g(V86)g(thread)f(is)h(running)f(there)h(is)f(no)75 850 y(chance)i(that)f(one)g(of)g(the)g(I/O)g(threads)g(is)g(modifying)e(the)i (V86)g(thread')m(s)g(state)h(when)f(the)g(Mach)h(kernel')m(s)f(routines)f(are) 75 900 y(running.)137 991 y(The)f(Emulator)q(')m(s)f(threads)g(must)f(acquire) h(the)g(critical)f(section)g(lock)g(before)h(they)f(can)i(access)h(data)d(str\ uctures)h(shared)75 1041 y(between)k(themselves.)21 b(The)13 b(mouse)g(lock)e (is)h(used)h(to)e(guarantee)i(the)f(integrity)e(of)i(the)g(data)g(structures) g(shared)g(by)g(the)75 1091 y(Monitor)c(thread)h(and)h(the)g(Mouse)g(thread.) 15 b(The)10 b(critical)f(section)g(lock)h(is)f(also)h(used)g(by)f(the)h(I/O)f (threads)h(to)f(preserve)h(the)75 1140 y(interrupt)e(generation)i(table')m (s)h(integrity)-5 b(.)75 1305 y fg(4.)50 b(Integrating)11 b(DOS)h(with)g(the) g(Unix)g(server)75 1439 y ff(As)i(of)g(this)f(writing,)g(the)h(DOS)g(support) f(relies)h(heavily)f(upon)h(features)g(provided)f(by)g(the)h(4.3)g(BSD)g(Unix) f(server)i(in)75 1489 y(areas)f(including)c(I/O)i(device)h(access,)i(DOS)e (\256le)g(system)f(implementation,)h(and)f(the)g(management)i(of)e(multiple)f (DOS)75 1539 y(machines.)20 b(The)13 b(DOS)e(emulator)h(task)f(accesses)k(the) c(machine')n(s)h(keyboard,)g(mouse)g(and)g(disk)f(devices)h(through)e(Unix)75 1589 y(server)h(system)f(calls.)15 b(T)n(wo)10 b(approaches)g(to)g(accessing) h(DOS)f(\256le)g(systems)h(are)g(implemented)e(using)g(the)h(Unix)f(server)r (')n(s)75 1638 y(system)h(calls.)15 b(Finally)l(,)9 b(the)h(ability)d(to)h (create)j(and)e(schedule)h(multiple)d(DOS)j(machines)g(also)f(depends)g(on)g (functionality)75 1688 y(provided)f(by)g(the)h(Unix)g(server)n(.)15 b(In)8 b (the)h(future,)g(work)g(will)f(center)h(on)g(replacing)f(the)h(functionality) e(provided)h(by)g(the)h(4.3)75 1738 y(BSD)h(Unix)g(server)g(with)f(native)h (Mach)h(support.)75 1898 y fg(4.1.)51 b(Unix)11 b(support)h(for)g(DOS)g(I/O)g (Devices)75 2017 y ff(The)e(Keyboard,)g(mouse)f(and)h(disk)e(devices)i(are)g (all)f(accessed)j(by)d(the)g(emulator)g(task)g(by)g(using)f(Unix)h(system)g (calls.)15 b(The)75 2067 y(only)c(I/O)g(device)h(that)g(is)f(not)g(controlled) f(with)h(Unix)g(calls)h(is)g(the)f(display)m(.)20 b(In)11 b(general,)i(for)f (input-only)c(devices)13 b(such)75 2117 y(as)f(the)g(keyboard)f(and)h(mouse,) h(an)f(I/O)g(thread)f(opens)h(the)f(Unix)g(device)i(\256le)f(and)f(enters)h (a)h(loop)d(that)i(performs)f(a)i(read)75 2167 y(select)g(on)f(the)g(device') n(s)g(\256le)h(descriptor)e(before)i(reading)f(data)g(from)g(the)g(device.)22 b(The)13 b(select)g(is)f(performed)g(to)g(check)75 2217 y(whether)e(or)g(not) f(the)i(Emulator)e(has)i(been)g(resumed)g(from)f(a)h(paused)f(state)h(\(see)g (below\).)k(The)c(emulator)q(')m(s)g(disk)e(support)75 2266 y(code)i(uses)g (both)e(Unix)g(server)i(raw)g(disk)e(device)i(\256les)f(and)h(regular)f(UFS)g (\256les)h(to)e(implement)h(DOS)h(\256le)f(systems.)137 2358 y(The)16 b(machi\ ne')o(s)f(VGA)h(display)e(is)i(controlled)e(by)h(code)h(in)f(the)g(Emulator)g (task)h(that)f(directly)f(manipulates)h(the)75 2408 y(VGA)-5 b(')n(s)9 b(scre\ en)i(memory)m(.)k(Direct)10 b(control)e(over)h(the)g(VGA)g(is)g(needed)h(beca\ use)h(DOS)e(programs)g(use)h(much)g(more)f(of)g(the)75 2457 y(VGA)-5 b(')n (s)10 b(functionality)e(than)i(do)g(any)g(Unix)f(programs,)i(including)d(X.)p eop %%Page: 11 11 bop 75 42 a fg(4.2.)51 b(Unix)11 b(Support)g(for)h(DOS)g(File)h(Systems)75 161 y ff(The)i(DOS)g(emulator)g(uses)g(Unix)f(services)h(to)f(access)j(two)d (dif)n(ferent)h(types)f(of)h(DOS)g(\256le)f(systems:)24 b(Real)15 b(DOS)g(\ \256le)75 211 y(systems)e(residing)e(on)h(the)g(physical)g(hard)g(disk,)h(and) f(the)g(Unix)g(\256le)g(system)h(as)g(a)g(DOS)f(network)g(\256le)g(system.)22 b(A)13 b(real)75 260 y(DOS)c(\256le)g(system)g(is)g(one)g(laid)f(out)g(using) g(a)h(DOS)g(\256le)g(system)h(speci\256cation.)k(The)c(UFS)f(as)g(a)h(DOS)f (network)f(\256le)h(system)75 310 y(is)h(implemented)g(using)g(the)g(DOS)g (Network)g(Redirector)f(Interface.)75 470 y fg(4.2.1.)51 b(Real)12 b(DOS)g (File)h(Systems)75 589 y ff(The)h(Real)f(DOS)g(\256le)g(systems)g(supported)f (by)g(the)h(DOS)g(Emulator)g(are)g(physical)g(DOS)g(\256le)g(systems)g(laid)g (out)f(on)g(the)75 639 y(disk)d(that)g(are)h(pointed)f(to)g(by)g(either)g(a)h (Unix)f(device)h(\256le)g(or)f(a)i(regular)e(Unix)g(\256le.)15 b(Unix)9 b(dev\ ice)h(\256les)g(are)g(used)g(to)f(access)75 689 y(resident)h(DOS)g(hard)g(dis\ k)g(partitions)e(or)i(\257oppy)g(DOS)g(disks.)15 b(A)10 b(special)h(device)f (\256le)h(is)f(set)g(up)g(to)g(point)f(to)g(the)i(resident)75 739 y(DOS)j(har\ d)f(disk)g(partition)f(by)h(the)g(Mach)h fb(diskutil)f ff(command.)27 b(The) 14 b(Unix)f fb(dd)g ff(command)i(is)e(used)h(to)f(copy)g(the)75 789 y(image)e (of)f(a)h(DOS)f(\257oppy)f(into)g(a)i(regular)f(Unix)g(\256le.)137 880 y(Sinc\ e)h(the)e(Emulator)h(does)g(not)f(contain)h(a)g(copy)g(of)g(DOS,)g(one)g(of)g (these)g(real)g(DOS)h(\256le)f(system)g(images)h(must)f(have)75 930 y(a)k(ver\ sion)e(of)h(DOS)h(on)e(it)h(for)g(the)g(Emulator)f(to)h(boot)f(and)h(begin)g (operation.)23 b(The)14 b(Emulator)f(will)f(check)i(for)e(both)h(a)75 980 y (regular)c(\256le)g(image)h(with)f(DOS)g(in)g(it)f(or)h(for)g(a)h(special)f (device)h(\256le)g(at)f(run)g(time.)15 b(Run)8 b(time)h(\257ags)h(can)g(be)g (used)f(to)g(specify)75 1029 y(boot)g(\256les)i(other)e(than)h(the)g(defaults\ .)75 1190 y fg(4.2.2.)51 b(The)12 b(UFS)h(as)g(a)f(Network)g(DOS)g(File)g(Sys\ tem)75 1309 y ff(The)f(Emulator)e(implements)h(the)g(Unix)f(\256le)h(system)h (as)f(a)h(DOS)f(drive)f(using)g(the)h(DOS)g(Network)g(Redirector)f(Interface.) 75 1359 y(Several)i(DOS)f(programs)g(are)h(executed)g(by)f(the)f(V86)h(thread) g(when)g(DOS)h(boots)e(that)g(initialize)g(DOS)h(version-speci\256c)75 1408 y (variables)g(in)f(the)h(Emulator)g(task.)15 b(Using)9 b(these)i(variables,)f (the)g(Emulator)f(inserts)h(the)g(fake)g(UFS)h(drive)e(into)g(DOS)h(data)75 1458 y(structures,)j(making)g(DOS)g(believe)f(that)h(it)f(has)h(an)g(extra)g (disk)f(drive.)22 b(The)14 b(Emulator)e(supports)g(this)g(fake)h(DOS)g(disk) 75 1508 y(drive)d(by)g(intercepting)e(the)i(DOS)h(Network)e(Redirector)h(syst\ em)h(calls.)137 1599 y(There)e(are)g(several)f(bene\256ts)g(to)g(using)e(the) i(UFS)g(as)h(a)f(disk)f(drive)g(under)h(DOS.)g(The)h(lar)o(ge)f(amount)f(of)h (space)h(available)75 1649 y(under)i(the)g(UFS)g(disk)g(drive)f(provides)g (more)i(room)f(for)f(DOS)i(storage)f(than)f(do)h(the)g(early)g(versions)g(of) g(DOS)g(that)g(limit)75 1699 y(Real)g(DOS)h(\256le)f(system)g(disk)g(size.)18 b(Since)12 b(the)f(Emulator)g(uses)g(Unix)g(system)g(calls)g(to)g(access)i (\256les,)f(those)f(\256les)h(stored)75 1749 y(directly)g(in)g(the)h(UFS)h (are)g(accessed)h(faster)e(than)g(those)g(stored)f(in)h(the)g(Real)g(DOS)g (\256le)h(systems)f(which)g(must)g(use)g(the)75 1799 y(UFS)d(as)h(an)g(interm\ ediary)l(.)16 b(Finally)l(,)10 b(the)h(Emulator)e(can)i(easily)g(move)f(data) h(between)f(the)h(UFS)f(and)g(DOS)h(\256le)f(systems,)75 1848 y(making)g(\256\ le)g(transfers)h(between)f(the)g(operating)g(systems)g(trivial.)137 1940 y (The)h(ability)d(to)h(use)h(the)g(UFS)g(as)h(a)f(DOS)g(disk)f(enables)i(a)f (machine)h(that)e(does)h(not)f(have)h(a)g(DOS)g(hard)g(disk)f(partition)75 1990 y(to)i(effectively)g(utilize)g(the)h(DOS)g(emulator)n(.)20 b(The)13 b (Emulator)f(can)g(boot)f(from)h(a)h(\257oppy)e(image)i(and)f(then)f(use)i(the) f(UFS)75 2039 y(disk)e(drive)f(as)i(its)f(main)g(drive)g(for)g(execution)f (and)i(storage.)75 2199 y fg(4.3.)51 b(Unix)11 b(Support)g(for)h(Managing)g (Multiple)f(DOS)h(Machines)75 2319 y ff(The)g(ability)e(to)g(pause)i(the)g (DOS)f(Emulator)g(and)h(return)e(to)h(a)h(Unix)e(shell)h(enables)h(the)f(user) h(to)f(execute)h(multiple)e(DOS)75 2368 y(Emulators)k(running)e(in)h(separate) i(DOS)e(\252machines.\272)28 b(The)14 b(Emulator)g(can)g(be)g(paused)g(or)g (stopped)f(by)g(pressing)g(the)75 2418 y(down)d(the)g(Control,)f(Alt,)g(and)i (`Z')f(keys)h(simultaneously)-5 b(.)16 b(By)10 b(using)f(the)h(Unix)g(server) r(')m(s)h(ability)e(to)g(multitask,)h(the)g(user)75 2468 y(is)h(able)g(to)g (execute)h(as)g(many)f(DOS)h(programs)f(as)h(he)f(or)g(she)h(wants)f(and)g (to)f(change)i(back)g(and)f(forth)f(between)i(them)f(at)75 2518 y(will.)137 2609 y(The)d(problem)e(of)h(sharing)f(the)g(keyboard)h(and)g(mouse)g(devices) g(between)g(the)g(dif)n(ferent)g(DOS)g(Emulators)g(is)f(overcome)75 2659 y (by)15 b(using)f(the)h fb(select)g ff(system)g(call)g(to)g(check)h(for)f(inpu\ t)e(on)i(the)g(devices)h(before)f(reading)g(them.)30 b(When)15 b(a)h(DOS)p eop %%Page: 12 12 bop 75 42 a ff(Emulator)10 b(has)i(been)f(paused)g(and)g(then)g(put)f(into)f (the)i(foreground,)f(the)h fb(select)f ff(call)h(will)e(return)i(with)e(a)j fb (Bad)24 b(File)75 91 y(Descriptor)14 b ff(error)g(because)i(the)f(old)e(\256l\ e)i(descriptor)f(will)f(no)h(longer)g(have)h(a)g(valid)f(state.)29 b(This)14 b (error)g(tells)g(the)75 141 y(Emulator)c(to)g(reinitialize)e(the)j(\256le)f (descriptors)g(for)f(the)h(input)f(device)i(before)f(it)g(continues.)75 306 y fg(5.)50 b(Performance)13 b(issues)75 440 y ff(The)e(performance)g(of)e(most) h(DOS)g(programs)g(is)g(comparable)h(to)e(that)h(of)f(native)h(DOS)g(machines\ ,)i(in)d(the)h(sense)h(that)e(the)75 490 y(Mach)h(DOS)f(system)h(is)f(quite)g (useable)h(as)g(a)f(day-to-day)g(operating)f(environment.)14 b(In)9 b(general\ ,)h(the)f(Emulator)g(has)h(been)75 540 y(tuned)h(to)f(provide)g(good)g(perfor\ mance)i(for)f(the)g(average)h(DOS)g(program.)17 b(Optimizations)10 b(for)h (speci\256c)h(programs)f(like)75 589 y(W)o(indows)g(and)i(W)n(ing)f(Commander) h(were)h(provided)d(when)i(the)f(changes)i(were)f(bene\256cial)g(to)g(most)f (DOS)h(programs.)75 639 y(DOS)c(programs)g(that)g(rely)f(on)h(the)g(fact)g (that)g(privileged)e(instructions)g(execute)j(within)d(one)i(machine)h(instru\ ction)d(period)75 689 y(will)g(not)h(perform)g(correctly)m(.)15 b(Although)7 b (speci\256c)i(numbers)g(comparing)f(the)h(performance)g(of)f(the)h(Emulator)f (and)h(native)75 739 y(DOS)j(have)h(not)e(been)i(calculated,)h(some)f(work)e (has)i(been)g(done)f(to)f(analyze)j(the)e(performance)h(of)f(the)g(Mach)h(ker\ nel')m(s)75 789 y(support.)h(This)9 b(performance)h(is)g(determined)f(by)g (two)g(factors:)14 b(fault)9 b(handling)f(overheads,)i(and)g(instruction)d (emulation)75 838 y(overheads.)75 999 y fg(5.1.)51 b(General)12 b(fault)f(han\ dling)f(overheads)75 1118 y ff(The)f(fault)e(handling)f(overhead)j(correspond\ s)e(to)h(the)g(length)f(of)h(time)f(spent)h(in)g(forwarding)e(the)i(V86)g(thr\ ead')m(s)g(exceptions)75 1168 y(to)e(the)h(appropriate)f(emulation)f(routines\ .)13 b(This)7 b(overhead)g(lies)f(mainly)h(in)f(two)g(areas:)14 b(the)6 b(tim\ e)h(it)f(takes)h(for)f(the)h(processor)75 1217 y(to)12 b(switch)g(back)g(and) h(forth)e(between)i(processor)f(states,)i(and)e(the)g(Mach)h(Kernel)g(fault)e (handling)g(code.)22 b(T)m(ypically)l(,)14 b(an)75 1267 y(80386)7 b(processor) i(uses)g(about)f(500)g(clock)h(cycles)g(for)f(the)h(switch)f(from)g(V86)g(mod\ e)h(to)f(Protected)h(mode)f(and)h(back.)15 b(This)75 1317 y(roughly)10 b(tran\ slates)h(into)f(about)g(100)h(machine)h(instructions.)k(Once)c(the)f(switch)g (from)g(V86)g(mode)h(to)f(Protected)g(mode)75 1367 y(has)h(been)h(made,)h(it) d(takes)h(about)g(thirty)e(machine)j(instructions)d(to)h(get)h(to)f(the)h(V86) g(mode)g(support)f(code)h(in)g(the)f(Mach)75 1417 y(Kernel.)k(If)10 b(the)g (V86)g(exception)g(is)g(handled)g(by)f(the)i(Kernel')m(s)f(emulation)g(code,) h(it)e(typically)g(takes)i(about)e(forty)g(to)h(\256fty)75 1466 y(more)h(inst\ ructions)d(to)h(reach)j(the)e(proper)g(code)g(for)g(the)g(type)g(of)g(excepti\ on.)75 1627 y fg(5.2.)51 b(Instruction)11 b(emulation)h(overheads)75 1746 y ff (The)h(overhead)f(related)g(to)g(the)f(instruction)f(emulation)h(is)h(lar)o (ge)g(compared)h(to)f(native)f(DOS)i(code.)21 b(The)12 b(performance)75 1796 y (of)g(privileged)f(instructions)g(emulated)i(in)f(the)g(Mach)i(Kernel)f(depen\ ds)f(on)h(the)f(type)g(of)h(instruction)d(and)j(whether)f(the)75 1845 y(instr\ uction)g(generates)j(more)f(exceptions)g(or)g(write)g(to)f(the)h(user)g(space\ .)29 b(The)14 b(number)g(of)g(instructions)e(used)j(by)e(the)75 1895 y(Mach)e (Kernel')m(s)g(V86)f(support)f(code)h(for)g(each)i(of)e(the)g(following)e(pri\ vileged)g(instructions)g(are)j(as)g(follows:)137 2020 y fe(\017)21 b ff(CLI:) 10 b(29)f(instructions)g(to)g(clear)i(the)f(\252virtual\272)g(interrupt)e(bit) 137 2103 y fe(\017)21 b ff(STI:)12 b(37)g(instructions)e(for)i(the)h(General) g(Protection)e(fault)g(plus)h(another)g(200)g(instructions)e(for)i(the)h(trac\ e)g(break)179 2153 y(point.)137 2236 y fe(\017)21 b ff(PUSHF:)10 b(118)g(inst\ ructions)e(to)h(emulate,)i(46)f(instructions)e(for)i(the)g(copyout)f(to)h(use\ r)h(space)137 2319 y fe(\017)21 b ff(POPF:)10 b(121)g(instructions)137 2402 y fe(\017)21 b ff(IRET)n(:)10 b(131)g(instructions)137 2485 y fe(\017)21 b ff (INT)m(,)11 b(IN,)f(OUT)n(:)g(21)g(instructions)e(to)i(leave)h(the)f(kernel)g (V86)g(support.)137 2609 y(Clearly)f(there)g(is)g(a)g(performance)h(cost)f (for)g(programs)g(that)f(use)i(these)f(instructions)e(in)i(tight)e(loops.)14 b (This)9 b(cost)g(is)g(one)75 2659 y(of)h(the)g(reasons)h(why)f(it)f(was)i(dec\ ided)g(to)e(move)i(some)g(of)f(the)g(emulation)f(from)i(user)f(space)i(into)d (the)h(kernel.)p eop %%Page: 13 13 bop 75 42 a fg(6.)50 b(Implementation)12 b(Lessons)75 176 y ff(Some)e(lesson\ s)g(learned)g(about)f(Mach)h(during)e(the)h(course)h(of)g(this)e(project)h (were:)15 b(the)10 b(suitability)c(of)k(the)f(Mach)h(Kernel')n(s)75 225 y(386) f(machine)i(dependent)e(code)h(to)f(support)g(a)h(layered)g(OS)g(with)f(inten\ sive)f(machine)j(dependent)e(applications,)g(how)h(to)75 275 y(balance)h(the) f(exception)f(handling)f(code)j(between)f(the)g(kernel)g(and)g(user)g(space,) i(how)d(to)h(provide)f(a)h(\256ner)g(granularity)e(of)75 325 y(timing)g(than) h(the)g(kernel)g(supports)f(to)g(a)i(Mach)g(application,)f(and)g(how)g(useful) f(the)i(Mach)f(virtual)f(memory)i(system)g(is)f(for)75 375 y(implementing)g (dif)n(ferent)i(types)f(of)g(memory)g(support.)137 466 y(Several)17 b(feature\ s)g(were)g(added)g(to)f(the)g(Mach)h(Kernel')m(s)g(386)f(Machine)g(dependent) g(code:)27 b(the)17 b(ability)d(to)i(take)75 516 y(threads)11 b(into)f(and)i (out)e(of)h(the)g(V86)g(execution)g(mode,)h(a)g(port-speci\256c)f(protection) f(mechanism)i(for)f(the)g(ISA)g(I/O)g(ports)75 566 y(by)i(implementing)f(the) h(bitmap)g(in)f(the)h(task')n(s)g(TSS,)i(new)e(\257avors)g(of)g(thread)g(stat\ e,)i(and)e(a)h(way)g(to)e(generate)i(external)75 616 y(interrupts)8 b(within) h(the)h(V86)g(thread.)137 707 y(In)h(order)g(to)f(achieve)i(reasonable)g(exec\ ution)f(speeds,)h(some)g(V86)f(emulation)f(had)h(to)g(be)g(done)g(in)g(the)g (kernel.)17 b(The)75 757 y(types)12 b(of)f(emulation)g(performed)h(by)f(the)h (kernel)g(are)g(related)g(to)f(hardware)i(speci\256c)f(and)g(non)f(system)i (call)e(instruction)75 807 y(emulation.)23 b(Several)14 b(dif)n(ferent)g(solu\ tions)d(were)j(implemented)f(both)f(within)g(the)h(kernel)g(and)g(user)g(spac\ e)i(before)e(the)75 856 y(current)d(balance)h(described)g(in)e(this)h(paper)g (was)h(decided)g(upon.)137 948 y(Many)g(DOS)h(programs)e(need)i(time)f(slices) g(smaller)h(than)f(the)f(smallest)i(slice)f(available)g(from)g(the)g(Mach)h (Kernel)f(to)75 998 y(perform)i(precise)h(sound)f(output.)23 b(T)m(o)14 b(pro\ vide)e(for)h(this,)h(the)f(Emulator)g(task)g(has)h(to)f(compute)h(the)f(numbe\ r)g(of)g(timer)75 1047 y(interrupts)8 b(required)i(to)g(induce)g(the)g(DOS)g (application)f(into)g(producing)g(the)h(right)f(sounds.)137 1139 y(The)j(Mach) g(V)m(irtual)e(Memory)i(system)f(was)h(very)f(successful)h(in)f(implementing) f(the)h(many)g(special)h(features)g(asso-)75 1188 y(ciated)g(with)g(DOS)g(mem\ ory)h(and)f(its)f(speci\256cations)i(for)e(memory)i(extension.)20 b(The)13 b (Emulator)f(was)h(able)f(to)g(map)h(two)75 1238 y(dif)n(ferent)e(address)g (ranges)f(to)g(the)g(same)i(piece)f(of)f(virtual)f(memory)i(by)f(using)f(an)i (external)f(pager)n(.)15 b(The)c(Mach)g(VM)f(was)75 1288 y(very)g(useful)g (for)g(implementing)f(the)h(expanded)g(and)h(extended)f(DOS)g(memory)h(speci\ \256cations.)75 1453 y fg(7.)50 b(Conclusions)75 1587 y ff(W)m(e)13 b(have)g (shown)f(that)g(it)g(is)g(possible)g(to)g(implement)g(DOS)h(as)g(a)g(Mach)g (3.0)g(application)e(by)h(using)g(a)h(combination)e(of)75 1637 y(kernel)i(and) g(user)h(level)f(support.)22 b(As)14 b(of)f(the)g(writing)e(of)i(this)f(paper) o(,)i(we)g(have)f(implemented)g(DOS)h(as)g(a)f(Mach)h(task)75 1687 y(that)g (uses)g(the)g(4.3)g(BSD)g(Unix)g(server)g(for)g(many)h(of)f(its)f(services.) 28 b(There)15 b(were)g(problems)f(in)f(this)g(implementation)75 1736 y(in)e (the)g(form)g(of)g(de\256ciencies)i(in)e(the)g(Mach)h(Kernel')m(s)g(machine)g (dependent)f(code)h(for)f(the)g(386)g(processor)g(which)g(were)75 1786 y(over\ come)f(as)g(described)f(above.)15 b(Over)10 b(100)e(DOS)i(programs)f(have)h (been)f(effectively)f(run)h(on)g(the)g(Mach)h(DOS)f(support,)75 1836 y(many)i (of)f(which)g(demand)h(very)f(close)h(integration)d(with)i(the)g(machine)h (hardware.)16 b(In)10 b(the)h(future,)f(work)f(will)h(center)g(on)75 1886 y (severing)g(the)g(Unix)g(dependencies)h(and)f(expanding)f(the)h(functionality) e(of)i(the)g(DOS)g(Emulator)g(even)h(further)m(.)p eop %%Trailer end %%EOF